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