1 /// \file
2 /// \brief SocketLayer class implementation
3 ///
4 /// This file is part of RakNet Copyright 2003 Jenkins Software LLC
5 ///
6 /// Raknet is available under the terms of the GPLv3 license, see /usr/local/share/licenses/raknet-3.9.2_10,1/GPLv3.
7 
8 
9 #include "SocketLayer.h"
10 #include "RakAssert.h"
11 #include "RakNetTypes.h"
12 #include "GetTime.h"
13 
14 #if USE_SLIDING_WINDOW_CONGESTION_CONTROL!=1
15 #include "CCRakNetUDT.h"
16 #else
17 #include "CCRakNetSlidingWindow.h"
18 #endif
19 
20 
21 SocketLayerOverride *SocketLayer::slo=0;
22 
23 #ifdef _WIN32
24 #else
25 #include <string.h> // memcpy
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <arpa/inet.h>
29 #include <errno.h>  // error numbers
30 #include <stdio.h> // RAKNET_DEBUG_PRINTF
31 #if !defined(ANDROID)
32 #include <ifaddrs.h>
33 #endif
34 #include <netinet/in.h>
35 #include <net/if.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/ioctl.h>
39 
40 #endif
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 #if   defined(_WIN32)
52 #include "WSAStartupSingleton.h"
53 #include <ws2tcpip.h> // 'IP_DONTFRAGMENT' 'IP_TTL'
54 #elif defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
55 #define closesocket socketclose
56 #else
57 #define closesocket close
58 #include <unistd.h>
59 #endif
60 
61 #include "RakSleep.h"
62 #include <stdio.h>
63 
64 #include "ExtendedOverlappedPool.h"
65 
66 #ifdef _MSC_VER
67 #pragma warning( push )
68 #endif
69 
70 extern void ProcessNetworkPacket( const SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNetSmartPtr<RakNetSocket> rakNetSocket, RakNetTimeUS timeRead );
71 extern void ProcessNetworkPacket( const SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNetTimeUS timeRead );
72 extern void ProcessPortUnreachable( const unsigned int binaryAddress, const unsigned short port, RakPeer *rakPeer );
73 
74 #ifdef _DEBUG
75 #include <stdio.h>
76 #endif
77 
78 // Frogwares: Define this
79 // #define DEBUG_SENDTO_SPIKES
80 
81 
Connect(SOCKET writeSocket,unsigned int binaryAddress,unsigned short port)82 SOCKET SocketLayer::Connect( SOCKET writeSocket, unsigned int binaryAddress, unsigned short port )
83 {
84 	RakAssert( writeSocket != (SOCKET) -1 );
85 	sockaddr_in connectSocketAddress;
86 	memset(&connectSocketAddress,0,sizeof(sockaddr_in));
87 
88 	connectSocketAddress.sin_family = AF_INET;
89 	connectSocketAddress.sin_port = htons( port );
90 	connectSocketAddress.sin_addr.s_addr = binaryAddress;
91 
92 	if ( connect( writeSocket, ( struct sockaddr * ) & connectSocketAddress, sizeof( struct sockaddr ) ) != 0 )
93 	{
94 #if defined(_WIN32) &&  defined(_DEBUG)
95 		DWORD dwIOError = GetLastError();
96 		LPVOID messageBuffer;
97 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
98 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
99 			( LPTSTR ) &messageBuffer, 0, NULL );
100 		// something has gone wrong here...
101 		RAKNET_DEBUG_PRINTF( "WSAConnect failed:Error code - %d\n%s", dwIOError, messageBuffer );
102 		//Free the buffer.
103 		LocalFree( messageBuffer );
104 #endif
105 	}
106 
107 	return writeSocket;
108 }
IsPortInUse(unsigned short port,const char * hostAddress)109 bool SocketLayer::IsPortInUse(unsigned short port, const char *hostAddress)
110 {
111 	SOCKET listenSocket;
112 	sockaddr_in listenerSocketAddress;
113 	memset(&listenerSocketAddress,0,sizeof(sockaddr_in));
114 	// Listen on our designated Port#
115 	listenerSocketAddress.sin_port = htons( port );
116 	listenSocket = socket( AF_INET, SOCK_DGRAM, 0 );
117 	if ( listenSocket == (SOCKET) -1 )
118 		return true;
119 	// bind our name to the socket
120 	// Fill in the rest of the address structure
121 	listenerSocketAddress.sin_family = AF_INET;
122 	if ( hostAddress && hostAddress[0] )
123 		listenerSocketAddress.sin_addr.s_addr = inet_addr( hostAddress );
124 	else
125 		listenerSocketAddress.sin_addr.s_addr = INADDR_ANY;
126 	int ret = bind( listenSocket, ( struct sockaddr * ) & listenerSocketAddress, sizeof( listenerSocketAddress ) );
127 	closesocket(listenSocket);
128 
129 
130 
131 
132 	#if defined(_DEBUG)
133 	if (ret == -1)
134 		perror("Failed to bind to address:");
135 	#endif
136 	return ret <= -1;
137 
138 }
SetDoNotFragment(SOCKET listenSocket,int opt)139 void SocketLayer::SetDoNotFragment( SOCKET listenSocket, int opt )
140 {
141 
142 #if defined(IP_DONTFRAGMENT )
143 
144 #if defined(_WIN32) &&  defined(_DEBUG)
145 	// If this assert hit you improperly linked against WSock32.h
146 	RakAssert(IP_DONTFRAGMENT==14);
147 #endif
148 
149 	if ( setsockopt( listenSocket, IPPROTO_IP, IP_DONTFRAGMENT, ( char * ) & opt, sizeof ( opt ) ) == -1 )
150 	{
151 #if defined(_WIN32) && defined(_DEBUG)
152 		DWORD dwIOError = GetLastError();
153 		LPVOID messageBuffer;
154 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
155 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
156 			( LPTSTR ) & messageBuffer, 0, NULL );
157 		RAKNET_DEBUG_PRINTF( "setsockopt(IP_DONTFRAGMENT) failed:Error code - %d\n%s", dwIOError, messageBuffer );
158 		LocalFree( messageBuffer );
159 #endif
160 	}
161 #endif
162 
163 }
164 
SetNonBlocking(SOCKET listenSocket)165 void SocketLayer::SetNonBlocking( SOCKET listenSocket)
166 {
167 #ifdef _WIN32
168 	unsigned long nonBlocking = 1;
169 	ioctlsocket( listenSocket, FIONBIO, &nonBlocking );
170 
171 
172 
173 #else
174 	int flags = fcntl(listenSocket, F_GETFL, 0);
175 	fcntl(listenSocket, F_SETFL, flags | O_NONBLOCK);
176 #endif
177 }
178 
SetSocketOptions(SOCKET listenSocket)179 void SocketLayer::SetSocketOptions( SOCKET listenSocket)
180 {
181 	int sock_opt = 1;
182 	// // On Vista, can get WSAEACCESS (10013)
183 	/*
184 	if ( setsockopt( listenSocket, SOL_SOCKET, SO_REUSEADDR, ( char * ) & sock_opt, sizeof ( sock_opt ) ) == -1 )
185 	{
186 	#if defined(_WIN32) && !defined(_XBOX) && defined(_DEBUG) && !defined(X360)
187 	DWORD dwIOError = GetLastError();
188 	LPVOID messageBuffer;
189 	FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
190 	NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
191 	( LPTSTR ) & messageBuffer, 0, NULL );
192 	// something has gone wrong here...
193 	RAKNET_DEBUG_PRINTF( "setsockopt(SO_REUSEADDR) failed:Error code - %d\n%s", dwIOError, messageBuffer );
194 	//Free the buffer.
195 	LocalFree( messageBuffer );
196 	#endif
197 	}
198 	*/
199 
200 	// This doubles the max throughput rate
201 	sock_opt=1024*256;
202 	setsockopt(listenSocket, SOL_SOCKET, SO_RCVBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
203 
204 	// Immediate hard close. Don't linger the socket, or recreating the socket quickly on Vista fails.
205 	sock_opt=0;
206 	setsockopt(listenSocket, SOL_SOCKET, SO_LINGER, ( char * ) & sock_opt, sizeof ( sock_opt ) );
207 
208 
209 	// This doesn't make much difference: 10% maybe
210 	// Not supported on console 2
211 	sock_opt=1024*16;
212 	setsockopt(listenSocket, SOL_SOCKET, SO_SNDBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
213 
214 
215 	/*
216 	#ifdef _WIN32
217 		unsigned long nonblocking = 1;
218 		ioctlsocket( listenSocket, FIONBIO, &nonblocking );
219 	#elif defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
220 		sock_opt=1;
221 		setsockopt(listenSocket, SOL_SOCKET, SO_NBIO, ( char * ) & sock_opt, sizeof ( sock_opt ) );
222 	#else
223 		fcntl( listenSocket, F_SETFL, O_NONBLOCK );
224 	#endif
225 	*/
226 
227 	// Set broadcast capable
228 	sock_opt=1;
229 	if ( setsockopt( listenSocket, SOL_SOCKET, SO_BROADCAST, ( char * ) & sock_opt, sizeof( sock_opt ) ) == -1 )
230 		{
231 #if defined(_WIN32) && defined(_DEBUG)
232 		DWORD dwIOError = GetLastError();
233 		// On Vista, can get WSAEACCESS (10013)
234 		// See http://support.microsoft.com/kb/819124
235 		// http://blogs.msdn.com/wndp/archive/2007/03/19/winsock-so-exclusiveaddruse-on-vista.aspx
236 		// http://msdn.microsoft.com/en-us/library/ms740621(VS.85).aspx
237 
238 		LPVOID messageBuffer;
239 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
240 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
241 			( LPTSTR ) & messageBuffer, 0, NULL );
242 		// something has gone wrong here...
243 		RAKNET_DEBUG_PRINTF( "setsockopt(SO_BROADCAST) failed:Error code - %d\n%s", dwIOError, messageBuffer );
244 		//Free the buffer.
245 		LocalFree( messageBuffer );
246 
247 #endif
248 
249 		}
250 }
CreateBoundSocket_PS3Lobby(unsigned short port,bool blockingSocket,const char * forceHostAddress)251 SOCKET SocketLayer::CreateBoundSocket_PS3Lobby( unsigned short port, bool blockingSocket, const char *forceHostAddress )
252 {
253 	(void) port;
254 	(void) blockingSocket;
255 	(void) forceHostAddress;
256 
257 
258 
259 
260 
261 
262 
263 
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 
282 
283 
284 
285 
286 
287 
288 
289 
290 
291 
292 
293 
294 
295 
296 
297 
298 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
317 
318 
319 
320 
321 
322 
323 
324 
325 	return 0;
326 
327 }
CreateBoundSocket(unsigned short port,bool blockingSocket,const char * forceHostAddress,unsigned int sleepOn10048)328 SOCKET SocketLayer::CreateBoundSocket( unsigned short port, bool blockingSocket, const char *forceHostAddress, unsigned int sleepOn10048 )
329 {
330 	(void) blockingSocket;
331 
332 	int ret;
333 	SOCKET listenSocket;
334 	sockaddr_in listenerSocketAddress;
335 	memset(&listenerSocketAddress,0,sizeof(sockaddr_in));
336 	// Listen on our designated Port#
337 	listenerSocketAddress.sin_port = htons( port );
338 
339 
340 
341 	listenSocket = socket( AF_INET, SOCK_DGRAM, 0 );
342 
343 
344 	if ( listenSocket == (SOCKET) -1 )
345 	{
346 #if defined(_WIN32) &&  defined(_DEBUG)
347 		DWORD dwIOError = GetLastError();
348 		LPVOID messageBuffer;
349 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
350 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
351 			( LPTSTR ) & messageBuffer, 0, NULL );
352 		// something has gone wrong here...
353 		RAKNET_DEBUG_PRINTF( "socket(...) failed:Error code - %d\n%s", dwIOError, messageBuffer );
354 		//Free the buffer.
355 		LocalFree( messageBuffer );
356 #endif
357 
358 		return (SOCKET) -1;
359 	}
360 
361 	SetSocketOptions(listenSocket);
362 
363 	// Fill in the rest of the address structure
364 	listenerSocketAddress.sin_family = AF_INET;
365 
366 	if (forceHostAddress && forceHostAddress[0])
367 	{
368 //		printf("Force binding %s:%i\n", forceHostAddress, port);
369 		listenerSocketAddress.sin_addr.s_addr = inet_addr( forceHostAddress );
370 	}
371 	else
372 	{
373 //		printf("Binding any on port %i\n", port);
374 		listenerSocketAddress.sin_addr.s_addr = INADDR_ANY;
375 	}
376 
377 	// bind our name to the socket
378 	ret = bind( listenSocket, ( struct sockaddr * ) & listenerSocketAddress, sizeof( listenerSocketAddress ) );
379 
380 	if ( ret <= -1 )
381 	{
382 #if defined(_WIN32)
383 		DWORD dwIOError = GetLastError();
384 		if (dwIOError==10048)
385 		{
386 			if (sleepOn10048==0)
387 				return (SOCKET) -1;
388 			// Vista has a bug where it returns WSAEADDRINUSE (10048) if you create, shutdown, then rebind the socket port unless you wait a while first.
389 			// Wait, then rebind
390 			RakSleep(100);
391 
392 			closesocket(listenSocket);
393 			listenerSocketAddress.sin_port = htons( port );
394 			listenSocket = socket( AF_INET, SOCK_DGRAM, 0 );
395 			if ( listenSocket == (SOCKET) -1 )
396 				return false;
397 			SetSocketOptions(listenSocket);
398 
399 			// Fill in the rest of the address structure
400 			listenerSocketAddress.sin_family = AF_INET;
401 			if (forceHostAddress && forceHostAddress[0])
402 				listenerSocketAddress.sin_addr.s_addr = inet_addr( forceHostAddress );
403 			else
404 				listenerSocketAddress.sin_addr.s_addr = INADDR_ANY;
405 
406 			// bind our name to the socket
407 			ret = bind( listenSocket, ( struct sockaddr * ) & listenerSocketAddress, sizeof( listenerSocketAddress ) );
408 
409 			if ( ret >= 0 )
410 				return listenSocket;
411 		}
412 		dwIOError = GetLastError();
413 		LPVOID messageBuffer;
414 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
415 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
416 			( LPTSTR ) & messageBuffer, 0, NULL );
417 		// something has gone wrong here...
418 		RAKNET_DEBUG_PRINTF( "bind(...) failed:Error code - %d\n%s", (unsigned int) dwIOError, (char*) messageBuffer );
419 		//Free the buffer.
420 		LocalFree( messageBuffer );
421 #elif (defined(__GNUC__)  || defined(__GCCXML__)  ) && !defined(__WIN32)
422 		switch (ret)
423 		{
424 		case EBADF:
425 			RAKNET_DEBUG_PRINTF("bind(): sockfd is not a valid descriptor.\n"); break;
426 
427 		case ENOTSOCK:
428 			RAKNET_DEBUG_PRINTF("bind(): Argument is a descriptor for a file, not a socket.\n"); break;
429 
430 		case EINVAL:
431 			RAKNET_DEBUG_PRINTF("bind(): The addrlen is wrong, or the socket was not in the AF_UNIX family.\n"); break;
432 		case EROFS:
433 			RAKNET_DEBUG_PRINTF("bind(): The socket inode would reside on a read-only file system.\n"); break;
434 		case EFAULT:
435 			RAKNET_DEBUG_PRINTF("bind(): my_addr points outside the user's accessible address space.\n"); break;
436 		case ENAMETOOLONG:
437 			RAKNET_DEBUG_PRINTF("bind(): my_addr is too long.\n"); break;
438 		case ENOENT:
439 			RAKNET_DEBUG_PRINTF("bind(): The file does not exist.\n"); break;
440 		case ENOMEM:
441 			RAKNET_DEBUG_PRINTF("bind(): Insufficient kernel memory was available.\n"); break;
442 		case ENOTDIR:
443 			RAKNET_DEBUG_PRINTF("bind(): A component of the path prefix is not a directory.\n"); break;
444 		case EACCES:
445 			RAKNET_DEBUG_PRINTF("bind(): Search permission is denied on a component of the path prefix.\n"); break;
446 
447 		case ELOOP:
448 			RAKNET_DEBUG_PRINTF("bind(): Too many symbolic links were encountered in resolving my_addr.\n"); break;
449 
450 		default:
451 			RAKNET_DEBUG_PRINTF("Unknown bind() error %i.\n", ret); break;
452 		}
453 #endif
454 
455 		return (SOCKET) -1;
456 	}
457 
458 	return listenSocket;
459 }
460 
DomainNameToIP(const char * domainName)461 const char* SocketLayer::DomainNameToIP( const char *domainName )
462 {
463 	struct in_addr addr;
464 
465 
466 
467 
468 
469 
470 
471 
472 
473 
474 
475 
476 
477 
478 
479 
480 
481 
482 
483 
484 
485 
486 
487 
488 
489 
490 
491 
492 
493 
494 
495 
496 	struct hostent * phe = gethostbyname( domainName );
497 
498 	if ( phe == 0 || phe->h_addr_list[ 0 ] == 0 )
499 	{
500 		//cerr << "Yow! Bad host lookup." << endl;
501 		return 0;
502 	}
503 
504 	if (phe->h_addr_list[ 0 ]==0)
505 		return 0;
506 
507 	memcpy( &addr, phe->h_addr_list[ 0 ], sizeof( struct in_addr ) );
508 	return inet_ntoa( addr );
509 
510 
511 //	return "";
512 }
513 
514 
Write(const SOCKET writeSocket,const char * data,const int length)515 void SocketLayer::Write( const SOCKET writeSocket, const char* data, const int length )
516 {
517 #ifdef _DEBUG
518 	RakAssert( writeSocket != (SOCKET) -1 );
519 #endif
520 
521 	send( writeSocket, data, length, 0 );
522 }
RecvFrom(const SOCKET s,RakPeer * rakPeer,int * errorCode,RakNetSmartPtr<RakNetSocket> rakNetSocket,unsigned short remotePortRakNetWasStartedOn_PS3)523 int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode, RakNetSmartPtr<RakNetSocket> rakNetSocket, unsigned short remotePortRakNetWasStartedOn_PS3 )
524 {
525 	int len=0;
526 
527 
528 
529 
530 	char data[ MAXIMUM_MTU_SIZE ];
531 
532 
533 	if (slo)
534 	{
535 		SystemAddress sender;
536 		len = slo->RakNetRecvFrom(s,rakPeer,data,&sender,true);
537 		if (len>0)
538 		{
539 			ProcessNetworkPacket( sender, data, len, rakPeer, rakNetSocket, RakNet::GetTimeUS() );
540 			return 1;
541 		}
542 	}
543 
544 	if ( s == (SOCKET) -1 )
545 	{
546 		*errorCode = -1;
547 		return -1;
548 	}
549 
550 #if defined (_WIN32) || !defined(MSG_DONTWAIT)
551 	const int flag=0;
552 #else
553 	const int flag=MSG_DONTWAIT;
554 #endif
555 
556 	sockaddr_in sa;
557 	memset(&sa,0,sizeof(sockaddr_in));
558 	socklen_t len2;
559 	unsigned short portnum=0;
560 	if (remotePortRakNetWasStartedOn_PS3!=0)
561 	{
562 
563 
564 
565 
566 
567 
568 
569 
570 	}
571 	else
572 	{
573 		len2 = sizeof( sa );
574 		sa.sin_family = AF_INET;
575 		sa.sin_port=0;
576 
577 
578 
579 
580 
581 
582 
583 
584 
585 
586 
587 
588 
589 
590 
591 
592 
593 
594 
595 
596 
597 
598 
599 
600 
601 
602 		len = recvfrom( s, data, MAXIMUM_MTU_SIZE, flag, ( sockaddr* ) & sa, ( socklen_t* ) & len2 );
603 
604 
605 		portnum = ntohs( sa.sin_port );
606 	}
607 
608 	if ( len == 0 )
609 	{
610 #ifdef _DEBUG
611 		RAKNET_DEBUG_PRINTF( "Error: recvfrom returned 0 on a connectionless blocking call\non port %i.  This is a bug with Zone Alarm.  Please turn off Zone Alarm.\n", portnum );
612 		RakAssert( 0 );
613 #endif
614 
615 		// 4/13/09 Changed from returning -1 to 0, to prevent attackers from sending 0 byte messages to shutdown the server
616 		*errorCode = 0;
617 		return 0;
618 	}
619 
620 	if ( len > 0 )
621 	{
622 		ProcessNetworkPacket( SystemAddress(sa.sin_addr.s_addr, portnum), data, len, rakPeer, rakNetSocket, RakNet::GetTimeUS() );
623 
624 		return 1;
625 	}
626 	else
627 	{
628 		*errorCode = 0;
629 
630 
631 #if defined(_WIN32) && defined(_DEBUG)
632 
633 		DWORD dwIOError = WSAGetLastError();
634 
635 		if ( dwIOError == WSAEWOULDBLOCK )
636 		{
637 			return SOCKET_ERROR;
638 		}
639 		if ( dwIOError == WSAECONNRESET )
640 		{
641 #if defined(_DEBUG)
642 //			RAKNET_DEBUG_PRINTF( "A previous send operation resulted in an ICMP Port Unreachable message.\n" );
643 #endif
644 
645 
646 			unsigned short portnum=0;
647 			ProcessPortUnreachable(sa.sin_addr.s_addr, portnum, rakPeer);
648 			// *errorCode = dwIOError;
649 			return -1;
650 		}
651 		else
652 		{
653 #if defined(_DEBUG)
654 			if ( dwIOError != WSAEINTR && dwIOError != WSAETIMEDOUT)
655 			{
656 				LPVOID messageBuffer;
657 				FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
658 					NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
659 					( LPTSTR ) & messageBuffer, 0, NULL );
660 				// something has gone wrong here...
661 				RAKNET_DEBUG_PRINTF( "recvfrom failed:Error code - %d\n%s", dwIOError, messageBuffer );
662 
663 				//Free the buffer.
664 				LocalFree( messageBuffer );
665 			}
666 #endif
667 		}
668 #endif
669 	}
670 
671 	return 0; // no data
672 }
RecvFromBlocking(const SOCKET s,RakPeer * rakPeer,unsigned short remotePortRakNetWasStartedOn_PS3,char * dataOut,int * bytesReadOut,SystemAddress * systemAddressOut,RakNetTimeUS * timeRead)673 void SocketLayer::RecvFromBlocking( const SOCKET s, RakPeer *rakPeer, unsigned short remotePortRakNetWasStartedOn_PS3, char *dataOut, int *bytesReadOut, SystemAddress *systemAddressOut, RakNetTimeUS *timeRead )
674 {
675 	(void) rakPeer;
676 	// Randomly crashes, slo is 0, yet gets inside loop.
677 	/*
678 	if (SocketLayer::slo)
679 	{
680 		SystemAddress sender;
681 		*bytesReadOut = SocketLayer::slo->RakNetRecvFrom(s,rakPeer,dataOut,systemAddressOut,false);
682 		if (*bytesReadOut>0)
683 		{
684 			*timeRead=RakNet::GetTimeUS();
685 			return;
686 		}
687 		else if (*bytesReadOut==0)
688 		{
689 			return;
690 		}
691 		// Negative, process as normal
692 	}
693 	*/
694 
695 
696 	sockaddr* sockAddrPtr;
697 	socklen_t sockLen;
698 	socklen_t* socketlenPtr=(socklen_t*) &sockLen;
699 	sockaddr_in sa;
700 	memset(&sa,0,sizeof(sockaddr_in));
701 	char *dataOutModified;
702 	int dataOutSize;
703 	const int flag=0;
704 
705 	(void) remotePortRakNetWasStartedOn_PS3;
706 
707 
708 
709 
710 
711 
712 
713 
714 
715 
716 
717 	{
718 		sockLen=sizeof(sa);
719 		sa.sin_family = AF_INET;
720 		sa.sin_port=0;
721 		sockAddrPtr=(sockaddr*) &sa;
722 	}
723 
724 
725 
726 
727 
728 	dataOutModified=dataOut;
729 	dataOutSize=MAXIMUM_MTU_SIZE;
730 
731 	*bytesReadOut = recvfrom( s, dataOutModified, dataOutSize, flag, sockAddrPtr, socketlenPtr );
732 	if (*bytesReadOut<=0)
733 	{
734 		/*
735 #if defined(_WIN32) && !defined(_XBOX) && !defined(X360) && defined(_DEBUG)
736 		DWORD dwIOError = GetLastError();
737 		LPVOID messageBuffer;
738 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
739 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
740 			( LPTSTR ) & messageBuffer, 0, NULL );
741 		// something has gone wrong here...
742 		RAKNET_DEBUG_PRINTF( "sendto failed:Error code - %d\n%s", dwIOError, messageBuffer );
743 
744 		//Free the buffer.
745 		LocalFree( messageBuffer );
746 #endif
747 		*/
748 		return;
749 	}
750 	*timeRead=RakNet::GetTimeUS();
751 
752 
753 
754 
755 
756 
757 
758 
759 
760 	{
761 		systemAddressOut->port=ntohs( sa.sin_port );
762 		systemAddressOut->binaryAddress=sa.sin_addr.s_addr;
763 	}
764 
765 // 	if (systemAddressOut->port!=61111)
766 // 		printf("Got %i bytes from %s\n", *bytesReadOut, systemAddressOut->ToString());
767 
768 }
769 
RawRecvFromNonBlocking(const SOCKET s,unsigned short remotePortRakNetWasStartedOn_PS3,char * dataOut,int * bytesReadOut,SystemAddress * systemAddressOut,RakNetTimeUS * timeRead)770 void SocketLayer::RawRecvFromNonBlocking( const SOCKET s, unsigned short remotePortRakNetWasStartedOn_PS3, char *dataOut, int *bytesReadOut, SystemAddress *systemAddressOut, RakNetTimeUS *timeRead )
771 {
772 
773 	sockaddr* sockAddrPtr;
774 	socklen_t sockLen;
775 	socklen_t* socketlenPtr=(socklen_t*) &sockLen;
776 	sockaddr_in sa;
777 	memset(&sa,0,sizeof(sockaddr_in));
778 	char *dataOutModified;
779 	int dataOutSize;
780 	const int flag=0;
781 
782 	(void) remotePortRakNetWasStartedOn_PS3;
783 
784 // This is the wrong place for this - call on the socket before calling the function
785 // 	#if defined(_WIN32)
786 // 	u_long val = 1;
787 // 	ioctlsocket (s,FIONBIO,&val);//non block
788 // 	#else
789 // 	int flags = fcntl(s, F_GETFL, 0);
790 // 	fcntl(s, F_SETFL, flags | O_NONBLOCK);
791 // 	#endif
792 
793 
794 
795 
796 
797 
798 
799 
800 
801 
802 
803 	{
804 		sockLen=sizeof(sa);
805 		sa.sin_family = AF_INET;
806 		sa.sin_port=0;
807 		sockAddrPtr=(sockaddr*) &sa;
808 	}
809 
810 
811 
812 
813 
814 	dataOutModified=dataOut;
815 	dataOutSize=MAXIMUM_MTU_SIZE;
816 
817 
818 	*bytesReadOut = recvfrom( s, dataOutModified, dataOutSize, flag, sockAddrPtr, socketlenPtr );
819 	if (*bytesReadOut<=0)
820 	{
821 		return;
822 	}
823 	*timeRead=RakNet::GetTimeUS();
824 
825 
826 
827 
828 
829 
830 
831 
832 
833 	{
834 		systemAddressOut->port=ntohs( sa.sin_port );
835 		systemAddressOut->binaryAddress=sa.sin_addr.s_addr;
836 	}
837 }
838 
SendTo_PS3Lobby(SOCKET s,const char * data,int length,unsigned int binaryAddress,unsigned short port,unsigned short remotePortRakNetWasStartedOn_PS3)839 int SocketLayer::SendTo_PS3Lobby( SOCKET s, const char *data, int length, unsigned int binaryAddress, unsigned short port, unsigned short remotePortRakNetWasStartedOn_PS3 )
840 {
841 	(void) s;
842 	(void) data;
843 	(void) length;
844 	(void) binaryAddress;
845 	(void) port;
846 	(void) remotePortRakNetWasStartedOn_PS3;
847 
848 	int len=0;
849 
850 
851 
852 
853 
854 
855 
856 
857 
858 
859 
860 
861 
862 
863 	return len;
864 }
SendTo_360(SOCKET s,const char * data,int length,const char * voiceData,int voiceLength,unsigned int binaryAddress,unsigned short port)865 int SocketLayer::SendTo_360( SOCKET s, const char *data, int length, const char *voiceData, int voiceLength, unsigned int binaryAddress, unsigned short port )
866 {
867 	(void) s;
868 	(void) data;
869 	(void) length;
870 	(void) voiceData;
871 	(void) voiceLength;
872 	(void) binaryAddress;
873 	(void) port;
874 
875 	int len=0;
876 
877 
878 
879 
880 
881 
882 
883 
884 
885 
886 
887 
888 
889 
890 
891 
892 
893 
894 
895 
896 
897 
898 
899 
900 
901 
902 	return len;
903 }
SendTo_PC(SOCKET s,const char * data,int length,unsigned int binaryAddress,unsigned short port,const char * file,const long line)904 int SocketLayer::SendTo_PC( SOCKET s, const char *data, int length, unsigned int binaryAddress, unsigned short port, const char *file, const long line )
905 {
906 // 	if (port!=61111)
907 // 	{
908 // 		SystemAddress testa(binaryAddress,port);
909 // 		printf("Sending %i bytes to %s\n", length, testa.ToString());
910 // 	}
911 
912 
913 	sockaddr_in sa;
914 	memset(&sa,0,sizeof(sockaddr_in));
915 	sa.sin_port = htons( port ); // User port
916 	sa.sin_addr.s_addr = binaryAddress;
917 	sa.sin_family = AF_INET;
918 	int len=0;
919 	do
920 	{
921 #ifdef DEBUG_SENDTO_SPIKES
922 		RakNetTime start = RakNet::GetTime();
923 #else
924 		(void) file;
925 		(void) line;
926 #endif
927 		len = sendto( s, data, length, 0, ( const sockaddr* ) & sa, sizeof( sa ) );
928 #ifdef DEBUG_SENDTO_SPIKES
929 		RakNetTime end = RakNet::GetTime();
930 		static unsigned int callCount=1;
931 		printf("%i. SendTo_PC, time=%"PRINTF_64_BIT_MODIFIER"u, elapsed=%"PRINTF_64_BIT_MODIFIER"u, length=%i, returned=%i, binaryAddress=%i, port=%i, file=%s, line=%i\n", callCount++, end, end-start, length, len, binaryAddress, port, file, line);
932 #endif
933 		if (len<0)
934 		{
935 
936 #if defined(_WIN32)
937 			DWORD dwIOError = GetLastError();
938 			if (dwIOError!= 10040 && dwIOError != WSAEADDRNOTAVAIL)
939 			{
940 	#if defined(_DEBUG)
941 				LPVOID messageBuffer;
942 				FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
943 					NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
944 					( LPTSTR ) &messageBuffer, 0, NULL );
945 				// something has gone wrong here...
946 				RAKNET_DEBUG_PRINTF( "SendTo_PC failed:Error code - %d\n%s", dwIOError, messageBuffer );
947 				//Free the buffer.
948 				LocalFree( messageBuffer );
949 	#endif
950 			}
951 			else
952 			{
953 				// buffer size exceeded
954 				return -10040;
955 			}
956 #endif
957 
958 			printf("sendto failed with code %i for char %i and length %i.\n", len, data[0], length);
959 		}
960 	}
961 	while ( len == 0 );
962 	return len;
963 }
964 
965 #ifdef _MSC_VER
966 #pragma warning( disable : 4702 ) // warning C4702: unreachable code
967 #endif
SendTo(SOCKET s,const char * data,int length,unsigned int binaryAddress,unsigned short port,unsigned short remotePortRakNetWasStartedOn_PS3,const char * file,const long line)968 int SocketLayer::SendTo( SOCKET s, const char *data, int length, unsigned int binaryAddress, unsigned short port, unsigned short remotePortRakNetWasStartedOn_PS3, const char *file, const long line )
969 {
970 	RakAssert(length<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
971 	RakAssert(port!=0);
972 	if (slo)
973 	{
974 		SystemAddress sa(binaryAddress,port);
975 		return slo->RakNetSendTo(s,data,length,sa);
976 	}
977 
978 	if ( s == (SOCKET) -1 )
979 	{
980 		return -1;
981 	}
982 
983 	int len=0;
984 
985 	if (remotePortRakNetWasStartedOn_PS3!=0)
986 	{
987 		len = SendTo_PS3Lobby(s,data,length,binaryAddress,port, remotePortRakNetWasStartedOn_PS3);
988 	}
989 	else
990 	{
991 
992 
993 
994 
995 		len = SendTo_PC(s,data,length,binaryAddress,port,file,line);
996 
997 	}
998 
999 	if ( len != -1 )
1000 		return 0;
1001 
1002 #if defined(_WIN32) && !defined(_WIN32_WCE)
1003 
1004 	DWORD dwIOError = WSAGetLastError();
1005 
1006 	if ( dwIOError == WSAECONNRESET )
1007 	{
1008 #if defined(_DEBUG)
1009 		RAKNET_DEBUG_PRINTF( "A previous send operation resulted in an ICMP Port Unreachable message.\n" );
1010 #endif
1011 
1012 	}
1013 	else if ( dwIOError != WSAEWOULDBLOCK && dwIOError != WSAEADDRNOTAVAIL)
1014 	{
1015 #if defined(_WIN32) &&  defined(_DEBUG)
1016 		LPVOID messageBuffer;
1017 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1018 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1019 			( LPTSTR ) & messageBuffer, 0, NULL );
1020 		// something has gone wrong here...
1021 		RAKNET_DEBUG_PRINTF( "sendto failed:Error code - %d\n%s", dwIOError, messageBuffer );
1022 
1023 		//Free the buffer.
1024 		LocalFree( messageBuffer );
1025 #endif
1026 
1027 	}
1028 
1029 	return dwIOError;
1030 #endif
1031 
1032 	return 1; // error
1033 }
SendTo(SOCKET s,const char * data,int length,const char ip[16],unsigned short port,unsigned short remotePortRakNetWasStartedOn_PS3,const char * file,const long line)1034 int SocketLayer::SendTo( SOCKET s, const char *data, int length, const char ip[ 16 ], unsigned short port, unsigned short remotePortRakNetWasStartedOn_PS3, const char *file, const long line )
1035 {
1036 	unsigned int binaryAddress;
1037 	binaryAddress = inet_addr( ip );
1038 	return SendTo( s, data, length, binaryAddress, port,remotePortRakNetWasStartedOn_PS3, file, line );
1039 }
SendToTTL(SOCKET s,const char * data,int length,const char ip[16],unsigned short port,int ttl)1040 int SocketLayer::SendToTTL( SOCKET s, const char *data, int length, const char ip[ 16 ], unsigned short port, int ttl )
1041 {
1042 	unsigned int binaryAddress;
1043 	binaryAddress = inet_addr( ip );
1044 	SystemAddress sa(binaryAddress,port);
1045 
1046 	if (slo)
1047 		return slo->RakNetSendTo(s,data,length,sa);
1048 
1049 
1050 	int oldTTL;
1051 	socklen_t opLen=sizeof(oldTTL);
1052 	// Get the current TTL
1053 	if (getsockopt(s, IPPROTO_IP, IP_TTL, ( char * ) & oldTTL, &opLen ) == -1)
1054 	{
1055 #if defined(_WIN32) && defined(_DEBUG)
1056 		DWORD dwIOError = GetLastError();
1057 		LPVOID messageBuffer;
1058 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1059 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1060 			( LPTSTR ) & messageBuffer, 0, NULL );
1061 		// something has gone wrong here...
1062 		RAKNET_DEBUG_PRINTF( "getsockopt(IPPROTO_IP,IP_TTL) failed:Error code - %d\n%s", dwIOError, messageBuffer );
1063 		//Free the buffer.
1064 		LocalFree( messageBuffer );
1065 #endif
1066 	}
1067 
1068 	// Set to TTL
1069 	int newTTL=ttl;
1070 	if (setsockopt(s, IPPROTO_IP, IP_TTL, ( char * ) & newTTL, sizeof ( newTTL ) ) == -1)
1071 	{
1072 
1073 #if defined(_WIN32) && defined(_DEBUG)
1074 		DWORD dwIOError = GetLastError();
1075 		LPVOID messageBuffer;
1076 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1077 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1078 			( LPTSTR ) & messageBuffer, 0, NULL );
1079 		// something has gone wrong here...
1080 		RAKNET_DEBUG_PRINTF( "setsockopt(IPPROTO_IP,IP_TTL) failed:Error code - %d\n%s", dwIOError, messageBuffer );
1081 		//Free the buffer.
1082 		LocalFree( messageBuffer );
1083 #endif
1084 	}
1085 
1086 	// Send
1087 	int res = SendTo(s,data,length,ip,port,false, __FILE__, __LINE__ );
1088 
1089 	// Restore the old TTL
1090 	setsockopt(s, IPPROTO_IP, IP_TTL, ( char * ) & oldTTL, opLen );
1091 
1092 	return res;
1093 
1094 
1095 
1096 }
1097 
1098 
GetSubNetForSocketAndIp(SOCKET inSock,RakNet::RakString inIpString)1099 RakNet::RakString SocketLayer::GetSubNetForSocketAndIp(SOCKET inSock, RakNet::RakString inIpString)
1100 {
1101 	RakNet::RakString netMaskString;
1102 	RakNet::RakString ipString;
1103 
1104 
1105 
1106 
1107 
1108 #if   defined(_WIN32)
1109 	INTERFACE_INFO InterfaceList[20];
1110 	unsigned long nBytesReturned;
1111 	if (WSAIoctl(inSock, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
1112 		sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
1113 			return "";
1114 	}
1115 
1116 	int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
1117 
1118 	for (int i = 0; i < nNumInterfaces; ++i)
1119 	{
1120 		sockaddr_in *pAddress;
1121 		pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress);
1122 		ipString=inet_ntoa(pAddress->sin_addr);
1123 
1124 		if (inIpString==ipString)
1125 		{
1126 			pAddress = (sockaddr_in *) & (InterfaceList[i].iiNetmask);
1127 			netMaskString=inet_ntoa(pAddress->sin_addr);
1128 			return netMaskString;
1129 		}
1130 	}
1131 	return "";
1132 #else
1133 
1134 	int fd,fd2;
1135 	fd2 = socket(AF_INET, SOCK_DGRAM, 0);
1136 
1137 	if(fd2 < 0)
1138 	{
1139 		return "";
1140 	}
1141 
1142 	struct ifconf ifc;
1143 	char          buf[1999];
1144 	ifc.ifc_len = sizeof(buf);
1145 	ifc.ifc_buf = buf;
1146 	if(ioctl(fd2, SIOCGIFCONF, &ifc) < 0)
1147 	{
1148 		return "";
1149 	}
1150 
1151 	struct ifreq *ifr;
1152 	ifr         = ifc.ifc_req;
1153 	int intNum = ifc.ifc_len / sizeof(struct ifreq);
1154 	for(int i = 0; i < intNum; i++)
1155 	{
1156 		ipString=inet_ntoa(((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr);
1157 
1158 		if (inIpString==ipString)
1159 		{
1160 			struct ifreq ifr2;
1161 			fd = socket(AF_INET, SOCK_DGRAM, 0);
1162 			if(fd < 0)
1163 			{
1164 				return "";
1165 			}
1166 			ifr2.ifr_addr.sa_family = AF_INET;
1167 
1168 			strncpy(ifr2.ifr_name, ifr[i].ifr_name, IFNAMSIZ-1);
1169 
1170 			ioctl(fd, SIOCGIFNETMASK, &ifr2);
1171 
1172 			close(fd);
1173 			close(fd2);
1174 			netMaskString=inet_ntoa(((struct sockaddr_in *)&ifr2.ifr_addr)->sin_addr);
1175 
1176 			return netMaskString;
1177 		}
1178 	}
1179 
1180 	close(fd2);
1181 	return "";
1182 
1183 #endif
1184 
1185 }
1186 
1187 
1188 
1189 
1190 
1191 
1192 
1193 
1194 
1195 
1196 #if   defined(_WIN32)
GetMyIP_Win32(char ipList[MAXIMUM_NUMBER_OF_INTERNAL_IDS][16],unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS])1197 void GetMyIP_Win32( char ipList[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ][ 16 ], unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
1198 {
1199 	char ac[ 80 ];
1200 	if ( gethostname( ac, sizeof( ac ) ) == -1 )
1201 	{
1202 		DWORD dwIOError = GetLastError();
1203 		LPVOID messageBuffer;
1204 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1205 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1206 			( LPTSTR ) & messageBuffer, 0, NULL );
1207 		// something has gone wrong here...
1208 		RAKNET_DEBUG_PRINTF( "gethostname failed:Error code - %d\n%s", dwIOError, messageBuffer );
1209 		//Free the buffer.
1210 		LocalFree( messageBuffer );
1211 		return ;
1212 	}
1213 
1214 	struct hostent *phe = gethostbyname( ac );
1215 
1216 	if ( phe == 0 )
1217 	{
1218 		DWORD dwIOError = GetLastError();
1219 		LPVOID messageBuffer;
1220 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1221 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1222 			( LPTSTR ) & messageBuffer, 0, NULL );
1223 		// something has gone wrong here...
1224 		RAKNET_DEBUG_PRINTF( "gethostbyname failed:Error code - %d\n%s", dwIOError, messageBuffer );
1225 
1226 		//Free the buffer.
1227 		LocalFree( messageBuffer );
1228 		return ;
1229 	}
1230 
1231 	struct in_addr addr[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ];
1232 	int idx;
1233 	for ( idx = 0; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
1234 	{
1235 		if (phe->h_addr_list[ idx ] == 0)
1236 			break;
1237 
1238 		memcpy( &addr[idx], phe->h_addr_list[ idx ], sizeof( struct in_addr ) );
1239 		binaryAddresses[idx]=addr[idx].S_un.S_addr;
1240 		strcpy( ipList[ idx ], inet_ntoa( addr[idx] ) );
1241 
1242 	}
1243 
1244 	for ( ; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
1245 	{
1246 		ipList[idx][0]=0;
1247 	}
1248 }
1249 #elif defined(ANDROID)
GetMyIP_Linux(char ipList[MAXIMUM_NUMBER_OF_INTERNAL_IDS][16],unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS])1250 void GetMyIP_Linux( char ipList[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ][ 16 ], unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
1251 {
1252 	struct ifreq ifreqs[MAXIMUM_NUMBER_OF_INTERNAL_IDS];
1253 	struct ifconf ifconf;
1254 	struct in_addr bin_addr;
1255 
1256 	memset(&ifconf,0,sizeof(ifconf));
1257 	ifconf.ifc_buf = (char*) (ifreqs);
1258 	ifconf.ifc_len = sizeof(ifreqs);
1259 
1260 	{ // get list of interfaces
1261 		int sock = socket(AF_INET,SOCK_STREAM,0);
1262 		if (sock < 0)
1263 		{
1264 			perror("Error creating socket");
1265 			return;
1266 		}
1267 		if ((ioctl(sock, SIOCGIFCONF, (char*) &ifconf  )) < 0 )
1268 		{
1269 			perror("Error returned from ioctl(SIOGIFCONF)");
1270 			ifconf.ifc_len = 0;
1271 		}
1272 		close(sock);
1273 	}
1274 
1275 	int idx = 0;
1276 	int iface_count =  ifconf.ifc_len/sizeof(struct ifreq);
1277 	printf("Interfaces (%d):\n", iface_count);
1278 	for( ; idx < iface_count; idx++)
1279 	{
1280 		char ip_addr[ 16/*INET_ADDRSTRLEN */];
1281 		struct sockaddr_in *b = (struct sockaddr_in *) &(ifreqs[idx].ifr_addr);
1282 		const char* host = inet_ntop(AF_INET, & b->sin_addr, ip_addr, sizeof ip_addr);
1283 		strcpy( ipList[idx], host );
1284 		if (inet_aton(host, &bin_addr) == 0)
1285 		{
1286 			perror("inet_aton error");
1287 			continue;
1288 		}
1289 		else
1290 		{
1291 			binaryAddresses[idx] = bin_addr.s_addr;
1292 		}
1293 		printf("\t%-10s\t%s (%08x)\n", ifreqs[idx].ifr_name, ipList[idx], binaryAddresses[idx]);
1294 	}
1295 	for ( ; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
1296 	{
1297 		ipList[idx][0]=0;
1298 	}
1299 }
1300 #else
GetMyIP_Linux(char ipList[MAXIMUM_NUMBER_OF_INTERNAL_IDS][16],unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS])1301 void GetMyIP_Linux( char ipList[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ][ 16 ], unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
1302 {
1303 	struct ifaddrs *ifaddr, *ifa;
1304 	int family, s;
1305 	char host[NI_MAXHOST];
1306 	struct in_addr linux_in_addr;
1307 
1308 	if (getifaddrs(&ifaddr) == -1) {
1309 		printf( "Error getting interface list\n");
1310 	}
1311 
1312 	int idx = 0;
1313 	for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
1314 		if (!ifa->ifa_addr) continue;
1315 		family = ifa->ifa_addr->sa_family;
1316 
1317 		if (family == AF_INET) {
1318 			s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1319 			if (s != 0) {
1320 				printf ("getnameinfo() failed: %s\n", gai_strerror(s));
1321 			}
1322 			//printf ("IP address: %s\n", host);
1323 			if (strcmp(host,"127.0.0.1")!=0)
1324 			{
1325 				strcpy( ipList[ idx ], host );
1326 				if (inet_aton(host, &linux_in_addr) == 0) {
1327 					perror("inet_aton");
1328 				}
1329 				else {
1330 					binaryAddresses[idx]=linux_in_addr.s_addr;
1331 				}
1332 
1333 				idx++;
1334 			}
1335 		}
1336 	}
1337 
1338 	for ( ; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
1339 	{
1340 		ipList[idx][0]=0;
1341 	}
1342 
1343 	freeifaddrs(ifaddr);
1344 }
1345 #endif
1346 
1347 
GetMyIP(char ipList[MAXIMUM_NUMBER_OF_INTERNAL_IDS][16],unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS])1348 void SocketLayer::GetMyIP( char ipList[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ][ 16 ], unsigned int binaryAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
1349 {
1350 
1351 
1352 #if   defined(_WIN32)
1353 	GetMyIP_Win32(ipList, binaryAddresses);
1354 #else
1355 	GetMyIP_Linux(ipList, binaryAddresses);
1356 #endif
1357 }
1358 
1359 
GetLocalPort(SOCKET s)1360 unsigned short SocketLayer::GetLocalPort ( SOCKET s )
1361 {
1362 	sockaddr_in sa;
1363 	memset(&sa,0,sizeof(sockaddr_in));
1364 	socklen_t len = sizeof(sa);
1365 	if (getsockname(s, (sockaddr*)&sa, &len)!=0)
1366 	{
1367 #if defined(_WIN32) &&  defined(_DEBUG)
1368 		DWORD dwIOError = GetLastError();
1369 		LPVOID messageBuffer;
1370 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1371 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1372 			( LPTSTR ) & messageBuffer, 0, NULL );
1373 		// something has gone wrong here...
1374 		RAKNET_DEBUG_PRINTF( "getsockname failed:Error code - %d\n%s", dwIOError, messageBuffer );
1375 
1376 		//Free the buffer.
1377 		LocalFree( messageBuffer );
1378 #endif
1379 		return 0;
1380 	}
1381 	return ntohs(sa.sin_port);
1382 }
1383 
GetSystemAddress(SOCKET s)1384 SystemAddress SocketLayer::GetSystemAddress ( SOCKET s )
1385 {
1386 	sockaddr_in sa;
1387 	memset(&sa,0,sizeof(sockaddr_in));
1388 	socklen_t len = sizeof(sa);
1389 	if (getsockname(s, (sockaddr*)&sa, &len)!=0)
1390 	{
1391 #if defined(_WIN32) &&  defined(_DEBUG)
1392 		DWORD dwIOError = GetLastError();
1393 		LPVOID messageBuffer;
1394 		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1395 			NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),  // Default language
1396 			( LPTSTR ) & messageBuffer, 0, NULL );
1397 		// something has gone wrong here...
1398 		RAKNET_DEBUG_PRINTF( "getsockname failed:Error code - %d\n%s", dwIOError, messageBuffer );
1399 
1400 		//Free the buffer.
1401 		LocalFree( messageBuffer );
1402 #endif
1403 		return UNASSIGNED_SYSTEM_ADDRESS;
1404 	}
1405 
1406 	SystemAddress out;
1407 	out.port=ntohs(sa.sin_port);
1408 	out.binaryAddress=sa.sin_addr.s_addr;
1409 	return out;
1410 }
1411 
SetSocketLayerOverride(SocketLayerOverride * _slo)1412 void SocketLayer::SetSocketLayerOverride(SocketLayerOverride *_slo)
1413 {
1414 	slo=_slo;
1415 }
1416 
1417 #ifdef _MSC_VER
1418 #pragma warning( pop )
1419 #endif
1420