SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SocketLayer.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
19
20
21 #include "slikenet/SocketLayer.h"
22 #include "slikenet/assert.h"
23 #include "slikenet/types.h"
24 #include "slikenet/peer.h"
25 #include "slikenet/GetTime.h"
26 #include "slikenet/LinuxStrings.h"
27 #include "slikenet/SocketDefines.h"
28 #include "slikenet/linux_adapter.h"
29 #include "slikenet/osx_adapter.h"
30 #if (defined(__GNUC__) || defined(__GCCXML__)) && !defined(__WIN32__)
31 #include <netdb.h>
32 #endif
33
34 #ifdef _WIN32
35 #include <tchar.h>
36 #else
37 #ifndef _T
38 #define _T(x) (x)
39 #endif
40 #endif
41
42 using namespace SLNet;
43
44 /*
45 #if defined(__native_client__)
46 using namespace pp;
47 #endif
48 */
49
50 #if USE_SLIDING_WINDOW_CONGESTION_CONTROL!=1
51 #include "slikenet/CCRakNetUDT.h"
52 #else
53 #include "slikenet/CCRakNetSlidingWindow.h"
54 #endif
55
56 //SocketLayerOverride *SocketLayer::slo=0;
57
58 #ifdef _WIN32
59 #else
60 #include <string.h> // memcpy
61 #include <unistd.h>
62 #include <fcntl.h>
63 #include <arpa/inet.h>
64 #include <errno.h> // error numbers
65 #include <stdio.h> // RAKNET_DEBUG_PRINTF
66 #if !defined(ANDROID)
67 #include <ifaddrs.h>
68 #endif
69 #include <netinet/in.h>
70 #include <net/if.h>
71 #include <sys/types.h>
72 #include <sys/socket.h>
73 #include <sys/ioctl.h>
74
75 #endif
76
77
78
79
80
81
82
83
84
85
86
87
88
89 #if defined(_WIN32)
90 #include "slikenet/WSAStartupSingleton.h"
91 #include "slikenet/WindowsIncludes.h"
92
93 #else
94 #include <unistd.h>
95 #endif
96
97 #include "slikenet/sleep.h"
98 #include <stdio.h>
99 #include "slikenet/Itoa.h"
100
101 namespace SLNet
102 {
103 extern void ProcessNetworkPacket( const SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, SLNet::TimeUS timeRead );
104 //extern void ProcessNetworkPacket( const SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNetSocket* rakNetSocket, SLNet::TimeUS timeRead );
105 }
106
107 #ifdef _DEBUG
108 #include <stdio.h>
109 #endif
110
111
112
113 // http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#ip4to6
114 // http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#getaddrinfo
115
116 #if RAKNET_SUPPORT_IPV6==1
117 void PrepareAddrInfoHints(addrinfo *hints)
118 {
119 memset(hints, 0, sizeof (addrinfo)); // make sure the struct is empty
120 hints->ai_socktype = SOCK_DGRAM; // UDP sockets
121 hints->ai_flags = AI_PASSIVE; // fill in my IP for me
122 }
123 #endif
124
125 void SocketLayer::SetSocketOptions( __UDPSOCKET__ listenSocket, bool blockingSocket, bool setBroadcast)
126 {
127 #ifdef __native_client__
128 (void) listenSocket;
129 #else
130 int sock_opt = 1;
131
132 // This doubles the max throughput rate
133 sock_opt=1024*256;
134 setsockopt__(listenSocket, SOL_SOCKET, SO_RCVBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
135
136 // Immediate hard close. Don't linger the socket, or recreating the socket quickly on Vista fails.
137 // Fail with voice and xbox
138
139 sock_opt=0;
140 setsockopt__(listenSocket, SOL_SOCKET, SO_LINGER, ( char * ) & sock_opt, sizeof ( sock_opt ) );
141
142
143
144 // This doesn't make much difference: 10% maybe
145 // Not supported on console 2
146 sock_opt=1024*16;
147 setsockopt__(listenSocket, SOL_SOCKET, SO_SNDBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
148
149
150 if (blockingSocket==false)
151 {
152 #ifdef _WIN32
153 unsigned long nonblocking = 1;
154 ioctlsocket__(listenSocket, FIONBIO, &nonblocking );
155
156
157
158 #else
159 fcntl( listenSocket, F_SETFL, O_NONBLOCK );
160 #endif
161 }
162 if (setBroadcast)
163 {
164 // Note: Fails with VDP but not xbox
165 // Set broadcast capable
166 sock_opt=1;
167 if ( setsockopt__(listenSocket, SOL_SOCKET, SO_BROADCAST, ( char * ) & sock_opt, sizeof( sock_opt ) ) == -1 )
168 {
169 #if defined(_WIN32) && defined(_DEBUG)
170 #if !defined(WINDOWS_PHONE_8)
171 DWORD dwIOError = GetLastError();
172 // On Vista, can get WSAEACCESS (10013)
173 // See http://support.microsoft.com/kb/819124
174 // http://blogs.msdn.com/wndp/archive/2007/03/19/winsock-so-exclusiveaddruse-on-vista.aspx
175 // http://msdn.microsoft.com/en-us/library/ms740621(VS.85).aspx
176 LPTSTR messageBuffer;
177 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
178 NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
179 ( LPTSTR ) & messageBuffer, 0, NULL );
180 // something has gone wrong here...
181 RAKNET_DEBUG_TPRINTF( _T("setsockopt__(SO_BROADCAST) failed:Error code - %lu\n%s"), dwIOError, messageBuffer );
182 //Free the buffer.
183 LocalFree( messageBuffer );
184 #endif
185 #endif
186
187 }
188
189 }
190
191 #endif
192 }
193
194
195 SLNet::RakString SocketLayer::GetSubNetForSocketAndIp(__UDPSOCKET__ inSock, SLNet::RakString inIpString)
196 {
197 SLNet::RakString netMaskString;
198 SLNet::RakString ipString;
199
200
201
202
203
204 #if defined(WINDOWS_STORE_RT)
205 RakAssert("Not yet supported" && 0);
206 return "";
207 #elif defined(_WIN32)
208 INTERFACE_INFO InterfaceList[20];
209 unsigned long nBytesReturned;
210 if (WSAIoctl(inSock, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
211 sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
212 return "";
213 }
214
215 int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
216
217 for (int i = 0; i < nNumInterfaces; ++i)
218 {
219 sockaddr_in *pAddress;
220 pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress);
221 char ip[65];
222 inet_ntop(pAddress->sin_family, &pAddress->sin_addr, ip, 65);
223 ipString = ip;
224
225 if (inIpString==ipString)
226 {
227 pAddress = (sockaddr_in *) & (InterfaceList[i].iiNetmask);
228 char netmaskIP[65];
229 inet_ntop(pAddress->sin_family, &pAddress->sin_addr, netmaskIP, 65);
230 netMaskString=netmaskIP;
231 return netMaskString;
232 }
233 }
234 return "";
235 #else
236
237 int fd,fd2;
238 fd2 = socket__(AF_INET, SOCK_DGRAM, 0);
239
240 if(fd2 < 0)
241 {
242 return "";
243 }
244
245 struct ifconf ifc;
246 char buf[1999];
247 ifc.ifc_len = sizeof(buf);
248 ifc.ifc_buf = buf;
249 if(ioctl(fd2, SIOCGIFCONF, &ifc) < 0)
250 {
251 close(fd2);
252 return "";
253 }
254
255 struct ifreq *ifr;
256 ifr = ifc.ifc_req;
257 int intNum = ifc.ifc_len / sizeof(struct ifreq);
258 for(int i = 0; i < intNum; i++)
259 {
260 char ip[65];
261 inet_ntop(AF_INET, &((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr, ip, 65);
262 ipString = ip;
263
264 if (inIpString==ipString)
265 {
266 struct ifreq ifr2;
267 fd = socket__(AF_INET, SOCK_DGRAM, 0);
268 if(fd < 0)
269 {
270 return "";
271 }
272 ifr2.ifr_addr.sa_family = AF_INET;
273
274 strncpy_s(ifr2.ifr_name, IFNAMSIZ, ifr[i].ifr_name, IFNAMSIZ-1);
275
276 ioctl(fd, SIOCGIFNETMASK, &ifr2);
277
278 close(fd);
279 close(fd2);
280 inet_ntop(AF_INET, &((struct sockaddr_in *)&ifr2.ifr_addr)->sin_addr, ip, 65);
281 netMaskString=ip;
282
283 return netMaskString;
284 }
285 }
286
287 close(fd2);
288 return "";
289
290 #endif
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
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369 #if defined(WINDOWS_STORE_RT)
370 void GetMyIP_WinRT( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
371 {
372 // Perhaps DatagramSocket.BindEndpointAsynch, use localHostName as an empty string, then query what it bound to?
373 RakAssert("Not yet supported" && 0);
374 }
375 #else
376 void GetMyIP_Win32( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
377 {
378 int idx=0;
379 idx=0;
380 char ac[ 80 ];
381 if ( gethostname( ac, sizeof( ac ) ) == -1 )
382 {
383 #if defined(_WIN32) && !defined(WINDOWS_PHONE_8)
384 DWORD dwIOError = GetLastError();
385 LPTSTR messageBuffer;
386 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
387 NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
388 ( LPTSTR ) & messageBuffer, 0, NULL );
389 // something has gone wrong here...
390 RAKNET_DEBUG_TPRINTF( _T("gethostname failed:Error code - %lu\n%s"), dwIOError, messageBuffer );
391 //Free the buffer.
392 LocalFree( messageBuffer );
393 #endif
394 return ;
395 }
396
397 #if RAKNET_SUPPORT_IPV6==1
398 struct addrinfo hints;
399 struct addrinfo *servinfo=0, *aip; // will point to the results
400 PrepareAddrInfoHints(&hints);
401 getaddrinfo(ac, "", &hints, &servinfo);
402
403 for (idx=0, aip = servinfo; aip != NULL && idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; aip = aip->ai_next, idx++)
404 {
405 if (aip->ai_family == AF_INET)
406 {
407 struct sockaddr_in *ipv4 = (struct sockaddr_in *)aip->ai_addr;
408 memcpy(&addresses[idx].address.addr4,ipv4,sizeof(sockaddr_in));
409 }
410 else
411 {
412 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)aip->ai_addr;
413 memcpy(&addresses[idx].address.addr4,ipv6,sizeof(sockaddr_in6));
414 }
415
416 }
417
418 freeaddrinfo(servinfo); // free the linked-list
419 #else
420 struct addrinfo *curAddress = NULL;
421 int err = getaddrinfo(ac, NULL, NULL, &curAddress);
422
423 if ( err != 0 )
424 {
425 #if defined(_WIN32) && !defined(WINDOWS_PHONE_8)
426 int wsaError = WSAGetLastError();
427 LPTSTR messageBuffer;
428 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
429 NULL, wsaError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
430 ( LPTSTR ) & messageBuffer, 0, NULL );
431 // something has gone wrong here...
432 RAKNET_DEBUG_TPRINTF( _T("getaddrinfo failed:Error code - %d\n%s"), wsaError, messageBuffer );
433
434 //Free the buffer.
435 LocalFree( messageBuffer );
436 #endif
437 return ;
438 }
439 while (curAddress != NULL && idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
440 {
441 if (curAddress->ai_family == AF_INET) {
442 addresses[idx].address.addr4 = *((struct sockaddr_in *)curAddress->ai_addr);
443 ++idx;
444 }
445 curAddress = curAddress->ai_next;
446 }
447
448 #endif // else RAKNET_SUPPORT_IPV6==1
449
450 while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
451 {
452 addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
453 idx++;
454 }
455 }
456
457 #endif
458
459
460 void SocketLayer::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
461 {
462
463
464
465
466
467
468 #if defined(WINDOWS_STORE_RT)
469 GetMyIP_WinRT(addresses);
470 #elif defined(_WIN32)
471 GetMyIP_Win32(addresses);
472 #else
473 // GetMyIP_Linux(addresses);
474 GetMyIP_Win32(addresses);
475 #endif
476 }
477
478
479 /*
480 unsigned short SocketLayer::GetLocalPort(RakNetSocket *s)
481 {
482 SystemAddress sa;
483 GetSystemAddress(s,&sa);
484 return sa.GetPort();
485 }
486 */
487 unsigned short SocketLayer::GetLocalPort(__UDPSOCKET__ s)
488 {
489 SystemAddress sa;
490 GetSystemAddress(s,&sa);
491 return sa.GetPort();
492 }
493 void SocketLayer::GetSystemAddress_Old ( __UDPSOCKET__ s, SystemAddress *systemAddressOut )
494 {
495 #if defined(__native_client__)
496 *systemAddressOut = UNASSIGNED_SYSTEM_ADDRESS;
497 #else
498 sockaddr_in sa;
499 memset(&sa,0,sizeof(sockaddr_in));
500 socklen_t len = sizeof(sa);
501 if (getsockname__(s, (sockaddr*)&sa, &len)!=0)
502 {
503 #if defined(_WIN32) && defined(_DEBUG) && !defined(WINDOWS_PHONE_8)
504 DWORD dwIOError = GetLastError();
505 LPTSTR messageBuffer;
506 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
507 NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
508 ( LPTSTR ) & messageBuffer, 0, NULL );
509 // something has gone wrong here...
510 RAKNET_DEBUG_TPRINTF( _T("getsockname failed:Error code - %lu\n%s"), dwIOError, messageBuffer );
511
512 //Free the buffer.
513 LocalFree( messageBuffer );
514 #endif
515 *systemAddressOut = UNASSIGNED_SYSTEM_ADDRESS;
516 return;
517 }
518
519 systemAddressOut->SetPortNetworkOrder(sa.sin_port);
520 systemAddressOut->address.addr4.sin_addr.s_addr=sa.sin_addr.s_addr;
521 #endif
522 }
523 /*
524 void SocketLayer::GetSystemAddress_Old ( RakNetSocket *s, SystemAddress *systemAddressOut )
525 {
526 return GetSystemAddress_Old(s->s, systemAddressOut);
527 }
528 */
529 void SocketLayer::GetSystemAddress ( __UDPSOCKET__ s, SystemAddress *systemAddressOut )
530 {
531 #if RAKNET_SUPPORT_IPV6!=1
532 GetSystemAddress_Old(s, systemAddressOut);
533 #else
534 socklen_t slen;
535 sockaddr_storage ss;
536 slen = sizeof(ss);
537
538 if (getsockname__(s, (struct sockaddr *)&ss, &slen)!=0)
539 {
540 #if defined(_WIN32) && defined(_DEBUG)
541 DWORD dwIOError = GetLastError();
542 LPVOID messageBuffer;
543 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
544 NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
545 ( LPTSTR ) & messageBuffer, 0, NULL );
546 // something has gone wrong here...
547 RAKNET_DEBUG_TPRINTF( _T("getsockname failed:Error code - %d\n%s"), dwIOError, static_cast<LPTSTR>(messageBuffer));
548
549 //Free the buffer.
550 LocalFree( messageBuffer );
551 #endif
552 systemAddressOut->FromString(0);
553 return;
554 }
555
556 if (ss.ss_family==AF_INET)
557 {
558 memcpy(&systemAddressOut->address.addr4,(sockaddr_in *)&ss,sizeof(sockaddr_in));
559 systemAddressOut->debugPort=ntohs(systemAddressOut->address.addr4.sin_port);
560
561 uint32_t zero = 0;
562 if (memcmp(&systemAddressOut->address.addr4.sin_addr.s_addr, &zero, sizeof(zero))==0)
563 systemAddressOut->SetToLoopback(4);
564 // systemAddressOut->address.addr4.sin_port=ntohs(systemAddressOut->address.addr4.sin_port);
565 }
566 else
567 {
568 memcpy(&systemAddressOut->address.addr6,(sockaddr_in6 *)&ss,sizeof(sockaddr_in6));
569 systemAddressOut->debugPort=ntohs(systemAddressOut->address.addr6.sin6_port);
570
571 char zero[16];
572 memset(zero,0,sizeof(zero));
573 if (memcmp(&systemAddressOut->address.addr4.sin_addr.s_addr, &zero, sizeof(zero))==0)
574 systemAddressOut->SetToLoopback(6);
575
576 // systemAddressOut->address.addr6.sin6_port=ntohs(systemAddressOut->address.addr6.sin6_port);
577 }
578 #endif // #if RAKNET_SUPPORT_IPV6!=1
579 }
580 /*
581 void SocketLayer::GetSystemAddress ( RakNetSocket *s, SystemAddress *systemAddressOut )
582 {
583 return GetSystemAddress(s->s, systemAddressOut);
584 }
585 */
586
587 // void SocketLayer::SetSocketLayerOverride(SocketLayerOverride *_slo)
588 // {
589 // slo=_slo;
590 // }
591
592 bool SocketLayer::GetFirstBindableIP(char firstBindable[128], int ipProto)
593 {
594 SystemAddress ipList[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ];
595 SocketLayer::GetMyIP( ipList );
596
597
598 if (ipProto==AF_UNSPEC)
599
600 {
601 ipList[0].ToString(false,firstBindable,static_cast<size_t>(128));
602 return true;
603 }
604
605 // Find the first valid host address
606 unsigned int l;
607 for (l=0; l < MAXIMUM_NUMBER_OF_INTERNAL_IDS; l++)
608 {
609 if (ipList[l]==UNASSIGNED_SYSTEM_ADDRESS)
610 break;
611 if (ipList[l].GetIPVersion()==4 && ipProto==AF_INET)
612 break;
613 if (ipList[l].GetIPVersion()==6 && ipProto==AF_INET6)
614 break;
615 }
616
617 if (l==MAXIMUM_NUMBER_OF_INTERNAL_IDS || ipList[l]==UNASSIGNED_SYSTEM_ADDRESS)
618 return false;
619 // RAKNET_DEBUG_PRINTF("%i %i %i %i\n",
620 // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[0],
621 // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[1],
622 // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[2],
623 // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[3]
624 // );
625 ipList[l].ToString(false,firstBindable,static_cast<size_t>(128));
626 return true;
627
628 }