EzSockets: Don't leak WinAPI everywhere this gets included. Fixes #1455

This commit is contained in:
Colby Klein
2017-05-24 01:23:22 -07:00
parent 631523ace3
commit 41b602c90f
3 changed files with 176 additions and 87 deletions
+6 -6
View File
@@ -212,7 +212,7 @@ void NetworkSyncManager::StartUp()
PostStartUp( ServerIP ); PostStartUp( ServerIP );
BroadcastReception = new EzSockets; BroadcastReception = new EzSockets;
BroadcastReception->create( IPPROTO_UDP ); BroadcastReception->create( EZS_UDP );
BroadcastReception->bind( 8765 ); BroadcastReception->bind( 8765 );
BroadcastReception->blocking = false; BroadcastReception->blocking = false;
} }
@@ -537,7 +537,7 @@ void NetworkSyncManager::Update(float fDeltaTime)
ThisServer.Name = BroadIn.ReadNT(); ThisServer.Name = BroadIn.ReadNT();
int port = BroadIn.Read2(); int port = BroadIn.Read2();
BroadIn.Read2(); //Num players connected. BroadIn.Read2(); //Num players connected.
uint32_t addy = EzSockets::LongFromAddrIn(BroadcastReception->fromAddr); uint32_t addy = BroadcastReception->getAddress();
ThisServer.Address = ssprintf( "%u.%u.%u.%u:%d", ThisServer.Address = ssprintf( "%u.%u.%u.%u:%d",
(addy<<0)>>24, (addy<<8)>>24, (addy<<16)>>24, (addy<<24)>>24, port ); (addy<<0)>>24, (addy<<8)>>24, (addy<<16)>>24, (addy<<24)>>24, port );
@@ -867,7 +867,7 @@ uint16_t PacketFunctions::Read2()
uint16_t Temp; uint16_t Temp;
memcpy( &Temp, Data + Position,2 ); memcpy( &Temp, Data + Position,2 );
Position+=2; Position+=2;
return ntohs(Temp); return EzSockets::ntohs(Temp);
} }
uint32_t PacketFunctions::Read4() uint32_t PacketFunctions::Read4()
@@ -878,7 +878,7 @@ uint32_t PacketFunctions::Read4()
uint32_t Temp; uint32_t Temp;
memcpy( &Temp, Data + Position,4 ); memcpy( &Temp, Data + Position,4 );
Position+=4; Position+=4;
return ntohl(Temp); return EzSockets::ntohl(Temp);
} }
RString PacketFunctions::ReadNT() RString PacketFunctions::ReadNT()
@@ -905,7 +905,7 @@ void PacketFunctions::Write2(uint16_t data)
{ {
if (Position>=NETMAXBUFFERSIZE-1) if (Position>=NETMAXBUFFERSIZE-1)
return; return;
data = htons(data); data = EzSockets::htons(data);
memcpy( &Data[Position], &data, 2 ); memcpy( &Data[Position], &data, 2 );
Position+=2; Position+=2;
} }
@@ -915,7 +915,7 @@ void PacketFunctions::Write4(uint32_t data)
if (Position>=NETMAXBUFFERSIZE-3) if (Position>=NETMAXBUFFERSIZE-3)
return ; return ;
data = htonl(data); data = EzSockets::htonl(data);
memcpy( &Data[Position], &data, 4 ); memcpy( &Data[Position], &data, 4 );
Position+=4; Position+=4;
} }
+148 -50
View File
@@ -22,6 +22,12 @@
#include <netdb.h> #include <netdb.h>
#endif #endif
#if defined(_WINDOWS)
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
#if !defined(SOCKET_ERROR) #if !defined(SOCKET_ERROR)
#define SOCKET_ERROR -1 #define SOCKET_ERROR -1
#endif #endif
@@ -44,9 +50,28 @@ inline timeval timevalFromMs(unsigned int ms)
return tv; return tv;
} }
namespace
EzSockets::EzSockets()
{ {
struct ezs_internal
{
// Only necessary for Windows
#if defined(_WINDOWS)
WSADATA wsda;
#endif
int MAXCON;
int sock;
struct sockaddr_in addr;
struct sockaddr_in fromAddr;
unsigned long fromAddr_len;
// Used for Select() command
fd_set *scks;
timeval *times;
ezs_internal()
{
MAXCON = 5; MAXCON = 5;
memset (&addr,0,sizeof(addr)); //Clear the sockaddr_in structure memset (&addr,0,sizeof(addr)); //Clear the sockaddr_in structure
@@ -54,52 +79,102 @@ EzSockets::EzSockets()
WSAStartup( MAKEWORD(1,1), &wsda ); WSAStartup( MAKEWORD(1,1), &wsda );
#endif #endif
sock = INVALID_SOCKET;
blocking = true;
scks = new fd_set; scks = new fd_set;
times = new timeval; times = new timeval;
times->tv_sec = 0; }
times->tv_usec = 0; ~ezs_internal()
{
delete scks;
delete times;
}
};
}
uint32_t EzSockets::ntohl(uint32_t in)
{
return ::ntohl(in);
}
uint16_t EzSockets::ntohs(uint16_t in)
{
return ::ntohs(in);
}
uint32_t EzSockets::htonl(uint32_t in)
{
return ::htonl(in);
}
uint16_t EzSockets::htons(uint16_t in) {
return ::htons(in);
}
EzSockets::EzSockets()
{
ezs_internal *data = new ezs_internal();
this->opaque = (void*)data;
blocking = true;
data->sock = INVALID_SOCKET;
data->times->tv_sec = 0;
data->times->tv_usec = 0;
state = skDISCONNECTED; state = skDISCONNECTED;
} }
EzSockets::~EzSockets() EzSockets::~EzSockets()
{ {
close(); close();
delete scks;
delete times; ezs_internal *data = (ezs_internal*)(this->opaque);
delete data;
} }
//Check to see if the socket has been created //Check to see if the socket has been created
bool EzSockets::check() bool EzSockets::check()
{ {
return sock > SOCKET_NONE; ezs_internal *data = (ezs_internal*)(this->opaque);
return data->sock > SOCKET_NONE;
} }
bool EzSockets::create() bool EzSockets::create()
{ {
return create(IPPROTO_TCP, SOCK_STREAM); return create(EZS_TCP, SOCK_STREAM);
} }
bool EzSockets::create(int Protocol) bool EzSockets::create(EzSockets_Proto Protocol)
{ {
switch(Protocol) switch(Protocol)
{ {
case IPPROTO_TCP: case EZS_TCP:
return create(IPPROTO_TCP, SOCK_STREAM); return create(EZS_TCP, SOCK_STREAM);
case IPPROTO_UDP: case EZS_UDP:
return create(IPPROTO_UDP, SOCK_DGRAM); return create(EZS_UDP, SOCK_DGRAM);
default: default:
return create(Protocol, SOCK_RAW); return create(Protocol, SOCK_RAW);
} }
} }
bool EzSockets::create(int Protocol, int Type) bool EzSockets::create(EzSockets_Proto Protocol, int Type)
{ {
ezs_internal *data = (ezs_internal*)(this->opaque);
state = skDISCONNECTED; state = skDISCONNECTED;
sock = socket(AF_INET, Type, Protocol);
lastCode = sock; int realproto = 0;
return sock > SOCKET_NONE; // Socket must be Greater than 0 switch (Protocol) {
case EZS_TCP:
realproto = IPPROTO_TCP;
break;
case EZS_UDP:
realproto = IPPROTO_UDP;
break;
case EZS_NONE:
realproto = IPPROTO_IP;
break;
}
data->sock = socket(AF_INET, Type, realproto);
lastCode = data->sock;
return data->sock > SOCKET_NONE; // Socket must be Greater than 0
} }
bool EzSockets::bind(unsigned short port) bool EzSockets::bind(unsigned short port)
@@ -107,16 +182,18 @@ bool EzSockets::bind(unsigned short port)
if(!check()) if(!check())
return false; return false;
addr.sin_family = AF_INET; ezs_internal *data = (ezs_internal*)(this->opaque);
addr.sin_addr.s_addr = htonl(INADDR_ANY); data->addr.sin_family = AF_INET;
addr.sin_port = htons(port); data->addr.sin_addr.s_addr = htonl(INADDR_ANY);
lastCode = ::bind(sock,(struct sockaddr*)&addr, sizeof(addr)); data->addr.sin_port = htons(port);
lastCode = ::bind(data->sock,(struct sockaddr*)&data->addr, sizeof(data->addr));
return !lastCode; return !lastCode;
} }
bool EzSockets::listen() bool EzSockets::listen()
{ {
lastCode = ::listen(sock, MAXCON); ezs_internal *data = (ezs_internal*)(this->opaque);
lastCode = ::listen(data->sock, data->MAXCON);
if (lastCode == SOCKET_ERROR) if (lastCode == SOCKET_ERROR)
return false; return false;
@@ -145,12 +222,14 @@ bool EzSockets::accept(EzSockets& socket)
int length = sizeof(socket); int length = sizeof(socket);
socket.sock = ::accept(sock,(struct sockaddr*) &socket.addr, ezs_internal *data = (ezs_internal*)(this->opaque);
ezs_internal *sdata = (ezs_internal*)(socket.opaque);
sdata->sock = ::accept(data->sock,(struct sockaddr*) &sdata->addr,
(socklen_t*) &length); (socklen_t*) &length);
lastCode = socket.sock; lastCode = sdata->sock;
if ( socket.sock == SOCKET_ERROR ) if ( sdata->sock == SOCKET_ERROR )
return false; return false;
socket.state = skCONNECTED; socket.state = skCONNECTED;
@@ -163,35 +242,44 @@ void EzSockets::close()
inBuffer = ""; inBuffer = "";
outBuffer = ""; outBuffer = "";
ezs_internal *data = (ezs_internal*)(this->opaque);
#if defined(WIN32) // The close socket command is different in Windows #if defined(WIN32) // The close socket command is different in Windows
::closesocket(sock); ::closesocket(data->sock);
#else #else
::close(sock); ::close(data->sock);
#endif #endif
} }
long EzSockets::uAddr() long EzSockets::uAddr()
{ {
return addr.sin_addr.s_addr; ezs_internal *data = (ezs_internal*)(this->opaque);
return data->addr.sin_addr.s_addr;
} }
bool EzSockets::connect(const std::string& host, unsigned short port) bool EzSockets::connect(const std::string& host, unsigned short port)
{ {
if(!check()) if (!check())
{
return false; return false;
}
struct hostent* phe; struct hostent* phe;
phe = gethostbyname(host.c_str()); phe = gethostbyname(host.c_str());
if (phe == NULL) if (phe == NULL)
{
return false; return false;
memcpy(&addr.sin_addr, phe->h_addr, sizeof(struct in_addr)); }
addr.sin_family = AF_INET; ezs_internal *data = (ezs_internal*)(this->opaque);
addr.sin_port = htons(port); memcpy(&data->addr.sin_addr, phe->h_addr, sizeof(struct in_addr));
if(::connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) data->addr.sin_family = AF_INET;
data->addr.sin_port = htons(port);
if(::connect(data->sock, (struct sockaddr*)&data->addr, sizeof(data->addr)) == SOCKET_ERROR)
{
return false; return false;
}
state = skCONNECTED; state = skCONNECTED;
return true; return true;
@@ -208,13 +296,15 @@ inline bool checkCanRead(int sock, timeval& timeout)
bool EzSockets::CanRead() bool EzSockets::CanRead()
{ {
return checkCanRead(sock, *times); ezs_internal *data = (ezs_internal*)(this->opaque);
return checkCanRead(data->sock, *data->times);
} }
bool EzSockets::CanRead(unsigned int msTimeout) bool EzSockets::CanRead(unsigned int msTimeout)
{ {
ezs_internal *data = (ezs_internal*)(this->opaque);
timeval tv = timevalFromMs(msTimeout); timeval tv = timevalFromMs(msTimeout);
return checkCanRead(sock, tv); return checkCanRead(data->sock, tv);
} }
bool EzSockets::IsError() bool EzSockets::IsError()
@@ -222,10 +312,11 @@ bool EzSockets::IsError()
if (state == skERROR) if (state == skERROR)
return true; return true;
FD_ZERO(scks); ezs_internal *data = (ezs_internal*)(this->opaque);
FD_SET((unsigned)sock, scks); FD_ZERO(data->scks);
FD_SET((unsigned)data->sock, data->scks);
if (select(sock+1, NULL, NULL, scks, times) >=0 ) if (select(data->sock+1, NULL, NULL, data->scks, data->times) >=0 )
return false; return false;
state = skERROR; state = skERROR;
@@ -243,13 +334,15 @@ inline bool checkCanWrite(int sock, timeval& timeout)
bool EzSockets::CanWrite() bool EzSockets::CanWrite()
{ {
return checkCanWrite(sock, *times); ezs_internal *data = (ezs_internal*)(this->opaque);
return checkCanWrite(data->sock, *data->times);
} }
bool EzSockets::CanWrite(unsigned int msTimeout) bool EzSockets::CanWrite(unsigned int msTimeout)
{ {
ezs_internal *data = (ezs_internal*)(this->opaque);
timeval tv = timevalFromMs(msTimeout); timeval tv = timevalFromMs(msTimeout);
return checkCanWrite(sock, tv); return checkCanWrite(data->sock, tv);
} }
void EzSockets::update() void EzSockets::update()
@@ -265,8 +358,11 @@ void EzSockets::update()
pUpdateWrite(); pUpdateWrite();
} }
unsigned long EzSockets::LongFromAddrIn( const sockaddr_in & s ) uint32_t EzSockets::getAddress()
{ {
ezs_internal *data = (ezs_internal*)(this->opaque);
sockaddr_in &s = data->fromAddr;
#if defined(_WINDOWS) #if defined(_WINDOWS)
return ntohl(s.sin_addr.S_un.S_addr); return ntohl(s.sin_addr.S_un.S_addr);
#else #else
@@ -475,17 +571,19 @@ int EzSockets::pUpdateWrite()
int EzSockets::pReadData(char* data) int EzSockets::pReadData(char* data)
{ {
if(state == skCONNECTED || state == skLISTENING) ezs_internal *sdata = (ezs_internal*)(this->opaque);
return recv(sock, data, 1024, 0); if (state == skCONNECTED || state == skLISTENING)
return recv(sdata->sock, data, 1024, 0);
fromAddr_len = sizeof(sockaddr_in); sdata->fromAddr_len = sizeof(sockaddr_in);
return recvfrom(sock, data, 1024, 0, (sockaddr*)&fromAddr, return recvfrom(sdata->sock, data, 1024, 0, (sockaddr*)&sdata->fromAddr,
(socklen_t*)&fromAddr_len); (socklen_t*)&sdata->fromAddr_len);
} }
int EzSockets::pWriteData(const char* data, int dataSize) int EzSockets::pWriteData(const char* data, int dataSize)
{ {
return send(sock, data, dataSize, 0); ezs_internal *sdata = (ezs_internal*)(this->opaque);
return send(sdata->sock, data, dataSize, 0);
} }
/* /*
+17 -26
View File
@@ -21,14 +21,15 @@
#endif #endif
#include <ctype.h> #include <ctype.h>
#if defined(_WINDOWS)
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
using namespace std; using namespace std;
enum EzSockets_Proto
{
EZS_NONE,
EZS_TCP,
EZS_UDP
};
class EzSockets class EzSockets
{ {
public: public:
@@ -38,8 +39,8 @@ public:
//Crate the socket //Crate the socket
bool create(); bool create();
bool create(int Protocol); bool create(EzSockets_Proto Protocol);
bool create(int Protocol, int Type); bool create(EzSockets_Proto Protocol, int Type);
//Bind Socket to local port //Bind Socket to local port
bool bind(unsigned short port); bool bind(unsigned short port);
@@ -107,9 +108,7 @@ public:
skERROR skERROR
}; };
struct sockaddr_in fromAddr; uint32_t getAddress();
unsigned long fromAddr_len;
static unsigned long LongFromAddrIn( const sockaddr_in & s );
// The following possibly should be private. // The following possibly should be private.
string inBuffer; string inBuffer;
@@ -127,23 +126,15 @@ public:
RString address; RString address;
// Wrapped here so we don't have to leak winapi everywhere...
static uint32_t ntohl(uint32_t);
static uint16_t ntohs(uint16_t);
static uint32_t htonl(uint32_t);
static uint16_t htons(uint16_t);
private: private:
// Only necessary for Windows void *opaque;
#if defined(_WINDOWS)
WSADATA wsda;
#endif
int MAXCON;
int sock;
struct sockaddr_in addr;
// Used for Select() command
fd_set *scks;
timeval *times;
// Buffers
}; };
istream& operator>>(istream& is, EzSockets& obj); istream& operator>>(istream& is, EzSockets& obj);