historical/toontown-classic.git/panda/include/socket_ip.h
2024-01-16 11:20:27 -06:00

262 lines
5.2 KiB
C++

#ifndef __SOCKET_IP_H__
#define __SOCKET_IP_H__
#include "pandabase.h"
#include "socket_portable.h"
#include "socket_address.h"
#include "typedObject.h"
#include "config_downloader.h"
// forward declarations for friends...
class Socket_TCP;
class Socket_UDP;
class Socket_TCP_Listen;
class Socket_UDP_Incoming;
class Socket_UDP_Outgoing;
/**
* Base functionality for a INET domain Socket This call should be the
* starting point for all other unix domain sockets.
*
* SocketIP |
* ------------------------------------------------------------------- |
* | | | SocketTCP
* SocketTCP_Listen SocketUDP_Incoming SocketUDP_OutBound
*
*/
class EXPCL_PANDA_NATIVENET Socket_IP : public TypedObject {
public:
PUBLISHED:
inline Socket_IP();
inline Socket_IP(SOCKET in);
virtual ~Socket_IP();
inline void Close();
inline static int GetLastError();
inline int SetNonBlocking();
inline int SetBlocking();
inline bool SetReuseAddress(bool flag = true);
inline bool SetV6Only(bool flag);
inline bool Active();
inline int SetRecvBufferSize(int size);
inline void SetSocket(SOCKET ins);
inline SOCKET GetSocket();
inline SOCKET GetSocket() const;
inline Socket_Address GetPeerName(void) const;
inline static int InitNetworkDriver() { return init_network(); };
private:
inline bool ErrorClose();
SOCKET _socket; // see socket_portable.h
friend class Socket_TCP;
friend class Socket_UDP;
friend class Socket_TCP_Listen;
friend class Socket_UDP_Incoming;
friend class Socket_UDP_Outgoing;
friend class Socket_TCP_SSL;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, "Socket_IP",
TypedObject::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
/**
* Used by internal to force a close. Returns false.
*/
inline bool Socket_IP::
ErrorClose() {
if (Active()) {
DO_CLOSE(_socket);
}
_socket = BAD_SOCKET;
return false;
}
/**
* Ask if the socket is open (allocated)
*/
inline bool Socket_IP::
Active() {
return (_socket != BAD_SOCKET);
}
/**
* Def Constructor
*/
inline Socket_IP::
Socket_IP() {
_socket = BAD_SOCKET;
}
/**
* Assigns an existing socket to this class
*/
inline Socket_IP::
Socket_IP(SOCKET ins) {
_socket = ins;
}
/**
* Destructor
*/
inline Socket_IP::
~Socket_IP() {
Close();
}
/**
* Closes a socket if it is open (allocated).
*/
inline void Socket_IP::
Close() {
if (Active()) {
DO_CLOSE(_socket);
}
_socket = BAD_SOCKET;
}
/**
* Gets the last errcode from a socket operation.
*/
inline int Socket_IP::
GetLastError() {
return GETERROR();
}
/**
* Assigns an existing socket to this class
*/
inline void Socket_IP::
SetSocket(SOCKET ins) {
Close();
_socket = ins;
}
/**
* Ok it sets the recv buffer size for both tcp and UDP
*/
int Socket_IP::
SetRecvBufferSize(int insize) {
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_RCVBUF, (char *) &insize, sizeof(int))) {
return BASIC_ERROR;
}
return ALL_OK;
}
/**
* this function will throw a socket into non-blocking mode
*/
inline int Socket_IP::
SetNonBlocking() {
#ifdef BSDBLOCK
int flags = fcntl(_socket, F_GETFL, 0);
flags = flags | O_NONBLOCK;
fcntl(_socket, F_SETFL, flags);
return ALL_OK;
#else
unsigned long val = LOCAL_NONBLOCK;
unsigned lanswer = 0;
lanswer = SOCKIOCTL(_socket, LOCAL_FL_SET, &val);
if (lanswer != 0) {
return BASIC_ERROR;
}
return ALL_OK;
#endif
}
/**
* Set the socket to block on subsequent calls to socket functions that
* address this socket
*/
inline int Socket_IP::
SetBlocking() {
#ifdef BSDBLOCK
int flags = fcntl(_socket, F_GETFL, 0);
flags &= ~O_NONBLOCK;
fcntl(_socket, F_SETFL, flags);
return ALL_OK;
#else
unsigned long val = 0;
unsigned lanswer = 0;
lanswer = SOCKIOCTL(_socket, LOCAL_FL_SET, &val);
if (lanswer != 0) {
return BASIC_ERROR;
}
return ALL_OK;
#endif
}
/**
* Informs a socket to reuse IP address as needed
*/
inline bool Socket_IP::
SetReuseAddress(bool flag) {
int value = flag;
if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&value, sizeof(value)) != 0) {
return false;
}
return true;
}
/**
* Sets a flag indicating whether this IPv6 socket should operate in
* dual-stack mode or not.
*/
inline bool Socket_IP::
SetV6Only(bool flag) {
int value = flag ? 1 : 0;
if (setsockopt(_socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&value, sizeof(value))) {
return false;
}
return true;
}
/**
* Gets the base socket type
*/
inline SOCKET Socket_IP::
GetSocket() {
return _socket;
}
/**
* Get The RAW file id of the socket
*/
inline SOCKET Socket_IP::
GetSocket() const {
return _socket;
}
/**
* Wrapper on berkly getpeername...
*/
inline Socket_Address Socket_IP::
GetPeerName(void) const {
sockaddr_storage name;
socklen_t name_len = sizeof(name);
memset(&name, 0, name_len);
getpeername(_socket, (sockaddr *)&name, &name_len);
return Socket_Address(name);
}
#endif //__SOCKET_IP_H__