SocketLayer.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  2. * 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. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file
  11. /// \brief SocketLayer class implementation
  12. ///
  13. #include "SocketLayer.h"
  14. #include "RakAssert.h"
  15. #include "RakNetTypes.h"
  16. #include "RakPeer.h"
  17. #include "GetTime.h"
  18. #include "LinuxStrings.h"
  19. #include "SocketDefines.h"
  20. #if (defined(__GNUC__) || defined(__GCCXML__)) && !defined(__WIN32__)
  21. #include <netdb.h>
  22. #endif
  23. using namespace RakNet;
  24. /*
  25. #if defined(__native_client__)
  26. using namespace pp;
  27. #endif
  28. */
  29. #if USE_SLIDING_WINDOW_CONGESTION_CONTROL!=1
  30. #include "CCRakNetUDT.h"
  31. #else
  32. #include "CCRakNetSlidingWindow.h"
  33. #endif
  34. //SocketLayerOverride *SocketLayer::slo=0;
  35. #ifdef _WIN32
  36. #else
  37. #include <string.h> // memcpy
  38. #include <unistd.h>
  39. #include <fcntl.h>
  40. #include <arpa/inet.h>
  41. #include <errno.h> // error numbers
  42. #include <stdio.h> // RAKNET_DEBUG_PRINTF
  43. #if !defined(ANDROID)
  44. #include <ifaddrs.h>
  45. #endif
  46. #include <netinet/in.h>
  47. #include <net/if.h>
  48. #include <sys/types.h>
  49. #include <sys/socket.h>
  50. #include <sys/ioctl.h>
  51. #endif
  52. #if defined(_WIN32)
  53. #include "WSAStartupSingleton.h"
  54. #include "WindowsIncludes.h"
  55. #else
  56. #include <unistd.h>
  57. #endif
  58. #include "RakSleep.h"
  59. #include <stdio.h>
  60. #include "Itoa.h"
  61. #ifdef _MSC_VER
  62. #pragma warning( push )
  63. #endif
  64. namespace RakNet
  65. {
  66. extern void ProcessNetworkPacket( const SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNet::TimeUS timeRead );
  67. //extern void ProcessNetworkPacket( const SystemAddress systemAddress, const char *data, const int length, RakPeer *rakPeer, RakNetSocket* rakNetSocket, RakNet::TimeUS timeRead );
  68. }
  69. #ifdef _DEBUG
  70. #include <stdio.h>
  71. #endif
  72. // http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#ip4to6
  73. // http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#getaddrinfo
  74. #if RAKNET_SUPPORT_IPV6==1
  75. void PrepareAddrInfoHints(addrinfo *hints)
  76. {
  77. memset(hints, 0, sizeof (addrinfo)); // make sure the struct is empty
  78. hints->ai_socktype = SOCK_DGRAM; // UDP sockets
  79. hints->ai_flags = AI_PASSIVE; // fill in my IP for me
  80. }
  81. #endif
  82. void SocketLayer::SetSocketOptions( __UDPSOCKET__ listenSocket, bool blockingSocket, bool setBroadcast)
  83. {
  84. #ifdef __native_client__
  85. (void) listenSocket;
  86. #else
  87. int sock_opt = 1;
  88. // This doubles the max throughput rate
  89. sock_opt=1024*256;
  90. setsockopt__(listenSocket, SOL_SOCKET, SO_RCVBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
  91. // Immediate hard close. Don't linger the socket, or recreating the socket quickly on Vista fails.
  92. // Fail with voice and xbox
  93. sock_opt=0;
  94. setsockopt__(listenSocket, SOL_SOCKET, SO_LINGER, ( char * ) & sock_opt, sizeof ( sock_opt ) );
  95. // This doesn't make much difference: 10% maybe
  96. // Not supported on console 2
  97. sock_opt=1024*16;
  98. setsockopt__(listenSocket, SOL_SOCKET, SO_SNDBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
  99. if (blockingSocket==false)
  100. {
  101. #ifdef _WIN32
  102. unsigned long nonblocking = 1;
  103. ioctlsocket__(listenSocket, FIONBIO, &nonblocking );
  104. #else
  105. fcntl( listenSocket, F_SETFL, O_NONBLOCK );
  106. #endif
  107. }
  108. if (setBroadcast)
  109. {
  110. // Note: Fails with VDP but not xbox
  111. // Set broadcast capable
  112. sock_opt=1;
  113. if ( setsockopt__(listenSocket, SOL_SOCKET, SO_BROADCAST, ( char * ) & sock_opt, sizeof( sock_opt ) ) == -1 )
  114. {
  115. #if defined(_WIN32) && defined(_DEBUG)
  116. #if !defined(WINDOWS_PHONE_8)
  117. DWORD dwIOError = GetLastError();
  118. // On Vista, can get WSAEACCESS (10013)
  119. // See http://support.microsoft.com/kb/819124
  120. // http://blogs.msdn.com/wndp/archive/2007/03/19/winsock-so-exclusiveaddruse-on-vista.aspx
  121. // http://msdn.microsoft.com/en-us/library/ms740621(VS.85).aspx
  122. LPVOID messageBuffer;
  123. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  124. NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
  125. ( LPTSTR ) & messageBuffer, 0, NULL );
  126. // something has gone wrong here...
  127. RAKNET_DEBUG_PRINTF( "setsockopt__(SO_BROADCAST) failed:Error code - %d\n%s", dwIOError, messageBuffer );
  128. //Free the buffer.
  129. LocalFree( messageBuffer );
  130. #endif
  131. #endif
  132. }
  133. }
  134. #endif
  135. }
  136. RakNet::RakString SocketLayer::GetSubNetForSocketAndIp(__UDPSOCKET__ inSock, RakNet::RakString inIpString)
  137. {
  138. RakNet::RakString netMaskString;
  139. RakNet::RakString ipString;
  140. #if defined(WINDOWS_STORE_RT)
  141. RakAssert("Not yet supported" && 0);
  142. return "";
  143. #elif defined(_WIN32)
  144. INTERFACE_INFO InterfaceList[20];
  145. unsigned long nBytesReturned;
  146. if (WSAIoctl(inSock, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
  147. sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
  148. return "";
  149. }
  150. int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
  151. for (int i = 0; i < nNumInterfaces; ++i)
  152. {
  153. sockaddr_in *pAddress;
  154. pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress);
  155. ipString=inet_ntoa(pAddress->sin_addr);
  156. if (inIpString==ipString)
  157. {
  158. pAddress = (sockaddr_in *) & (InterfaceList[i].iiNetmask);
  159. netMaskString=inet_ntoa(pAddress->sin_addr);
  160. return netMaskString;
  161. }
  162. }
  163. return "";
  164. #else
  165. int fd,fd2;
  166. fd2 = socket__(AF_INET, SOCK_DGRAM, 0);
  167. if(fd2 < 0)
  168. {
  169. return "";
  170. }
  171. struct ifconf ifc;
  172. char buf[1999];
  173. ifc.ifc_len = sizeof(buf);
  174. ifc.ifc_buf = buf;
  175. if(ioctl(fd2, SIOCGIFCONF, &ifc) < 0)
  176. {
  177. return "";
  178. }
  179. struct ifreq *ifr;
  180. ifr = ifc.ifc_req;
  181. int intNum = ifc.ifc_len / sizeof(struct ifreq);
  182. for(int i = 0; i < intNum; i++)
  183. {
  184. ipString=inet_ntoa(((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr);
  185. if (inIpString==ipString)
  186. {
  187. struct ifreq ifr2;
  188. fd = socket__(AF_INET, SOCK_DGRAM, 0);
  189. if(fd < 0)
  190. {
  191. return "";
  192. }
  193. ifr2.ifr_addr.sa_family = AF_INET;
  194. strncpy(ifr2.ifr_name, ifr[i].ifr_name, IFNAMSIZ-1);
  195. ioctl(fd, SIOCGIFNETMASK, &ifr2);
  196. close(fd);
  197. close(fd2);
  198. netMaskString=inet_ntoa(((struct sockaddr_in *)&ifr2.ifr_addr)->sin_addr);
  199. return netMaskString;
  200. }
  201. }
  202. close(fd2);
  203. return "";
  204. #endif
  205. }
  206. #if defined(WINDOWS_STORE_RT)
  207. void GetMyIP_WinRT( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
  208. {
  209. // Perhaps DatagramSocket.BindEndpointAsynch, use localHostName as an empty string, then query what it bound to?
  210. RakAssert("Not yet supported" && 0);
  211. }
  212. #else
  213. void GetMyIP_Win32( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
  214. {
  215. int idx=0;
  216. idx=0;
  217. char ac[ 80 ];
  218. if ( gethostname( ac, sizeof( ac ) ) == -1 )
  219. {
  220. #if defined(_WIN32) && !defined(WINDOWS_PHONE_8)
  221. DWORD dwIOError = GetLastError();
  222. LPVOID messageBuffer;
  223. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  224. NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
  225. ( LPTSTR ) & messageBuffer, 0, NULL );
  226. // something has gone wrong here...
  227. RAKNET_DEBUG_PRINTF( "gethostname failed:Error code - %d\n%s", dwIOError, messageBuffer );
  228. //Free the buffer.
  229. LocalFree( messageBuffer );
  230. #endif
  231. return ;
  232. }
  233. #if RAKNET_SUPPORT_IPV6==1
  234. struct addrinfo hints;
  235. struct addrinfo *servinfo=0, *aip; // will point to the results
  236. PrepareAddrInfoHints(&hints);
  237. getaddrinfo(ac, "", &hints, &servinfo);
  238. for (idx=0, aip = servinfo; aip != NULL && idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; aip = aip->ai_next, idx++)
  239. {
  240. if (aip->ai_family == AF_INET)
  241. {
  242. struct sockaddr_in *ipv4 = (struct sockaddr_in *)aip->ai_addr;
  243. memcpy(&addresses[idx].address.addr4,ipv4,sizeof(sockaddr_in));
  244. }
  245. else
  246. {
  247. struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)aip->ai_addr;
  248. memcpy(&addresses[idx].address.addr4,ipv6,sizeof(sockaddr_in6));
  249. }
  250. }
  251. freeaddrinfo(servinfo); // free the linked-list
  252. #else
  253. struct hostent *phe = gethostbyname( ac );
  254. if ( phe == 0 )
  255. {
  256. #if defined(_WIN32) && !defined(WINDOWS_PHONE_8)
  257. DWORD dwIOError = GetLastError();
  258. LPVOID messageBuffer;
  259. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  260. NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
  261. ( LPTSTR ) & messageBuffer, 0, NULL );
  262. // something has gone wrong here...
  263. RAKNET_DEBUG_PRINTF( "gethostbyname failed:Error code - %d\n%s", dwIOError, messageBuffer );
  264. //Free the buffer.
  265. LocalFree( messageBuffer );
  266. #endif
  267. return ;
  268. }
  269. for ( idx = 0; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
  270. {
  271. if (phe->h_addr_list[ idx ] == 0)
  272. break;
  273. memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[ idx ],sizeof(struct in_addr));
  274. }
  275. #endif // else RAKNET_SUPPORT_IPV6==1
  276. while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
  277. {
  278. addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
  279. idx++;
  280. }
  281. }
  282. #endif
  283. void SocketLayer::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
  284. {
  285. #if defined(WINDOWS_STORE_RT)
  286. GetMyIP_WinRT(addresses);
  287. #elif defined(_WIN32)
  288. GetMyIP_Win32(addresses);
  289. #else
  290. // GetMyIP_Linux(addresses);
  291. GetMyIP_Win32(addresses);
  292. #endif
  293. }
  294. /*
  295. unsigned short SocketLayer::GetLocalPort(RakNetSocket *s)
  296. {
  297. SystemAddress sa;
  298. GetSystemAddress(s,&sa);
  299. return sa.GetPort();
  300. }
  301. */
  302. unsigned short SocketLayer::GetLocalPort(__UDPSOCKET__ s)
  303. {
  304. SystemAddress sa;
  305. GetSystemAddress(s,&sa);
  306. return sa.GetPort();
  307. }
  308. void SocketLayer::GetSystemAddress_Old ( __UDPSOCKET__ s, SystemAddress *systemAddressOut )
  309. {
  310. #if defined(__native_client__)
  311. *systemAddressOut = UNASSIGNED_SYSTEM_ADDRESS;
  312. #else
  313. sockaddr_in sa;
  314. memset(&sa,0,sizeof(sockaddr_in));
  315. socklen_t len = sizeof(sa);
  316. if (getsockname__(s, (sockaddr*)&sa, &len)!=0)
  317. {
  318. #if defined(_WIN32) && defined(_DEBUG) && !defined(WINDOWS_PHONE_8)
  319. DWORD dwIOError = GetLastError();
  320. LPVOID messageBuffer;
  321. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  322. NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
  323. ( LPTSTR ) & messageBuffer, 0, NULL );
  324. // something has gone wrong here...
  325. RAKNET_DEBUG_PRINTF( "getsockname failed:Error code - %d\n%s", dwIOError, messageBuffer );
  326. //Free the buffer.
  327. LocalFree( messageBuffer );
  328. #endif
  329. *systemAddressOut = UNASSIGNED_SYSTEM_ADDRESS;
  330. return;
  331. }
  332. systemAddressOut->SetPortNetworkOrder(sa.sin_port);
  333. systemAddressOut->address.addr4.sin_addr.s_addr=sa.sin_addr.s_addr;
  334. #endif
  335. }
  336. /*
  337. void SocketLayer::GetSystemAddress_Old ( RakNetSocket *s, SystemAddress *systemAddressOut )
  338. {
  339. return GetSystemAddress_Old(s->s, systemAddressOut);
  340. }
  341. */
  342. void SocketLayer::GetSystemAddress ( __UDPSOCKET__ s, SystemAddress *systemAddressOut )
  343. {
  344. #if RAKNET_SUPPORT_IPV6!=1
  345. GetSystemAddress_Old(s, systemAddressOut);
  346. #else
  347. socklen_t slen;
  348. sockaddr_storage ss;
  349. slen = sizeof(ss);
  350. if (getsockname__(s, (struct sockaddr *)&ss, &slen)!=0)
  351. {
  352. #if defined(_WIN32) && defined(_DEBUG)
  353. DWORD dwIOError = GetLastError();
  354. LPVOID messageBuffer;
  355. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  356. NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
  357. ( LPTSTR ) & messageBuffer, 0, NULL );
  358. // something has gone wrong here...
  359. RAKNET_DEBUG_PRINTF( "getsockname failed:Error code - %d\n%s", dwIOError, messageBuffer );
  360. //Free the buffer.
  361. LocalFree( messageBuffer );
  362. #endif
  363. systemAddressOut->FromString(0);
  364. return;
  365. }
  366. if (ss.ss_family==AF_INET)
  367. {
  368. memcpy(&systemAddressOut->address.addr4,(sockaddr_in *)&ss,sizeof(sockaddr_in));
  369. systemAddressOut->debugPort=ntohs(systemAddressOut->address.addr4.sin_port);
  370. uint32_t zero = 0;
  371. if (memcmp(&systemAddressOut->address.addr4.sin_addr.s_addr, &zero, sizeof(zero))==0)
  372. systemAddressOut->SetToLoopback(4);
  373. // systemAddressOut->address.addr4.sin_port=ntohs(systemAddressOut->address.addr4.sin_port);
  374. }
  375. else
  376. {
  377. memcpy(&systemAddressOut->address.addr6,(sockaddr_in6 *)&ss,sizeof(sockaddr_in6));
  378. systemAddressOut->debugPort=ntohs(systemAddressOut->address.addr6.sin6_port);
  379. char zero[16];
  380. memset(zero,0,sizeof(zero));
  381. if (memcmp(&systemAddressOut->address.addr4.sin_addr.s_addr, &zero, sizeof(zero))==0)
  382. systemAddressOut->SetToLoopback(6);
  383. // systemAddressOut->address.addr6.sin6_port=ntohs(systemAddressOut->address.addr6.sin6_port);
  384. }
  385. #endif // #if RAKNET_SUPPORT_IPV6!=1
  386. }
  387. /*
  388. void SocketLayer::GetSystemAddress ( RakNetSocket *s, SystemAddress *systemAddressOut )
  389. {
  390. return GetSystemAddress(s->s, systemAddressOut);
  391. }
  392. */
  393. // void SocketLayer::SetSocketLayerOverride(SocketLayerOverride *_slo)
  394. // {
  395. // slo=_slo;
  396. // }
  397. bool SocketLayer::GetFirstBindableIP(char firstBindable[128], int ipProto)
  398. {
  399. SystemAddress ipList[ MAXIMUM_NUMBER_OF_INTERNAL_IDS ];
  400. SocketLayer::GetMyIP( ipList );
  401. if (ipProto==AF_UNSPEC)
  402. {
  403. ipList[0].ToString(false,firstBindable);
  404. return true;
  405. }
  406. // Find the first valid host address
  407. unsigned int l;
  408. for (l=0; l < MAXIMUM_NUMBER_OF_INTERNAL_IDS; l++)
  409. {
  410. if (ipList[l]==UNASSIGNED_SYSTEM_ADDRESS)
  411. break;
  412. if (ipList[l].GetIPVersion()==4 && ipProto==AF_INET)
  413. break;
  414. if (ipList[l].GetIPVersion()==6 && ipProto==AF_INET6)
  415. break;
  416. }
  417. if (ipList[l]==UNASSIGNED_SYSTEM_ADDRESS || l==MAXIMUM_NUMBER_OF_INTERNAL_IDS)
  418. return false;
  419. // RAKNET_DEBUG_PRINTF("%i %i %i %i\n",
  420. // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[0],
  421. // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[1],
  422. // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[2],
  423. // ((char*)(&ipList[l].address.addr4.sin_addr.s_addr))[3]
  424. // );
  425. ipList[l].ToString(false,firstBindable);
  426. return true;
  427. }
  428. #ifdef _MSC_VER
  429. #pragma warning( pop )
  430. #endif
粤ICP备19079148号