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>
2012-04-20 03:04:05 +02:00
# include <winsock2.h>
2010-04-13 08:59:30 +02:00
# include <winsock.h>
2017-09-23 01:58:54 +02:00
# include <ws2tcpip.h>
2010-04-13 08:59:30 +02:00
# include <iphlpapi.h>
2017-09-23 01:58:54 +02:00
2010-04-13 09:29:48 +02:00
# include <strstream>
2014-01-01 22:24:24 +01:00
# include <strsafe.h>
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>
2011-11-27 01:11:18 +01:00
# include <netinet/tcp.h>
2010-04-11 09:13:14 +02:00
# endif
2011-11-27 01:11:18 +01:00
2010-04-11 09:13:14 +02:00
# 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 {
2011-11-27 01:07:55 +01:00
bool Socket : : disableNagle = false ;
int Socket : : DEFAULT_SOCKET_SENDBUF_SIZE = - 1 ;
int Socket : : DEFAULT_SOCKET_RECVBUF_SIZE = - 1 ;
2016-01-01 01:48:55 +01:00
string Socket : : host_name = " " ;
2016-06-02 05:16:34 +02:00
std : : vector < string > Socket : : intfTypes ;
2011-11-27 01:07:55 +01:00
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 ;
2011-10-23 02:55:34 +02:00
SDL_Thread * ServerSocket : : upnpdiscoverThread = NULL ;
2014-01-04 00:10:30 +01:00
bool ServerSocket : : cancelUpnpdiscoverThread = false ;
2011-10-23 02:55:34 +02:00
Mutex ServerSocket : : mutexUpnpdiscoverThread ;
2010-12-21 06:07:10 +01:00
//
// 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 ;
2011-11-23 09:00:09 +01:00
Mutex UPNP_Tools : : mutexUPNP ;
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
2013-05-15 02:45:34 +02:00
//#define PLATFORM_SOCKET_TRY_AGAIN WSAEWOULDBLOCK
//#define PLATFORM_SOCKET_INPROGRESS WSAEINPROGRESS
//#define PLATFORM_SOCKET_INTERRUPTED WSAEWOULDBLOCK
2010-04-13 08:59:30 +02:00
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 ;
}
2011-11-23 09:11:30 +01:00
const int kNumMessages = sizeof ( gaErrorList ) / sizeof ( ErrorEntry ) ;
2010-04-13 08:59:30 +02:00
//// 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
2013-02-08 08:54:12 +01:00
static char acErrorBuffer [ 8096 ] ;
2013-02-08 08:56:46 +01:00
std : : ostrstream outs ( acErrorBuffer , 8095 ) ;
2010-04-13 08:59:30 +02:00
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
2013-01-18 02:12:32 +01:00
outs < < " unknown socket error " ;
2010-04-13 08:59:30 +02:00
}
outs < < " ( " < < Target . nID < < " ) " ;
// Finish error message off and return it.
outs < < std : : ends ;
2013-02-08 08:54:12 +01:00
acErrorBuffer [ 8095 ] = ' \0 ' ;
2010-04-13 08:59:30 +02:00
return acErrorBuffer ;
}
2011-01-18 00:45:09 +01:00
// keeps in scope for duration of the application
2016-06-02 05:31:46 +02:00
//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)
2013-05-15 02:45:34 +02:00
//#define PLATFORM_SOCKET_TRY_AGAIN EAGAIN
//#define PLATFORM_SOCKET_INPROGRESS EINPROGRESS
//#define PLATFORM_SOCKET_INTERRUPTED EINTR
2010-04-13 08:59:30 +02:00
# endif
2013-05-15 02:45:34 +02:00
int Socket : : getLastSocketError ( ) {
2010-04-13 08:59:30 +02:00
# ifndef WIN32
return errno ;
# else
return WSAGetLastError ( ) ;
# endif
}
2013-05-15 02:45:34 +02:00
const char * Socket : : getLastSocketErrorText ( int * errNumber ) {
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
}
2013-05-15 02:45:34 +02:00
string Socket : : getLastSocketErrorFormattedText ( int * errNumber ) {
2010-04-13 08:59:30 +02:00
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 ;
}
2017-10-01 06:46:56 +02:00
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 ;
2017-10-01 06:46:56 +02:00
if ( ipString . empty ( ) = = false ) {
for ( byteIndex = 0 ; byteIndex < 4 ; + + byteIndex ) {
size_t dotPos = ipString . find_first_of ( ' . ' , offset ) ;
2010-03-16 22:37:11 +01:00
2017-10-01 06:46:56 +02:00
bytes [ byteIndex ] = atoi ( ipString . substr ( offset , dotPos - offset ) . c_str ( ) ) ;
offset = dotPos + 1 ;
}
2010-03-16 22:37:11 +01:00
}
}
string Ip : : getString ( ) const {
return intToStr ( bytes [ 0 ] ) + " . " + intToStr ( bytes [ 1 ] ) + " . " + intToStr ( bytes [ 2 ] ) + " . " + intToStr ( bytes [ 3 ] ) ;
}
// ===============================================
// class Socket
// ===============================================
2016-12-11 23:09:34 +01:00
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
2010-04-11 09:13:14 +02:00
# define USE_GETIFADDRS 1
# include <ifaddrs.h>
2010-12-30 17:05:47 +01:00
# endif
2011-11-25 00:15:21 +01:00
static uint32 SockAddrToUint32 ( struct in_addr * a ) {
uint32 result = 0 ;
//printf("a [%p]\n",a);
if ( a ! = NULL ) {
result = ntohl ( a - > s_addr ) ;
}
return result ;
}
static uint32 SockAddrToUint32 ( struct sockaddr * a ) {
uint32 result = 0 ;
//printf("a [%p] family = %d\n",a,(a ? a->sa_family : -1));
if ( a ! = NULL & & ( a - > sa_family = = AF_INET | | a - > sa_family = = AF_UNSPEC ) ) {
//result = SockAddrToUint32((((struct sockaddr_in *)a)->sin_addr.s_addr);
result = SockAddrToUint32 ( & ( ( struct sockaddr_in * ) a ) - > sin_addr ) ;
}
return result ;
2010-04-11 09:13:14 +02:00
}
// convert a numeric IP address into its string representation
2011-11-29 06:07:18 +01:00
void Ip : : Inet_NtoA ( uint32 addr , char * ipbuf )
2010-04-11 09:13:14 +02:00
{
sprintf ( ipbuf , " %d.%d.%d.%d " , ( addr > > 24 ) & 0xFF , ( addr > > 16 ) & 0xFF , ( addr > > 8 ) & 0xFF , ( addr > > 0 ) & 0xFF ) ;
}
2013-11-19 07:14:06 +01:00
# if defined(WIN32)
2010-04-11 09:13:14 +02:00
// 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 ;
}
2013-11-19 07:14:06 +01:00
# endif
2012-09-22 23:00:31 +02:00
2010-04-11 09:13:14 +02:00
/*
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 )
{
2011-11-29 06:07:18 +01:00
char ifaAddrStr [ 32 ] ; Ip : : Inet_NtoA ( ifaAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Ip : : Inet_NtoA ( maskAddr , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Ip : : Inet_NtoA ( dstAddr , dstAddrStr ) ;
2010-04-11 09:13:14 +02:00
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 )
{
2012-10-19 03:31:20 +02:00
snprintf ( buf , 128 , " unnamed-%i " , i ) ;
2010-04-11 09:13:14 +02:00
name = buf ;
}
uint32 ipAddr = ntohl ( row . dwAddr ) ;
uint32 netmask = ntohl ( row . dwMask ) ;
uint32 baddr = ipAddr & netmask ;
if ( row . dwBCastAddr ) baddr | = ~ netmask ;
2011-11-29 06:07:18 +01:00
char ifaAddrStr [ 32 ] ; Ip : : Inet_NtoA ( ipAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Ip : : Inet_NtoA ( netmask , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Ip : : Inet_NtoA ( baddr , dstAddrStr ) ;
2010-04-11 09:13:14 +02:00
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
2011-11-29 06:07:18 +01:00
char ifaAddrStr [ 32 ] ; Ip : : Inet_NtoA ( ifaAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ; Ip : : Inet_NtoA ( maskAddr , maskAddrStr ) ;
char dstAddrStr [ 32 ] ; Ip : : Inet_NtoA ( dstAddr , dstAddrStr ) ;
2010-04-11 09:13:14 +02:00
//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.
2013-12-25 20:48:08 +01:00
PMIB_IPADDRTABLE ipTable = NULL ;
2013-12-25 20:42:00 +01:00
// Before calling AddIPAddress we use GetIpAddrTable to get
// an adapter to which we can add the IP.
2013-12-25 20:48:08 +01:00
ipTable = ( PMIB_IPADDRTABLE ) malloc ( sizeof ( MIB_IPADDRTABLE ) ) ;
2013-12-25 20:42:00 +01:00
ipTable - > dwNumEntries = 0 ;
2010-04-11 09:13:14 +02:00
{
ULONG bufLen = 0 ;
2013-12-15 07:37:15 +01:00
for ( int i = 0 ; i < 5 ; i + + ) {
2013-12-25 20:42:00 +01:00
2010-04-11 09:13:14 +02:00
DWORD ipRet = GetIpAddrTable ( ipTable , & bufLen , false ) ;
2013-12-15 07:37:15 +01:00
if ( ipRet = = ERROR_INSUFFICIENT_BUFFER ) {
2010-04-11 09:13:14 +02:00
free ( ipTable ) ; // in case we had previously allocated it
ipTable = ( MIB_IPADDRTABLE * ) malloc ( bufLen ) ;
2013-12-25 20:42:00 +01:00
ipTable - > dwNumEntries = 0 ;
2010-04-11 09:13:14 +02:00
}
2013-12-15 07:37:15 +01:00
else if ( ipRet = = NO_ERROR ) {
break ;
}
else {
2010-04-11 09:13:14 +02:00
free ( ipTable ) ;
ipTable = NULL ;
break ;
}
}
}
2013-12-15 07:37:15 +01:00
if ( ipTable ) {
2010-04-11 09:13:14 +02:00
// 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 ;
2013-12-15 07:37:15 +01:00
for ( int i = 0 ; i < 5 ; i + + ) {
2010-04-11 09:13:14 +02:00
DWORD apRet = GetAdaptersInfo ( pAdapterInfo , & bufLen ) ;
2013-12-15 07:37:15 +01:00
if ( apRet = = ERROR_BUFFER_OVERFLOW ) {
2010-04-11 09:13:14 +02:00
free ( pAdapterInfo ) ; // in case we had previously allocated it
pAdapterInfo = ( IP_ADAPTER_INFO * ) malloc ( bufLen ) ;
}
2013-12-15 07:37:15 +01:00
else if ( apRet = = ERROR_SUCCESS ) {
break ;
}
else {
2010-04-11 09:13:14 +02:00
free ( pAdapterInfo ) ;
pAdapterInfo = NULL ;
break ;
}
}
}
2013-12-15 07:37:15 +01:00
for ( DWORD i = 0 ; i < ipTable - > dwNumEntries ; i + + ) {
2010-04-11 09:13:14 +02:00
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 ;
2013-05-26 08:03:32 +02:00
//const char * desc = NULL;
2013-12-15 07:37:15 +01:00
if ( pAdapterInfo ) {
2010-04-11 09:13:14 +02:00
IP_ADAPTER_INFO * next = pAdapterInfo ;
2013-12-15 07:37:15 +01:00
while ( ( next ) & & ( name = = NULL ) ) {
2010-04-11 09:13:14 +02:00
IP_ADDR_STRING * ipAddr = & next - > IpAddressList ;
2013-12-15 07:37:15 +01:00
while ( ipAddr ) {
if ( Inet_AtoN ( ipAddr - > IpAddress . String ) = = ntohl ( row . dwAddr ) ) {
2010-04-11 09:13:14 +02:00
name = next - > AdapterName ;
2013-05-26 08:03:32 +02:00
//desc = next->Description;
2010-04-11 09:13:14 +02:00
break ;
}
ipAddr = ipAddr - > Next ;
}
next = next - > Next ;
}
}
2013-12-15 07:37:15 +01:00
if ( name = = NULL ) {
2011-12-02 18:46:02 +01:00
name = " " ;
2010-04-11 09:13:14 +02:00
}
uint32 ipAddr = ntohl ( row . dwAddr ) ;
uint32 netmask = ntohl ( row . dwMask ) ;
uint32 baddr = ipAddr & netmask ;
2013-12-15 07:37:15 +01:00
if ( row . dwBCastAddr ) {
baddr | = ~ netmask ;
}
2010-04-11 09:13:14 +02:00
2013-12-15 07:37:15 +01:00
char ifaAddrStr [ 32 ] ;
Ip : : Inet_NtoA ( ipAddr , ifaAddrStr ) ;
char maskAddrStr [ 32 ] ;
Ip : : Inet_NtoA ( netmask , maskAddrStr ) ;
char dstAddrStr [ 32 ] ;
Ip : : Inet_NtoA ( baddr , dstAddrStr ) ;
2010-04-11 09:13:14 +02:00
//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 ;
}
}
2013-12-25 20:48:08 +01:00
if ( pAdapterInfo ) free ( pAdapterInfo ) ;
2013-12-25 20:42:00 +01:00
if ( ipTable ) free ( ipTable ) ;
2010-04-11 09:13:14 +02:00
}
# 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 ) ;
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 ] = " " ;
2011-11-25 00:15:21 +01:00
for ( int ipIdx = 0 ; myhostent - > h_addr_list [ ipIdx ] ! = NULL ; + + ipIdx ) {
2011-11-29 06:07:18 +01:00
Ip : : Inet_NtoA ( SockAddrToUint32 ( ( struct in_addr * ) myhostent - > h_addr_list [ ipIdx ] ) , myhostaddr ) ;
2011-11-23 09:00:09 +01:00
2016-05-28 01:15:27 +02:00
//printf("ipIdx = %d [%s]\n",ipIdx,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 ) ;
}
}
2010-09-07 19:30:13 +02:00
}
2010-04-01 08:31:10 +02:00
2017-09-23 08:21:40 +02:00
Socket : : getLocalIPAddressListForPlatform ( ipList ) ;
return ipList ;
}
2010-04-13 08:59:30 +02:00
2017-09-23 08:21:40 +02:00
# ifndef WIN32
void Socket : : getLocalIPAddressListForPlatform ( std : : vector < std : : string > & ipList ) {
2010-04-01 08:31:10 +02:00
// Now check all linux network devices
2017-09-23 08:21:40 +02:00
struct ifaddrs * ifap = NULL ;
getifaddrs ( & ifap ) ;
2022-08-01 10:21:26 +02:00
for ( struct ifaddrs * ifa = ifap ; ifa ! = NULL ; ifa = ifa - > ifa_next ) {
2022-08-14 14:37:07 +02:00
if ( ! ifa - > ifa_addr ) {
continue ;
}
2022-08-01 10:21:26 +02:00
if ( ifa - > ifa_addr - > sa_family = = AF_INET ) { // check it is IP4
2022-08-14 14:37:07 +02:00
// is a valid IP4 Address
2017-09-23 08:21:40 +02:00
struct sockaddr_in * sa = ( struct sockaddr_in * ) ifa - > ifa_addr ;
char * addr = inet_ntoa ( sa - > sin_addr ) ;
2017-09-22 02:46:23 +02:00
//printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr);
2017-09-23 08:21:40 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Interface: [%s] address: [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ifa - > ifa_name , addr ) ;
}
2022-08-14 14:37:07 +02:00
if ( strlen ( addr ) > 0 & &
strncmp ( addr , " 127. " , 4 ) ! = 0 & &
strncmp ( addr , " 0. " , 2 ) ! = 0 ) {
if ( std : : find ( ipList . begin ( ) , ipList . end ( ) , addr ) = = ipList . end ( ) ) {
ipList . push_back ( addr ) ;
}
}
2017-09-22 02:46:23 +02:00
}
}
2022-08-01 10:21:26 +02:00
if ( ifap ! = NULL ) freeifaddrs ( ifap ) ;
2017-09-22 02:46:23 +02:00
2016-06-02 05:16:34 +02:00
if ( Socket : : intfTypes . empty ( ) ) {
Socket : : intfTypes . push_back ( " lo " ) ;
Socket : : intfTypes . push_back ( " eth " ) ;
Socket : : intfTypes . push_back ( " wlan " ) ;
Socket : : intfTypes . push_back ( " vlan " ) ;
Socket : : intfTypes . push_back ( " vboxnet " ) ;
Socket : : intfTypes . push_back ( " br-lan " ) ;
Socket : : intfTypes . push_back ( " br-gest " ) ;
Socket : : intfTypes . push_back ( " enp0s " ) ;
Socket : : intfTypes . push_back ( " enp1s " ) ;
Socket : : intfTypes . push_back ( " enp2s " ) ;
Socket : : intfTypes . push_back ( " enp3s " ) ;
Socket : : intfTypes . push_back ( " enp4s " ) ;
Socket : : intfTypes . push_back ( " enp5s " ) ;
Socket : : intfTypes . push_back ( " enp6s " ) ;
Socket : : intfTypes . push_back ( " enp7s " ) ;
Socket : : intfTypes . push_back ( " enp8s " ) ;
Socket : : intfTypes . push_back ( " enp9s " ) ;
}
for ( unsigned int intfIdx = 0 ; intfIdx < Socket : : intfTypes . size ( ) ; intfIdx + + ) {
string intfName = Socket : : intfTypes [ intfIdx ] ;
2010-06-14 23:03:23 +02:00
for ( int idx = 0 ; idx < 10 ; + + idx ) {
PLATFORM_SOCKET fd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
/* 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 ] = " " ;
2012-10-19 03:31:20 +02:00
snprintf ( szBuf , 100 , " %s%d " , intfName . c_str ( ) , idx ) ;
2017-02-05 04:03:13 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] Trying NIC named [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , szBuf ) ;
//printf("In [%s::%s Line: %d] Trying NIC named [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf);
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 ) ;
2017-09-23 08:21:40 +02:00
if ( fd > = 0 ) {
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 ) {
2013-05-17 05:59:34 +02:00
char myhostaddr [ 101 ] = " " ;
2011-11-29 06:07:18 +01:00
Ip : : Inet_NtoA ( SockAddrToUint32 ( & pSockAddr - > sin_addr ) , myhostaddr ) ;
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
}
}
}
2017-09-23 08:21:40 +02:00
}
# endif
2010-04-01 08:31:10 +02:00
2017-09-23 08:21:40 +02:00
# ifdef WIN32
void Socket : : getLocalIPAddressListForPlatform ( std : : vector < std : : string > & ipList ) {
2017-09-23 00:44:25 +02:00
ULONG outBufLen = 0 ;
GetAdaptersAddresses ( AF_INET , 0 , NULL , NULL , & outBufLen ) ;
PIP_ADAPTER_ADDRESSES pAddresses = ( IP_ADAPTER_ADDRESSES * ) malloc ( outBufLen ) ;
GetAdaptersAddresses ( AF_INET , GAA_FLAG_SKIP_ANYCAST , NULL , pAddresses , & outBufLen ) ;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL ;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL ;
LPSOCKADDR addr = NULL ;
pCurrAddresses = pAddresses ;
2017-10-10 04:09:36 +02:00
//char buff[100];
2017-09-23 00:44:25 +02:00
DWORD bufflen = 100 ;
while ( pCurrAddresses ) {
if ( pCurrAddresses - > OperStatus ! = IfOperStatusUp ) {
pCurrAddresses = pCurrAddresses - > Next ;
continue ;
}
pUnicast = pCurrAddresses - > FirstUnicastAddress ;
while ( pUnicast ) {
addr = pUnicast - > Address . lpSockaddr ;
if ( addr - > sa_family = = AF_INET & & pCurrAddresses - > IfType ! = MIB_IF_TYPE_LOOPBACK ) {
2017-09-23 08:21:40 +02:00
sockaddr_in * sa_in = ( sockaddr_in * ) addr ;
char * strIP = : : inet_ntoa ( ( sa_in - > sin_addr ) ) ;
//printf("\tIPV4:%s\n", strIP);
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] strIP [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , strIP ) ;
}
if ( strlen ( strIP ) > 0 & &
strncmp ( strIP , " 127. " , 4 ) ! = 0 & &
strncmp ( strIP , " 0. " , 2 ) ! = 0 ) {
if ( std : : find ( ipList . begin ( ) , ipList . end ( ) , strIP ) = = ipList . end ( ) ) {
ipList . push_back ( strIP ) ;
2017-09-23 00:44:25 +02:00
}
}
}
pUnicast = pUnicast - > Next ;
}
pCurrAddresses = pCurrAddresses - > Next ;
}
free ( pAddresses ) ;
2017-09-23 08:21:40 +02:00
}
2010-04-13 08:59:30 +02:00
# endif
2010-04-01 08:31:10 +02:00
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
2012-01-20 05:15:13 +01:00
if ( validateSocket = = NULL | | ( * validateSocket ) = = 0 ) {
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 ) {
2013-12-25 07:27:44 +01:00
dataSynchAccessorRead = new Mutex ( CODE_AT_LINE ) ;
dataSynchAccessorWrite = new Mutex ( CODE_AT_LINE ) ;
inSocketDestructorSynchAccessor = new Mutex ( CODE_AT_LINE ) ;
2013-11-09 20:30:36 +01:00
lastSocketError = 0 ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( inSocketDestructorSynchAccessor , CODE_AT_LINE ) ;
inSocketDestructorSynchAccessor - > setOwnerId ( CODE_AT_LINE ) ;
2011-11-27 06:27:50 +01:00
this - > inSocketDestructor = false ;
2012-09-22 22:13:57 +02:00
lastThreadedPing = 0 ;
lastDebugEvent = 0 ;
2011-05-25 23:57:01 +02:00
//safeMutexSocketDestructorFlag.ReleaseLock();
2011-02-15 08:49:40 +01:00
//this->pingThread = NULL;
2011-11-26 09:14:23 +01:00
//pingThreadAccessor.setOwnerId(CODE_AT_LINE);
2011-12-02 17:07:59 +01:00
dataSynchAccessorRead - > setOwnerId ( CODE_AT_LINE ) ;
dataSynchAccessorWrite - > setOwnerId ( CODE_AT_LINE ) ;
2011-11-27 06:27:50 +01:00
2010-03-16 22:37:11 +01:00
this - > sock = sock ;
2013-03-08 09:42:08 +01:00
this - > isSocketBlocking = true ;
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 ( ) {
2013-12-25 07:27:44 +01:00
dataSynchAccessorRead = new Mutex ( CODE_AT_LINE ) ;
dataSynchAccessorWrite = new Mutex ( CODE_AT_LINE ) ;
inSocketDestructorSynchAccessor = new Mutex ( CODE_AT_LINE ) ;
2013-11-09 20:30:36 +01:00
lastSocketError = 0 ;
2013-12-14 08:04:12 +01:00
lastDebugEvent = 0 ;
lastThreadedPing = 0 ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( inSocketDestructorSynchAccessor , CODE_AT_LINE ) ;
inSocketDestructorSynchAccessor - > setOwnerId ( CODE_AT_LINE ) ;
2011-11-27 06:27:50 +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
2013-03-08 09:42:08 +01:00
this - > isSocketBlocking = true ;
2011-01-11 04:56:38 +01:00
# ifdef __APPLE__
int set = 1 ;
setsockopt ( sock , SOL_SOCKET , SO_NOSIGPIPE , ( void * ) & set , sizeof ( int ) ) ;
# endif
2011-11-27 01:07:55 +01:00
/* Disable the Nagle (TCP No Delay) algorithm */
if ( Socket : : disableNagle = = true ) {
int flag = 1 ;
int ret = setsockopt ( sock , IPPROTO_TCP , TCP_NODELAY , ( char * ) & flag , sizeof ( flag ) ) ;
if ( ret = = - 1 ) {
printf ( " Couldn't setsockopt(TCP_NODELAY) \n " ) ;
}
}
if ( Socket : : DEFAULT_SOCKET_SENDBUF_SIZE > = 0 ) {
int bufsize = 0 ;
socklen_t optlen = sizeof ( bufsize ) ;
2011-11-27 01:11:18 +01:00
int ret = getsockopt ( sock , SOL_SOCKET , SO_SNDBUF , ( char * ) & bufsize , & optlen ) ;
2012-10-20 09:15:13 +02:00
printf ( " Original setsockopt(SO_SNDBUF) = [%d] new will be [%d] ret = %d \n " , bufsize , Socket : : DEFAULT_SOCKET_SENDBUF_SIZE , ret ) ;
2011-11-27 01:07:55 +01:00
ret = setsockopt ( sock , SOL_SOCKET , SO_SNDBUF , ( char * ) & Socket : : DEFAULT_SOCKET_SENDBUF_SIZE , sizeof ( int ) ) ;
if ( ret = = - 1 ) {
printf ( " Couldn't setsockopt(SO_SNDBUF) [%d] \n " , Socket : : DEFAULT_SOCKET_SENDBUF_SIZE ) ;
}
}
if ( Socket : : DEFAULT_SOCKET_RECVBUF_SIZE > = 0 ) {
int bufsize = 0 ;
socklen_t optlen = sizeof ( bufsize ) ;
2011-11-27 01:11:18 +01:00
int ret = getsockopt ( sock , SOL_SOCKET , SO_RCVBUF , ( char * ) & bufsize , & optlen ) ;
2012-10-20 09:15:13 +02:00
printf ( " Original setsockopt(SO_RCVBUF) = [%d] new will be [%d] ret = %d \n " , bufsize , Socket : : DEFAULT_SOCKET_RECVBUF_SIZE , ret ) ;
2011-11-27 01:07:55 +01:00
ret = setsockopt ( sock , SOL_SOCKET , SO_RCVBUF , ( char * ) & Socket : : DEFAULT_SOCKET_RECVBUF_SIZE , sizeof ( int ) ) ;
if ( ret = = - 1 ) {
printf ( " Couldn't setsockopt(SO_RCVBUF) [%d] \n " , Socket : : DEFAULT_SOCKET_RECVBUF_SIZE ) ;
}
}
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-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutex ( & pingThreadAccessor , CODE_AT_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-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( inSocketDestructorSynchAccessor , CODE_AT_LINE ) ;
2011-11-27 06:27:50 +01:00
if ( this - > inSocketDestructor = = true ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] this->inSocketDestructor == true \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
return ;
}
2011-12-02 17:07:59 +01:00
inSocketDestructorSynchAccessor - > setOwnerId ( CODE_AT_LINE ) ;
2011-11-27 06:27:50 +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
2011-11-27 06:27:50 +01:00
for ( time_t elapsed = time ( NULL ) ;
2011-12-02 17:07:59 +01:00
( dataSynchAccessorRead - > getRefCount ( ) > 0 | |
dataSynchAccessorWrite - > getRefCount ( ) > 0 ) & &
2012-09-22 22:13:57 +02:00
difftime ( ( long int ) time ( NULL ) , elapsed ) < = 2 ; ) {
2011-12-02 17:07:59 +01:00
printf ( " Waiting in socket destructor \n " ) ;
2011-04-13 03:20:40 +02:00
//sleep(0);
2011-11-27 06:27:50 +01:00
}
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;
2011-11-23 09:00:09 +01:00
safeMutexSocketDestructorFlag . ReleaseLock ( ) ;
2011-12-02 17:07:59 +01:00
delete dataSynchAccessorRead ;
dataSynchAccessorRead = NULL ;
delete dataSynchAccessorWrite ;
dataSynchAccessorWrite = NULL ;
delete inSocketDestructorSynchAccessor ;
inSocketDestructorSynchAccessor = NULL ;
2010-03-16 22:37:11 +01:00
}
2011-01-02 17:24:44 +01:00
void Socket : : disconnectSocket ( ) {
2013-03-15 01:31:51 +01:00
//printf("Socket disconnecting sock = %d\n",sock);
2013-02-15 19:25:10 +01:00
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-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
MutexSafeWrapper safeMutex1 ( dataSynchAccessorWrite , CODE_AT_LINE ) ;
2012-01-06 22:18:36 +01:00
if ( isSocketValid ( ) = = true ) {
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 ) ;
2013-12-25 07:44:46 +01:00
sock = - 1 ;
2010-04-13 08:59:30 +02:00
# else
: : closesocket ( sock ) ;
2013-02-09 07:57:05 +01:00
sock = INVALID_SOCKET ;
2010-04-13 08:59:30 +02:00
# endif
2012-01-06 22:18:36 +01:00
}
2011-11-27 06:27:50 +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 ;
2013-03-06 15:29:49 +01:00
if ( socketTriggeredList . empty ( ) = = false ) {
2010-03-16 22:37:11 +01:00
/* Watch stdin (fd 0) to see when it has input. */
fd_set rfds ;
FD_ZERO ( & rfds ) ;
2012-01-20 05:15:13 +01:00
string socketDebugList = " " ;
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET imaxsocket = 0 ;
for ( std : : map < PLATFORM_SOCKET , bool > : : iterator itermap = socketTriggeredList . begin ( ) ;
2013-03-06 15:29:49 +01:00
itermap ! = socketTriggeredList . end ( ) ; + + itermap ) {
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET socket = itermap - > first ;
2013-03-06 15:29:49 +01:00
if ( Socket : : isSocketValid ( & socket ) = = true ) {
2010-03-16 22:37:11 +01:00
FD_SET ( socket , & rfds ) ;
imaxsocket = max ( socket , imaxsocket ) ;
2012-01-20 05:15:13 +01:00
if ( socketDebugList ! = " " ) {
socketDebugList + = " , " ;
}
socketDebugList + = intToStr ( socket ) ;
2010-03-16 22:37:11 +01:00
}
}
2013-03-06 15:29:49 +01:00
if ( imaxsocket > 0 ) {
2010-03-16 22:37:11 +01:00
/* 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
}
2013-03-06 15:29:49 +01:00
if ( retval < 0 ) {
2012-01-20 05:15:13 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s, socketDebugList [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) , socketDebugList . c_str ( ) ) ;
2013-11-12 16:01:37 +01:00
printf ( " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2013-03-06 15:29:49 +01:00
else if ( retval ) {
2010-03-16 22:37:11 +01:00
bResult = true ;
2010-04-13 08:59:30 +02:00
for ( std : : map < PLATFORM_SOCKET , bool > : : iterator itermap = socketTriggeredList . begin ( ) ;
2013-03-06 15:29:49 +01:00
itermap ! = socketTriggeredList . end ( ) ; + + itermap ) {
2010-04-13 08:59:30 +02:00
PLATFORM_SOCKET socket = itermap - > first ;
2013-03-06 15:29:49 +01:00
if ( FD_ISSET ( socket , & rfds ) ) {
2010-03-16 22:37:11 +01:00
itermap - > second = true ;
}
2013-03-06 15:29:49 +01:00
else {
2010-03-16 22:37:11 +01:00
itermap - > second = false ;
}
}
}
}
}
return bResult ;
}
bool Socket : : hasDataToRead ( )
{
2015-12-29 04:59:45 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
2010-03-16 22:37:11 +01:00
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
}
2013-11-12 16:01:37 +01:00
if ( retval < 0 ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
printf ( " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
}
else if ( retval )
2010-03-16 22:37:11 +01:00
{
if ( FD_ISSET ( socket , & rfds ) )
{
bResult = true ;
}
}
}
return bResult ;
}
2013-03-23 23:32:51 +01:00
bool Socket : : hasDataToReadWithWait ( int waitMicroseconds ) {
2015-12-29 04:59:45 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
2013-03-23 23:32:51 +01:00
return Socket : : hasDataToReadWithWait ( sock , waitMicroseconds ) ;
2011-11-25 21:03:07 +01:00
}
2013-03-23 23:32:51 +01:00
bool Socket : : hasDataToReadWithWait ( PLATFORM_SOCKET socket , int waitMicroseconds ) {
2011-11-25 21:03:07 +01:00
bool bResult = false ;
Chrono chono ;
chono . start ( ) ;
if ( Socket : : isSocketValid ( & socket ) = = true )
{
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 ;
2013-03-23 23:32:51 +01:00
tv . tv_usec = waitMicroseconds ;
2011-11-25 21:03:07 +01:00
int retval = 0 ;
{
//MutexSafeWrapper safeMutex(&dataSynchAccessor);
retval = select ( ( int ) socket + 1 , & rfds , NULL , NULL , & tv ) ;
}
2013-11-12 16:01:37 +01:00
if ( retval < 0 ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
printf ( " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , retval , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
}
2011-11-25 21:03:07 +01:00
if ( retval )
{
if ( FD_ISSET ( socket , & rfds ) )
{
bResult = true ;
}
}
}
//printf("hasdata waited [%d] milliseconds [%d], bResult = %d\n",chono.getMillis(),waitMilliseconds,bResult);
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
{
2011-11-25 10:12:53 +01:00
//int loopCount = 1;
2012-09-22 22:13:57 +02:00
for ( time_t elapsed = time ( NULL ) ; difftime ( ( long int ) time ( NULL ) , elapsed ) < 1 ; ) {
2010-04-20 04:19:37 +02:00
/* 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
2012-01-20 05:15:13 +01:00
int lastSocketError = getLastSocketError ( ) ;
if ( err < 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN )
2010-04-20 04:19:37 +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] 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 ) {
2012-11-10 07:37:23 +01: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 = " MG_SIZE_T_SPECIFIER ", loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount);
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 = " MG_SIZE_T_SPECIFIER " \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , size ) ;
2010-04-20 04:19:37 +02:00
}
else {
2012-11-10 07:37:23 +01: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 = " MG_SIZE_T_SPECIFIER ", loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount);
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER " \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , size ) ;
2010-04-20 04:19:37 +02:00
break ;
}
2010-07-09 17:01:49 +02:00
if ( wantImmediateReply = = true ) {
break ;
}
2011-11-25 10:12:53 +01:00
//loopCount++;
2010-04-20 04:19:37 +02:00
}
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-11-25 06:37:55 +01:00
// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE);
// if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return -1;
// }
2011-12-02 17:07:59 +01:00
// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE);
2011-11-25 06:37:55 +01:00
// safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorWrite , CODE_AT_LINE ) ;
2010-08-07 06:49:06 +02:00
2012-01-06 22:21:52 +01:00
if ( isSocketValid ( ) = = true ) {
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
2012-01-06 22:21:52 +01:00
}
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
2012-01-20 05:15:13 +01:00
int lastSocketError = getLastSocketError ( ) ;
if ( bytesSent < 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2012-02-10 07:21:06 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s dataSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesSent , getLastSocketErrorFormattedText ( & lastSocketError ) . c_str ( ) , dataSize ) ;
2010-03-16 22:37:11 +01:00
}
2012-01-20 05:15:13 +01:00
else if ( bytesSent < 0 & & lastSocketError = = PLATFORM_SOCKET_TRY_AGAIN & & isConnected ( ) = = true ) {
2012-02-10 07:21:06 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #1 EAGAIN during send, trying again... dataSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , dataSize ) ;
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 ) ;
2012-01-20 05:15:13 +01:00
while ( ( bytesSent < 0 & & lastSocketError = = PLATFORM_SOCKET_TRY_AGAIN ) & &
2012-09-22 22:13:57 +02:00
( difftime ( ( long int ) 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
2012-07-20 17:21:32 +02:00
MutexSafeWrapper safeMutex ( dataSynchAccessorWrite , CODE_AT_LINE ) ;
2011-01-09 05:49:21 +01:00
if ( isConnected ( ) = = true ) {
2012-02-10 07:21:06 +01:00
struct timeval timeVal ;
timeVal . tv_sec = 1 ;
timeVal . tv_usec = 0 ;
bool canWrite = isWritable ( & timeVal ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p, canWrite = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount , sock , dataSize , data , canWrite ) ;
2011-01-02 17:24:44 +01:00
2011-11-25 06:37:55 +01:00
// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE);
// if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return -1;
// }
2011-12-02 17:07:59 +01:00
// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE);
2011-11-25 06:37:55 +01:00
// safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2012-07-20 17:21:32 +02:00
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
2012-01-20 05:15:13 +01:00
lastSocketError = getLastSocketError ( ) ;
if ( bytesSent < 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-01-11 04:56:38 +01:00
break ;
}
2011-02-13 04:06:12 +01:00
2012-07-20 17:21:32 +02: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 ( ) ;
2012-07-20 17:21:32 +02:00
safeMutex . ReleaseLock ( ) ;
2011-01-09 05:49:21 +01:00
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 ) {
2012-01-20 05:15:13 +01:00
lastSocketError = getLastSocketError ( ) ;
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__ , lastSocketError , 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 ;
2012-01-20 05:15:13 +01:00
2010-08-26 04:36:17 +02:00
time_t tStartTimer = time ( NULL ) ;
while ( ( ( bytesSent > 0 & & totalBytesSent < dataSize ) | |
2012-01-20 05:15:13 +01:00
( bytesSent < 0 & & lastSocketError = = PLATFORM_SOCKET_TRY_AGAIN ) ) & &
2012-09-22 22:13:57 +02:00
( difftime ( ( long int ) 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
2012-07-20 17:21:32 +02:00
MutexSafeWrapper safeMutex ( dataSynchAccessorWrite , CODE_AT_LINE ) ;
2011-01-09 05:49:21 +01:00
if ( isConnected ( ) = = true ) {
2012-02-10 07:21:06 +01:00
struct timeval timeVal ;
timeVal . tv_sec = 1 ;
timeVal . tv_usec = 0 ;
bool canWrite = isWritable ( & timeVal ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p, canWrite = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , attemptCount , sock , dataSize , data , canWrite ) ;
2010-08-26 04:36:17 +02:00
2011-11-25 06:37:55 +01:00
// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE);
// if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return -1;
// }
2011-12-02 17:07:59 +01:00
// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE);
2011-11-25 06:37:55 +01:00
// safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2012-07-20 17:21:32 +02:00
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
2012-01-20 05:15:13 +01:00
lastSocketError = getLastSocketError ( ) ;
2010-08-26 04:36:17 +02:00
if ( bytesSent > 0 ) {
totalBytesSent + = bytesSent ;
}
2011-01-11 04:56:38 +01:00
2012-01-20 05:15:13 +01:00
if ( bytesSent < 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2011-01-11 04:56:38 +01:00
break ;
}
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 ( ) ;
2012-07-20 17:21:32 +02:00
safeMutex . ReleaseLock ( ) ;
2011-01-09 05:49:21 +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 ( ) ) ;
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 ) {
2010-03-16 22:37:11 +01:00
ssize_t bytesReceived = 0 ;
2010-05-31 08:11:31 +02:00
if ( isSocketValid ( ) = = true ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
2012-01-06 22:21:52 +01:00
if ( isSocketValid ( ) = = true ) {
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
}
2015-12-26 18:34:55 +01:00
2012-01-20 05:15:13 +01:00
int lastSocketError = getLastSocketError ( ) ;
if ( bytesReceived < 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) {
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 ( & lastSocketError ) . c_str ( ) ) ;
2010-03-16 22:37:11 +01:00
}
2012-01-20 05:15:13 +01:00
else if ( bytesReceived < 0 & & lastSocketError = = 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
2015-12-26 08:12:00 +01:00
Chrono chronoElapsed ( true ) ;
2013-05-26 08:03:32 +02:00
const int MAX_RECV_WAIT_SECONDS = 3 ;
2010-03-16 22:37:11 +01:00
time_t tStartTimer = time ( NULL ) ;
2012-01-20 05:15:13 +01:00
while ( ( bytesReceived < 0 & & lastSocketError = = PLATFORM_SOCKET_TRY_AGAIN ) & &
2012-09-22 22:13:57 +02:00
( difftime ( ( long int ) time ( NULL ) , tStartTimer ) < = MAX_RECV_WAIT_SECONDS ) ) {
2011-01-09 05:49:21 +01:00
if ( isConnected ( ) = = false ) {
2015-12-26 08:12:00 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] Socket is NOT connected! \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
int iErr = getLastSocketError ( ) ;
2011-01-09 05:49:21 +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 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 ;
}
2015-12-26 08:12:00 +01:00
//else if(Socket::isReadable(true) == true) {
else {
if ( Socket : : isReadable ( true ) = = true ) {
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
//SafeSocketBlockToggleWrapper safeBlock(this, true);
errno = 0 ;
bytesReceived = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , 0 ) ;
lastSocketError = getLastSocketError ( ) ;
//safeBlock.Restore();
safeMutex . ReleaseLock ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d, lastSocketError = %d, dataSize = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived , lastSocketError , ( int ) dataSize ) ;
2015-12-26 18:34:55 +01:00
//printf("In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d, lastSocketError = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,lastSocketError,(int)dataSize);
2015-12-26 08:12:00 +01:00
}
else {
2015-12-29 02:59:26 +01:00
//if(chronoElapsed.getMillis() % 3 == 0) {
// sleep(1);
//}
//else {
sleep ( 0 ) ;
//}
2015-12-26 08:12:00 +01:00
}
2010-03-16 22:37:11 +01:00
}
}
}
2010-05-31 08:11:31 +02:00
if ( bytesReceived < = 0 ) {
2015-12-26 08:12:00 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] bytesReceived = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , bytesReceived ) ;
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 ) {
2013-11-05 07:31:48 +01:00
int newBufferSize = ( dataSize - ( int ) bytesReceived ) ;
2011-04-27 01:34:48 +02:00
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 ) ;
2012-04-16 21:29:37 +02:00
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 ) ;
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 ) ;
2012-07-06 23:01:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] WARNING, additionalBytes = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , additionalBytes ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n In [%s::%s Line: %d] WARNING, additionalBytes = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , additionalBytes ) ;
2011-04-24 06:22:19 +02:00
if ( additionalBytes > 0 ) {
bytesReceived + = additionalBytes ;
}
else {
2012-04-14 23:21:09 +02:00
//throw megaglest_runtime_error("additionalBytes == " + intToStr(additionalBytes));
2011-05-30 01:01:16 +02:00
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 ) ;
}
2013-03-08 09:42:08 +01:00
SafeSocketBlockToggleWrapper : : SafeSocketBlockToggleWrapper ( Socket * socket , bool toggle ) {
this - > socket = socket ;
2013-12-14 08:04:12 +01:00
2013-03-08 09:42:08 +01:00
if ( this - > socket ! = NULL ) {
this - > originallyBlocked = socket - > getBlock ( ) ;
this - > newBlocked = toggle ;
if ( this - > originallyBlocked ! = this - > newBlocked ) {
socket - > setBlock ( this - > newBlocked ) ;
}
}
2013-12-14 08:04:12 +01:00
else {
this - > originallyBlocked = false ;
this - > newBlocked = false ;
}
2013-03-08 09:42:08 +01:00
}
void SafeSocketBlockToggleWrapper : : Restore ( ) {
if ( this - > socket ! = NULL ) {
if ( this - > originallyBlocked ! = this - > newBlocked ) {
socket - > setBlock ( this - > originallyBlocked ) ;
this - > newBlocked = this - > originallyBlocked ;
}
}
}
SafeSocketBlockToggleWrapper : : ~ SafeSocketBlockToggleWrapper ( ) {
Restore ( ) ;
}
2012-02-11 23:52:52 +01:00
int Socket : : peek ( void * data , int dataSize , bool mustGetData , int * pLastSocketError ) {
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
2013-03-08 09:42:08 +01:00
int lastSocketError = 0 ;
2011-12-02 17:07:59 +01:00
int 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-11-25 06:37:55 +01:00
// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE);
// if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return -1;
// }
2011-12-02 17:07:59 +01:00
// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE);
2011-11-25 06:37:55 +01:00
// safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2011-11-23 09:00:09 +01:00
//MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize));
2015-12-29 04:59:45 +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());
2012-01-06 22:21:52 +01:00
if ( isSocketValid ( ) = = true ) {
2015-12-29 04:59:45 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
2013-03-08 09:42:08 +01:00
// Chrono recvTimer(true);
2015-12-29 04:59:45 +01:00
SafeSocketBlockToggleWrapper safeUnblock ( this , false ) ;
2013-03-08 09:42:08 +01:00
errno = 0 ;
2012-01-06 22:21:52 +01:00
err = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , MSG_PEEK ) ;
2013-03-08 09:42:08 +01:00
lastSocketError = getLastSocketError ( ) ;
if ( pLastSocketError ! = NULL ) {
* pLastSocketError = lastSocketError ;
}
2015-12-29 04:59:45 +01:00
safeUnblock . Restore ( ) ;
2013-03-08 09:42:08 +01:00
// if(recvTimer.getMillis() > 1000 || (err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) {
// printf("#1 PEEK err = %d lastSocketError = %d ms: %lld\n",err,lastSocketError,(long long int)recvTimer.getMillis());
2013-03-15 01:31:51 +01:00
//if(err != dataSize) {
// printf("#1 PEEK err = %d lastSocketError = %d\n",err,lastSocketError);
//}
2013-03-08 09:42:08 +01:00
// }
2015-12-29 04:59:45 +01:00
safeMutex . ReleaseLock ( ) ;
2012-01-06 22:21:52 +01:00
}
2015-12-29 02:59:26 +01:00
//safeMutex.ReleaseLock();
2011-02-08 19:23:41 +01:00
2011-12-02 17:07:59 +01:00
//printf("Peek #1 err = %d\n",err);
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
}
2012-03-24 02:09:55 +01:00
else {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] SOCKET appears to be invalid [%d] \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock ) ;
}
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());
2012-01-20 05:15:13 +01:00
if ( err < 0 & & lastSocketError ! = 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 ( ) ;
}
2012-01-20 05:15:13 +01:00
else if ( err < 0 & & lastSocketError = = 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
2011-12-02 17:07:59 +01:00
//printf("Peek #2 err = %d\n",err);
2016-01-01 03:28:43 +01:00
Chrono chronoElapsed ( true ) ;
2013-05-26 08:03:32 +02:00
const int MAX_PEEK_WAIT_SECONDS = 3 ;
2010-03-16 22:37:11 +01:00
time_t tStartTimer = time ( NULL ) ;
2012-01-20 05:15:13 +01:00
while ( ( err < 0 & & lastSocketError = = PLATFORM_SOCKET_TRY_AGAIN ) & &
2013-03-08 09:42:08 +01:00
isSocketValid ( ) = = true & &
2012-09-22 22:13:57 +02:00
( difftime ( ( long int ) 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
*/
2016-01-01 03:28:43 +01:00
if ( Socket : : isReadable ( true ) = = true | | chronoElapsed . getMillis ( ) % 100 = = 0 ) {
2011-03-11 12:11:46 +01:00
2011-11-25 06:37:55 +01:00
// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE);
// if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return -1;
// }
2011-12-02 17:07:59 +01:00
// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE);
2011-11-25 06:37:55 +01:00
// safeMutexSocketDestructorFlag.ReleaseLock();
2011-03-11 12:11:46 +01:00
2011-11-23 09:00:09 +01:00
//MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize));
2015-12-29 04:59:45 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
2013-03-08 09:42:08 +01:00
// Chrono recvTimer(true);
2015-12-29 04:59:45 +01:00
SafeSocketBlockToggleWrapper safeUnblock ( this , false ) ;
2013-03-08 09:42:08 +01:00
errno = 0 ;
2010-03-16 22:37:11 +01:00
err = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , MSG_PEEK ) ;
2012-01-20 05:15:13 +01:00
lastSocketError = getLastSocketError ( ) ;
2012-02-11 23:52:52 +01:00
if ( pLastSocketError ! = NULL ) {
* pLastSocketError = lastSocketError ;
}
2015-12-29 04:59:45 +01:00
safeUnblock . Restore ( ) ;
2013-03-08 09:42:08 +01:00
// if(recvTimer.getMillis() > 1000 || (err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) {
// printf("#2 PEEK err = %d lastSocketError = %d ms: %lld\n",err,lastSocketError,(long long int)recvTimer.getMillis());
// }
//printf("Socket peek delayed checking for sock = %d err = %d\n",sock,err);
2012-02-11 23:52:52 +01:00
2015-12-29 04:59:45 +01:00
safeMutex . ReleaseLock ( ) ;
2010-03-16 22:37:11 +01:00
2016-01-01 03:28:43 +01:00
if ( err = = 0 | | err = = PLATFORM_SOCKET_TRY_AGAIN ) {
2015-12-29 02:59:26 +01:00
sleep ( 0 ) ;
}
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 ) ;
2015-12-29 04:59:45 +01:00
}
2015-12-29 02:59:26 +01:00
//else {
2013-03-08 09:42:08 +01:00
//printf("Socket peek delayed [NOT READABLE] checking for sock = %d err = %d\n",sock,err);
2015-12-29 02:59:26 +01:00
//}
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
}
2015-12-25 23:08:54 +01:00
else if ( err = = 0 ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] #2 SOCKET appears to be invalid [%d] lastSocketError [%d] err [%d] mustGetData [%d] dataSize [%d] \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , lastSocketError , err , mustGetData , dataSize ) ;
2012-03-24 02:09:55 +01:00
}
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());
2013-03-08 09:42:08 +01:00
if ( err < 0 | | ( err = = 0 & & dataSize ! = 0 ) | |
( ( err = = 0 | | err = = - 1 ) & & dataSize = = 0 & & lastSocketError ! = 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) ) {
//printf("** #1 Socket peek error for sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError);
2013-02-26 08:05:46 +01:00
int iErr = lastSocketError ;
2015-12-25 23:08:54 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, dataSize = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , dataSize , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2011-12-02 17:07:59 +01:00
//printf("Peek #3 err = %d\n",err);
2012-02-11 23:52:52 +01:00
//lastSocketError = getLastSocketError();
2012-01-20 05:15:13 +01:00
if ( mustGetData = = true | | lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) {
2015-12-30 23:41:10 +01:00
printf ( " ** #2 Socket peek error for sock = %d err = %d lastSocketError = %d mustGetData = %d \n " , sock , err , lastSocketError , mustGetData ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, dataSize = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , dataSize , getLastSocketErrorFormattedText ( & iErr ) . c_str ( ) ) ;
2013-03-08 09:42:08 +01:00
2016-01-21 03:03:37 +01:00
if ( err = = 0 ) {
printf ( " ** LAST CHANCE for disconnection check for sock = %d \n " , sock ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " ** LAST CHANCE for disconnection check for sock = %d \n " , sock ) ;
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
SafeSocketBlockToggleWrapper safeUnblock ( this , false ) ;
errno = 0 ;
int second_err = recv ( sock , reinterpret_cast < char * > ( data ) , dataSize , MSG_PEEK ) ;
safeUnblock . Restore ( ) ;
safeMutex . ReleaseLock ( ) ;
if ( second_err = = 0 | | second_err < 0 ) {
printf ( " ** Disconnecting sock = %d \n " , sock ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " ** Disconnecting sock = %d \n " , sock ) ;
disconnectSocket ( ) ;
}
}
else {
printf ( " ** Disconnecting sock = %d \n " , sock ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " ** Disconnecting sock = %d \n " , sock ) ;
disconnectSocket ( ) ;
}
2011-02-08 19:23:41 +01:00
2015-12-25 23:08:54 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] DISCONNECTED SOCKET error while peeking socket data for socket [%d], err = %d, dataSize = %d, error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , err , dataSize , 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 ) ;
}
2013-03-08 09:42:08 +01:00
bool Socket : : getBlock ( ) {
bool blocking = true ;
// don't waste time if the socket is invalid
if ( isSocketValid ( & sock ) = = false ) {
return blocking ;
}
//#ifndef WIN32
// int currentFlags = fcntl(sock, F_GETFL);
// blocking = !((currentFlags & O_NONBLOCK) == O_NONBLOCK);
//#else
blocking = this - > isSocketBlocking ;
//#endif
return blocking ;
}
2010-03-16 22:37:11 +01:00
void Socket : : setBlock ( bool block ) {
2010-04-02 04:33:32 +02:00
setBlock ( block , this - > sock ) ;
2013-03-08 09:42:08 +01:00
this - > isSocketBlocking = block ;
2010-04-02 04:33:32 +02:00
}
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 " ) ;
}
}
2015-12-29 07:27:45 +01:00
inline bool Socket : : isReadable ( bool lockMutex ) {
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 ) ;
2015-12-23 21:42:39 +01:00
2015-12-29 07:27:45 +01:00
Mutex * lockMutexObj = ( lockMutex = = true ? dataSynchAccessorRead : NULL ) ;
MutexSafeWrapper safeMutex ( lockMutexObj , CODE_AT_LINE ) ;
//if(lockMutex == true) {
// safeMutex.setMutex(dataSynchAccessorRead,CODE_AT_LINE);
//}
2015-12-24 06:37:35 +01:00
FD_SET ( sock , & set ) ;
2015-12-23 23:26:03 +01:00
int i = select ( ( int ) sock + 1 , & set , NULL , NULL , & tv ) ;
2015-12-23 21:42:39 +01:00
safeMutex . ReleaseLock ( ) ;
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 ( ) ) ;
2013-11-12 16:01:37 +01:00
printf ( " In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , 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
}
2015-12-29 07:27:45 +01:00
inline bool Socket : : isWritable ( struct timeval * timeVal , bool lockMutex ) {
2010-04-13 08:59:30 +02:00
if ( isSocketValid ( ) = = false ) return false ;
2010-03-16 22:37:11 +01:00
struct timeval tv ;
2012-02-10 07:21:06 +01:00
if ( timeVal ! = NULL ) {
tv = * timeVal ;
}
else {
tv . tv_sec = 0 ;
tv . tv_usec = 0 ;
}
2010-03-16 22:37:11 +01:00
fd_set set ;
FD_ZERO ( & set ) ;
2015-12-23 21:42:39 +01:00
2015-12-29 07:27:45 +01:00
Mutex * lockMutexObj = ( lockMutex = = true ? dataSynchAccessorWrite : NULL ) ;
MutexSafeWrapper safeMutex ( lockMutexObj , CODE_AT_LINE ) ;
// MutexSafeWrapper safeMutex(NULL,CODE_AT_LINE);
// if(lockMutex == true) {
// safeMutex.setMutex(dataSynchAccessorWrite,CODE_AT_LINE);
// }
2015-12-24 06:37:35 +01:00
FD_SET ( sock , & set ) ;
2015-12-23 23:26:03 +01:00
int i = select ( ( int ) sock + 1 , NULL , & set , NULL , & tv ) ;
2015-12-23 21:42:39 +01:00
safeMutex . ReleaseLock ( ) ;
2015-12-23 23:26:03 +01:00
2011-02-15 08:49:40 +01:00
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 ( ) ) ;
2013-11-09 20:30:36 +01:00
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 ;
2013-11-09 20:30:36 +01:00
if ( difftime ( time ( NULL ) , lastSocketError ) > 1 ) {
lastSocketError = time ( NULL ) ;
2013-11-09 20:32:13 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " SOCKET WRITE TIMEOUT In [%s::%s Line: %d] i = %d sock = %d [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , i , sock , ipAddress . c_str ( ) ) ;
2013-11-09 20:30:36 +01:00
}
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-11-25 06:37:55 +01:00
// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE);
// if(this->inSocketDestructor == true) {
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__);
// return false;
// }
2011-12-02 17:07:59 +01:00
// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE);
2011-05-28 21:22:03 +02:00
2010-03-16 22:37:11 +01:00
//if the socket is not writable then it is not conencted
2013-03-11 04:27:20 +01:00
if ( isWritable ( NULL , true ) = = 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
2013-03-11 04:27:20 +01:00
if ( isReadable ( true ) ) {
2011-05-28 21:22:03 +02:00
char tmp = 0 ;
2013-03-08 09:42:08 +01:00
int peekDataBytes = 1 ;
2012-02-11 23:52:52 +01:00
int lastSocketError = 0 ;
2015-12-25 23:08:54 +01:00
2013-03-08 09:42:08 +01:00
int err = peek ( & tmp , peekDataBytes , false , & lastSocketError ) ;
2011-12-02 17:07:59 +01:00
//if(err <= 0 && err != PLATFORM_SOCKET_TRY_AGAIN) {
2013-03-15 01:31:51 +01:00
//if(err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) {
2014-12-16 06:07:13 +01:00
//if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0) ||
// ((err == 0 || err == -1) && peekDataBytes == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) {
if ( ( err < 0 & & lastSocketError ! = PLATFORM_SOCKET_TRY_AGAIN ) | | ( err = = 0 & & peekDataBytes ! = 0 ) ) {
2013-03-15 07:51:57 +01:00
//printf("IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError);
2015-12-30 23:41:10 +01:00
if ( err = = 0 ) {
printf ( " IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d \n " , sock , err , lastSocketError ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , getLastSocketErrorFormattedText ( ) . c_str ( ) , lastSocketError ) ;
}
2012-02-11 23:52:52 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " [%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , getLastSocketErrorFormattedText ( ) . c_str ( ) , lastSocketError ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) SystemFlags : : OutputDebug ( SystemFlags : : debugError , " SOCKET DISCONNECTED In [%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , err , sock , getLastSocketErrorFormattedText ( ) . c_str ( ) , lastSocketError ) ;
2010-07-09 07:29:42 +02:00
return false ;
}
2015-12-31 03:29:27 +01:00
if ( isSocketValid ( ) = = false ) 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 ( ) {
2016-01-01 01:48:55 +01:00
if ( Socket : : host_name = = " " ) {
2010-08-23 17:17:36 +02:00
const int strSize = 257 ;
char hostname [ strSize ] = " " ;
int result = gethostname ( hostname , strSize ) ;
if ( result = = 0 ) {
2016-01-01 01:48:55 +01:00
Socket : : host_name = ( hostname [ 0 ] ! = ' \0 ' ? hostname : " " ) ;
2010-08-23 17:17:36 +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] 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
}
2016-01-01 01:48:55 +01:00
return Socket : : host_name ;
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 ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Error getting host by name " ) ;
2010-03-16 22:37:11 +01:00
}
address = reinterpret_cast < unsigned char * > ( info - > h_addr_list [ 0 ] ) ;
if ( address = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Error getting host ip " ) ;
2010-03-16 22:37:11 +01:00
}
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 ( ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_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 ( ) ;
2013-01-23 15:51:28 +01:00
static string mutexOwnerId = string ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2010-04-02 04:33:32 +02:00
broadCastClientThread = new BroadCastClientSocketThread ( cb ) ;
2013-01-23 15:51:28 +01:00
broadCastClientThread - > setUniqueID ( mutexOwnerId ) ;
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
2012-01-20 05:15:13 +01:00
int lastSocketError = getLastSocketError ( ) ;
if ( lastSocketError = = PLATFORM_SOCKET_INPROGRESS | |
lastSocketError = = 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-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
2010-10-21 17:21:46 +02:00
err = select ( ( int ) sock + 1 , NULL , & myset , NULL , & tv ) ;
2012-01-20 05:15:13 +01:00
lastSocketError = getLastSocketError ( ) ;
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
2012-01-20 05:15:13 +01:00
if ( err < 0 & & lastSocketError ! = 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 ) ;
2013-11-05 07:31:48 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Apparent recovery for connection sock = " PLATFORM_SOCKET_FORMAT_TYPE " , 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 ( ) ) ;
2013-11-05 07:31:48 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Before END sock = " PLATFORM_SOCKET_FORMAT_TYPE " , 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 ( ) ) ;
2013-11-05 07:31:48 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] Valid recovery for connection sock = " PLATFORM_SOCKET_FORMAT_TYPE " , 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 ) ;
2013-11-05 07:31:48 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " Connected to host [%s] on port = %d sock = " PLATFORM_SOCKET_FORMAT_TYPE " 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 ;
2013-05-21 22:28:42 +02:00
uniqueID = " BroadCastClientSocketThread " ;
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
}
//=======================================================================
// 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.
2011-09-01 03:11:23 +02:00
//bool one = true; // Parameter for "setscokopt".
2011-11-29 06:07:18 +01:00
socklen_t alen = 0 ;
2010-04-01 08:31:10 +02:00
port = htons ( Socket : : getBroadCastPort ( ) ) ;
// Prepare to receive the broadcast.
bcfd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( bcfd < = 0 ) {
2013-05-15 02:45:34 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " socket failed: %s \n " , Socket : : 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
2013-12-14 08:04:12 +01:00
int opt_result = setsockopt ( bcfd , SOL_SOCKET , SO_REUSEADDR , & val , sizeof ( val ) ) ;
2010-04-13 08:59:30 +02:00
# else
2013-12-14 08:04:12 +01:00
int opt_result = setsockopt ( bcfd , SOL_SOCKET , SO_REUSEADDR , ( char * ) & val , sizeof ( val ) ) ;
2010-04-13 08:59:30 +02:00
# endif
2011-12-25 04:09:39 +01:00
if ( : : bind ( bcfd , ( struct sockaddr * ) & bcaddr , sizeof ( bcaddr ) ) < 0 ) {
2013-12-14 08:04:12 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " bind failed: %s opt_result = %d \n " , Socket : : getLastSocketErrorFormattedText ( ) . c_str ( ) , opt_result ) ;
2010-04-01 08:31:10 +02:00
}
else {
2013-12-14 08:04:12 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] opt_result = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , opt_result ) ;
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 {
2017-10-09 05:31:42 +02:00
char buff [ 10025 ] = " " ; // Buffers the data to be broadcasted.
2010-04-02 04:33:32 +02:00
// Keep getting packets forever.
2012-09-22 22:13:57 +02:00
for ( time_t elapsed = time ( NULL ) ; difftime ( ( long int ) time ( NULL ) , elapsed ) < = 5 ; ) {
2010-04-02 04:33:32 +02:00
alen = sizeof ( struct sockaddr ) ;
2011-11-29 06:07:18 +01:00
int nb = 0 ; // The number of bytes read.
2010-12-19 00:03:53 +01:00
bool gotData = ( nb = recvfrom ( bcfd , buff , 10024 , 0 , ( struct sockaddr * ) & bcSender , & alen ) ) > 0 ;
2017-10-09 05:31:42 +02:00
if ( nb > = 0 ) {
buff [ nb ] = 0 ;
}
2010-12-19 00:03:53 +01:00
2011-11-29 06:07:18 +01:00
//printf("Broadcasting client nb = %d buff [%s] gotData = %d\n",nb,buff,gotData);
2010-12-19 00:03:53 +01:00
if ( gotData = = false ) {
2013-05-15 02:45:34 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " recvfrom failed: %s \n " , Socket : : getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-04-02 04:33:32 +02:00
}
else {
2011-11-23 09:00:09 +01:00
//string fromIP = inet_ntoa(bcSender.sin_addr);
char szHostFrom [ 100 ] = " " ;
2011-11-29 06:07:18 +01:00
Ip : : Inet_NtoA ( SockAddrToUint32 ( & bcSender . sin_addr ) , szHostFrom ) ;
2011-11-25 00:15:21 +01:00
//printf("Client szHostFrom [%s]\n",szHostFrom);
2011-11-23 09:00:09 +01:00
string fromIP = szHostFrom ;
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
2012-10-06 01:53:10 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Client got broadcast from server: [%s] data [%s] \n " , fromIP . c_str ( ) , buff ) ;
int serverGamePort = Socket : : getBroadCastPort ( ) ;
vector < string > paramPartPortsTokens ;
Tokenize ( buff , paramPartPortsTokens , " : " ) ;
if ( paramPartPortsTokens . size ( ) > = 3 & & paramPartPortsTokens [ 2 ] . length ( ) > 0 ) {
serverGamePort = strToInt ( paramPartPortsTokens [ 2 ] ) ;
}
2010-04-03 04:21:04 +02:00
if ( std : : find ( foundServers . begin ( ) , foundServers . end ( ) , fromIP ) = = foundServers . end ( ) ) {
2012-10-06 01:53:10 +02:00
foundServers . push_back ( fromIP + " : " + intToStr ( serverGamePort ) ) ;
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
}
2013-12-18 02:35:51 +01:00
}
2010-04-15 03:19:00 +02:00
# ifndef WIN32
2013-12-18 17:26:16 +01:00
if ( bcfd > = 0 ) : : close ( bcfd ) ;
2013-12-25 07:44:46 +01:00
bcfd = - 1 ;
2010-04-15 03:19:00 +02:00
# else
2013-12-25 20:42:00 +01:00
if ( bcfd ! = INVALID_SOCKET ) : : closesocket ( bcfd ) ;
2013-12-18 02:35:51 +01:00
bcfd = INVALID_SOCKET ;
2010-04-15 03:19:00 +02:00
# endif
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
// ===============================================
2012-03-25 08:55:43 +02:00
ServerSocket : : ServerSocket ( bool basicMode ) : Socket ( ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] basicMode = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , basicMode ) ;
2010-04-01 08:31:10 +02:00
2012-03-25 08:55:43 +02:00
this - > basicMode = basicMode ;
2012-03-27 07:39:02 +02:00
this - > bindSpecificAddress = " " ;
2011-11-23 09:00:09 +01:00
//printf("SERVER SOCKET CONSTRUCTOR\n");
2011-10-23 02:55:34 +02:00
2012-09-22 22:13:57 +02:00
boundPort = 0 ;
2010-06-24 03:23:18 +02:00
portBound = false ;
2010-04-01 08:31:10 +02:00
broadCastThread = NULL ;
2012-03-25 08:55:43 +02:00
if ( this - > basicMode = = false ) {
UPNP_Tools : : enabledUPNP = false ;
}
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
}
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
2011-10-23 02:55:34 +02:00
//printf("In [%s::%s] Line: %d UPNP_Tools::enabledUPNP = %d\n",__FILE__,__FUNCTION__,__LINE__,UPNP_Tools::enabledUPNP);
2010-04-01 08:31:10 +02:00
stopBroadCastThread ( ) ;
2010-12-30 19:51:25 +01:00
2012-03-25 08:55:43 +02:00
if ( this - > basicMode = = false ) {
MutexSafeWrapper safeMutexUPNP ( & ServerSocket : : mutexUpnpdiscoverThread , CODE_AT_LINE ) ;
if ( ServerSocket : : upnpdiscoverThread ! = NULL ) {
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = true ;
2012-03-25 08:55:43 +02:00
SDL_WaitThread ( ServerSocket : : upnpdiscoverThread , NULL ) ;
ServerSocket : : upnpdiscoverThread = NULL ;
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = false ;
2012-03-25 08:55:43 +02:00
}
safeMutexUPNP . ReleaseLock ( ) ;
if ( UPNP_Tools : : enabledUPNP ) {
2012-10-16 18:23:24 +02:00
UPNP_Tools : : NETremRedirects ( this - > getExternalPort ( ) ) ;
2012-03-25 08:55:43 +02:00
}
2011-09-27 22:35:45 +02:00
2012-03-25 08:55:43 +02:00
MutexSafeWrapper safeMutexUPNP1 ( & UPNP_Tools : : mutexUPNP , CODE_AT_LINE ) ;
if ( urls . controlURL & & urls . ipcondescURL & & urls . controlURL_CIF ) {
FreeUPNPUrls ( & urls ) ;
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
safeMutexUPNP1 . ReleaseLock ( ) ;
}
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
2011-09-27 22:35:45 +02:00
//printf("Stopping broadcast thread [%p]\n",broadCastThread);
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-09-27 22:35:45 +02:00
//printf("Stopping broadcast thread [%p] - A\n",broadCastThread);
if ( broadCastThread - > canShutdown ( false ) = = true ) {
sleep ( 0 ) ;
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
//printf("Stopping broadcast thread [%p] - B\n",broadCastThread);
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-09-27 22:35:45 +02:00
delete broadCastThread ;
//printf("Stopping broadcast thread [%p] - C\n",broadCastThread);
2011-01-13 02:46:32 +01:00
}
2010-04-01 08:31:10 +02:00
broadCastThread = NULL ;
2011-09-27 22:35:45 +02:00
//printf("Stopping broadcast thread [%p] - D\n",broadCastThread);
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 ( ) ;
2012-10-06 01:53:10 +02:00
broadCastThread = new BroadCastSocketThread ( this - > boundPort ) ;
2011-09-27 22:35:45 +02:00
//printf("Start broadcast thread [%p]\n",broadCastThread);
2013-01-23 15:51:28 +01:00
static string mutexOwnerId = string ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
broadCastThread - > setUniqueID ( mutexOwnerId ) ;
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
}
2011-11-23 09:00:09 +01:00
void ServerSocket : : resumeBroadcast ( ) {
if ( broadCastThread ! = NULL ) {
broadCastThread - > setPauseBroadcast ( false ) ;
}
}
void ServerSocket : : pauseBroadcast ( ) {
if ( broadCastThread ! = NULL ) {
broadCastThread - > setPauseBroadcast ( true ) ;
}
}
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 ;
2012-03-27 07:39:02 +02:00
if ( this - > bindSpecificAddress ! = " " ) {
addr . sin_addr . s_addr = inet_addr ( this - > bindSpecificAddress . c_str ( ) ) ;
}
else {
addr . sin_addr . s_addr = INADDR_ANY ;
}
2010-03-16 22:37:11 +01:00
addr . sin_port = htons ( port ) ;
2013-12-14 08:04:12 +01:00
addr . sin_zero [ 0 ] = 0 ;
2010-03-16 22:37:11 +01:00
int val = 1 ;
2010-04-13 08:59:30 +02:00
# ifndef WIN32
2013-12-14 08:04:12 +01:00
int opt_result = setsockopt ( sock , SOL_SOCKET , SO_REUSEADDR , & val , sizeof ( val ) ) ;
2010-04-13 08:59:30 +02:00
# else
2013-12-14 08:04:12 +01:00
int opt_result = setsockopt ( sock , SOL_SOCKET , SO_REUSEADDR , ( char * ) & val , sizeof ( val ) ) ;
2010-04-13 08:59:30 +02:00
# endif
2010-03-16 22:37:11 +01:00
int err = : : bind ( sock , reinterpret_cast < sockaddr * > ( & addr ) , sizeof ( addr ) ) ;
2012-03-25 08:55:43 +02:00
if ( err < 0 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-12-14 08:04:12 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s] Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE " , address [%s] port = %d err = %d, error = %s opt_result = %d \n " , __FILE__ , __FUNCTION__ , sock , this - > bindSpecificAddress . c_str ( ) , port , err , getLastSocketErrorFormattedText ( ) . c_str ( ) , opt_result ) ;
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
2013-12-23 19:34:52 +01:00
snprintf ( szBuf , 8096 , " Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE " , address [%s] port = %d err = %d, error = %s \n " , sock , this - > bindSpecificAddress . c_str ( ) , port , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-11-05 07:31:48 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s] Error listening socket sock = " PLATFORM_SOCKET_FORMAT_TYPE " , err = %d, error = %s \n " , __FILE__ , __FUNCTION__ , sock , err , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2010-05-12 17:25:56 +02:00
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
2012-03-25 08:55:43 +02:00
if ( this - > basicMode = = false ) {
if ( connectionQueueSize > 0 ) {
if ( isBroadCastThreadRunning ( ) = = false ) {
startBroadCastThread ( ) ;
}
else {
resumeBroadcast ( ) ;
}
2010-04-12 23:40:57 +02:00
}
2011-11-23 09:00:09 +01:00
else {
2012-03-25 08:55:43 +02:00
pauseBroadcast ( ) ;
2011-11-23 09:00:09 +01:00
}
2010-04-12 23:40:57 +02:00
}
2010-03-16 22:37:11 +01:00
}
2012-01-20 05:15:13 +01:00
Socket * ServerSocket : : accept ( bool errorOnFail ) {
2010-06-24 03:23:18 +02:00
if ( isSocketValid ( ) = = false ) {
2012-01-20 05:15:13 +01:00
if ( errorOnFail = = true ) {
throwException ( " socket is invalid! " ) ;
}
else {
return NULL ;
}
2010-06-24 03:23:18 +02:00
}
2012-03-24 02:09:55 +01:00
PLATFORM_SOCKET newSock = 0 ;
2010-06-04 21:42:58 +02:00
char client_host [ 100 ] = " " ;
2013-12-14 08:04:12 +01:00
//const int max_attempts = 100;
//for(int attempt = 0; attempt < max_attempts; ++attempt) {
2012-03-24 02:09:55 +01:00
struct sockaddr_in cli_addr ;
socklen_t clilen = sizeof ( cli_addr ) ;
client_host [ 0 ] = ' \0 ' ;
MutexSafeWrapper safeMutex ( dataSynchAccessorRead , CODE_AT_LINE ) ;
newSock = : : accept ( sock , ( struct sockaddr * ) & cli_addr , & clilen ) ;
safeMutex . ReleaseLock ( ) ;
2010-08-21 01:53:10 +02:00
2012-03-24 02:09:55 +01:00
if ( isSocketValid ( & newSock ) = = false ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-12-23 19:34:52 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Error accepting socket connection sock = " PLATFORM_SOCKET_FORMAT_TYPE " , err = " PLATFORM_SOCKET_FORMAT_TYPE " , error = %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , sock , newSock , getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2012-03-24 02:09:55 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] %s \n " , __FILE__ , __FUNCTION__ , __LINE__ , szBuf ) ;
int lastSocketError = getLastSocketError ( ) ;
if ( lastSocketError = = PLATFORM_SOCKET_TRY_AGAIN ) {
2013-12-14 08:04:12 +01:00
//if(attempt+1 >= max_attempts) {
// return NULL;
//}
//else {
2012-03-24 02:09:55 +01:00
sleep ( 0 ) ;
2013-12-14 08:04:12 +01:00
//}
2012-03-24 02:09:55 +01:00
}
if ( errorOnFail = = true ) {
throwException ( szBuf ) ;
}
else {
2013-12-15 07:59:32 +01:00
# ifndef WIN32
: : close ( newSock ) ;
2013-12-25 07:44:46 +01:00
newSock = - 1 ;
2013-12-15 07:59:32 +01:00
# else
: : closesocket ( newSock ) ;
newSock = INVALID_SOCKET ;
# endif
2013-12-15 07:37:15 +01:00
2012-03-24 02:09:55 +01:00
return NULL ;
}
2010-03-16 22:37:11 +01:00
2012-01-20 05:15:13 +01:00
}
else {
2012-03-24 02:09:55 +01:00
Ip : : Inet_NtoA ( SockAddrToUint32 ( ( struct sockaddr * ) & cli_addr ) , client_host ) ;
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-03-16 22:37:11 +01:00
}
2012-03-24 02:09:55 +01:00
if ( isIPAddressBlocked ( ( client_host [ 0 ] ! = ' \0 ' ? 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 ) ;
2010-03-16 22:37:11 +01:00
2012-03-24 02:09:55 +01:00
# ifndef WIN32
: : close ( newSock ) ;
2013-12-25 07:44:46 +01:00
newSock = - 1 ;
2012-03-24 02:09:55 +01:00
# else
: : closesocket ( newSock ) ;
2013-02-09 07:57:05 +01:00
newSock = INVALID_SOCKET ;
2012-03-24 02:09:55 +01:00
# endif
2011-04-13 06:04:08 +02:00
2012-03-24 02:09:55 +01:00
return NULL ;
}
2011-04-13 07:07:47 +02:00
2013-12-14 08:04:12 +01:00
//break;
//}
2010-06-04 21:42:58 +02:00
Socket * result = new Socket ( newSock ) ;
2011-11-23 09:00:09 +01:00
result - > setIpAddress ( ( client_host [ 0 ] ! = ' \0 ' ? client_host : " " ) ) ;
2010-06-04 21:42:58 +02:00
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
2011-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutexUPNP ( & ServerSocket : : mutexUpnpdiscoverThread , CODE_AT_LINE ) ;
2011-10-23 02:55:34 +02:00
if ( ServerSocket : : upnpdiscoverThread ! = NULL ) {
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = true ;
2011-10-23 02:55:34 +02:00
SDL_WaitThread ( ServerSocket : : upnpdiscoverThread , NULL ) ;
ServerSocket : : upnpdiscoverThread = NULL ;
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = false ;
2010-12-31 09:21:26 +01:00
}
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)
2011-11-23 09:00:09 +01:00
//printf("STARTING UPNP Thread\n");
2015-09-29 08:28:11 +02:00
ServerSocket : : upnpdiscoverThread = SDL_CreateThread ( & UPNP_Tools : : upnp_init , " upnpdiscoverThread " , dynamic_cast < UPNPInitInterface * > ( this ) ) ;
2011-10-23 02:55:34 +02:00
safeMutexUPNP . ReleaseLock ( ) ;
//printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__);
2011-11-23 09:00:09 +01:00
//printf("SERVER SOCKET NETdiscoverUPnPDevices - END\n");
2010-12-31 09:21:26 +01:00
}
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 ) ;
}
2011-10-23 02:55:34 +02:00
UPNP_Tools : : NETaddRedirects ( UPNPPortForwardList , false ) ;
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 ) {
2011-11-23 09:00:09 +01:00
int result = - 1 ;
2010-12-31 09:21:26 +01:00
struct UPNPDev * devlist = NULL ;
struct UPNPDev * dev = 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
2011-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutexUPNP ( & UPNP_Tools : : mutexUPNP , CODE_AT_LINE ) ;
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
2014-01-04 00:10:30 +01:00
if ( UPNP_Tools : : isUPNP = = true ) {
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 " ) ;
2011-10-12 21:21:13 +02:00
2011-10-21 05:24:04 +02:00
int upnp_delay = 5000 ;
const char * upnp_multicastif = NULL ;
const char * upnp_minissdpdsock = NULL ;
int upnp_sameport = 0 ;
int upnp_ipv6 = 0 ;
int upnp_error = 0 ;
2011-10-13 00:04:00 +02:00
# ifndef MINIUPNPC_VERSION_PRE1_6
2015-10-22 03:11:19 +02:00
# if !defined(MINIUPNPC_API_VERSION) || MINIUPNPC_API_VERSION < 14
2011-10-21 05:24:04 +02:00
devlist = upnpDiscover ( upnp_delay , upnp_multicastif , upnp_minissdpdsock , upnp_sameport , upnp_ipv6 , & upnp_error ) ;
2015-10-22 03:11:19 +02:00
# else
// miniupnpc 1.9.20150730
devlist = upnpDiscover ( upnp_delay , upnp_multicastif , upnp_minissdpdsock , upnp_sameport , upnp_ipv6 , 2 , & upnp_error ) ;
# endif
2011-10-21 05:24:04 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP discover returned upnp_error = %d. \n " , upnp_error ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " UPnP discover returned upnp_error = %d. \n " , upnp_error ) ;
2011-10-13 00:04:00 +02:00
# else
2011-10-21 05:24:04 +02:00
devlist = upnpDiscover ( upnp_delay , upnp_multicastif , upnp_minissdpdsock , upnp_sameport ) ;
2011-10-13 00:04:00 +02:00
# endif
2011-10-21 05:24:04 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP device search finished devlist = %p. \n " , devlist ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " UPnP device search finished devlist = %p. \n " , devlist ) ;
2010-12-21 06:07:10 +01:00
2014-01-04 00:10:30 +01:00
if ( ServerSocket : : cancelUpnpdiscoverThread = = true ) {
if ( devlist ! = NULL ) {
freeUPNPDevlist ( devlist ) ;
}
devlist = NULL ;
return result ;
}
2010-12-21 06:07:10 +01:00
if ( devlist ) {
2011-10-21 05:24:04 +02:00
dev = devlist ;
while ( dev ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP discover deviceList [%s]. \n " , ( dev - > st ? dev - > st : " null " ) ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " UPnP discover deviceList [%s]. \n " , ( dev - > st ? dev - > st : " null " ) ) ;
dev = dev - > pNext ;
}
2010-12-21 06:07:10 +01:00
dev = devlist ;
2013-02-04 09:30:43 +01:00
while ( dev & & dev - > st ) {
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-11-23 09:00:09 +01:00
if ( dev ! = NULL ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP device found: %s %s \n " , dev - > descURL , dev - > st ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " UPnP device found: %s %s \n " , dev - > descURL , dev - > st ) ;
2010-12-21 06:07:10 +01:00
2011-11-23 09:00:09 +01:00
//printf("UPnP device found: [%s] [%s] lanaddr [%s]\n", dev->descURL, dev->st,lanaddr);
2016-05-23 19:54:38 +02:00
# if (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 16)
char * descXML = ( char * ) miniwget_getaddr ( dev - > descURL , & descXMLsize , lanaddr , ( sizeof ( lanaddr ) / sizeof ( lanaddr [ 0 ] ) ) , 0 , NULL ) ;
# elif (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 9) || (!defined(MINIUPNPC_VERSION_PRE1_7) && !defined(MINIUPNPC_VERSION_PRE1_6))
char * descXML = ( char * ) miniwget_getaddr ( dev - > descURL , & descXMLsize , lanaddr , ( sizeof ( lanaddr ) / sizeof ( lanaddr [ 0 ] ) ) , 0 ) ;
2012-12-26 02:11:11 +01:00
# else
2013-05-26 08:03:32 +02:00
char * descXML = ( char * ) miniwget_getaddr ( dev - > descURL , & descXMLsize , lanaddr , ( sizeof ( lanaddr ) / sizeof ( lanaddr [ 0 ] ) ) ) ;
2012-12-26 02:11:11 +01:00
# endif
2011-11-23 09:00:09 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " LAN address: %s \n " , lanaddr ) ;
2011-10-21 05:24:04 +02:00
2011-11-23 09:00:09 +01:00
if ( descXML ) {
parserootdesc ( descXML , descXMLsize , & data ) ;
free ( descXML ) ; descXML = 0 ;
2012-12-26 02:11:11 +01:00
2013-06-14 05:32:10 +02:00
# if (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 9) || (!defined(MINIUPNPC_VERSION_PRE1_7) && !defined(MINIUPNPC_VERSION_PRE1_6))
2012-12-26 02:11:11 +01:00
GetUPNPUrls ( & urls , & data , dev - > descURL , 0 ) ;
# else
2011-11-23 09:00:09 +01:00
GetUPNPUrls ( & urls , & data , dev - > descURL ) ;
2012-12-26 02:11:11 +01:00
# endif
2011-11-23 09:00:09 +01:00
}
2012-10-19 03:31:20 +02:00
snprintf ( buf , 255 , " UPnP device found: %s %s LAN address %s " , dev - > descURL , dev - > st , lanaddr ) ;
2010-12-31 09:21:26 +01:00
2011-11-23 09:00:09 +01:00
freeUPNPDevlist ( devlist ) ;
devlist = NULL ;
}
2010-12-21 06:07:10 +01:00
2014-01-04 00:10:30 +01:00
if ( ServerSocket : : cancelUpnpdiscoverThread = = true ) {
2014-12-16 06:07:13 +01:00
//if(devlist != NULL) {
// freeUPNPDevlist(devlist);
//}
2014-12-20 04:08:04 +01:00
//devlist = NULL;
2014-01-04 00:10:30 +01:00
return result ;
}
2010-12-21 06:07:10 +01:00
if ( ! urls . controlURL | | urls . controlURL [ 0 ] = = ' \0 ' ) {
2012-10-19 03:31:20 +02:00
snprintf ( buf , 255 , " controlURL not available, UPnP disabled " ) ;
2010-12-31 09:21:26 +01:00
if ( callback ) {
2011-11-23 09:00:09 +01:00
safeMutexUPNP . ReleaseLock ( ) ;
2010-12-31 09:21:26 +01:00
callback - > UPNPInitStatus ( false ) ;
}
2011-11-23 09:00:09 +01:00
result = 0 ;
2010-12-21 06:07:10 +01:00
}
2011-11-23 09:00:09 +01:00
else {
char externalIP [ 16 ] = " " ;
2011-10-13 00:04:00 +02:00
# ifndef MINIUPNPC_VERSION_PRE1_5
2011-11-23 09:00:09 +01:00
UPNP_GetExternalIPAddress ( urls . controlURL , data . first . servicetype , externalIP ) ;
2011-05-27 08:37:43 +02:00
# else
2011-11-23 09:00:09 +01:00
UPNP_GetExternalIPAddress ( urls . controlURL , data . servicetype , externalIP ) ;
2011-05-27 08:37:43 +02:00
# endif
2011-11-23 09:00:09 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UPnP device found at: [%s] callback [%p] \n " , externalIP , callback ) ;
//UPNP_Tools::NETaddRedirects(ports);
UPNP_Tools : : enabledUPNP = true ;
if ( callback ) {
safeMutexUPNP . ReleaseLock ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
callback - > UPNPInitStatus ( true ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
result = 1 ;
}
2010-12-21 06:07:10 +01:00
}
2010-12-31 09:21:26 +01:00
2011-11-23 09:00:09 +01:00
if ( result = = - 1 ) {
2012-10-19 03:31:20 +02:00
snprintf ( buf , 255 , " UPnP device not found. " ) ;
2010-12-21 06:07:10 +01:00
2011-11-23 09:00:09 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " No UPnP devices found. \n " ) ;
2014-01-04 00:10:30 +01:00
if ( ServerSocket : : cancelUpnpdiscoverThread = = true ) {
2014-12-01 00:30:02 +01:00
//if(devlist != NULL) {
// freeUPNPDevlist(devlist);
//}
//devlist = NULL;
2014-01-04 00:10:30 +01:00
return result ;
}
2011-11-23 09:00:09 +01:00
if ( callback ) {
safeMutexUPNP . ReleaseLock ( ) ;
callback - > UPNPInitStatus ( false ) ;
}
result = 0 ;
}
2010-12-21 06:07:10 +01:00
}
else {
2012-10-19 03:31:20 +02:00
snprintf ( buf , 255 , " 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
2014-01-04 00:10:30 +01:00
if ( ServerSocket : : cancelUpnpdiscoverThread = = true ) {
2014-12-17 16:28:06 +01:00
//if(devlist != NULL) {
// freeUPNPDevlist(devlist);
//}
//devlist = NULL;
2014-01-04 00:10:30 +01:00
return result ;
}
2010-12-31 09:21:26 +01:00
if ( callback ) {
2011-11-23 09:00:09 +01:00
safeMutexUPNP . ReleaseLock ( ) ;
2010-12-31 09:21:26 +01:00
callback - > UPNPInitStatus ( false ) ;
}
2011-11-23 09:00:09 +01:00
result = 0 ;
2010-12-21 06:07:10 +01:00
}
2011-11-23 09:00:09 +01:00
//printf("ENDING UPNP Thread\n");
return result ;
2010-12-21 06:07:10 +01:00
}
2011-10-23 02:55:34 +02:00
bool UPNP_Tools : : upnp_add_redirect ( int ports [ 2 ] , bool mutexLock ) {
2011-11-23 09:00:09 +01:00
bool result = true ;
2010-12-21 06:07:10 +01:00
2011-11-23 09:00:09 +01:00
//printf("SERVER SOCKET upnp_add_redirect - START\n");
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-10-23 02:55:34 +02:00
if ( mutexLock ) {
2011-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutexUPNP ( & ServerSocket : : mutexUpnpdiscoverThread , CODE_AT_LINE ) ;
2011-10-23 02:55:34 +02:00
if ( ServerSocket : : upnpdiscoverThread ! = NULL ) {
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = true ;
2011-10-23 02:55:34 +02:00
SDL_WaitThread ( ServerSocket : : upnpdiscoverThread , NULL ) ;
ServerSocket : : upnpdiscoverThread = NULL ;
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = false ;
2011-10-23 02:55:34 +02:00
}
safeMutexUPNP . ReleaseLock ( ) ;
}
2011-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutexUPNP ( & UPNP_Tools : : mutexUPNP , CODE_AT_LINE ) ;
2011-06-02 07:05:54 +02:00
if ( ! urls . controlURL | | urls . controlURL [ 0 ] = = ' \0 ' ) {
2011-11-23 09:00:09 +01:00
result = false ;
2011-06-02 07:05:54 +02:00
}
2011-11-23 09:00:09 +01:00
else {
2013-05-26 08:03:32 +02:00
char externalIP [ 16 ] = " " ;
2011-10-13 00:04:00 +02:00
# ifndef MINIUPNPC_VERSION_PRE1_5
2011-11-23 09:00:09 +01:00
UPNP_GetExternalIPAddress ( urls . controlURL , data . first . servicetype , externalIP ) ;
2011-05-27 08:37:43 +02:00
# else
2011-11-23 09:00:09 +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
2013-05-26 08:03:32 +02:00
char ext_port_str [ 16 ] = " " ;
char int_port_str [ 16 ] = " " ;
2011-11-23 09:00:09 +01:00
sprintf ( ext_port_str , " %d " , ports [ 0 ] ) ;
sprintf ( int_port_str , " %d " , ports [ 1 ] ) ;
2010-12-21 06:07:10 +01:00
2012-10-18 10:16:47 +02:00
//int r = 0;
2011-10-13 00:04:00 +02:00
# ifndef MINIUPNPC_VERSION_PRE1_5
# ifndef MINIUPNPC_VERSION_PRE1_6
2012-10-18 10:16:47 +02:00
int r = UPNP_AddPortMapping ( urls . controlURL , data . first . servicetype , ext_port_str , int_port_str , lanaddr , " MegaGlest - www.megaglest.org " , " TCP " , 0 , NULL ) ;
2011-10-13 00:04:00 +02:00
# else
2012-10-18 10:16:47 +02:00
int r = UPNP_AddPortMapping ( urls . controlURL , data . first . servicetype , ext_port_str , int_port_str , lanaddr , " MegaGlest - www.megaglest.org " , " TCP " , 0 ) ;
2011-10-13 00:04:00 +02:00
# endif
2011-05-27 08:37:43 +02:00
# else
2012-10-18 10:16:47 +02:00
int 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
2011-11-23 09:00:09 +01:00
if ( r ! = UPNPCOMMAND_SUCCESS ) {
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 ) ;
result = false ;
}
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
}
2010-12-29 21:28:25 +01:00
2011-11-23 09:00:09 +01:00
//printf("SERVER SOCKET upnp_add_redirect - END [%d]\n",result);
return result ;
2010-12-21 06:07:10 +01:00
}
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-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutexUPNP ( & ServerSocket : : mutexUpnpdiscoverThread , CODE_AT_LINE ) ;
2011-10-23 02:55:34 +02:00
if ( ServerSocket : : upnpdiscoverThread ! = NULL ) {
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = true ;
2011-10-23 02:55:34 +02:00
SDL_WaitThread ( ServerSocket : : upnpdiscoverThread , NULL ) ;
ServerSocket : : upnpdiscoverThread = NULL ;
2014-01-04 00:10:30 +01:00
ServerSocket : : cancelUpnpdiscoverThread = false ;
2011-10-23 02:55:34 +02:00
}
safeMutexUPNP . ReleaseLock ( ) ;
2011-11-23 09:00:09 +01:00
MutexSafeWrapper safeMutexUPNP1 ( & UPNP_Tools : : mutexUPNP , CODE_AT_LINE ) ;
2011-06-02 07:05:54 +02:00
if ( urls . controlURL & & urls . controlURL [ 0 ] ! = ' \0 ' ) {
2011-06-01 21:06:14 +02:00
char ext_port_str [ 16 ] = " " ;
sprintf ( ext_port_str , " %d " , ext_port ) ;
2011-10-23 02:55:34 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #1 DEBUGGING urls.controlURL [%s] \n " , urls . controlURL ) ;
2011-06-01 21:06:14 +02:00
2011-10-23 02:55:34 +02:00
int result = 0 ;
2011-10-13 00:04:00 +02:00
# ifndef MINIUPNPC_VERSION_PRE1_5
2011-10-23 02:55:34 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #1 DEBUGGING data.first.servicetype [%s] \n " , data . first . servicetype ) ;
result = UPNP_DeletePortMapping ( urls . controlURL , data . first . servicetype , ext_port_str , " TCP " , 0 ) ;
2011-06-01 21:06:14 +02:00
# else
2011-10-23 02:55:34 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #1 DEBUGGING data.servicetype [%s] \n " , data . servicetype ) ;
result = UPNP_DeletePortMapping ( urls . controlURL , data . servicetype , ext_port_str , " TCP " , 0 ) ;
2011-06-01 21:06:14 +02:00
# endif
2011-10-23 02:55:34 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n result = %d \n " , result ) ;
//printf("\n\nresult = %d\n",result);
2011-06-01 21:06:14 +02:00
}
2011-10-23 02:55:34 +02:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " \n \n #2 DEBUGGING urls.controlURL [%s] \n " , urls . controlURL ) ;
2011-11-23 09:00:09 +01:00
//printf("SERVER SOCKET upnp_rem_redirect - END\n");
2010-12-21 06:07:10 +01:00
}
2011-10-23 02:55:34 +02:00
void UPNP_Tools : : NETaddRedirects ( std : : vector < int > UPNPPortForwardList , bool mutexLock ) {
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
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " UPNPPortForwardList.size() MUST BE divisable by 2 " ) ;
2011-01-06 01:52:00 +01:00
}
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 ] } ;
2011-10-23 02:55:34 +02:00
upnp_add_redirect ( ports , mutexLock ) ;
2011-01-06 01:52:00 +01:00
}
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>
//
2012-10-06 01:53:10 +02:00
BroadCastSocketThread : : BroadCastSocketThread ( int boundPort ) : 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__ ) ;
2013-12-25 07:27:44 +01:00
mutexPauseBroadcast = new Mutex ( CODE_AT_LINE ) ;
2011-11-29 06:07:18 +01:00
setPauseBroadcast ( false ) ;
2012-10-06 01:53:10 +02:00
this - > boundPort = boundPort ;
2013-05-21 22:28:42 +02:00
uniqueID = " BroadCastSocketThread " ;
2011-09-27 22:35:45 +02:00
//printf("new broadcast thread [%p]\n",this);
2010-12-21 06:07:10 +01:00
}
2011-09-27 12:16:09 +02:00
BroadCastSocketThread : : ~ BroadCastSocketThread ( ) {
2011-09-27 22:35:45 +02:00
//printf("delete broadcast thread [%p]\n",this);
2011-12-02 17:07:59 +01:00
delete mutexPauseBroadcast ;
mutexPauseBroadcast = NULL ;
2011-09-27 12:16:09 +02:00
}
2011-11-23 09:00:09 +01:00
bool BroadCastSocketThread : : getPauseBroadcast ( ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( mutexPauseBroadcast , CODE_AT_LINE ) ;
mutexPauseBroadcast - > setOwnerId ( CODE_AT_LINE ) ;
2011-11-23 09:00:09 +01:00
return pauseBroadcast ;
}
void BroadCastSocketThread : : setPauseBroadcast ( bool value ) {
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutexSocketDestructorFlag ( mutexPauseBroadcast , CODE_AT_LINE ) ;
mutexPauseBroadcast - > setOwnerId ( CODE_AT_LINE ) ;
2011-11-23 09:00:09 +01:00
pauseBroadcast = value ;
}
2011-01-13 02:46:32 +01:00
bool BroadCastSocketThread : : canShutdown ( bool deleteSelfIfShutdownDelayed ) {
bool ret = ( getExecutingTask ( ) = = false ) ;
if ( ret = = false & & deleteSelfIfShutdownDelayed = = true ) {
setDeleteSelfOnExecutionDone ( deleteSelfIfShutdownDelayed ) ;
2013-06-04 02:31:41 +02:00
deleteSelfIfRequired ( ) ;
2011-01-13 02:46:32 +01:00
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.
2011-12-02 17:07:59 +01:00
int one = 1 ; // Parameter for "setscokopt".
2010-10-23 07:12:28 +02:00
int pn = 0 ; // The number of the packet broadcasted.
2011-08-31 21:44:19 +02:00
const int buffMaxSize = 1024 ;
char buff [ buffMaxSize ] = " " ; // Buffers the data to be broadcasted.
2010-10-23 07:12:28 +02:00
char myhostname [ 100 ] = " " ; // hostname of local machine
//char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
2011-09-01 03:11:23 +02:00
//struct hostent* myhostent=NULL;
2010-04-01 08:31:10 +02:00
2013-12-18 02:35:51 +01:00
for ( unsigned int idx = 0 ; idx < ( unsigned int ) MAX_NIC_COUNT ; idx + + ) {
memset ( & bcLocal [ idx ] , 0 , sizeof ( struct sockaddr_in ) ) ;
# ifdef WIN32
bcfd [ idx ] = INVALID_SOCKET ;
# else
2013-12-25 07:44:46 +01:00
bcfd [ idx ] = - 1 ;
2013-12-18 02:35:51 +01:00
# endif
}
2010-04-01 08:31:10 +02:00
/* get my host name */
gethostname ( myhostname , 100 ) ;
2011-09-01 20:51:43 +02:00
//struct hostent*myhostent = gethostbyname(myhostname);
2010-04-01 08:31:10 +02:00
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 ;
2017-09-22 02:32:15 +02:00
//ipList.clear();
2017-09-22 02:18:50 +02:00
if ( ipList . empty ( ) = = false ) {
for ( unsigned int idx = 0 ; idx < ( unsigned int ) ipList . size ( ) & & idx < ( unsigned int ) MAX_NIC_COUNT ; idx + + ) {
string broadCastAddress = getNetworkInterfaceBroadcastAddress ( ipList [ idx ] ) ;
2017-09-22 02:32:15 +02:00
//printf("idx = %d broadCastAddress [%s]\n",idx,broadCastAddress.c_str());
2017-09-22 02:18:50 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " idx = %d broadCastAddress [%s] \n " , idx , broadCastAddress . c_str ( ) ) ;
2011-11-25 00:15:21 +01:00
2017-09-22 02:18:50 +02:00
//strcpy(subnetmask[idx], broadCastAddress.c_str());
if ( broadCastAddress ! = " " & & std : : find ( ipSubnetMaskList . begin ( ) , ipSubnetMaskList . end ( ) , broadCastAddress ) = = ipSubnetMaskList . end ( ) ) {
//printf("Adding index [%d] address to list ...\n",idx);
2017-09-22 02:04:56 +02:00
2017-09-22 02:18:50 +02:00
ipSubnetMaskList . push_back ( broadCastAddress ) ;
}
2010-10-23 07:12:28 +02:00
}
2017-09-22 02:18:50 +02:00
}
else {
2017-09-22 02:32:15 +02:00
//printf("NO Addresses found for broadCastAddress using INADDR_ANY\n");
2017-09-22 02:18:50 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " NO Addresses found for broadCastAddress using INADDR_ANY \n " ) ;
2017-09-22 02:23:11 +02:00
//ipSubnetMaskList.push_back(INADDR_ANY);
ipSubnetMaskList . push_back ( " * " ) ;
2017-09-22 02:18:50 +02:00
}
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++) {
2013-11-19 07:42:32 +01:00
for ( unsigned int idx = 0 ; idx < ( unsigned int ) 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 ;
2017-09-22 02:23:11 +02:00
if ( ipSubnetMaskList [ idx ] = = " * " ) {
2017-09-22 02:32:15 +02:00
//printf("UDP Socket broadcast using INADDR_ANY\n");
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UDP Socket broadcast using INADDR_ANY \n " ) ;
2017-09-22 02:23:11 +02:00
bcLocal [ idx ] . sin_addr . s_addr = INADDR_ANY ;
}
else {
2017-09-22 02:32:15 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " UDP Socket broadcast using IP [%s] \n " , ipSubnetMaskList [ idx ] . c_str ( ) ) ;
2017-09-22 02:23:11 +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
2013-12-25 07:44:46 +01:00
bcfd [ idx ] = - 1 ;
2010-06-14 23:03:23 +02:00
# 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 ) {
2013-05-15 02:45:34 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Unable to allocate broadcast socket [%s]: %s \n " , ipSubnetMaskList [ idx ] . c_str ( ) , Socket : : getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2017-09-22 02:04:56 +02:00
//printf("Unable to allocate broadcast socket [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::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 ) {
2013-05-15 02:45:34 +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 ( ) , Socket : : getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2017-09-22 02:04:56 +02:00
//printf("Could not set socket to broadcast [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::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
2012-10-19 03:31:20 +02:00
snprintf ( buff , 1024 , " %s " , myhostname ) ;
2010-04-11 09:13:14 +02:00
for ( unsigned int idx1 = 0 ; idx1 < ipList . size ( ) ; idx1 + + ) {
2013-12-18 02:35:51 +01:00
// strcat(buff,":");
// strcat(buff,ipList[idx1].c_str());
// strcat(buff,":");
// string port_string = intToStr(this->boundPort);
//#ifdef WIN32
// strncat(buff,port_string.c_str(),min((int)port_string.length(),100));
//#else
// strncat(buff,port_string.c_str(),std::min((int)port_string.length(),100));
//#endif
2013-12-19 08:35:27 +01:00
string buffCopy = buff ;
snprintf ( buff , 1024 , " %s:%s:%d " , buffCopy . c_str ( ) , ipList [ idx1 ] . c_str ( ) , this - > boundPort ) ;
2017-09-22 02:04:56 +02:00
//printf("About to broadcast index [%d] host info [%s]\n", idx1,buff);
2010-04-11 09:13:14 +02:00
}
2010-04-01 08:31:10 +02:00
2012-09-22 22:13:57 +02:00
if ( difftime ( ( long int ) time ( NULL ) , elapsed ) > = 1 & & getQuitStatus ( ) = = false ) {
2010-04-11 09:13:14 +02:00
elapsed = time ( NULL ) ;
2010-04-01 08:31:10 +02:00
2011-11-29 06:07:18 +01:00
bool pauseBroadCast = getPauseBroadcast ( ) ;
if ( pauseBroadCast = = false ) {
2011-11-23 09:00:09 +01:00
// Broadcast the packet to the subnet
//if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
2012-10-06 01:53:10 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Server is sending broadcast data [%s] \n " , buff ) ;
2017-09-22 02:04:56 +02:00
//printf("Broadcasting index host info [%s]\n", buff);
2012-10-06 01:53:10 +02:00
2012-03-28 08:25:57 +02:00
ssize_t send_res = sendto ( bcfd [ idx ] , buff , buffMaxSize , 0 , ( struct sockaddr * ) & bcLocal [ idx ] , sizeof ( struct sockaddr_in ) ) ;
2011-11-29 06:07:18 +01:00
if ( send_res ! = buffMaxSize ) {
2013-05-15 02:45:34 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Sendto error: %s \n " , Socket : : getLastSocketErrorFormattedText ( ) . c_str ( ) ) ;
2011-11-23 09:00:09 +01:00
}
else {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugNetwork ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugNetwork , " Broadcasting on port [%d] the message: [%s] \n " , Socket : : getBroadCastPort ( ) , buff ) ;
}
}
2011-11-29 06:07:18 +01:00
//printf("Broadcasting server send_res = %d buff [%s] ip [%s] getPauseBroadcast() = %d\n",send_res,buff,ipSubnetMaskList[idx].c_str(),pauseBroadCast);
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 ] ) ;
2013-12-25 07:44:46 +01:00
bcfd [ idx ] = - 1 ;
2010-04-15 03:19:00 +02:00
# else
: : closesocket ( bcfd [ idx ] ) ;
2013-02-09 07:57:05 +01:00
bcfd [ idx ] = INVALID_SOCKET ;
2010-04-15 03:19:00 +02:00
# 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 ) ;
2011-11-23 09:00:09 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugError ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Blocked IP Address [%s]. \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , value . c_str ( ) ) ;
2011-04-13 06:04:08 +02:00
}
}
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