SLikeNet  0.1.3
 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
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)
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 
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
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 
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 */
488 {
489  SystemAddress sa;
490  GetSystemAddress(s,&sa);
491  return sa.GetPort();
492 }
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 */
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 {
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 }