262 lines
5.2 KiB
C++
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__
|