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 );
BroadcastReception = new EzSockets;
BroadcastReception->create( IPPROTO_UDP );
BroadcastReception->create( EZS_UDP );
BroadcastReception->bind( 8765 );
BroadcastReception->blocking = false;
}
@@ -537,7 +537,7 @@ void NetworkSyncManager::Update(float fDeltaTime)
ThisServer.Name = BroadIn.ReadNT();
int port = BroadIn.Read2();
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",
(addy<<0)>>24, (addy<<8)>>24, (addy<<16)>>24, (addy<<24)>>24, port );
@@ -867,7 +867,7 @@ uint16_t PacketFunctions::Read2()
uint16_t Temp;
memcpy( &Temp, Data + Position,2 );
Position+=2;
return ntohs(Temp);
return EzSockets::ntohs(Temp);
}
uint32_t PacketFunctions::Read4()
@@ -878,7 +878,7 @@ uint32_t PacketFunctions::Read4()
uint32_t Temp;
memcpy( &Temp, Data + Position,4 );
Position+=4;
return ntohl(Temp);
return EzSockets::ntohl(Temp);
}
RString PacketFunctions::ReadNT()
@@ -905,7 +905,7 @@ void PacketFunctions::Write2(uint16_t data)
{
if (Position>=NETMAXBUFFERSIZE-1)
return;
data = htons(data);
data = EzSockets::htons(data);
memcpy( &Data[Position], &data, 2 );
Position+=2;
}
@@ -915,7 +915,7 @@ void PacketFunctions::Write4(uint32_t data)
if (Position>=NETMAXBUFFERSIZE-3)
return ;
data = htonl(data);
data = EzSockets::htonl(data);
memcpy( &Data[Position], &data, 4 );
Position+=4;
}
+153 -55
View File
@@ -22,6 +22,12 @@
#include <netdb.h>
#endif
#if defined(_WINDOWS)
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
#if !defined(SOCKET_ERROR)
#define SOCKET_ERROR -1
#endif
@@ -44,62 +50,131 @@ inline timeval timevalFromMs(unsigned int ms)
return tv;
}
namespace
{
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;
memset (&addr,0,sizeof(addr)); //Clear the sockaddr_in structure
#if defined(_WINDOWS) // Windows REQUIRES WinSock Startup
WSAStartup( MAKEWORD(1,1), &wsda );
#endif
scks = new fd_set;
times = new timeval;
}
~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()
{
MAXCON = 5;
memset (&addr,0,sizeof(addr)); //Clear the sockaddr_in structure
ezs_internal *data = new ezs_internal();
this->opaque = (void*)data;
#if defined(_WINDOWS) // Windows REQUIRES WinSock Startup
WSAStartup( MAKEWORD(1,1), &wsda );
#endif
sock = INVALID_SOCKET;
blocking = true;
scks = new fd_set;
times = new timeval;
times->tv_sec = 0;
times->tv_usec = 0;
data->sock = INVALID_SOCKET;
data->times->tv_sec = 0;
data->times->tv_usec = 0;
state = skDISCONNECTED;
}
EzSockets::~EzSockets()
{
close();
delete scks;
delete times;
ezs_internal *data = (ezs_internal*)(this->opaque);
delete data;
}
//Check to see if the socket has been created
bool EzSockets::check()
{
return sock > SOCKET_NONE;
ezs_internal *data = (ezs_internal*)(this->opaque);
return data->sock > SOCKET_NONE;
}
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)
{
case IPPROTO_TCP:
return create(IPPROTO_TCP, SOCK_STREAM);
case IPPROTO_UDP:
return create(IPPROTO_UDP, SOCK_DGRAM);
case EZS_TCP:
return create(EZS_TCP, SOCK_STREAM);
case EZS_UDP:
return create(EZS_UDP, SOCK_DGRAM);
default:
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;
sock = socket(AF_INET, Type, Protocol);
lastCode = sock;
return sock > SOCKET_NONE; // Socket must be Greater than 0
int realproto = 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)
@@ -107,16 +182,18 @@ bool EzSockets::bind(unsigned short port)
if(!check())
return false;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
lastCode = ::bind(sock,(struct sockaddr*)&addr, sizeof(addr));
ezs_internal *data = (ezs_internal*)(this->opaque);
data->addr.sin_family = AF_INET;
data->addr.sin_addr.s_addr = htonl(INADDR_ANY);
data->addr.sin_port = htons(port);
lastCode = ::bind(data->sock,(struct sockaddr*)&data->addr, sizeof(data->addr));
return !lastCode;
}
bool EzSockets::listen()
{
lastCode = ::listen(sock, MAXCON);
ezs_internal *data = (ezs_internal*)(this->opaque);
lastCode = ::listen(data->sock, data->MAXCON);
if (lastCode == SOCKET_ERROR)
return false;
@@ -145,12 +222,14 @@ bool EzSockets::accept(EzSockets& 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);
lastCode = socket.sock;
lastCode = sdata->sock;
if ( socket.sock == SOCKET_ERROR )
if ( sdata->sock == SOCKET_ERROR )
return false;
socket.state = skCONNECTED;
@@ -163,35 +242,44 @@ void EzSockets::close()
inBuffer = "";
outBuffer = "";
ezs_internal *data = (ezs_internal*)(this->opaque);
#if defined(WIN32) // The close socket command is different in Windows
::closesocket(sock);
::closesocket(data->sock);
#else
::close(sock);
::close(data->sock);
#endif
}
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)
{
if(!check())
if (!check())
{
return false;
}
struct hostent* phe;
phe = gethostbyname(host.c_str());
if (phe == NULL)
{
return false;
memcpy(&addr.sin_addr, phe->h_addr, sizeof(struct in_addr));
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
ezs_internal *data = (ezs_internal*)(this->opaque);
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;
}
state = skCONNECTED;
return true;
@@ -208,13 +296,15 @@ inline bool checkCanRead(int sock, timeval& timeout)
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)
{
ezs_internal *data = (ezs_internal*)(this->opaque);
timeval tv = timevalFromMs(msTimeout);
return checkCanRead(sock, tv);
return checkCanRead(data->sock, tv);
}
bool EzSockets::IsError()
@@ -222,10 +312,11 @@ bool EzSockets::IsError()
if (state == skERROR)
return true;
FD_ZERO(scks);
FD_SET((unsigned)sock, scks);
ezs_internal *data = (ezs_internal*)(this->opaque);
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;
state = skERROR;
@@ -243,13 +334,15 @@ inline bool checkCanWrite(int sock, timeval& timeout)
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)
{
ezs_internal *data = (ezs_internal*)(this->opaque);
timeval tv = timevalFromMs(msTimeout);
return checkCanWrite(sock, tv);
return checkCanWrite(data->sock, tv);
}
void EzSockets::update()
@@ -265,8 +358,11 @@ void EzSockets::update()
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)
return ntohl(s.sin_addr.S_un.S_addr);
#else
@@ -475,17 +571,19 @@ int EzSockets::pUpdateWrite()
int EzSockets::pReadData(char* data)
{
if(state == skCONNECTED || state == skLISTENING)
return recv(sock, data, 1024, 0);
ezs_internal *sdata = (ezs_internal*)(this->opaque);
if (state == skCONNECTED || state == skLISTENING)
return recv(sdata->sock, data, 1024, 0);
fromAddr_len = sizeof(sockaddr_in);
return recvfrom(sock, data, 1024, 0, (sockaddr*)&fromAddr,
(socklen_t*)&fromAddr_len);
sdata->fromAddr_len = sizeof(sockaddr_in);
return recvfrom(sdata->sock, data, 1024, 0, (sockaddr*)&sdata->fromAddr,
(socklen_t*)&sdata->fromAddr_len);
}
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
#include <ctype.h>
#if defined(_WINDOWS)
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
using namespace std;
enum EzSockets_Proto
{
EZS_NONE,
EZS_TCP,
EZS_UDP
};
class EzSockets
{
public:
@@ -38,8 +39,8 @@ public:
//Crate the socket
bool create();
bool create(int Protocol);
bool create(int Protocol, int Type);
bool create(EzSockets_Proto Protocol);
bool create(EzSockets_Proto Protocol, int Type);
//Bind Socket to local port
bool bind(unsigned short port);
@@ -107,9 +108,7 @@ public:
skERROR
};
struct sockaddr_in fromAddr;
unsigned long fromAddr_len;
static unsigned long LongFromAddrIn( const sockaddr_in & s );
uint32_t getAddress();
// The following possibly should be private.
string inBuffer;
@@ -127,23 +126,15 @@ public:
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:
// Only necessary for Windows
#if defined(_WINDOWS)
WSADATA wsda;
#endif
int MAXCON;
int sock;
struct sockaddr_in addr;
// Used for Select() command
fd_set *scks;
timeval *times;
// Buffers
void *opaque;
};
istream& operator>>(istream& is, EzSockets& obj);