2010-03-16 22:37:11 +01:00
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code and/or modify it under
//the terms of the GNU General Public License as published by the Free Software
//Foundation; either version 2 of the License, or (at your option) any later
//version.
# include "socket.h"
# include <cstring>
# include <cstdio>
# include <cstdlib>
# include <stdexcept>
2010-04-13 08:59:30 +02:00
2010-12-07 08:00:11 +01:00
# if defined(HAVE_SYS_IOCTL_H) || defined(__linux__)
2010-04-13 08:59:30 +02:00
# define BSD_COMP /* needed for FIONREAD on Solaris2 */
# include <sys/ioctl.h>
2010-03-16 22:37:11 +01:00
# endif
2011-01-11 04:56:38 +01:00
# if defined(HAVE_SYS_FILIO_H) /* needed for FIONREAD on Solaris 2.5 */
2010-04-13 08:59:30 +02:00
# include <sys/filio.h>
2010-03-16 22:37:11 +01:00
# endif
# include "conversion.h"
2010-03-20 00:26:00 +01:00
# include "util.h"
2010-04-01 08:31:10 +02:00
# include "platform_util.h"
2010-04-03 04:21:04 +02:00
# include <algorithm>
2010-03-16 22:37:11 +01:00
2010-04-11 09:13:14 +02:00
# ifdef WIN32
2010-04-13 08:59:30 +02:00
# include <windows.h>
# include <winsock.h>
# include <iphlpapi.h>
2010-04-13 09:29:48 +02:00
# include <strstream>
2010-04-13 08:59:30 +02:00
2010-08-07 08:28:00 +02:00
# define MSG_NOSIGNAL 0
2011-01-11 04:56:38 +01:00
# define MSG_DONTWAIT 0
2010-08-07 08:28:00 +02:00
2010-04-11 09:13:14 +02:00
# else
2010-04-13 08:59:30 +02:00
# include <unistd.h>
# include <stdlib.h>
# include <sys/socket.h>
# include <netdb.h>
# include <netinet/in.h>
2010-04-13 09:29:48 +02:00
# include <net/if.h>
2010-04-13 08:59:30 +02:00
2010-04-11 09:13:14 +02:00
# endif
# include <string.h>
# include <sys/stat.h>
2010-04-13 08:59:30 +02:00
# include <time.h>
2010-12-21 06:07:10 +01:00
# include "miniwget.h"
# include "miniupnpc.h"
# include "upnpcommands.h"
2010-04-13 08:59:30 +02:00
# include "leak_dumper.h"
2010-04-11 09:13:14 +02:00
2010-03-16 22:37:11 +01:00
using namespace std ;
using namespace Shared : : Util ;
namespace Shared { namespace Platform {
2010-12-29 21:28:25 +01:00
int Socket : : broadcast_portno = 61357 ;
int ServerSocket : : ftpServerPort = 61358 ;
2011-01-06 01:52:00 +01:00
int ServerSocket : : maxPlayerCount = - 1 ;
2010-12-31 09:21:26 +01:00
int ServerSocket : : externalPort = Socket : : broadcast_portno ;
2010-12-21 06:07:10 +01:00
BroadCastClientSocketThread * ClientSocket : : broadCastClientThread = NULL ;
//
// UPnP - Start
//
static struct UPNPUrls urls ;
static struct IGDdatas data ;
// local ip address
2010-12-31 09:21:26 +01:00
static char lanaddr [ 16 ] = " " ;
bool UPNP_Tools : : isUPNP = true ;
bool UPNP_Tools : : enabledUPNP = false ;
2010-12-21 06:07:10 +01:00
// UPnP - End
2010-04-13 08:59:30 +02:00
# ifdef WIN32
# define socklen_t int
# define MAXHOSTNAME 254
# define PLATFORM_SOCKET_TRY_AGAIN WSAEWOULDBLOCK
# define PLATFORM_SOCKET_INPROGRESS WSAEINPROGRESS
# define PLATFORM_SOCKET_INTERRUPTED WSAEWOULDBLOCK
typedef SSIZE_T ssize_t ;
//// Constants /////////////////////////////////////////////////////////
const int kBufferSize = 1024 ;
//// Statics ///////////////////////////////////////////////////////////
// List of Winsock error constants mapped to an interpretation string.
// Note that this list must remain sorted by the error constants'
// values, because we do a binary search on the list when looking up
// items.
static class ErrorEntry
{
public :
int nID ;
const char * pcMessage ;
ErrorEntry ( int id , const char * pc = 0 ) : nID ( id ) , pcMessage ( pc )
{
}
bool operator < ( const ErrorEntry & rhs )
{
return nID < rhs . nID ;
}
} gaErrorList [ ] =
{
ErrorEntry ( 0 , " No error " ) ,
ErrorEntry ( WSAEINTR , " Interrupted system call " ) ,
ErrorEntry ( WSAEBADF , " Bad file number " ) ,
ErrorEntry ( WSAEACCES , " Permission denied " ) ,
ErrorEntry ( WSAEFAULT , " Bad address " ) ,
ErrorEntry ( WSAEINVAL , " Invalid argument " ) ,
ErrorEntry ( WSAEMFILE , " Too many open sockets " ) ,
ErrorEntry ( WSAEWOULDBLOCK , " Operation would block " ) ,
ErrorEntry ( WSAEINPROGRESS , " Operation now in progress " ) ,
ErrorEntry ( WSAEALREADY , " Operation already in progress " ) ,
ErrorEntry ( WSAENOTSOCK , " Socket operation on non-socket " ) ,
ErrorEntry ( WSAEDESTADDRREQ , " Destination address required " ) ,
ErrorEntry ( WSAEMSGSIZE , " Message too long " ) ,
ErrorEntry ( WSAEPROTOTYPE , " Protocol wrong type for socket " ) ,
ErrorEntry ( WSAENOPROTOOPT , " Bad protocol option " ) ,
ErrorEntry ( WSAEPROTONOSUPPORT , " Protocol not supported " ) ,
ErrorEntry ( WSAESOCKTNOSUPPORT , " Socket type not supported " ) ,
ErrorEntry ( WSAEOPNOTSUPP , " Operation not supported on socket " ) ,
ErrorEntry ( WSAEPFNOSUPPORT , " Protocol family not supported " ) ,
ErrorEntry ( WSAEAFNOSUPPORT , " Address family not supported " ) ,
ErrorEntry ( WSAEADDRINUSE , " Address already in use " ) ,
ErrorEntry ( WSAEADDRNOTAVAIL , " Can't assign requested address " ) ,
ErrorEntry ( WSAENETDOWN , " Network is down " ) ,
ErrorEntry ( WSAENETUNREACH , " Network is unreachable " ) ,
ErrorEntry ( WSAENETRESET , " Net connection reset " ) ,
ErrorEntry ( WSAECONNABORTED , " Software caused connection abort " ) ,
ErrorEntry ( WSAECONNRESET , " Connection reset by peer " ) ,
ErrorEntry ( WSAENOBUFS , " No buffer space available " ) ,
ErrorEntry ( WSAEISCONN , " Socket is already connected " ) ,
ErrorEntry ( WSAENOTCONN , " Socket is not connected " ) ,
ErrorEntry ( WSAESHUTDOWN , " Can't send after socket shutdown " ) ,
ErrorEntry ( WSAETOOMANYREFS , " Too many references, can't splice " ) ,
ErrorEntry ( WSAETIMEDOUT , " Connection timed out " ) ,
ErrorEntry ( WSAECONNREFUSED , " Connection refused " ) ,
ErrorEntry ( WSAELOOP , " Too many levels of symbolic links " ) ,
ErrorEntry ( WSAENAMETOOLONG , " File name too long " ) ,
ErrorEntry ( WSAEHOSTDOWN , " Host is down " ) ,
ErrorEntry ( WSAEHOSTUNREACH , " No route to host " ) ,
ErrorEntry ( WSAENOTEMPTY , " Directory not empty " ) ,
ErrorEntry ( WSAEPROCLIM , " Too many processes " ) ,
ErrorEntry ( WSAEUSERS , " Too many users " ) ,
ErrorEntry ( WSAEDQUOT , " Disc quota exceeded " ) ,
ErrorEntry ( WSAESTALE , " Stale NFS file handle " ) ,
ErrorEntry ( WSAEREMOTE , " Too many levels of remote in path " ) ,
ErrorEntry ( WSASYSNOTREADY , " Network system is unavailable " ) ,
ErrorEntry ( WSAVERNOTSUPPORTED , " Winsock version out of range " ) ,
ErrorEntry ( WSANOTINITIALISED , " WSAStartup not yet called " ) ,
ErrorEntry ( WSAEDISCON , " Graceful shutdown in progress " ) ,
ErrorEntry ( WSAHOST_NOT_FOUND , " Host not found " ) ,
ErrorEntry ( WSANO_DATA , " No host data of that type was found " )
} ;
bool operator < ( const ErrorEntry & rhs1 , const ErrorEntry & rhs2 )
{
return rhs1 . nID < rhs2 . nID ;
}
const int kNumMessages = sizeof ( gaErrorList ) / sizeof ( ErrorEntry ) ;
//// WSAGetLastErrorMessage ////////////////////////////////////////////
// A function similar in spirit to Unix's perror() that tacks a canned
// interpretation of the value of WSAGetLastError() onto the end of a
// passed string, separated by a ": ". Generally, you should implement
// smarter error handling than this, but for default cases and simple
// programs, this function is sufficient.
//
// This function returns a pointer to an internal static buffer, so you
// must copy the data from this function before you call it again. It
// follows that this function is also not thread-safe.
const char * WSAGetLastErrorMessage ( const char * pcMessagePrefix ,
2010-04-13 09:29:48 +02:00
int nErrorID = 0 )
2010-04-13 08:59:30 +02:00
{
// Build basic error string
static char acErrorBuffer [ 256 ] ;
std : : ostrstream outs ( acErrorBuffer , sizeof ( acErrorBuffer ) ) ;
outs < < pcMessagePrefix < < " : " ;
// Tack appropriate canned message onto end of supplied message
// prefix. Note that we do a binary search here: gaErrorList must be
// sorted by the error constant's value.
ErrorEntry * pEnd = gaErrorList + kNumMessages ;
ErrorEntry Target ( nErrorID ? nErrorID : WSAGetLastError ( ) ) ;
ErrorEntry * it = std : : lower_bound ( gaErrorList , pEnd , Target ) ;
if ( ( it ! = pEnd ) & & ( it - > nID = = Target . nID ) )
{
outs < < it - > pcMessage ;
}
else
{
// Didn't find error in list, so make up a generic one
outs < < " unknown error " ;
}
outs < < " ( " < < Target . nID < < " ) " ;
// Finish error message off and return it.
outs < < std : : ends ;
acErrorBuffer [ sizeof ( acErrorBuffer ) - 1 ] = ' \0 ' ;
return acErrorBuffer ;
}
2011-01-18 00:45:09 +01:00
// keeps in scope for duration of the application
SocketManager Socket : : wsaManager ;
2010-04-13 08:59:30 +02:00
2011-01-17 22:31:59 +01:00
SocketManager : : SocketManager ( ) {
2010-04-13 08:59:30 +02:00
WSADATA wsaData ;
WORD wVersionRequested = MAKEWORD ( 2 , 0 ) ;
2011-01-18 00:45:09 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " SocketManager calling WSAStartup... \n " ) ;
2010-04-13 08:59:30 +02:00
WSAStartup ( wVersionRequested , & wsaData ) ;
//dont throw exceptions here, this is a static initializacion
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Winsock initialized. \n " ) ;
2010-04-13 08:59:30 +02:00
}
2011-01-17 22:31:59 +01:00
SocketManager : : ~ SocketManager ( ) {
2011-01-18 00:45:09 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " SocketManager calling WSACleanup... \n " ) ;
2010-04-13 08:59:30 +02:00
WSACleanup ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Winsock cleanup complete. \n " ) ;
2010-04-13 08:59:30 +02:00
}
# else
typedef unsigned int UINT_PTR , * PUINT_PTR ;
typedef UINT_PTR SOCKET ;
# define INVALID_SOCKET (SOCKET)(~0)
# define PLATFORM_SOCKET_TRY_AGAIN EAGAIN
# define PLATFORM_SOCKET_INPROGRESS EINPROGRESS
# define PLATFORM_SOCKET_INTERRUPTED EINTR
# endif
int getLastSocketError ( ) {
# ifndef WIN32
return errno ;
# else
return WSAGetLastError ( ) ;
# endif
}
2010-04-13 09:29:48 +02:00
const char * getLastSocketErrorText ( int * errNumber = NULL ) {
2010-04-13 08:59:30 +02:00
int errId = ( errNumber ! = NULL ? * errNumber : getLastSocketError ( ) ) ;
# ifndef WIN32
return strerror ( errId ) ;
# else
2010-04-13 09:29:48 +02:00
return WSAGetLastErrorMessage ( " " , errId ) ;
2010-04-13 08:59:30 +02:00
# endif
}
string getLastSocketErrorFormattedText ( int * errNumber = NULL ) {
int errId = ( errNumber ! = NULL ? * errNumber : getLastSocketError ( ) ) ;
string msg = " (Error: " + intToStr ( errId ) + " - [ " + string ( getLastSocketErrorText ( & errId ) ) + " ]) " ;
return msg ;
}
2010-03-16 22:37:11 +01:00
// =====================================================
// class Ip
// =====================================================
Ip : : Ip ( ) {
bytes [ 0 ] = 0 ;
bytes [ 1 ] = 0 ;
bytes [ 2 ] = 0 ;
bytes [ 3 ] = 0 ;
}
Ip : : Ip ( unsigned char byte0 , unsigned char byte1 , unsigned char byte2 , unsigned char byte3 ) {
bytes [ 0 ] = byte0 ;
bytes [ 1 ] = byte1 ;
bytes [ 2 ] = byte2 ;
bytes [ 3 ] = byte3 ;
}
Ip : : Ip ( const string & ipString ) {
2010-09-06 08:22:08 +02:00
size_t offset = 0 ;
2010-03-16 22:37:11 +01:00
int byteIndex = 0 ;
for ( byteIndex = 0 ; byteIndex < 4 ; + + byteIndex ) {
2010-09-06 08:22:08 +02:00
size_t dotPos = ipString . find_first_of ( ' . ' , offset ) ;
2010-03-16 22:37:11 +01:00
bytes [ byteIndex ] = atoi ( ipString . substr ( offset , dotPos - offset ) . c_str ( ) ) ;
offset = dotPos + 1 ;
}
}
string Ip : : getString ( ) const {
return intToStr ( bytes [ 0 ] ) + " . " + intToStr ( bytes [ 1 ] ) + " . " + intToStr ( bytes [ 2 ] ) + " . " + intToStr ( bytes [ 3 ] ) ;
}
// ===============================================
// class Socket
// ===============================================
2010-04-11 09:13:14 +02:00
# if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
# define USE_GETIFADDRS 1
# include <ifaddrs.h>
2010-12-30 17:05:47 +01:00
# endif
2010-04-11 09:13:14 +02:00
static uint32 SockAddrToUint32 ( struct sockaddr * a )
{
return ( ( a ) & & ( a - > sa_family = = AF_INET ) ) ? ntohl ( ( ( struct sockaddr_in * ) a ) - > sin_addr . s_addr ) : 0 ;
}
// convert a numeric IP address into its string representation
static void Inet_NtoA ( uint32 addr , char * ipbuf )
{
sprintf ( ipbuf , " %d.%d.%d.%d " , ( addr > > 24 ) & 0xFF , ( addr > > 16 ) & 0xFF , ( addr > > 8 ) & 0xFF , ( addr > > 0 ) & 0xFF ) ;
}
// convert a string represenation of an IP address into its numeric equivalent
static uint32 Inet_AtoN ( const char * buf )
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0 ;
int shift = 24 ; // fill out the MSB first
bool startQuad = true ;
while ( ( shift > = 0 ) & & ( * buf ) )
{
if ( startQuad )
{
unsigned char quad = ( unsigned char ) atoi ( buf ) ;
ret | = ( ( ( uint32 ) quad ) < < shift ) ;
shift - = 8 ;
}
startQuad = ( * buf = = ' . ' ) ;
buf + + ;
}
return ret ;
}
/*
static void PrintNetworkInterfaceInfos ( )
{
# if defined(USE_GETIFADDRS)
// BSD-style implementation
struct ifaddrs * ifap ;
if ( getifaddrs ( & ifap ) = = 0 )
{
struct ifaddrs * p = ifap ;
while ( p )
{
uint32 ifaAddr = SockAddrToUint32 ( p - > ifa_addr ) ;
uint32 maskAddr = SockAddrToUint32 ( p - > ifa_netmask ) ;
uint32 dstAddr = SockAddrToUint32 ( p - > ifa_dstaddr ) ;
if ( ifaAddr > 0 )
{
char ifaAddrStr [ 32 ] ; Inet_NtoA ( ifaAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Inet_NtoA ( maskAddr , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Inet_NtoA ( dstAddr , dstAddrStr ) ;
printf ( " Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s] \n " , p - > ifa_name , " unavailable " , ifaAddrStr , maskAddrStr , dstAddrStr ) ;
}
p = p - > ifa_next ;
}
freeifaddrs ( ifap ) ;
}
# elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL ;
{
ULONG bufLen = 0 ;
for ( int i = 0 ; i < 5 ; i + + )
{
DWORD ipRet = GetIpAddrTable ( ipTable , & bufLen , false ) ;
if ( ipRet = = ERROR_INSUFFICIENT_BUFFER )
{
free ( ipTable ) ; // in case we had previously allocated it
ipTable = ( MIB_IPADDRTABLE * ) malloc ( bufLen ) ;
}
else if ( ipRet = = NO_ERROR ) break ;
else
{
free ( ipTable ) ;
ipTable = NULL ;
break ;
}
}
}
if ( ipTable )
{
// Try to get the Adapters-info table, so we can given useful names to the IP
// addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle
// the potential race condition between the size-query call and the get-data call.
// I love a well-designed API :^P
IP_ADAPTER_INFO * pAdapterInfo = NULL ;
{
ULONG bufLen = 0 ;
for ( int i = 0 ; i < 5 ; i + + )
{
DWORD apRet = GetAdaptersInfo ( pAdapterInfo , & bufLen ) ;
if ( apRet = = ERROR_BUFFER_OVERFLOW )
{
free ( pAdapterInfo ) ; // in case we had previously allocated it
pAdapterInfo = ( IP_ADAPTER_INFO * ) malloc ( bufLen ) ;
}
else if ( apRet = = ERROR_SUCCESS ) break ;
else
{
free ( pAdapterInfo ) ;
pAdapterInfo = NULL ;
break ;
}
}
}
for ( DWORD i = 0 ; i < ipTable - > dwNumEntries ; i + + )
{
const MIB_IPADDRROW & row = ipTable - > table [ i ] ;
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL ;
const char * desc = NULL ;
if ( pAdapterInfo )
{
IP_ADAPTER_INFO * next = pAdapterInfo ;
while ( ( next ) & & ( name = = NULL ) )
{
IP_ADDR_STRING * ipAddr = & next - > IpAddressList ;
while ( ipAddr )
{
if ( Inet_AtoN ( ipAddr - > IpAddress . String ) = = ntohl ( row . dwAddr ) )
{
name = next - > AdapterName ;
desc = next - > Description ;
break ;
}
ipAddr = ipAddr - > Next ;
}
next = next - > Next ;
}
}
char buf [ 128 ] ;
if ( name = = NULL )
{
sprintf ( buf , " unnamed-%i " , i ) ;
name = buf ;
}
uint32 ipAddr = ntohl ( row . dwAddr ) ;
uint32 netmask = ntohl ( row . dwMask ) ;
uint32 baddr = ipAddr & netmask ;
if ( row . dwBCastAddr ) baddr | = ~ netmask ;
char ifaAddrStr [ 32 ] ; Inet_NtoA ( ipAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Inet_NtoA ( netmask , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Inet_NtoA ( baddr , dstAddrStr ) ;
printf ( " Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s] \n " , name , desc ? desc : " unavailable " , ifaAddrStr , maskAddrStr , dstAddrStr ) ;
}
free ( pAdapterInfo ) ;
free ( ipTable ) ;
}
# else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
# endif
}
*/
string getNetworkInterfaceBroadcastAddress ( string ipAddress )
{
string broadCastAddress = " " ;
# if defined(USE_GETIFADDRS)
// BSD-style implementation
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-11 09:13:14 +02:00
struct ifaddrs * ifap ;
if ( getifaddrs ( & ifap ) = = 0 )
{
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-11 09:13:14 +02:00
struct ifaddrs * p = ifap ;
while ( p )
{
uint32 ifaAddr = SockAddrToUint32 ( p - > ifa_addr ) ;
uint32 maskAddr = SockAddrToUint32 ( p - > ifa_netmask ) ;
uint32 dstAddr = SockAddrToUint32 ( p - > ifa_dstaddr ) ;
if ( ifaAddr > 0 )
{
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-14 23:03:23 +02:00
2010-04-11 09:13:14 +02:00
char ifaAddrStr [ 32 ] ; Inet_NtoA ( ifaAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Inet_NtoA ( maskAddr , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Inet_NtoA ( dstAddr , dstAddrStr ) ;
//printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
2010-06-14 23:03:23 +02:00
if ( strcmp ( ifaAddrStr , ipAddress . c_str ( ) ) = = 0 ) {
2010-04-11 09:13:14 +02:00
broadCastAddress = dstAddrStr ;
2010-06-14 23:03:23 +02:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ifaAddrStr [%s], maskAddrStr [%s], dstAddrStr[%s], ipAddress [%s], broadCastAddress [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ifaAddrStr , maskAddrStr , dstAddrStr , ipAddress . c_str ( ) , broadCastAddress . c_str ( ) ) ;
2010-04-11 09:13:14 +02:00
}
p = p - > ifa_next ;
}
freeifaddrs ( ifap ) ;
}
# elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL ;
{
ULONG bufLen = 0 ;
for ( int i = 0 ; i < 5 ; i + + )
{
DWORD ipRet = GetIpAddrTable ( ipTable , & bufLen , false ) ;
if ( ipRet = = ERROR_INSUFFICIENT_BUFFER )
{
free ( ipTable ) ; // in case we had previously allocated it
ipTable = ( MIB_IPADDRTABLE * ) malloc ( bufLen ) ;
}
else if ( ipRet = = NO_ERROR ) break ;
else
{
free ( ipTable ) ;
ipTable = NULL ;
break ;
}
}
}
if ( ipTable )
{
// Try to get the Adapters-info table, so we can given useful names to the IP
// addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle
// the potential race condition between the size-query call and the get-data call.
// I love a well-designed API :^P
IP_ADAPTER_INFO * pAdapterInfo = NULL ;
{
ULONG bufLen = 0 ;
for ( int i = 0 ; i < 5 ; i + + )
{
DWORD apRet = GetAdaptersInfo ( pAdapterInfo , & bufLen ) ;
if ( apRet = = ERROR_BUFFER_OVERFLOW )
{
free ( pAdapterInfo ) ; // in case we had previously allocated it
pAdapterInfo = ( IP_ADAPTER_INFO * ) malloc ( bufLen ) ;
}
else if ( apRet = = ERROR_SUCCESS ) break ;
else
{
free ( pAdapterInfo ) ;
pAdapterInfo = NULL ;
break ;
}
}
}
for ( DWORD i = 0 ; i < ipTable - > dwNumEntries ; i + + )
{
const MIB_IPADDRROW & row = ipTable - > table [ i ] ;
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL ;
const char * desc = NULL ;
if ( pAdapterInfo )
{
IP_ADAPTER_INFO * next = pAdapterInfo ;
while ( ( next ) & & ( name = = NULL ) )
{
IP_ADDR_STRING * ipAddr = & next - > IpAddressList ;
while ( ipAddr )
{
if ( Inet_AtoN ( ipAddr - > IpAddress . String ) = = ntohl ( row . dwAddr ) )
{
name = next - > AdapterName ;
desc = next - > Description ;
break ;
}
ipAddr = ipAddr - > Next ;
}
next = next - > Next ;
}
}
char buf [ 128 ] ;
if ( name = = NULL )
{
//sprintf(buf, "unnamed-%i", i);
name = buf ;
}
uint32 ipAddr = ntohl ( row . dwAddr ) ;
uint32 netmask = ntohl ( row . dwMask ) ;
uint32 baddr = ipAddr & netmask ;
if ( row . dwBCastAddr ) baddr | = ~ netmask ;
char ifaAddrStr [ 32 ] ; Inet_NtoA ( ipAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Inet_NtoA ( netmask , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Inet_NtoA ( baddr , dstAddrStr ) ;
//printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
if ( strcmp ( ifaAddrStr , ipAddress . c_str ( ) ) = = 0 ) {
broadCastAddress = dstAddrStr ;
}
}
free ( pAdapterInfo ) ;
free ( ipTable ) ;
}
# else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
# endif
return broadCastAddress ;
}
2010-12-30 16:56:02 +01:00
uint32 Socket : : getConnectedIPAddress ( string IP ) {
sockaddr_in addr ;
memset ( & addr , 0 , sizeof ( addr ) ) ;
addr . sin_family = AF_INET ;
if ( IP = = " " ) {
IP = connectedIpAddress ;
}
addr . sin_addr . s_addr = inet_addr ( IP . c_str ( ) ) ;
//addr.sin_port= htons(port);
return SockAddrToUint32 ( ( struct sockaddr * ) & addr ) ;
}
2010-04-01 08:31:10 +02:00
std : : vector < std : : string > Socket : : getLocalIPAddressList ( ) {
std : : vector < std : : string > ipList ;
/* get my host name */
char myhostname [ 101 ] = " " ;
gethostname ( myhostname , 100 ) ;
2010-06-14 23:03:23 +02:00
char myhostaddr [ 101 ] = " " ;
2010-04-01 08:31:10 +02:00
struct hostent * myhostent = gethostbyname ( myhostname ) ;
2010-06-14 23:03:23 +02:00
if ( myhostent ) {
// get all host IP addresses (Except for loopback)
char myhostaddr [ 101 ] = " " ;
int ipIdx = 0 ;
while ( myhostent - > h_addr_list [ ipIdx ] ! = 0 ) {
sprintf ( myhostaddr , " %s " , inet_ntoa ( * ( struct in_addr * ) myhostent - > h_addr_list [ ipIdx ] ) ) ;
//printf("%s\n",myhostaddr);
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] myhostaddr = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , myhostaddr ) ;
2010-06-14 23:03:23 +02:00
2010-07-16 18:53:19 +02:00
if ( strlen ( myhostaddr ) > 0 & &
strncmp ( myhostaddr , " 127. " , 4 ) ! = 0 & &
strncmp ( myhostaddr , " 0. " , 2 ) ! = 0 ) {
2010-06-14 23:03:23 +02:00
ipList . push_back ( myhostaddr ) ;
}
ipIdx + + ;
}
2010-09-07 19:30:13 +02:00
}
2010-04-01 08:31:10 +02:00
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2010-04-01 08:31:10 +02:00
// Now check all linux network devices
2010-06-14 23:03:23 +02:00
std : : vector < string > intfTypes ;
2010-07-16 22:02:44 +02:00
intfTypes . push_back ( " lo " ) ;
2010-06-14 23:03:23 +02:00
intfTypes . push_back ( " eth " ) ;
intfTypes . push_back ( " wlan " ) ;
2010-07-16 22:02:44 +02:00
intfTypes . push_back ( " vlan " ) ;
2010-06-14 23:03:23 +02:00
intfTypes . push_back ( " vboxnet " ) ;
2010-07-16 22:02:44 +02:00
intfTypes . push_back ( " br-lan " ) ;
intfTypes . push_back ( " br-gest " ) ;
2010-06-14 23:03:23 +02:00
for ( int intfIdx = 0 ; intfIdx < intfTypes . size ( ) ; intfIdx + + ) {
string intfName = intfTypes [ intfIdx ] ;
for ( int idx = 0 ; idx < 10 ; + + idx ) {
PLATFORM_SOCKET fd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
2010-07-16 22:02:44 +02:00
//PLATFORM_SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2010-06-14 23:03:23 +02:00
/* I want to get an IPv4 IP address */
struct ifreq ifr ;
2010-07-16 22:02:44 +02:00
struct ifreq ifrA ;
2010-06-14 23:03:23 +02:00
ifr . ifr_addr . sa_family = AF_INET ;
2010-07-16 22:02:44 +02:00
ifrA . ifr_addr . sa_family = AF_INET ;
2010-06-14 23:03:23 +02:00
/* I want IP address attached to "eth0" */
char szBuf [ 100 ] = " " ;
sprintf ( szBuf , " %s%d " , intfName . c_str ( ) , idx ) ;
2010-07-16 22:02:44 +02:00
int maxIfNameLength = std : : min ( ( int ) strlen ( szBuf ) , IFNAMSIZ - 1 ) ;
strncpy ( ifr . ifr_name , szBuf , maxIfNameLength ) ;
ifr . ifr_name [ maxIfNameLength ] = ' \0 ' ;
strncpy ( ifrA . ifr_name , szBuf , maxIfNameLength ) ;
ifrA . ifr_name [ maxIfNameLength ] = ' \0 ' ;
2010-09-07 19:30:13 +02:00
int result_ifaddrr = ioctl ( fd , SIOCGIFADDR , & ifr ) ;
2010-07-16 22:02:44 +02:00
ioctl ( fd , SIOCGIFFLAGS , & ifrA ) ;
2010-06-14 23:03:23 +02:00
close ( fd ) ;
2010-09-07 19:30:13 +02:00
if ( result_ifaddrr > = 0 ) {
struct sockaddr_in * pSockAddr = ( struct sockaddr_in * ) & ifr . ifr_addr ;
if ( pSockAddr ! = NULL ) {
sprintf ( myhostaddr , " %s " , inet_ntoa ( pSockAddr - > sin_addr ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] szBuf [%s], myhostaddr = [%s], ifr.ifr_flags = %d, ifrA.ifr_flags = %d, ifr.ifr_name [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , szBuf , myhostaddr , ifr . ifr_flags , ifrA . ifr_flags , ifr . ifr_name ) ;
2010-09-07 19:30:13 +02:00
// Now only include interfaces that are both UP and running
if ( ( ifrA . ifr_flags & IFF_UP ) = = IFF_UP & &
( ifrA . ifr_flags & IFF_RUNNING ) = = IFF_RUNNING ) {
if ( strlen ( myhostaddr ) > 0 & &
strncmp ( myhostaddr , " 127. " , 4 ) ! = 0 & &
strncmp ( myhostaddr , " 0. " , 2 ) ! = 0 ) {
if ( std : : find ( ipList . begin ( ) , ipList . end ( ) , myhostaddr ) = = ipList . end ( ) ) {
ipList . push_back ( myhostaddr ) ;
}
}
2010-07-16 22:02:44 +02:00
}
2010-06-14 23:03:23 +02:00
}
2010-04-03 04:21:04 +02:00
}
}
}
2010-04-01 08:31:10 +02:00
2010-04-13 08:59:30 +02:00
# endif
2010-04-01 08:31:10 +02:00
return ipList ;
}
2010-04-15 03:19:00 +02:00
bool Socket : : isSocketValid ( ) const {
return Socket : : isSocketValid ( & sock ) ;
}
bool Socket : : isSocketValid ( const PLATFORM_SOCKET * validateSocket ) {
2010-04-13 08:59:30 +02:00
# ifdef WIN32
if ( validateSocket = = NULL ) {
2010-04-15 03:19:00 +02:00
return false ;
2010-04-13 08:59:30 +02:00
}
else {
return ( * validateSocket ! = INVALID_SOCKET ) ;
}
# else
if ( validateSocket = = NULL ) {
2010-04-15 03:19:00 +02:00
return false ;
2010-04-13 08:59:30 +02:00
}
else {
return ( * validateSocket > 0 ) ;
}
# endif
}
2010-12-30 16:56:02 +01:00
Socket : : Socket ( PLATFORM_SOCKET sock ) {
2011-05-25 23:57:01 +02:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
this - > inSocketDestructor = false ;
//safeMutexSocketDestructorFlag.ReleaseLock();
2011-02-15 08:49:40 +01:00
//this->pingThread = NULL;
2011-03-19 13:04:18 +01:00
pingThreadAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
dataSynchAccessorRead . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
dataSynchAccessorWrite . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-05-25 23:57:01 +02:00
2011-03-11 12:11:46 +01:00
2010-03-16 22:37:11 +01:00
this - > sock = sock ;
2010-12-30 16:56:02 +01:00
this - > connectedIpAddress = " " ;
2010-03-16 22:37:11 +01:00
}
2010-12-30 16:56:02 +01:00
Socket : : Socket ( ) {
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-04-13 03:20:40 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
this - > inSocketDestructor = false ;
2011-05-25 23:57:01 +02:00
//safeMutexSocketDestructorFlag.ReleaseLock();
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
//this->pingThread = NULL;
2011-03-11 12:11:46 +01:00
2010-12-30 16:56:02 +01:00
this - > connectedIpAddress = " " ;
2010-04-13 08:59:30 +02:00
sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ;
2010-07-09 17:01:49 +02:00
if ( isSocketValid ( ) = = false ) {
2010-03-16 22:37:11 +01:00
throwException ( " Error creating socket " ) ;
}
2011-01-11 04:56:38 +01:00
# ifdef __APPLE__
int set = 1 ;
setsockopt ( sock , SOL_SOCKET , SO_NOSIGPIPE , ( void * ) & set , sizeof ( int ) ) ;
# endif
2010-03-16 22:37:11 +01:00
}
2010-06-04 21:42:58 +02:00
float Socket : : getThreadedPingMS ( std : : string host ) {
2010-06-22 16:12:57 +02:00
float result = - 1 ;
/*
2010-06-04 21:42:58 +02:00
if ( pingThread = = NULL ) {
2010-06-04 22:37:42 +02:00
lastThreadedPing = 0 ;
2010-06-04 21:42:58 +02:00
pingThread = new SimpleTaskThread ( this , 0 , 50 ) ;
2010-06-23 16:49:20 +02:00
pingThread - > setUniqueID ( __FILE__ + " _ " + __FUNCTION ) ;
2010-06-04 21:42:58 +02:00
pingThread - > start ( ) ;
}
if ( pingCache . find ( host ) = = pingCache . end ( ) ) {
MutexSafeWrapper safeMutex ( & pingThreadAccessor ) ;
safeMutex . ReleaseLock ( ) ;
result = getAveragePingMS ( host , 1 ) ;
2010-06-04 22:39:23 +02:00
pingCache [ host ] = result ;
2010-06-04 21:42:58 +02:00
}
else {
MutexSafeWrapper safeMutex ( & pingThreadAccessor ) ;
result = pingCache [ host ] ;
safeMutex . ReleaseLock ( ) ;
}
2010-06-22 16:12:57 +02:00
*/
2010-06-04 21:42:58 +02:00
return result ;
}
2011-02-15 08:49:40 +01:00
/*
2011-01-02 07:46:48 +01:00
void Socket : : simpleTask ( BaseThread * callingThread ) {
2010-06-04 21:42:58 +02:00
// update ping times every x seconds
const int pingFrequencySeconds = 2 ;
if ( difftime ( time ( NULL ) , lastThreadedPing ) < pingFrequencySeconds ) {
return ;
}
lastThreadedPing = time ( NULL ) ;
//printf("Pinging hosts...\n");
2010-09-06 08:22:08 +02:00
for ( std : : map < string , double > : : iterator iterMap = pingCache . begin ( ) ;
2010-06-04 21:42:58 +02:00
iterMap ! = pingCache . end ( ) ; iterMap + + ) {
2011-02-01 00:01:39 +01:00
MutexSafeWrapper safeMutex ( & pingThreadAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-06-04 21:42:58 +02:00
iterMap - > second = getAveragePingMS ( iterMap - > first , 1 ) ;
safeMutex . ReleaseLock ( ) ;
}
}
2011-02-15 08:49:40 +01:00
*/
2010-06-04 21:42:58 +02:00
2011-05-25 23:57:01 +02:00
Socket : : ~ Socket ( ) {
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-05-25 23:57:01 +02:00
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-05-25 23:57:01 +02:00
return ;
}
2011-04-13 03:20:40 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
this - > inSocketDestructor = true ;
2011-05-25 23:57:01 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] START closing socket = %d... \n " , __FILE__ , __FUNCTION__ , sock ) ;
//safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2010-03-16 22:37:11 +01:00
disconnectSocket ( ) ;
2011-03-19 13:04:18 +01:00
// Allow other callers with a lock on the mutexes to let them go
for ( time_t elapsed = time ( NULL ) ;
( dataSynchAccessorRead . getRefCount ( ) > 0 | |
dataSynchAccessorWrite . getRefCount ( ) > 0 ) & &
difftime ( time ( NULL ) , elapsed ) < = 5 ; ) {
2011-04-13 03:20:40 +02:00
//sleep(0);
2011-03-19 13:04:18 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] END closing socket = %d... \n " , __FILE__ , __FUNCTION__ , sock ) ;
2010-06-04 21:42:58 +02:00
2011-02-15 08:49:40 +01:00
//delete pingThread;
//pingThread = NULL;
2010-03-16 22:37:11 +01:00
}
2011-01-02 17:24:44 +01:00
void Socket : : disconnectSocket ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] START closing socket = %d... \n " , __FILE__ , __FUNCTION__ , sock ) ;
2010-03-16 22:37:11 +01:00
2011-01-02 17:24:44 +01:00
if ( isSocketValid ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] calling shutdown and close for socket = %d... \n " , __FILE__ , __FUNCTION__ , sock ) ;
2011-01-02 17:24:44 +01:00
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
MutexSafeWrapper safeMutex1 ( & dataSynchAccessorWrite , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-03-16 22:37:11 +01:00
: : shutdown ( sock , 2 ) ;
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2010-03-16 22:37:11 +01:00
: : close ( sock ) ;
2010-04-13 08:59:30 +02:00
sock = INVALID_SOCKET ;
# else
: : closesocket ( sock ) ;
2010-03-16 22:37:11 +01:00
sock = - 1 ;
2010-04-13 08:59:30 +02:00
# endif
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
safeMutex1 . ReleaseLock ( ) ;
2010-03-16 22:37:11 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] END closing socket = %d... \n " , __FILE__ , __FUNCTION__ , sock ) ;
2010-03-16 22:37:11 +01:00
}
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
2010-04-13 08:59:30 +02:00
bool Socket : : hasDataToRead ( std : : map < PLATFORM_SOCKET , bool > & socketTriggeredList )
2010-03-16 22:37:11 +01:00
{
bool bResult = false ;
if ( socketTriggeredList . size ( ) > 0 )
{
/* Watch stdin (fd 0) to see when it has input. */
fd_set rfds ;
FD_ZERO ( & rfds ) ;
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET imaxsocket = 0 ;
for ( std : : map < PLATFORM_SOCKET , bool > : : iterator itermap = socketTriggeredList . begin ( ) ;
2010-03-16 22:37:11 +01:00
itermap ! = socketTriggeredList . end ( ) ; itermap + + )
{
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET socket = itermap - > first ;
2010-04-15 03:19:00 +02:00
if ( Socket : : isSocketValid ( & socket ) = = true )
2010-03-16 22:37:11 +01:00
{
FD_SET ( socket , & rfds ) ;
imaxsocket = max ( socket , imaxsocket ) ;
}
}
if ( imaxsocket > 0 )
{
/* Wait up to 0 seconds. */
struct timeval tv ;
tv . tv_sec = 0 ;
tv . tv_usec = 0 ;
2010-08-07 05:26:38 +02:00
int retval = 0 ;
{
//MutexSafeWrapper safeMutex(&dataSynchAccessor);
2010-10-21 17:21:46 +02:00
retval = select ( ( int ) imaxsocket + 1 , & rfds , NULL , NULL , & tv ) ;
2010-08-07 05:26:38 +02:00
}
2010-03-16 22:37:11 +01:00
if ( retval < 0 )
{
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
else if ( retval )
{
bResult = true ;
2010-04-13 08:59:30 +02:00
for ( std : : map < PLATFORM_SOCKET , bool > : : iterator itermap = socketTriggeredList . begin ( ) ;
2010-03-16 22:37:11 +01:00
itermap ! = socketTriggeredList . end ( ) ; itermap + + )
{
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET socket = itermap - > first ;
2010-03-16 22:37:11 +01:00
if ( FD_ISSET ( socket , & rfds ) )
{
itermap - > second = true ;
}
else
{
itermap - > second = false ;
}
}
}
}
}
return bResult ;
}
bool Socket : : hasDataToRead ( )
{
return Socket : : hasDataToRead ( sock ) ;
}
2010-04-13 08:59:30 +02:00
bool Socket : : hasDataToRead ( PLATFORM_SOCKET socket )
2010-03-16 22:37:11 +01:00
{
bool bResult = false ;
2010-04-15 03:19:00 +02:00
if ( Socket : : isSocketValid ( & socket ) = = true )
2010-03-16 22:37:11 +01:00
{
fd_set rfds ;
struct timeval tv ;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO ( & rfds ) ;
FD_SET ( socket , & rfds ) ;
/* Wait up to 0 seconds. */
tv . tv_sec = 0 ;
tv . tv_usec = 0 ;
2010-08-07 05:26:38 +02:00
int retval = 0 ;
{
//MutexSafeWrapper safeMutex(&dataSynchAccessor);
2010-10-21 17:21:46 +02:00
retval = select ( ( int ) socket + 1 , & rfds , NULL , NULL , & tv ) ;
2010-08-07 05:26:38 +02:00
}
2010-03-16 22:37:11 +01:00
if ( retval )
{
if ( FD_ISSET ( socket , & rfds ) )
{
bResult = true ;
}
}
}
return bResult ;
}
2010-07-09 17:01:49 +02:00
int Socket : : getDataToRead ( bool wantImmediateReply ) {
2010-03-16 22:37:11 +01:00
unsigned long size = 0 ;
//fd_set rfds;
//struct timeval tv;
//int retval;
/* Watch stdin (fd 0) to see when it has input. */
//FD_ZERO(&rfds);
//FD_SET(sock, &rfds);
/* Wait up to 0 seconds. */
//tv.tv_sec = 0;
//tv.tv_usec = 0;
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
//if(retval)
2010-04-13 08:59:30 +02:00
if ( isSocketValid ( ) = = true )
2010-03-16 22:37:11 +01:00
{
2010-04-20 04:19:37 +02:00
int loopCount = 1 ;
for ( time_t elapsed = time ( NULL ) ; difftime ( time ( NULL ) , elapsed ) < 1 ; ) {
/* ioctl isn't posix, but the following seems to work on all modern
* unixes */
# ifndef WIN32
int err = ioctl ( sock , FIONREAD , & size ) ;
# else
int err = ioctlsocket ( sock , FIONREAD , & size ) ;
# endif
if ( err < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN )
{
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-04-20 04:19:37 +02:00
break ;
}
else if ( err = = 0 )
{
2010-08-07 05:26:38 +02:00
if ( isConnected ( ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-08-07 05:26:38 +02:00
break ;
}
2010-04-20 04:19:37 +02:00
}
if ( size > 0 ) {
break ;
}
else if ( hasDataToRead ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = %lu, loopCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , size , loopCount ) ;
2010-04-20 04:19:37 +02:00
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = %lu, loopCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , size , loopCount ) ;
2010-04-20 04:19:37 +02:00
break ;
}
2010-07-09 17:01:49 +02:00
if ( wantImmediateReply = = true ) {
break ;
}
2010-04-20 04:19:37 +02:00
loopCount + + ;
}
2010-03-16 22:37:11 +01:00
}
return static_cast < int > ( size ) ;
}
int Socket : : send ( const void * data , int dataSize ) {
2011-01-09 05:49:21 +01:00
const int MAX_SEND_WAIT_SECONDS = 3 ;
2010-10-21 09:20:17 +02:00
int bytesSent = 0 ;
2010-05-31 08:11:31 +02:00
if ( isSocketValid ( ) = = true ) {
2010-07-08 10:29:51 +02:00
errno = 0 ;
2010-08-07 05:26:38 +02:00
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorWrite , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-08-07 06:49:06 +02:00
2010-09-11 07:14:42 +02:00
# ifdef __APPLE__
bytesSent = : : send ( sock , ( const char * ) data , dataSize , SO_NOSIGPIPE ) ;
# else
2011-02-21 02:34:31 +01:00
bytesSent = : : send ( sock , ( const char * ) data , dataSize , MSG_NOSIGNAL | MSG_DONTWAIT ) ;
2010-09-11 07:14:42 +02:00
# endif
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2010-03-16 22:37:11 +01:00
}
2010-07-08 10:29:51 +02:00
// TEST errors
//bytesSent = -1;
// END TEST
2010-05-31 08:11:31 +02:00
if ( bytesSent < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2011-01-11 04:56:38 +01:00
else if ( isConnected ( ) = = true & & bytesSent < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 EAGAIN during send, trying again... \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-16 22:37:11 +01:00
2010-07-08 10:29:51 +02:00
int attemptCount = 0 ;
2010-03-16 22:37:11 +01:00
time_t tStartTimer = time ( NULL ) ;
2010-08-26 05:15:36 +02:00
while ( ( bytesSent < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) & &
2011-01-09 05:49:21 +01:00
( difftime ( time ( NULL ) , tStartTimer ) < = MAX_SEND_WAIT_SECONDS ) ) {
2010-07-08 10:29:51 +02:00
attemptCount + + ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount ) ;
2010-07-08 10:29:51 +02:00
2011-01-09 05:49:21 +01:00
if ( isConnected ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount , sock , dataSize , data ) ;
2011-01-02 17:24:44 +01:00
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorWrite , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-09-11 07:14:42 +02:00
# ifdef __APPLE__
bytesSent = : : send ( sock , ( const char * ) data , dataSize , SO_NOSIGPIPE ) ;
2010-12-07 08:00:11 +01:00
# else
2011-02-21 02:34:31 +01:00
bytesSent = : : send ( sock , ( const char * ) data , dataSize , MSG_NOSIGNAL | MSG_DONTWAIT ) ;
2010-09-11 07:14:42 +02:00
# endif
2011-01-11 04:56:38 +01:00
if ( bytesSent < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN ) {
break ;
}
2011-02-13 04:06:12 +01:00
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2011-02-13 04:06:12 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 EAGAIN during send, trying again returned: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent ) ;
2011-01-09 05:49:21 +01:00
}
else {
int iErr = getLastSocketError ( ) ;
disconnectSocket ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s \n " , __FILE__ , __FUNCTION__ , bytesSent , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2011-01-09 05:49:21 +01:00
break ;
2011-01-02 17:24:44 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount ) ;
2010-03-16 22:37:11 +01:00
}
}
2010-08-07 06:49:06 +02:00
2011-01-11 04:56:38 +01:00
if ( isConnected ( ) = = true & & bytesSent > 0 & & bytesSent < dataSize ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] need to send more data, trying again getLastSocketError() = %d, bytesSent = %d, dataSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , getLastSocketError ( ) , bytesSent , dataSize ) ;
2010-08-26 04:36:17 +02:00
2010-10-21 09:20:17 +02:00
int totalBytesSent = bytesSent ;
2010-08-26 04:36:17 +02:00
int attemptCount = 0 ;
time_t tStartTimer = time ( NULL ) ;
while ( ( ( bytesSent > 0 & & totalBytesSent < dataSize ) | |
( bytesSent < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) ) & &
2011-01-09 05:49:21 +01:00
( difftime ( time ( NULL ) , tStartTimer ) < = MAX_SEND_WAIT_SECONDS ) ) {
2010-08-26 04:36:17 +02:00
attemptCount + + ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount , totalBytesSent ) ;
2010-08-26 04:36:17 +02:00
2011-01-09 05:49:21 +01:00
if ( isConnected ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount , sock , dataSize , data ) ;
2010-08-26 04:36:17 +02:00
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorWrite , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-08-26 04:36:17 +02:00
const char * sendBuf = ( const char * ) data ;
2010-09-11 07:14:42 +02:00
# ifdef __APPLE__
2011-01-02 17:24:44 +01:00
bytesSent = : : send ( sock , & sendBuf [ totalBytesSent ] , dataSize - totalBytesSent , SO_NOSIGPIPE ) ;
2010-09-11 07:14:42 +02:00
# else
2011-02-21 02:34:31 +01:00
bytesSent = : : send ( sock , & sendBuf [ totalBytesSent ] , dataSize - totalBytesSent , MSG_NOSIGNAL | MSG_DONTWAIT ) ;
2010-09-11 07:14:42 +02:00
# endif
2010-08-26 04:36:17 +02:00
if ( bytesSent > 0 ) {
totalBytesSent + = bytesSent ;
}
2011-01-11 04:56:38 +01:00
if ( bytesSent < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN ) {
break ;
}
2011-02-13 04:06:12 +01:00
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2011-02-13 04:06:12 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] retry send returned: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent ) ;
2011-01-02 17:24:44 +01:00
}
2011-01-09 05:49:21 +01:00
else {
int iErr = getLastSocketError ( ) ;
disconnectSocket ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2011-01-09 05:49:21 +01:00
break ;
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount ) ;
2010-08-26 04:36:17 +02:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] bytesSent = %d, totalBytesSent = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent , totalBytesSent ) ;
2010-08-26 05:15:36 +02:00
2010-08-26 04:36:17 +02:00
if ( bytesSent > 0 ) {
bytesSent = totalBytesSent ;
}
}
2011-01-11 04:56:38 +01:00
if ( bytesSent < = 0 | | isConnected ( ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-07-08 10:29:51 +02:00
2010-04-13 08:59:30 +02:00
int iErr = getLastSocketError ( ) ;
2010-03-16 22:37:11 +01:00
disconnectSocket ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] sock = %d, bytesSent = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , bytesSent ) ;
2010-03-16 22:37:11 +01:00
return static_cast < int > ( bytesSent ) ;
}
2011-04-24 06:22:19 +02:00
int Socket : : receive ( void * data , int dataSize , bool tryReceiveUntilDataSizeMet ) {
2011-01-09 05:49:21 +01:00
const int MAX_RECV_WAIT_SECONDS = 3 ;
2010-03-16 22:37:11 +01:00
ssize_t bytesReceived = 0 ;
2010-05-31 08:11:31 +02:00
if ( isSocketValid ( ) = = true ) {
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-03-16 22:37:11 +01:00
bytesReceived = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , 0 ) ;
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2010-03-16 22:37:11 +01:00
}
2010-05-31 08:11:31 +02:00
if ( bytesReceived < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2010-05-31 08:11:31 +02:00
else if ( bytesReceived < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 EAGAIN during receive, trying again... \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-16 22:37:11 +01:00
time_t tStartTimer = time ( NULL ) ;
2010-12-05 02:52:38 +01:00
while ( ( bytesReceived < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) & &
2011-01-09 05:49:21 +01:00
( difftime ( time ( NULL ) , tStartTimer ) < = MAX_RECV_WAIT_SECONDS ) ) {
if ( isConnected ( ) = = false ) {
int iErr = getLastSocketError ( ) ;
disconnectSocket ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesSent = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2011-01-09 05:49:21 +01:00
break ;
}
else if ( Socket : : isReadable ( ) = = true ) {
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-03-16 22:37:11 +01:00
bytesReceived = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , 0 ) ;
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2010-03-16 22:37:11 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived ) ;
2010-03-16 22:37:11 +01:00
}
}
}
2010-05-31 08:11:31 +02:00
if ( bytesReceived < = 0 ) {
2010-04-13 08:59:30 +02:00
int iErr = getLastSocketError ( ) ;
2010-03-16 22:37:11 +01:00
disconnectSocket ( ) ;
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) , dataSize , tryReceiveUntilDataSizeMet ) ;
}
else if ( tryReceiveUntilDataSizeMet = = true & & bytesReceived < dataSize ) {
2011-04-27 01:34:48 +02:00
int newBufferSize = ( dataSize - bytesReceived ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d, newBufferSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived , dataSize , newBufferSize ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n In [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d, newBufferSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( int ) bytesReceived , dataSize , newBufferSize , newBufferSize ) ;
2011-04-24 06:22:19 +02:00
char * dataAsCharPointer = reinterpret_cast < char * > ( data ) ;
2011-04-27 01:34:48 +02:00
int additionalBytes = receive ( & dataAsCharPointer [ bytesReceived ] , newBufferSize , tryReceiveUntilDataSizeMet ) ;
2011-04-24 06:22:19 +02:00
if ( additionalBytes > 0 ) {
bytesReceived + = additionalBytes ;
}
else {
2011-05-30 01:01:16 +02:00
//throw runtime_error("additionalBytes == " + intToStr(additionalBytes));
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] additionalBytes == %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , additionalBytes ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n In [%s::%s Line: %d] additionalBytes == %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , additionalBytes ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugError ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] additionalBytes == %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , additionalBytes ) ;
int iErr = getLastSocketError ( ) ;
disconnectSocket ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) , dataSize , tryReceiveUntilDataSizeMet ) ;
2011-04-24 06:22:19 +02:00
}
2010-03-16 22:37:11 +01:00
}
return static_cast < int > ( bytesReceived ) ;
}
2011-02-08 19:23:41 +01:00
int Socket : : peek ( void * data , int dataSize , bool mustGetData ) {
2011-02-15 04:32:14 +01:00
Chrono chrono ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) chrono . start ( ) ;
2011-02-08 19:23:41 +01:00
2011-01-09 05:49:21 +01:00
const int MAX_PEEK_WAIT_SECONDS = 3 ;
2010-03-16 22:37:11 +01:00
ssize_t err = 0 ;
2010-05-31 08:11:31 +02:00
if ( isSocketValid ( ) = = true ) {
2011-02-08 19:23:41 +01:00
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 04:32:14 +01:00
//MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize));
2011-02-15 08:49:40 +01:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , mutexOwnerId ) ;
2011-02-08 19:23:41 +01:00
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
2010-03-16 22:37:11 +01:00
err = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , MSG_PEEK ) ;
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2011-02-08 19:23:41 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] action running for msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( long long int ) chrono . getMillis ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2011-02-08 19:23:41 +01:00
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
2010-05-31 08:11:31 +02:00
if ( err < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] ERROR PEEKING SOCKET DATA error while sending socket data, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
disconnectSocket ( ) ;
}
2011-02-08 19:23:41 +01:00
else if ( err < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN & & mustGetData = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 ERROR EAGAIN during peek, trying again... \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-02-08 19:23:41 +01:00
2010-03-16 22:37:11 +01:00
time_t tStartTimer = time ( NULL ) ;
2010-12-05 02:52:38 +01:00
while ( ( err < 0 & & getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) & &
2011-01-09 05:49:21 +01:00
( difftime ( time ( NULL ) , tStartTimer ) < = MAX_PEEK_WAIT_SECONDS ) ) {
2011-02-15 04:32:14 +01:00
/*
2011-01-09 05:49:21 +01:00
if ( isConnected ( ) = = false ) {
int iErr = getLastSocketError ( ) ;
disconnectSocket ( ) ;
break ;
}
2011-02-15 04:32:14 +01:00
*/
if ( Socket : : isReadable ( ) = = true ) {
2011-03-11 12:11:46 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
2011-05-28 21:22:03 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-11 12:11:46 +01:00
return - 1 ;
}
2011-05-28 21:22:03 +02:00
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-03-11 12:11:46 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-02-15 04:32:14 +01:00
//MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize));
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ) ;
2010-03-16 22:37:11 +01:00
err = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , MSG_PEEK ) ;
2011-02-15 08:49:40 +01:00
safeMutex . ReleaseLock ( ) ;
2010-03-16 22:37:11 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] action running for msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( long long int ) chrono . getMillis ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 EAGAIN during peek, trying again returned: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , err ) ;
2010-03-16 22:37:11 +01:00
}
}
2011-02-08 19:23:41 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] action running for msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( long long int ) chrono . getMillis ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2011-02-08 19:23:41 +01:00
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
2010-05-31 08:11:31 +02:00
if ( err < = 0 ) {
2011-02-08 19:23:41 +01:00
if ( mustGetData = = true | | getLastSocketError ( ) ! = PLATFORM_SOCKET_TRY_AGAIN ) {
int iErr = getLastSocketError ( ) ;
disconnectSocket ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while peeking socket data, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2011-02-08 19:23:41 +01:00
}
2010-03-16 22:37:11 +01:00
}
return static_cast < int > ( err ) ;
}
void Socket : : setBlock ( bool block ) {
2010-04-02 04:33:32 +02:00
setBlock ( block , this - > sock ) ;
}
2011-05-17 02:21:51 +02:00
void Socket : : setBlock ( bool block , PLATFORM_SOCKET socket ) {
// don't waste time if the socket is invalid
if ( isSocketValid ( & socket ) = = false ) {
return ;
}
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2010-11-09 17:51:03 +01:00
int currentFlags = fcntl ( socket , F_GETFL ) ;
2011-05-17 02:21:51 +02:00
if ( currentFlags < 0 ) {
currentFlags = 0 ;
}
2010-11-09 17:51:03 +01:00
if ( block = = true ) {
2010-12-19 00:03:53 +01:00
currentFlags & = ( ~ O_NONBLOCK ) ;
2010-11-09 17:51:03 +01:00
}
else {
2010-12-19 00:03:53 +01:00
currentFlags | = O_NONBLOCK ;
2010-11-09 17:51:03 +01:00
}
int err = fcntl ( socket , F_SETFL , currentFlags ) ;
2010-04-13 08:59:30 +02:00
# else
u_long iMode = ! block ;
int err = ioctlsocket ( socket , FIONBIO , & iMode ) ;
# endif
2011-05-17 02:21:51 +02:00
if ( err < 0 ) {
2010-03-16 22:37:11 +01:00
throwException ( " Error setting I/O mode for socket " ) ;
}
}
2010-05-31 08:11:31 +02:00
bool Socket : : isReadable ( ) {
2010-04-13 08:59:30 +02:00
if ( isSocketValid ( ) = = false ) return false ;
2010-09-03 00:34:25 +02:00
struct timeval tv ;
2010-03-16 22:37:11 +01:00
tv . tv_sec = 0 ;
2010-09-03 00:34:25 +02:00
tv . tv_usec = 0 ;
2010-03-16 22:37:11 +01:00
fd_set set ;
FD_ZERO ( & set ) ;
FD_SET ( sock , & set ) ;
2010-08-07 05:26:38 +02:00
int i = 0 ;
{
2011-05-28 21:22:03 +02:00
//MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__));
//if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return false;
//}
//inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__));
//safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2011-02-21 02:34:31 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-10-21 17:21:46 +02:00
i = select ( ( int ) sock + 1 , & set , NULL , NULL , & tv ) ;
2010-08-07 05:26:38 +02:00
}
2010-05-31 08:11:31 +02:00
if ( i < 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s] error while selecting socket data, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , i , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2011-03-26 03:00:41 +01:00
bool result = ( i = = 1 ) ;
//if(result == false) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET DISCONNECTED In [%s::%s Line: %d] i = %d sock = %d\n",__FILE__,__FUNCTION__,__LINE__,i,sock);
//}
return result ;
2010-03-16 22:37:11 +01:00
}
2011-02-15 08:49:40 +01:00
bool Socket : : isWritable ( ) {
2010-04-13 08:59:30 +02:00
if ( isSocketValid ( ) = = false ) return false ;
2010-03-16 22:37:11 +01:00
struct timeval tv ;
tv . tv_sec = 0 ;
2011-02-21 02:34:31 +01:00
tv . tv_usec = 1 ;
//tv.tv_usec= 0;
2010-03-16 22:37:11 +01:00
fd_set set ;
FD_ZERO ( & set ) ;
FD_SET ( sock , & set ) ;
2011-02-15 08:49:40 +01:00
int i = 0 ;
{
2011-05-28 21:22:03 +02:00
//MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__));
//if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return false;
//}
//inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__));
//safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2011-02-21 02:34:31 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorWrite , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2011-02-15 08:49:40 +01:00
i = select ( ( int ) sock + 1 , NULL , & set , NULL , & tv ) ;
}
bool result = false ;
if ( i < 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] error while selecting socket data, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , i , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2011-03-26 03:00:41 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " SOCKET DISCONNECTED In [%s::%s Line: %d] error while selecting socket data, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , i , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2011-02-15 08:49:40 +01:00
}
else if ( i = = 0 ) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] TIMEOUT while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str());
2011-03-26 03:00:41 +01:00
// Assume we are still connected, write buffer could be very busy
result = true ;
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " SOCKET WRITE TIMEOUT In [%s::%s Line: %d] i = %d sock = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , i , sock ) ;
2011-02-15 08:49:40 +01:00
}
else {
result = true ;
}
2010-03-16 22:37:11 +01:00
//return (i == 1 && FD_ISSET(sock, &set));
return result ;
}
2010-05-31 08:11:31 +02:00
bool Socket : : isConnected ( ) {
2011-02-15 08:49:40 +01:00
if ( isSocketValid ( ) = = false ) return false ;
2011-05-28 21:22:03 +02:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( & inSocketDestructorSynchAccessor , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
if ( this - > inSocketDestructor = = true ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
return false ;
}
inSocketDestructorSynchAccessor . setOwnerId ( string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-03-16 22:37:11 +01:00
//if the socket is not writable then it is not conencted
2011-02-15 08:49:40 +01:00
if ( isWritable ( ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] ERROR isWritable failed. \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-16 22:37:11 +01:00
return false ;
}
//if the socket is readable it is connected if we can read a byte from it
2010-05-31 08:11:31 +02:00
if ( isReadable ( ) ) {
2011-05-28 21:22:03 +02:00
char tmp = 0 ;
2011-02-08 19:23:41 +01:00
int err = peek ( & tmp , 1 , false ) ;
if ( err < = 0 & & err ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] ERROR Peek failed, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2011-04-11 01:50:47 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) SystemFlags : : OutputDebug ( SystemFlags : : debugError , " SOCKET DISCONNECTED In [%s::%s Line: %d] ERROR Peek failed, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-07-09 07:29:42 +02:00
return false ;
}
2010-03-16 22:37:11 +01:00
}
//otherwise the socket is connected
return true ;
}
2010-03-23 03:37:41 +01:00
string Socket : : getHostName ( ) {
2010-08-23 17:17:36 +02:00
static string host = " " ;
if ( host = = " " ) {
const int strSize = 257 ;
char hostname [ strSize ] = " " ;
int result = gethostname ( hostname , strSize ) ;
if ( result = = 0 ) {
host = ( hostname [ 0 ] ! = ' \0 ' ? hostname : " " ) ;
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] result = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , result , getLastSocketErrorText ( ) ) ;
2010-08-23 17:17:36 +02:00
}
2010-08-21 00:42:26 +02:00
}
return host ;
2010-03-16 22:37:11 +01:00
}
2010-03-23 03:37:41 +01:00
string Socket : : getIp ( ) {
2010-03-16 22:37:11 +01:00
hostent * info = gethostbyname ( getHostName ( ) . c_str ( ) ) ;
unsigned char * address ;
if ( info = = NULL ) {
throw runtime_error ( " Error getting host by name " ) ;
}
address = reinterpret_cast < unsigned char * > ( info - > h_addr_list [ 0 ] ) ;
if ( address = = NULL ) {
throw runtime_error ( " Error getting host ip " ) ;
}
return
intToStr ( address [ 0 ] ) + " . " +
intToStr ( address [ 1 ] ) + " . " +
intToStr ( address [ 2 ] ) + " . " +
intToStr ( address [ 3 ] ) ;
}
2010-04-13 08:59:30 +02:00
void Socket : : throwException ( string str ) {
string msg = str + " " + getLastSocketErrorFormattedText ( ) ;
throw runtime_error ( msg ) ;
2010-03-16 22:37:11 +01:00
}
// ===============================================
// class ClientSocket
// ===============================================
2010-04-02 04:33:32 +02:00
ClientSocket : : ClientSocket ( ) : Socket ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
stopBroadCastClientThread ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
ClientSocket : : ~ ClientSocket ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
stopBroadCastClientThread ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
void ClientSocket : : stopBroadCastClientThread ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
if ( broadCastClientThread ! = NULL ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-19 00:03:53 +01:00
broadCastClientThread - > shutdownAndWait ( ) ;
2010-04-02 04:33:32 +02:00
delete broadCastClientThread ;
broadCastClientThread = NULL ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
void ClientSocket : : startBroadCastClientThread ( DiscoveredServersInterface * cb ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
ClientSocket : : stopBroadCastClientThread ( ) ;
broadCastClientThread = new BroadCastClientSocketThread ( cb ) ;
2010-06-23 16:49:20 +02:00
broadCastClientThread - > setUniqueID ( string ( __FILE__ ) + string ( " _ " ) + string ( __FUNCTION__ ) ) ;
2010-04-02 04:33:32 +02:00
broadCastClientThread - > start ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
void ClientSocket : : discoverServers ( DiscoveredServersInterface * cb ) {
ClientSocket : : startBroadCastClientThread ( cb ) ;
}
2010-03-16 22:37:11 +01:00
void ClientSocket : : connect ( const Ip & ip , int port )
{
sockaddr_in addr ;
memset ( & addr , 0 , sizeof ( addr ) ) ;
addr . sin_family = AF_INET ;
addr . sin_addr . s_addr = inet_addr ( ip . getString ( ) . c_str ( ) ) ;
addr . sin_port = htons ( port ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Connecting to host [%s] on port = %d \n " , ip . getString ( ) . c_str ( ) , port ) ;
2010-12-30 21:02:30 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Connecting to host [%s] on port = %d \n " , ip . getString ( ) . c_str ( ) , port ) ;
2010-04-13 08:59:30 +02:00
2010-12-30 16:56:02 +01:00
connectedIpAddress = " " ;
2010-03-16 22:37:11 +01:00
int err = : : connect ( sock , reinterpret_cast < const sockaddr * > ( & addr ) , sizeof ( addr ) ) ;
2010-12-19 00:03:53 +01:00
if ( err < 0 ) {
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , ip . getString ( ) . c_str ( ) , port , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , ip . getString ( ) . c_str ( ) , port , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
2010-04-13 08:59:30 +02:00
if ( getLastSocketError ( ) = = PLATFORM_SOCKET_INPROGRESS | |
2010-12-19 00:03:53 +01:00
getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN ) {
2010-03-16 22:37:11 +01:00
fd_set myset ;
struct timeval tv ;
2011-04-24 06:22:19 +02:00
int valopt = 0 ;
socklen_t lon = 0 ;
2010-03-16 22:37:11 +01:00
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-16 22:37:11 +01:00
2010-12-19 00:03:53 +01:00
do {
2010-03-16 22:37:11 +01:00
tv . tv_sec = 10 ;
tv . tv_usec = 0 ;
FD_ZERO ( & myset ) ;
FD_SET ( sock , & myset ) ;
2010-08-07 05:26:38 +02:00
{
2011-02-21 02:34:31 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-10-21 17:21:46 +02:00
err = select ( ( int ) sock + 1 , NULL , & myset , NULL , & tv ) ;
2011-02-15 04:32:14 +01:00
//safeMutex.ReleaseLock();
2010-08-07 05:26:38 +02:00
}
2010-03-16 22:37:11 +01:00
2010-12-30 16:56:02 +01:00
if ( err < 0 & & getLastSocketError ( ) ! = PLATFORM_SOCKET_INTERRUPTED ) {
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Error connecting %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Error connecting %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-12-30 21:02:30 +01:00
2010-03-16 22:37:11 +01:00
break ;
}
2011-04-24 06:22:19 +02:00
else if ( err > 0 ) {
//else if(FD_ISSET(sock, &myset)) {
2010-03-16 22:37:11 +01:00
// Socket selected for write
2011-04-24 06:22:19 +02:00
lon = sizeof ( valopt ) ;
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2010-03-16 22:37:11 +01:00
if ( getsockopt ( sock , SOL_SOCKET , SO_ERROR , ( void * ) ( & valopt ) , & lon ) < 0 )
2010-04-13 08:59:30 +02:00
# else
if ( getsockopt ( sock , SOL_SOCKET , SO_ERROR , ( char * ) ( & valopt ) , & lon ) < 0 )
# endif
2010-03-16 22:37:11 +01:00
{
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Error in getsockopt() %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Error in getsockopt() %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
break ;
}
// Check the value returned...
2010-12-30 16:56:02 +01:00
if ( valopt ) {
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Error in delayed connection() %d - [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , valopt , strerror ( valopt ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Error in delayed connection() %d - [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , valopt , strerror ( valopt ) ) ;
2010-03-16 22:37:11 +01:00
break ;
}
errno = 0 ;
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Apparent recovery for connection sock = %d, err = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Apparent recovery for connection sock = %d, err = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err ) ;
2010-03-16 22:37:11 +01:00
break ;
}
2010-12-30 16:56:02 +01:00
else {
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Timeout in select() - Cancelling! \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Timeout in select() - Cancelling! \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-16 22:37:11 +01:00
disconnectSocket ( ) ;
break ;
}
} while ( 1 ) ;
}
2010-12-30 16:56:02 +01:00
if ( err < 0 ) {
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Before END sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Before END sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
disconnectSocket ( ) ;
}
2010-12-30 16:56:02 +01:00
else {
2011-04-24 06:22:19 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Valid recovery for connection sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Valid recovery for connection sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-12-30 16:56:02 +01:00
connectedIpAddress = ip . getString ( ) ;
2010-03-16 22:37:11 +01:00
}
}
2010-12-30 16:56:02 +01:00
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Connected to host [%s] on port = %d sock = %d err = %d " , ip . getString ( ) . c_str ( ) , port , sock , err ) ;
2010-12-30 21:02:30 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Connected to host [%s] on port = %d sock = %d err = %d " , ip . getString ( ) . c_str ( ) , port , sock , err ) ;
2010-12-30 16:56:02 +01:00
connectedIpAddress = ip . getString ( ) ;
2010-04-13 08:59:30 +02:00
}
2010-03-16 22:37:11 +01:00
}
2010-04-01 08:31:10 +02:00
//=======================================================================
2010-04-02 04:33:32 +02:00
// Function : discovery response thread
// Description: Runs in its own thread to listen for broadcasts from
2010-04-01 08:31:10 +02:00
// other servers
//
2010-05-01 00:54:24 +02:00
BroadCastClientSocketThread : : BroadCastClientSocketThread ( DiscoveredServersInterface * cb ) : BaseThread ( ) {
2010-04-02 04:33:32 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
discoveredServersCB = cb ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
//=======================================================================
// Function : broadcast thread
// Description: Runs in its own thread to send out a broadcast to the local network
// the current broadcast message is <myhostname:my.ip.address.dotted>
//
void BroadCastClientSocketThread : : execute ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-19 00:03:53 +01:00
RunningStatusSafeWrapper runningStatus ( this ) ;
2010-04-01 08:31:10 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Broadcast Client thread is running \n " ) ;
2010-06-15 07:36:07 +02:00
2010-04-01 08:31:10 +02:00
std : : vector < string > foundServers ;
short port ; // The port for the broadcast.
struct sockaddr_in bcSender ; // local socket address for the broadcast.
struct sockaddr_in bcaddr ; // The broadcast address for the receiver.
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET bcfd ; // The file descriptor used for the broadcast.
2010-04-01 08:31:10 +02:00
bool one = true ; // Parameter for "setscokopt".
char buff [ 10024 ] ; // Buffers the data to be broadcasted.
socklen_t alen ;
int nb ; // The number of bytes read.
port = htons ( Socket : : getBroadCastPort ( ) ) ;
// Prepare to receive the broadcast.
bcfd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( bcfd < = 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " socket failed: %s \n " , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-04-01 08:31:10 +02:00
}
else {
// Create the address we are receiving on.
memset ( ( char * ) & bcaddr , 0 , sizeof ( bcaddr ) ) ;
bcaddr . sin_family = AF_INET ;
bcaddr . sin_addr . s_addr = htonl ( INADDR_ANY ) ;
bcaddr . sin_port = port ;
int val = 1 ;
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2010-04-01 08:31:10 +02:00
setsockopt ( bcfd , SOL_SOCKET , SO_REUSEADDR , & val , sizeof ( val ) ) ;
2010-04-13 08:59:30 +02:00
# else
setsockopt ( bcfd , SOL_SOCKET , SO_REUSEADDR , ( char * ) & val , sizeof ( val ) ) ;
# endif
2010-04-01 08:31:10 +02:00
if ( bind ( bcfd , ( struct sockaddr * ) & bcaddr , sizeof ( bcaddr ) ) < 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " bind failed: %s \n " , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-04-01 08:31:10 +02:00
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
Socket : : setBlock ( false , bcfd ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-19 00:03:53 +01:00
try {
2010-04-02 04:33:32 +02:00
// Keep getting packets forever.
2010-12-19 00:03:53 +01:00
for ( time_t elapsed = time ( NULL ) ; difftime ( time ( NULL ) , elapsed ) < = 5 ; ) {
2010-04-02 04:33:32 +02:00
alen = sizeof ( struct sockaddr ) ;
2010-12-19 00:03:53 +01:00
bool gotData = ( nb = recvfrom ( bcfd , buff , 10024 , 0 , ( struct sockaddr * ) & bcSender , & alen ) ) > 0 ;
if ( gotData = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " recvfrom failed: %s \n " , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-04-02 04:33:32 +02:00
}
else {
2010-04-03 04:21:04 +02:00
string fromIP = inet_ntoa ( bcSender . sin_addr ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " broadcast message received: [%s] from: [%s] \n " , buff , fromIP . c_str ( ) ) ;
2010-04-03 04:21:04 +02:00
if ( std : : find ( foundServers . begin ( ) , foundServers . end ( ) , fromIP ) = = foundServers . end ( ) ) {
foundServers . push_back ( fromIP ) ;
2010-04-02 04:33:32 +02:00
}
2010-04-03 04:21:04 +02:00
// For now break as soon as we find a server
2010-04-02 04:33:32 +02:00
break ;
}
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
break ;
}
sleep ( 100 ) ; // send out broadcast every 1 seconds
2010-12-19 00:03:53 +01:00
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-19 00:03:53 +01:00
break ;
}
2010-04-01 09:50:15 +02:00
}
2010-04-01 08:31:10 +02:00
}
2010-04-02 04:33:32 +02:00
catch ( const exception & ex ) {
2010-10-06 22:22:06 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2010-04-02 04:33:32 +02:00
}
catch ( . . . ) {
2010-10-06 22:22:06 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] UNKNOWN Error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] unknown error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
2010-04-01 08:31:10 +02:00
}
2010-04-15 03:19:00 +02:00
# ifndef WIN32
: : close ( bcfd ) ;
bcfd = INVALID_SOCKET ;
# else
: : closesocket ( bcfd ) ;
bcfd = - 1 ;
# endif
2010-04-01 08:31:10 +02:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
2010-04-02 04:33:32 +02:00
// Here we callback into the implementer class
2010-12-19 00:03:53 +01:00
if ( getQuitStatus ( ) = = false & & discoveredServersCB ! = NULL ) {
2010-04-02 04:33:32 +02:00
discoveredServersCB - > DiscoveredServers ( foundServers ) ;
}
2010-06-15 07:36:07 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Broadcast Client thread is exiting \n " ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
2010-03-16 22:37:11 +01:00
// ===============================================
// class ServerSocket
// ===============================================
2010-04-01 08:31:10 +02:00
ServerSocket : : ServerSocket ( ) : Socket ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
2010-12-31 09:21:26 +01:00
upnpdiscoverThread = NULL ;
2010-06-24 03:23:18 +02:00
portBound = false ;
2010-04-01 08:31:10 +02:00
broadCastThread = NULL ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
ServerSocket : : ~ ServerSocket ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
stopBroadCastThread ( ) ;
2010-12-30 19:51:25 +01:00
2010-12-31 09:21:26 +01:00
if ( upnpdiscoverThread ! = NULL ) {
SDL_WaitThread ( upnpdiscoverThread , NULL ) ;
upnpdiscoverThread = NULL ;
}
if ( UPNP_Tools : : enabledUPNP ) {
UPNP_Tools : : NETremRedirects ( ServerSocket : : externalPort ) ;
UPNP_Tools : : enabledUPNP = false ;
2010-12-30 19:51:25 +01:00
}
2010-04-01 08:31:10 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
void ServerSocket : : stopBroadCastThread ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
if ( broadCastThread ! = NULL ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-26 21:50:18 +02:00
2011-01-13 02:46:32 +01:00
if ( broadCastThread - > canShutdown ( true ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-01-13 02:46:32 +01:00
if ( broadCastThread - > shutdownAndWait ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-01-13 02:46:32 +01:00
delete broadCastThread ;
}
}
2010-04-01 08:31:10 +02:00
broadCastThread = NULL ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
void ServerSocket : : startBroadCastThread ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
stopBroadCastThread ( ) ;
broadCastThread = new BroadCastSocketThread ( ) ;
2010-06-23 16:49:20 +02:00
broadCastThread - > setUniqueID ( string ( __FILE__ ) + string ( " _ " ) + string ( __FUNCTION__ ) ) ;
2010-04-01 08:31:10 +02:00
broadCastThread - > start ( ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
2010-04-12 23:40:57 +02:00
bool ServerSocket : : isBroadCastThreadRunning ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-12 23:40:57 +02:00
bool isThreadRunning = ( broadCastThread ! = NULL & & broadCastThread - > getRunningStatus ( ) = = true ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] isThreadRunning = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , isThreadRunning ) ;
2010-04-12 23:40:57 +02:00
return isThreadRunning ;
}
2010-06-24 03:23:18 +02:00
void ServerSocket : : bind ( int port ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d port = %d, portBound = %d START \n " , __FILE__ , __FUNCTION__ , __LINE__ , port , portBound ) ;
2010-06-24 03:23:18 +02:00
2010-05-12 17:25:56 +02:00
boundPort = port ;
2010-06-24 03:23:18 +02:00
if ( isSocketValid ( ) = = false ) {
sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ;
if ( isSocketValid ( ) = = false ) {
throwException ( " Error creating socket " ) ;
}
setBlock ( false ) ;
}
2010-03-16 22:37:11 +01:00
//sockaddr structure
sockaddr_in addr ;
addr . sin_family = AF_INET ;
addr . sin_addr . s_addr = INADDR_ANY ;
addr . sin_port = htons ( port ) ;
int val = 1 ;
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2010-03-16 22:37:11 +01:00
setsockopt ( sock , SOL_SOCKET , SO_REUSEADDR , & val , sizeof ( val ) ) ;
2010-04-13 08:59:30 +02:00
# else
setsockopt ( sock , SOL_SOCKET , SO_REUSEADDR , ( char * ) & val , sizeof ( val ) ) ;
# endif
2010-03-16 22:37:11 +01:00
int err = : : bind ( sock , reinterpret_cast < sockaddr * > ( & addr ) , sizeof ( addr ) ) ;
if ( err < 0 )
{
char szBuf [ 1024 ] = " " ;
2010-04-13 08:59:30 +02:00
sprintf ( szBuf , " In [%s::%s] Error binding socket sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " %s " , szBuf ) ;
2010-06-11 06:55:49 +02:00
sprintf ( szBuf , " Error binding socket sock = %d, err = %d, error = %s \n " , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
2010-03-16 22:37:11 +01:00
}
2010-06-24 03:23:18 +02:00
portBound = true ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d port = %d, portBound = %d END \n " , __FILE__ , __FUNCTION__ , __LINE__ , port , portBound ) ;
2010-06-24 03:23:18 +02:00
}
void ServerSocket : : disconnectSocket ( ) {
Socket : : disconnectSocket ( ) ;
portBound = false ;
2010-03-16 22:37:11 +01:00
}
2010-05-12 17:25:56 +02:00
void ServerSocket : : listen ( int connectionQueueSize ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d connectionQueueSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , connectionQueueSize ) ;
2010-05-12 17:25:56 +02:00
if ( connectionQueueSize > 0 ) {
if ( isSocketValid ( ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-05-12 17:25:56 +02:00
sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ;
if ( isSocketValid ( ) = = false ) {
throwException ( " Error creating socket " ) ;
}
setBlock ( false ) ;
2010-06-24 03:23:18 +02:00
}
if ( portBound = = false ) {
2010-05-12 17:25:56 +02:00
bind ( boundPort ) ;
}
int err = : : listen ( sock , connectionQueueSize ) ;
if ( err < 0 ) {
char szBuf [ 1024 ] = " " ;
sprintf ( szBuf , " In [%s::%s] Error listening socket sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
throwException ( szBuf ) ;
}
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-05-12 17:25:56 +02:00
disconnectSocket ( ) ;
2010-03-16 22:37:11 +01:00
}
2010-04-01 08:31:10 +02:00
2010-04-12 23:40:57 +02:00
if ( connectionQueueSize > 0 ) {
if ( isBroadCastThreadRunning ( ) = = false ) {
startBroadCastThread ( ) ;
}
}
else {
stopBroadCastThread ( ) ;
}
2010-03-16 22:37:11 +01:00
}
2010-06-24 03:23:18 +02:00
Socket * ServerSocket : : accept ( ) {
if ( isSocketValid ( ) = = false ) {
throwException ( " socket is invalid! " ) ;
}
2010-05-17 08:41:05 +02:00
struct sockaddr_in cli_addr ;
socklen_t clilen = sizeof ( cli_addr ) ;
2010-06-04 21:42:58 +02:00
char client_host [ 100 ] = " " ;
2011-02-15 08:49:40 +01:00
MutexSafeWrapper safeMutex ( & dataSynchAccessorRead , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-05-17 08:41:05 +02:00
PLATFORM_SOCKET newSock = : : accept ( sock , ( struct sockaddr * ) & cli_addr , & clilen ) ;
2010-08-21 01:53:10 +02:00
safeMutex . ReleaseLock ( ) ;
2011-01-09 05:49:21 +01:00
if ( isSocketValid ( & newSock ) = = false ) {
2010-03-16 22:37:11 +01:00
char szBuf [ 1024 ] = " " ;
2011-01-09 05:49:21 +01:00
sprintf ( szBuf , " In [%s::%s Line: %d] Error accepting socket connection sock = %d, err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , newSock , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , szBuf ) ;
2010-03-16 22:37:11 +01:00
2010-04-13 08:59:30 +02:00
if ( getLastSocketError ( ) = = PLATFORM_SOCKET_TRY_AGAIN )
2010-03-16 22:37:11 +01:00
{
return NULL ;
}
throwException ( szBuf ) ;
}
2010-05-12 17:25:56 +02:00
else {
2010-05-17 08:41:05 +02:00
sprintf ( client_host , " %s " , inet_ntoa ( cli_addr . sin_addr ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] got connection, newSock = %d client_host [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , newSock , client_host ) ;
2010-05-12 17:25:56 +02:00
}
2011-04-13 06:04:08 +02:00
if ( isIPAddressBlocked ( client_host ) = = true ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] BLOCKING connection, newSock = %d client_host [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , newSock , client_host ) ;
2011-04-13 07:07:47 +02:00
# ifndef WIN32
: : close ( newSock ) ;
newSock = INVALID_SOCKET ;
# else
: : closesocket ( newSock ) ;
newSock = - 1 ;
# endif
2011-04-13 06:04:08 +02:00
return NULL ;
}
2010-06-04 21:42:58 +02:00
Socket * result = new Socket ( newSock ) ;
result - > setIpAddress ( client_host ) ;
return result ;
2010-03-16 22:37:11 +01:00
}
2010-12-31 09:21:26 +01:00
void ServerSocket : : NETdiscoverUPnPDevices ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] UPNP - Start \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
if ( upnpdiscoverThread ! = NULL ) {
SDL_WaitThread ( upnpdiscoverThread , NULL ) ;
upnpdiscoverThread = NULL ;
}
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
// WATCH OUT! Because the thread takes void * as a parameter we MUST cast to the pointer type
// used on the other side (inside the thread)
upnpdiscoverThread = SDL_CreateThread ( & UPNP_Tools : : upnp_init , dynamic_cast < UPNPInitInterface * > ( this ) ) ;
}
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
void ServerSocket : : UPNPInitStatus ( bool result ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] result = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , result ) ;
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
if ( result = = true ) {
2011-01-06 01:52:00 +01:00
//int ports[4] = { this->getExternalPort(), this->getBindPort(), this->getFTPServerPort(), this->getFTPServerPort() };
std : : vector < int > UPNPPortForwardList ;
// Glest Game Server port
UPNPPortForwardList . push_back ( this - > getExternalPort ( ) ) ;
UPNPPortForwardList . push_back ( this - > getBindPort ( ) ) ;
// Glest mini FTP Server Listen Port
UPNPPortForwardList . push_back ( this - > getFTPServerPort ( ) ) ;
UPNPPortForwardList . push_back ( this - > getFTPServerPort ( ) ) ;
// GLest mini FTP Server Passive file TRansfer ports (1 per game player)
for ( int clientIndex = 1 ; clientIndex < = ServerSocket : : maxPlayerCount ; + + clientIndex ) {
UPNPPortForwardList . push_back ( this - > getFTPServerPort ( ) + clientIndex ) ;
UPNPPortForwardList . push_back ( this - > getFTPServerPort ( ) + clientIndex ) ;
}
UPNP_Tools : : NETaddRedirects ( UPNPPortForwardList ) ;
2010-12-31 09:21:26 +01:00
}
}
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
//
// UPNP Tools Start
//
void UPNP_Tools : : AddUPNPPortForward ( int internalPort , int externalPort ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] internalPort = %d, externalPort = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , internalPort , externalPort ) ;
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
bool addPorts = ( UPNP_Tools : : enabledUPNP = = true ) ;
if ( addPorts = = false ) {
int result = UPNP_Tools : : upnp_init ( NULL ) ;
addPorts = ( result ! = 0 ) ;
}
2010-12-30 16:56:02 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] internalPort = %d, externalPort = %d, addPorts = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , internalPort , externalPort , addPorts ) ;
2010-12-30 16:56:02 +01:00
2010-12-31 09:21:26 +01:00
if ( addPorts = = true ) {
int ports [ 2 ] = { externalPort , internalPort } ;
UPNP_Tools : : upnp_add_redirect ( ports ) ;
}
2010-12-30 16:56:02 +01:00
}
2010-12-31 09:21:26 +01:00
void UPNP_Tools : : RemoveUPNPPortForward ( int internalPort , int externalPort ) {
UPNP_Tools : : upnp_rem_redirect ( externalPort ) ;
2011-01-20 16:56:30 +01:00
}
2010-12-21 06:07:10 +01:00
//
2010-12-31 09:21:26 +01:00
// This code below handles Universal Plug and Play Router Discovery
2010-12-21 06:07:10 +01:00
//
2010-12-31 09:21:26 +01:00
int UPNP_Tools : : upnp_init ( void * param ) {
struct UPNPDev * devlist = NULL ;
struct UPNPDev * dev = NULL ;
char * descXML = NULL ;
int descXMLsize = 0 ;
char buf [ 255 ] = " " ;
// Callers MUST pass in NULL or a UPNPInitInterface *
UPNPInitInterface * callback = ( UPNPInitInterface * ) ( param ) ;
2010-12-21 06:07:10 +01:00
memset ( & urls , 0 , sizeof ( struct UPNPUrls ) ) ;
memset ( & data , 0 , sizeof ( struct IGDdatas ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] isUPNP = %d callback = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , UPNP_Tools : : isUPNP , callback ) ;
2010-12-21 06:07:10 +01:00
2010-12-31 09:21:26 +01:00
if ( UPNP_Tools : : isUPNP ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Searching for UPnP devices for automatic port forwarding... \n " ) ;
2010-12-21 06:07:10 +01:00
devlist = upnpDiscover ( 2000 , NULL , NULL , 0 ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP device search finished. \n " ) ;
2010-12-21 06:07:10 +01:00
if ( devlist ) {
dev = devlist ;
while ( dev ) {
2010-12-31 09:21:26 +01:00
if ( strstr ( dev - > st , " InternetGatewayDevice " ) ) {
2010-12-21 06:07:10 +01:00
break ;
2010-12-31 09:21:26 +01:00
}
2010-12-21 06:07:10 +01:00
dev = dev - > pNext ;
}
if ( ! dev ) {
dev = devlist ; /* defaulting to first device */
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP device found: %s %s \n " , dev - > descURL , dev - > st ) ;
2010-12-21 06:07:10 +01:00
descXML = ( char * ) miniwget_getaddr ( dev - > descURL , & descXMLsize , lanaddr , sizeof ( lanaddr ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " LAN address: %s \n " , lanaddr ) ;
2010-12-21 06:07:10 +01:00
if ( descXML ) {
parserootdesc ( descXML , descXMLsize , & data ) ;
free ( descXML ) ; descXML = 0 ;
GetUPNPUrls ( & urls , & data , dev - > descURL ) ;
}
sprintf ( buf , " UPnP device found: %s %s LAN address %s " , dev - > descURL , dev - > st , lanaddr ) ;
2010-12-31 09:21:26 +01:00
2010-12-21 06:07:10 +01:00
freeUPNPDevlist ( devlist ) ;
if ( ! urls . controlURL | | urls . controlURL [ 0 ] = = ' \0 ' ) {
sprintf ( buf , " controlURL not available, UPnP disabled " ) ;
2010-12-31 09:21:26 +01:00
if ( callback ) {
callback - > UPNPInitStatus ( false ) ;
}
2010-12-21 06:07:10 +01:00
return false ;
}
2010-12-31 09:21:26 +01:00
char externalIP [ 16 ] = " " ;
2011-05-27 08:37:43 +02:00
# ifndef MEGAGLEST_EMBEDDED_MINIUPNPC
UPNP_GetExternalIPAddress ( urls . controlURL , data . first . servicetype , externalIP ) ;
# else
2010-12-31 09:21:26 +01:00
UPNP_GetExternalIPAddress ( urls . controlURL , data . servicetype , externalIP ) ;
2011-05-27 08:37:43 +02:00
# endif
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP device found at: [%s] callback [%p] \n " , externalIP , callback ) ;
2010-12-31 09:21:26 +01:00
//UPNP_Tools::NETaddRedirects(ports);
UPNP_Tools : : enabledUPNP = true ;
if ( callback ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-31 09:21:26 +01:00
callback - > UPNPInitStatus ( true ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-31 09:21:26 +01:00
}
2010-12-21 06:07:10 +01:00
return true ;
}
sprintf ( buf , " UPnP device not found. " ) ;
2010-12-31 09:21:26 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " No UPnP devices found. \n " ) ;
2010-12-21 06:07:10 +01:00
2010-12-31 09:21:26 +01:00
if ( callback ) {
callback - > UPNPInitStatus ( false ) ;
}
2010-12-21 06:07:10 +01:00
return false ;
}
else {
sprintf ( buf , " UPnP detection routine disabled by user. " ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP detection routine disabled by user. \n " ) ;
2010-12-21 06:07:10 +01:00
2010-12-31 09:21:26 +01:00
if ( callback ) {
callback - > UPNPInitStatus ( false ) ;
}
2010-12-21 06:07:10 +01:00
return false ;
}
}
2010-12-31 09:21:26 +01:00
bool UPNP_Tools : : upnp_add_redirect ( int ports [ 2 ] ) {
char externalIP [ 16 ] = " " ;
char ext_port_str [ 16 ] = " " ;
char int_port_str [ 16 ] = " " ;
int r = 0 ;
2010-12-21 06:07:10 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] upnp_add_redir(%d : %d) \n " , __FILE__ , __FUNCTION__ , __LINE__ , ports [ 0 ] , ports [ 1 ] ) ;
2010-12-21 06:07:10 +01:00
2011-05-27 08:37:43 +02:00
# ifndef MEGAGLEST_EMBEDDED_MINIUPNPC
UPNP_GetExternalIPAddress ( urls . controlURL , data . first . servicetype , externalIP ) ;
# else
2010-12-21 06:07:10 +01:00
UPNP_GetExternalIPAddress ( urls . controlURL , data . servicetype , externalIP ) ;
2011-05-27 08:37:43 +02:00
# endif
2010-12-21 06:07:10 +01:00
sprintf ( ext_port_str , " %d " , ports [ 0 ] ) ;
sprintf ( int_port_str , " %d " , ports [ 1 ] ) ;
2011-05-27 08:37:43 +02:00
# ifndef MEGAGLEST_EMBEDDED_MINIUPNPC
r = UPNP_AddPortMapping ( urls . controlURL , data . first . servicetype , ext_port_str , int_port_str , lanaddr , " MegaGlest - www.megaglest.org " , " TCP " , 0 ) ;
# else
2010-12-31 09:21:26 +01:00
r = UPNP_AddPortMapping ( urls . controlURL , data . servicetype , ext_port_str , int_port_str , lanaddr , " MegaGlest - www.megaglest.org " , " TCP " , 0 ) ;
2011-05-27 08:37:43 +02:00
# endif
2010-12-21 06:07:10 +01:00
if ( r ! = UPNPCOMMAND_SUCCESS ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) failed \n " , __FILE__ , __FUNCTION__ , __LINE__ , ext_port_str , int_port_str , lanaddr ) ;
2010-12-21 06:07:10 +01:00
return false ;
}
2010-12-29 21:28:25 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) success \n " , __FILE__ , __FUNCTION__ , __LINE__ , ext_port_str , int_port_str , lanaddr ) ;
2010-12-21 06:07:10 +01:00
return true ;
}
2010-12-31 09:21:26 +01:00
void UPNP_Tools : : upnp_rem_redirect ( int ext_port ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] upnp_rem_redir(%d) \n " , __FILE__ , __FUNCTION__ , __LINE__ , ext_port ) ;
2010-12-31 09:21:26 +01:00
2011-06-01 21:06:14 +02:00
if ( urls . controlURL ! = NULL ) {
char ext_port_str [ 16 ] = " " ;
sprintf ( ext_port_str , " %d " , ext_port ) ;
2011-06-01 21:07:28 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #1 DEBUGGUNG urls.controlURL [%s] \n " , urls . controlURL ) ;
2011-06-01 21:06:14 +02:00
# ifndef MEGAGLEST_EMBEDDED_MINIUPNPC
2011-06-01 21:07:28 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #1 DEBUGGUNG data.first.servicetype [%s] \n " , data . first . servicetype ) ;
2011-06-01 21:06:14 +02:00
UPNP_DeletePortMapping ( urls . controlURL , data . first . servicetype , ext_port_str , " TCP " , 0 ) ;
# else
2011-06-01 21:07:28 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #1 DEBUGGUNG data.servicetype [%s] \n " , data . servicetype ) ;
2011-06-01 21:06:14 +02:00
UPNP_DeletePortMapping ( urls . controlURL , data . servicetype , ext_port_str , " TCP " , 0 ) ;
# endif
}
2011-06-01 21:07:28 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #2 DEBUGGUNG urls.controlURL [%s] \n " , urls . controlURL ) ;
2010-12-21 06:07:10 +01:00
}
2011-01-06 01:52:00 +01:00
void UPNP_Tools : : NETaddRedirects ( std : : vector < int > UPNPPortForwardList ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] upnp_rem_redir(%d) \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-31 09:21:26 +01:00
2011-01-06 01:52:00 +01:00
if ( UPNPPortForwardList . size ( ) % 2 ! = 0 ) {
// We need groups of 2 ports.. one external and one internal for opening ports on UPNP router
throw runtime_error ( " UPNPPortForwardList.size() MUST BE divisable by 2 " ) ;
}
2011-01-07 07:28:42 +01:00
for ( unsigned int clientIndex = 0 ; clientIndex < UPNPPortForwardList . size ( ) ; clientIndex + = 2 ) {
2011-01-06 01:52:00 +01:00
int ports [ 2 ] = { UPNPPortForwardList [ clientIndex ] , UPNPPortForwardList [ clientIndex + 1 ] } ;
upnp_add_redirect ( ports ) ;
}
2010-12-21 06:07:10 +01:00
}
2010-12-31 09:21:26 +01:00
void UPNP_Tools : : NETremRedirects ( int ext_port ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] upnp_rem_redir(%d) \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-30 19:51:25 +01:00
upnp_rem_redirect ( ext_port ) ;
2010-12-21 06:07:10 +01:00
}
2010-12-31 09:21:26 +01:00
//
// UPNP Tools END
//
2010-04-01 08:31:10 +02:00
//=======================================================================
// Function : broadcast_thread
// in : none
// return : none
// Description: To be forked in its own thread to send out a broadcast to the local subnet
// the current broadcast message is <myhostname:my.ip.address.dotted>
//
2010-12-21 06:07:10 +01:00
BroadCastSocketThread : : BroadCastSocketThread ( ) : BaseThread ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-21 06:07:10 +01:00
}
2011-01-13 02:46:32 +01:00
bool BroadCastSocketThread : : canShutdown ( bool deleteSelfIfShutdownDelayed ) {
bool ret = ( getExecutingTask ( ) = = false ) ;
if ( ret = = false & & deleteSelfIfShutdownDelayed = = true ) {
setDeleteSelfOnExecutionDone ( deleteSelfIfShutdownDelayed ) ;
signalQuit ( ) ;
}
return ret ;
}
2010-04-01 08:31:10 +02:00
void BroadCastSocketThread : : execute ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-19 00:03:53 +01:00
//setRunningStatus(true);
RunningStatusSafeWrapper runningStatus ( this ) ;
2011-01-13 02:46:32 +01:00
ExecutingTaskSafeWrapper safeExecutingTaskMutex ( this ) ;
2010-04-01 08:31:10 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Broadcast thread is running \n " ) ;
2010-06-15 07:36:07 +02:00
2010-04-11 09:13:14 +02:00
const int MAX_NIC_COUNT = 10 ;
2010-10-23 07:12:28 +02:00
short port = 0 ; // The port for the broadcast.
2010-04-11 09:13:14 +02:00
struct sockaddr_in bcLocal [ MAX_NIC_COUNT ] ; // local socket address for the broadcast.
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET bcfd [ MAX_NIC_COUNT ] ; // The socket used for the broadcast.
2010-04-01 08:31:10 +02:00
bool one = true ; // Parameter for "setscokopt".
2010-10-23 07:12:28 +02:00
int pn = 0 ; // The number of the packet broadcasted.
char buff [ 1024 ] = " " ; // Buffers the data to be broadcasted.
char myhostname [ 100 ] = " " ; // hostname of local machine
//char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
struct hostent * myhostent = NULL ;
2010-04-01 08:31:10 +02:00
/* get my host name */
gethostname ( myhostname , 100 ) ;
myhostent = gethostbyname ( myhostname ) ;
2010-04-11 09:13:14 +02:00
// get all host IP addresses
2010-04-01 08:31:10 +02:00
std : : vector < std : : string > ipList = Socket : : getLocalIPAddressList ( ) ;
2010-10-23 07:12:28 +02:00
// Subnet, IP Address
std : : vector < std : : string > ipSubnetMaskList ;
2010-04-11 09:13:14 +02:00
for ( unsigned int idx = 0 ; idx < ipList . size ( ) & & idx < MAX_NIC_COUNT ; idx + + ) {
string broadCastAddress = getNetworkInterfaceBroadcastAddress ( ipList [ idx ] ) ;
2010-10-23 07:12:28 +02:00
//strcpy(subnetmask[idx], broadCastAddress.c_str());
if ( broadCastAddress ! = " " & & std : : find ( ipSubnetMaskList . begin ( ) , ipSubnetMaskList . end ( ) , broadCastAddress ) = = ipSubnetMaskList . end ( ) ) {
ipSubnetMaskList . push_back ( broadCastAddress ) ;
}
2010-04-11 09:13:14 +02:00
}
2010-04-02 04:33:32 +02:00
port = htons ( Socket : : getBroadCastPort ( ) ) ;
2010-04-01 08:31:10 +02:00
2010-10-23 07:12:28 +02:00
//for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) {
for ( unsigned int idx = 0 ; idx < ipSubnetMaskList . size ( ) ; idx + + ) {
2010-04-11 09:13:14 +02:00
// Create the broadcast socket
memset ( & bcLocal [ idx ] , 0 , sizeof ( struct sockaddr_in ) ) ;
bcLocal [ idx ] . sin_family = AF_INET ;
2010-10-23 07:12:28 +02:00
bcLocal [ idx ] . sin_addr . s_addr = inet_addr ( ipSubnetMaskList [ idx ] . c_str ( ) ) ; //htonl( INADDR_BROADCAST );
2010-04-11 09:13:14 +02:00
bcLocal [ idx ] . sin_port = port ; // We are letting the OS fill in the port number for the local machine.
2010-06-14 23:03:23 +02:00
# ifdef WIN32
bcfd [ idx ] = INVALID_SOCKET ;
# else
bcfd [ idx ] = - 1 ;
# endif
2010-10-23 07:12:28 +02:00
//if(strlen(subnetmask[idx]) > 0) {
bcfd [ idx ] = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( bcfd [ idx ] < = 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Unable to allocate broadcast socket [%s]: %s \n " , ipSubnetMaskList [ idx ] . c_str ( ) , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-10-23 07:12:28 +02:00
//exit(-1);
2010-04-11 09:13:14 +02:00
}
2010-10-23 07:12:28 +02:00
// Mark the socket for broadcast.
else if ( setsockopt ( bcfd [ idx ] , SOL_SOCKET , SO_BROADCAST , ( const char * ) & one , sizeof ( int ) ) < 0 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Could not set socket to broadcast [%s]: %s \n " , ipSubnetMaskList [ idx ] . c_str ( ) , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-10-23 07:12:28 +02:00
//exit(-1);
}
//}
2010-04-01 08:31:10 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] setting up broadcast on address [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ipSubnetMaskList [ idx ] . c_str ( ) ) ;
2010-04-02 04:33:32 +02:00
}
2010-04-01 08:31:10 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
2010-04-11 09:13:14 +02:00
time_t elapsed = 0 ;
2010-10-23 07:12:28 +02:00
for ( pn = 1 ; getQuitStatus ( ) = = false ; pn + + ) {
for ( unsigned int idx = 0 ; getQuitStatus ( ) = = false & & idx < ipSubnetMaskList . size ( ) ; idx + + ) {
2010-04-15 03:19:00 +02:00
if ( Socket : : isSocketValid ( & bcfd [ idx ] ) = = true ) {
2010-04-11 09:13:14 +02:00
try {
// Send this machine's host name and address in hostname:n.n.n.n format
sprintf ( buff , " %s " , myhostname ) ;
for ( unsigned int idx1 = 0 ; idx1 < ipList . size ( ) ; idx1 + + ) {
sprintf ( buff , " %s:%s " , buff , ipList [ idx1 ] . c_str ( ) ) ;
}
2010-04-01 08:31:10 +02:00
2010-08-26 21:50:18 +02:00
if ( difftime ( time ( NULL ) , elapsed ) > = 1 & & getQuitStatus ( ) = = false ) {
2010-04-11 09:13:14 +02:00
elapsed = time ( NULL ) ;
// Broadcast the packet to the subnet
//if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
2010-10-23 07:12:28 +02:00
if ( sendto ( bcfd [ idx ] , buff , sizeof ( buff ) + 1 , 0 , ( struct sockaddr * ) & bcLocal [ idx ] , sizeof ( struct sockaddr_in ) ) ! = sizeof ( buff ) + 1 ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Sendto error: %s \n " , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-04-11 09:13:14 +02:00
}
else {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Broadcasting on port [%d] the message: [%s] \n " , Socket : : getBroadCastPort ( ) , buff ) ;
2010-04-11 09:13:14 +02:00
}
2010-04-01 08:31:10 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-02 04:33:32 +02:00
}
2010-04-11 09:13:14 +02:00
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-11 09:13:14 +02:00
break ;
2010-04-01 08:31:10 +02:00
}
2010-10-23 07:12:28 +02:00
sleep ( 100 ) ; // send out broadcast every 1 seconds
2010-04-01 08:31:10 +02:00
}
2010-04-11 09:13:14 +02:00
catch ( const exception & ex ) {
2010-10-06 22:22:06 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2010-08-26 21:50:18 +02:00
this - > setQuitStatus ( true ) ;
2010-04-11 09:13:14 +02:00
}
catch ( . . . ) {
2010-10-06 22:22:06 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] UNKNOWN Error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] unknown error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-26 21:50:18 +02:00
this - > setQuitStatus ( true ) ;
2010-04-01 08:31:10 +02:00
}
}
2010-04-11 09:13:14 +02:00
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-11 09:13:14 +02:00
break ;
}
2010-04-02 04:33:32 +02:00
}
2010-04-11 09:13:14 +02:00
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-11 09:13:14 +02:00
break ;
2010-04-02 04:33:32 +02:00
}
}
2010-04-01 08:31:10 +02:00
2010-10-23 07:12:28 +02:00
for ( unsigned int idx = 0 ; idx < ipSubnetMaskList . size ( ) ; idx + + ) {
2010-04-15 03:19:00 +02:00
if ( Socket : : isSocketValid ( & bcfd [ idx ] ) = = true ) {
# ifndef WIN32
: : close ( bcfd [ idx ] ) ;
bcfd [ idx ] = INVALID_SOCKET ;
# else
: : closesocket ( bcfd [ idx ] ) ;
bcfd [ idx ] = - 1 ;
# endif
}
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Broadcast thread is exiting \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-01 08:31:10 +02:00
}
2010-09-06 08:22:08 +02:00
double Socket : : getAveragePingMS ( std : : string host , int pingCount ) {
2010-06-04 21:42:58 +02:00
double result = - 1 ;
2010-06-05 02:00:36 +02:00
return result ;
2010-06-04 21:42:58 +02:00
2010-06-05 02:00:36 +02:00
/*
2010-06-04 22:37:42 +02:00
const bool debugPingOutput = false ;
2010-06-04 21:42:58 +02:00
char szCmd [ 1024 ] = " " ;
# ifdef WIN32
sprintf ( szCmd , " ping -n %d %s " , pingCount , host . c_str ( ) ) ;
2010-06-04 22:26:15 +02:00
if ( debugPingOutput ) printf ( " WIN32 is defined \n " ) ;
# elif defined(__GNUC__)
2010-06-04 21:42:58 +02:00
sprintf ( szCmd , " ping -c %d %s " , pingCount , host . c_str ( ) ) ;
2010-06-04 22:26:15 +02:00
if ( debugPingOutput ) printf ( " NON WIN32 is defined \n " ) ;
# else
# error "Your compiler needs to support popen!"
2010-06-04 21:42:58 +02:00
# endif
if ( szCmd [ 0 ] ! = ' \0 ' ) {
2010-06-04 22:11:31 +02:00
FILE * ping = NULL ;
2010-06-04 22:26:15 +02:00
# ifdef WIN32
2010-06-04 22:11:31 +02:00
ping = _popen ( szCmd , " r " ) ;
2010-06-04 22:26:15 +02:00
if ( debugPingOutput ) printf ( " WIN32 style _popen \n " ) ;
# elif defined(__GNUC__)
2010-06-04 22:11:31 +02:00
ping = popen ( szCmd , " r " ) ;
2010-06-04 22:26:15 +02:00
if ( debugPingOutput ) printf ( " POSIX style _popen \n " ) ;
# else
# error "Your compiler needs to support popen!"
2010-06-04 21:55:42 +02:00
# endif
2010-06-04 21:42:58 +02:00
if ( ping ! = NULL ) {
char buf [ 4000 ] = " " ;
int bufferPos = 0 ;
for ( ; feof ( ping ) = = false ; ) {
char * data = fgets ( & buf [ bufferPos ] , 256 , ping ) ;
bufferPos = strlen ( buf ) ;
}
2010-06-04 22:26:15 +02:00
# ifdef WIN32
2010-06-04 21:55:42 +02:00
_pclose ( ping ) ;
2010-06-04 22:26:15 +02:00
# elif defined(__GNUC__)
2010-06-04 21:42:58 +02:00
pclose ( ping ) ;
2010-06-04 22:26:15 +02:00
# else
# error "Your compiler needs to support popen!"
2010-06-04 21:55:42 +02:00
# endif
2010-06-04 21:42:58 +02:00
if ( debugPingOutput ) printf ( " Running cmd [%s] got [%s] \n " , szCmd , buf ) ;
// Linux
//softcoder@softhauslinux:~/Code/megaglest/trunk/mk/linux$ ping -c 5 soft-haus.com
//PING soft-haus.com (65.254.250.110) 56(84) bytes of data.
//64 bytes from 65-254-250-110.yourhostingaccount.com (65.254.250.110): icmp_seq=1 ttl=242 time=133 ms
//64 bytes from 65-254-250-110.yourhostingaccount.com (65.254.250.110): icmp_seq=2 ttl=242 time=137 ms
//
// Windows XP
//C:\Code\megaglest\trunk\data\glest_game>ping -n 5 soft-haus.com
//
//Pinging soft-haus.com [65.254.250.110] with 32 bytes of data:
//
//Reply from 65.254.250.110: bytes=32 time=125ms TTL=242
//Reply from 65.254.250.110: bytes=32 time=129ms TTL=242
std : : string str = buf ;
std : : string : : size_type ms_pos = 0 ;
int count = 0 ;
while ( ms_pos ! = std : : string : : npos ) {
ms_pos = str . find ( " time= " , ms_pos ) ;
if ( debugPingOutput ) printf ( " count = %d ms_pos = %d \n " , count , ms_pos ) ;
if ( ms_pos ! = std : : string : : npos ) {
+ + count ;
int endPos = str . find ( " ms " , ms_pos + 5 ) ;
if ( debugPingOutput ) printf ( " count = %d endPos = %d \n " , count , endPos ) ;
if ( endPos = = std : : string : : npos ) {
endPos = str . find ( " ms " , ms_pos + 5 ) ;
if ( debugPingOutput ) printf ( " count = %d endPos = %d \n " , count , endPos ) ;
}
if ( endPos ! = std : : string : : npos ) {
if ( count = = 1 ) {
result = 0 ;
}
int startPos = ms_pos + 5 ;
int posLength = endPos - startPos ;
if ( debugPingOutput ) printf ( " count = %d startPos = %d posLength = %d str = [%s] \n " , count , startPos , posLength , str . substr ( startPos , posLength ) . c_str ( ) ) ;
float pingMS = strToFloat ( str . substr ( startPos , posLength ) ) ;
result + = pingMS ;
}
ms_pos + = 5 ; // start next search after this "time="
}
}
if ( result > 0 & & count > 1 ) {
result / = count ;
}
}
}
return result ;
2010-06-05 02:00:36 +02:00
*/
2010-06-04 21:42:58 +02:00
}
std : : string Socket : : getIpAddress ( ) {
return ipAddress ;
}
2010-04-01 08:31:10 +02:00
2011-04-13 06:04:08 +02:00
void ServerSocket : : addIPAddressToBlockedList ( string value ) {
if ( isIPAddressBlocked ( value ) = = false ) {
blockIPList . push_back ( value ) ;
}
}
bool ServerSocket : : isIPAddressBlocked ( string value ) const {
bool result = ( std : : find ( blockIPList . begin ( ) , blockIPList . end ( ) , value ) ! = blockIPList . end ( ) ) ;
return result ;
}
void ServerSocket : : removeBlockedIPAddress ( string value ) {
vector < string > : : iterator iterFind = std : : find ( blockIPList . begin ( ) , blockIPList . end ( ) , value ) ;
if ( iterFind ! = blockIPList . end ( ) ) {
blockIPList . erase ( iterFind ) ;
}
}
void ServerSocket : : clearBlockedIPAddress ( ) {
blockIPList . clear ( ) ;
}
bool ServerSocket : : hasBlockedIPAddresses ( ) const {
return ( blockIPList . size ( ) > 0 ) ;
}
2010-03-16 22:37:11 +01:00
} } //end namespace