winNet.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platformWin32/platformWin32.h"
  23. #include "platform/platform.h"
  24. #include "platform/event.h"
  25. #include <winsock.h>
  26. #if !defined(USE_IPX) || defined(TORQUE_COMPILER_MINGW)
  27. # define NO_IPX_SUPPORT
  28. #endif
  29. #if !defined(NO_IPX_SUPPORT)
  30. # include <wsipx.h>
  31. #else
  32. typedef void* SOCKADDR_IPX;
  33. #endif
  34. #include "console/console.h"
  35. #include "game/gameInterface.h"
  36. #include "io/fileStream.h"
  37. struct NameLookup
  38. {
  39. U8 hostEntStruct[MAXGETHOSTSTRUCT];
  40. HANDLE lookupHandle;
  41. SOCKET socket;
  42. U16 port;
  43. NameLookup *nextLookup;
  44. };
  45. static NameLookup *lookupList = NULL;
  46. static Net::Error getLastError();
  47. static S32 defaultPort = 28000;
  48. static S32 netPort = 0;
  49. static SOCKET ipxSocket = INVALID_SOCKET;
  50. static SOCKET udpSocket = INVALID_SOCKET;
  51. enum WinNetConstants {
  52. MaxConnections = 1024, ///< Maximum allowed number of connections.
  53. };
  54. HWND winsockWindow = NULL;
  55. static LRESULT PASCAL WinsockProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  56. {
  57. U32 error;
  58. U32 bufLen;
  59. U32 event;
  60. SOCKET socket;
  61. Net::Error err;
  62. S32 bytesRead;
  63. static ConnectedNotifyEvent notifyEvent;
  64. static ConnectedReceiveEvent receiveEvent;
  65. static ConnectedAcceptEvent acceptEvent;
  66. switch(message)
  67. {
  68. case WM_USER:
  69. error = WSAGETSELECTERROR(lParam);
  70. event = WSAGETSELECTEVENT(lParam);
  71. socket = wParam;
  72. switch(event)
  73. {
  74. case FD_READ:
  75. err = Net::recv(socket, receiveEvent.data, MaxPacketDataSize, &bytesRead);
  76. if(err == Net::NoError && bytesRead != 0)
  77. {
  78. receiveEvent.tag = socket;
  79. receiveEvent.size = ConnectedReceiveEventHeaderSize + bytesRead;
  80. Game->postEvent(receiveEvent);
  81. }
  82. break;
  83. case FD_CONNECT:
  84. notifyEvent.tag = socket;
  85. if(error)
  86. notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
  87. else
  88. notifyEvent.state = ConnectedNotifyEvent::Connected;
  89. Game->postEvent(notifyEvent);
  90. break;
  91. case FD_CLOSE:
  92. // see first if there is anything to read:
  93. for(;;)
  94. {
  95. err = Net::recv(socket, receiveEvent.data, MaxPacketDataSize, &bytesRead);
  96. if(err != Net::NoError || bytesRead == 0)
  97. break;
  98. receiveEvent.tag = socket;
  99. receiveEvent.size = ConnectedReceiveEventHeaderSize + bytesRead;
  100. Game->postEvent(receiveEvent);
  101. }
  102. notifyEvent.tag = socket;
  103. notifyEvent.state = ConnectedNotifyEvent::Disconnected;
  104. Game->postEvent(notifyEvent);
  105. break;
  106. case FD_ACCEPT:
  107. acceptEvent.portTag = socket;
  108. acceptEvent.connectionTag = Net::accept(socket, &acceptEvent.address);
  109. if(acceptEvent.connectionTag != InvalidSocket)
  110. {
  111. Net::setBlocking(acceptEvent.connectionTag, false);
  112. WSAAsyncSelect(acceptEvent.connectionTag, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
  113. Game->postEvent(acceptEvent);
  114. }
  115. break;
  116. }
  117. break;
  118. case WM_USER + 1:
  119. error = WSAGETASYNCERROR(lParam);
  120. bufLen = WSAGETASYNCBUFLEN(lParam);
  121. HANDLE handle;
  122. handle = HANDLE(wParam);
  123. NameLookup **walk;
  124. for(walk = &lookupList; *walk; walk = &((*walk)->nextLookup))
  125. {
  126. if((*walk)->lookupHandle == handle)
  127. {
  128. NameLookup *temp = *walk;
  129. struct hostent *hp = (struct hostent *) temp->hostEntStruct;
  130. if(error)
  131. {
  132. notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
  133. notifyEvent.tag = temp->socket;
  134. ::closesocket(temp->socket);
  135. }
  136. else
  137. {
  138. SOCKADDR_IN ipAddr;
  139. memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
  140. ipAddr.sin_port = temp->port;
  141. ipAddr.sin_family = AF_INET;
  142. notifyEvent.tag = temp->socket;
  143. WSAAsyncSelect(temp->socket, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
  144. bool wserr = ::connect(temp->socket, (PSOCKADDR) &ipAddr, sizeof(ipAddr)); // always errors out
  145. if (wserr && WSAGetLastError() == WSAEWOULDBLOCK)
  146. notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
  147. else {
  148. Con::printf("Connect error: %d", WSAGetLastError());
  149. ::closesocket(temp->socket);
  150. notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
  151. }
  152. }
  153. Game->postEvent(notifyEvent);
  154. *walk = temp->nextLookup;
  155. delete temp;
  156. break;
  157. }
  158. }
  159. break;
  160. default:
  161. return DefWindowProc( hWnd, message, wParam, lParam );
  162. }
  163. return 0;
  164. }
  165. static void InitNetWindow()
  166. {
  167. WNDCLASS wc;
  168. dMemset(&wc, 0, sizeof(wc));
  169. wc.style = 0;
  170. wc.lpfnWndProc = WinsockProc;
  171. wc.cbClsExtra = 0;
  172. wc.cbWndExtra = 0;
  173. wc.hInstance = winState.appInstance;
  174. wc.hIcon = 0;
  175. wc.hCursor = 0;
  176. wc.hbrBackground = 0;
  177. wc.lpszMenuName = 0;
  178. wc.lpszClassName = dT("WinSockClass");
  179. RegisterClass( &wc );
  180. winsockWindow = CreateWindowEx(
  181. 0,
  182. dT("WinSockClass"),
  183. dT(""),
  184. 0,
  185. 0, 0, 0, 0,
  186. NULL, NULL,
  187. winState.appInstance,
  188. NULL);
  189. }
  190. bool Net::init()
  191. {
  192. WSADATA stWSAData;
  193. InitNetWindow();
  194. return !WSAStartup(0x0101, &stWSAData);
  195. }
  196. void Net::shutdown()
  197. {
  198. while(lookupList)
  199. {
  200. NameLookup *temp = lookupList;
  201. lookupList = temp->nextLookup;
  202. WSACancelAsyncRequest ( temp->lookupHandle );
  203. delete temp;
  204. }
  205. DestroyWindow(winsockWindow);
  206. closePort();
  207. WSACleanup();
  208. }
  209. static void netToIPSocketAddress(const NetAddress *address, SOCKADDR_IN *sockAddr)
  210. {
  211. dMemset(sockAddr, 0, sizeof(SOCKADDR_IN));
  212. sockAddr->sin_family = AF_INET;
  213. sockAddr->sin_port = htons(address->port);
  214. sockAddr->sin_addr.s_net = address->netNum[0];
  215. sockAddr->sin_addr.s_host = address->netNum[1];
  216. sockAddr->sin_addr.s_lh = address->netNum[2];
  217. sockAddr->sin_addr.s_impno = address->netNum[3];
  218. }
  219. static void IPSocketToNetAddress(const SOCKADDR_IN *sockAddr, NetAddress *address)
  220. {
  221. address->type = NetAddress::IPAddress;
  222. address->port = htons(sockAddr->sin_port);
  223. address->netNum[0] = sockAddr->sin_addr.s_net;
  224. address->netNum[1] = sockAddr->sin_addr.s_host;
  225. address->netNum[2] = sockAddr->sin_addr.s_lh;
  226. address->netNum[3] = sockAddr->sin_addr.s_impno;
  227. }
  228. static void netToIPXSocketAddress(const NetAddress *address, SOCKADDR_IPX *sockAddr)
  229. {
  230. #if !defined(NO_IPX_SUPPORT)
  231. dMemset(sockAddr, 0, sizeof(SOCKADDR_IPX));
  232. sockAddr->sa_family = AF_INET;
  233. sockAddr->sa_socket = htons(address->port);
  234. sockAddr->sa_netnum[0] = address->netNum[0];
  235. sockAddr->sa_netnum[1] = address->netNum[1];
  236. sockAddr->sa_netnum[2] = address->netNum[2];
  237. sockAddr->sa_netnum[3] = address->netNum[3];
  238. sockAddr->sa_nodenum[0] = address->nodeNum[0];
  239. sockAddr->sa_nodenum[1] = address->nodeNum[1];
  240. sockAddr->sa_nodenum[2] = address->nodeNum[2];
  241. sockAddr->sa_nodenum[3] = address->nodeNum[3];
  242. sockAddr->sa_nodenum[4] = address->nodeNum[4];
  243. sockAddr->sa_nodenum[5] = address->nodeNum[5];
  244. #endif
  245. }
  246. static void IPXSocketToNetAddress(const SOCKADDR_IPX *sockAddr, NetAddress *address)
  247. {
  248. #if !defined(NO_IPX_SUPPORT)
  249. address->type = NetAddress::IPXAddress;
  250. address->port = htons(sockAddr->sa_socket);
  251. address->netNum[0] = sockAddr->sa_netnum[0] ;
  252. address->netNum[1] = sockAddr->sa_netnum[1] ;
  253. address->netNum[2] = sockAddr->sa_netnum[2] ;
  254. address->netNum[3] = sockAddr->sa_netnum[3] ;
  255. address->nodeNum[0] = sockAddr->sa_nodenum[0];
  256. address->nodeNum[1] = sockAddr->sa_nodenum[1];
  257. address->nodeNum[2] = sockAddr->sa_nodenum[2];
  258. address->nodeNum[3] = sockAddr->sa_nodenum[3];
  259. address->nodeNum[4] = sockAddr->sa_nodenum[4];
  260. address->nodeNum[5] = sockAddr->sa_nodenum[5];
  261. #endif
  262. }
  263. NetSocket Net::openListenPort(U16 port)
  264. {
  265. #ifdef TORQUE_ALLOW_JOURNALING
  266. if(Game->isJournalReading())
  267. {
  268. U32 ret;
  269. Game->journalRead(&ret);
  270. return NetSocket(ret);
  271. }
  272. #endif //TORQUE_ALLOW_JOURNALING
  273. NetSocket sock = openSocket();
  274. bind(sock, port);
  275. listen(sock, 4);
  276. setBlocking(sock, false);
  277. if(WSAAsyncSelect ( sock, winsockWindow, WM_USER, FD_ACCEPT ))
  278. Con::printf("Connect error: %d", WSAGetLastError());
  279. #ifdef TORQUE_ALLOW_JOURNALING
  280. if(Game->isJournalWriting())
  281. Game->journalWrite(U32(sock));
  282. #endif //TORQUE_ALLOW_JOURNALING
  283. return sock;
  284. }
  285. NetSocket Net::openConnectTo(const char *addressString)
  286. {
  287. if(!dStrnicmp(addressString, "ipx:", 4))
  288. return InvalidSocket;
  289. if(!dStrnicmp(addressString, "ip:", 3))
  290. addressString += 3; // eat off the ip:
  291. char remoteAddr[256];
  292. dStrcpy(remoteAddr, addressString);
  293. char *portString = dStrchr(remoteAddr, ':');
  294. U16 port;
  295. if(portString)
  296. {
  297. *portString++ = 0;
  298. port = htons(dAtoi(portString));
  299. }
  300. else
  301. port = htons(defaultPort);
  302. if(!dStricmp(remoteAddr, "broadcast"))
  303. return InvalidSocket;
  304. #ifdef TORQUE_ALLOW_JOURNALING
  305. if(Game->isJournalReading())
  306. {
  307. U32 ret;
  308. Game->journalRead(&ret);
  309. return NetSocket(ret);
  310. }
  311. #endif //TORQUE_ALLOW_JOURNALING
  312. NetSocket sock = openSocket();
  313. setBlocking(sock, false);
  314. SOCKADDR_IN ipAddr;
  315. ipAddr.sin_addr.s_addr = inet_addr(remoteAddr);
  316. if(ipAddr.sin_addr.s_addr != INADDR_NONE)
  317. {
  318. ipAddr.sin_port = port;
  319. ipAddr.sin_family = AF_INET;
  320. WSAAsyncSelect(sock, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
  321. if(::connect(sock, (PSOCKADDR) &ipAddr, sizeof(ipAddr) ) )
  322. {
  323. if(WSAGetLastError() != WSAEWOULDBLOCK)
  324. {
  325. Con::printf("Connect error: %d", WSAGetLastError());
  326. ::closesocket(sock);
  327. sock = InvalidSocket;
  328. }
  329. }
  330. }
  331. else
  332. {
  333. NameLookup *lookup = new NameLookup;
  334. lookup->socket = sock;
  335. lookup->port = port;
  336. lookup->lookupHandle = WSAAsyncGetHostByName (winsockWindow, WM_USER + 1, remoteAddr, (char *) lookup->hostEntStruct, MAXGETHOSTSTRUCT );
  337. if(!lookup->lookupHandle)
  338. {
  339. delete lookup;
  340. ::closesocket(sock);
  341. sock = InvalidSocket;
  342. }
  343. else
  344. {
  345. lookup->nextLookup = lookupList;
  346. lookupList = lookup;
  347. }
  348. }
  349. #ifdef TORQUE_ALLOW_JOURNALING
  350. if(Game->isJournalWriting())
  351. Game->journalWrite(U32(sock));
  352. #endif //TORQUE_ALLOW_JOURNALING
  353. return sock;
  354. }
  355. void Net::closeConnectTo(NetSocket sock)
  356. {
  357. #ifdef TORQUE_ALLOW_JOURNALING
  358. if(Game->isJournalReading())
  359. return;
  360. #endif //TORQUE_ALLOW_JOURNALING
  361. for(NameLookup **walk = &lookupList; *walk; walk = &((*walk)->nextLookup) )
  362. {
  363. NameLookup *lookup = *walk;
  364. if(lookup->socket == sock)
  365. {
  366. WSACancelAsyncRequest ( lookup->lookupHandle );
  367. closesocket(lookup->socket);
  368. *walk = lookup->nextLookup;
  369. delete lookup;
  370. return;
  371. }
  372. }
  373. closesocket(sock);
  374. }
  375. Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, S32 bufferSize)
  376. {
  377. #ifdef TORQUE_ALLOW_JOURNALING
  378. if(Game->isJournalReading())
  379. {
  380. U32 e;
  381. Game->journalRead(&e);
  382. return (Net::Error) e;
  383. }
  384. #endif //TORQUE_ALLOW_JOURNALING
  385. Net::Error e = send(socket, buffer, bufferSize);
  386. #ifdef TORQUE_ALLOW_JOURNALING
  387. if(Game->isJournalWriting())
  388. Game->journalWrite(U32(e));
  389. #endif //TORQUE_ALLOW_JOURNALING
  390. return e;
  391. }
  392. bool Net::openPort(S32 port)
  393. {
  394. if(udpSocket != INVALID_SOCKET)
  395. closesocket(udpSocket);
  396. if(ipxSocket != INVALID_SOCKET)
  397. closesocket(ipxSocket);
  398. udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
  399. #if !defined(NO_IPX_SUPPORT)
  400. ipxSocket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
  401. #else
  402. ipxSocket = INVALID_SOCKET;
  403. #endif
  404. if(udpSocket != INVALID_SOCKET)
  405. {
  406. Net::Error error;
  407. error = bind(udpSocket, port);
  408. if(error == NoError)
  409. error = setBufferSize(udpSocket, 32768);
  410. if(error == NoError)
  411. error = setBroadcast(udpSocket, true);
  412. if(error == NoError)
  413. error = setBlocking(udpSocket, false);
  414. if(error == NoError)
  415. Con::printf("UDP initialized on port %d", port);
  416. else
  417. {
  418. closesocket(udpSocket);
  419. udpSocket = INVALID_SOCKET;
  420. Con::printf("Unable to initialize UDP - error %d", error);
  421. }
  422. }
  423. #if !defined(NO_IPX_SUPPORT)
  424. if(ipxSocket != INVALID_SOCKET)
  425. {
  426. Net::Error error = NoError;
  427. SOCKADDR_IPX ipxAddress;
  428. memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
  429. ipxAddress.sa_family = AF_IPX;
  430. ipxAddress.sa_socket = htons(port);
  431. S32 err = ::bind(ipxSocket, (PSOCKADDR) &ipxAddress, sizeof(ipxAddress));
  432. if(err)
  433. error = getLastError();
  434. if(error == NoError)
  435. error = setBufferSize(ipxSocket, 32768);
  436. if(error == NoError)
  437. error = setBroadcast(ipxSocket, true);
  438. if(error == NoError)
  439. error = setBlocking(ipxSocket, false);
  440. if(error == NoError)
  441. Con::printf("IPX initialized on port %d", port);
  442. else
  443. {
  444. closesocket(ipxSocket);
  445. ipxSocket = INVALID_SOCKET;
  446. Con::printf("Unable to initialize IPX - error %d", error);
  447. }
  448. }
  449. #endif
  450. netPort = port;
  451. return ipxSocket != INVALID_SOCKET || udpSocket != INVALID_SOCKET;
  452. }
  453. void Net::closePort()
  454. {
  455. if(ipxSocket != INVALID_SOCKET)
  456. closesocket(ipxSocket);
  457. if(udpSocket != INVALID_SOCKET)
  458. closesocket(udpSocket);
  459. }
  460. Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize)
  461. {
  462. #ifdef TORQUE_ALLOW_JOURNALING
  463. if(Game->isJournalReading())
  464. return NoError;
  465. #endif //TORQUE_ALLOW_JOURNALING
  466. if(address->type == NetAddress::IPXAddress)
  467. {
  468. SOCKADDR_IPX ipxAddr;
  469. netToIPXSocketAddress(address, &ipxAddr);
  470. if(::sendto(ipxSocket, (const char*)buffer, bufferSize, 0,
  471. (PSOCKADDR) &ipxAddr, sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)
  472. return getLastError();
  473. else
  474. return NoError;
  475. }
  476. else
  477. {
  478. SOCKADDR_IN ipAddr;
  479. netToIPSocketAddress(address, &ipAddr);
  480. if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
  481. (PSOCKADDR) &ipAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
  482. return getLastError();
  483. else
  484. return NoError;
  485. }
  486. }
  487. void Net::process()
  488. {
  489. SOCKADDR sa;
  490. PacketReceiveEvent receiveEvent;
  491. for(;;)
  492. {
  493. S32 addrLen = sizeof(sa);
  494. S32 bytesRead = SOCKET_ERROR;
  495. if(udpSocket != INVALID_SOCKET)
  496. bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
  497. if(bytesRead == SOCKET_ERROR && ipxSocket != INVALID_SOCKET)
  498. {
  499. addrLen = sizeof(sa);
  500. bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
  501. }
  502. if(bytesRead == SOCKET_ERROR)
  503. break;
  504. if(sa.sa_family == AF_INET)
  505. IPSocketToNetAddress((SOCKADDR_IN *) &sa, &receiveEvent.sourceAddress);
  506. else if(sa.sa_family == AF_IPX)
  507. IPXSocketToNetAddress((SOCKADDR_IPX *) &sa, &receiveEvent.sourceAddress);
  508. else
  509. continue;
  510. NetAddress &na = receiveEvent.sourceAddress;
  511. if(na.type == NetAddress::IPAddress &&
  512. na.netNum[0] == 127 &&
  513. na.netNum[1] == 0 &&
  514. na.netNum[2] == 0 &&
  515. na.netNum[3] == 1 &&
  516. na.port == netPort)
  517. continue;
  518. if(bytesRead <= 0)
  519. continue;
  520. receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
  521. Game->postEvent(receiveEvent);
  522. }
  523. }
  524. NetSocket Net::openSocket()
  525. {
  526. SOCKET retSocket;
  527. retSocket = socket(AF_INET, SOCK_STREAM, 0);
  528. if(retSocket == INVALID_SOCKET)
  529. return InvalidSocket;
  530. else
  531. return retSocket;
  532. }
  533. Net::Error Net::closeSocket(NetSocket socket)
  534. {
  535. if(socket != InvalidSocket)
  536. {
  537. if(!closesocket(socket))
  538. return NoError;
  539. else
  540. return getLastError();
  541. }
  542. else
  543. return NotASocket;
  544. }
  545. Net::Error Net::connect(NetSocket socket, const NetAddress *address)
  546. {
  547. if(address->type != NetAddress::IPAddress)
  548. return WrongProtocolType;
  549. SOCKADDR_IN socketAddress;
  550. netToIPSocketAddress(address, &socketAddress);
  551. if(!::connect(socket, (PSOCKADDR) &socketAddress, sizeof(socketAddress)))
  552. return NoError;
  553. return getLastError();
  554. }
  555. Net::Error Net::listen(NetSocket socket, S32 backlog)
  556. {
  557. if(!::listen(socket, backlog))
  558. return NoError;
  559. return getLastError();
  560. }
  561. NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
  562. {
  563. SOCKADDR_IN socketAddress;
  564. S32 addrLen = sizeof(socketAddress);
  565. SOCKET retVal = ::accept(acceptSocket, (PSOCKADDR) &socketAddress, &addrLen);
  566. if(retVal != INVALID_SOCKET)
  567. {
  568. IPSocketToNetAddress(&socketAddress, remoteAddress);
  569. return retVal;
  570. }
  571. return InvalidSocket;
  572. }
  573. Net::Error Net::bind(NetSocket socket, U16 port)
  574. {
  575. S32 error;
  576. SOCKADDR_IN socketAddress;
  577. dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
  578. socketAddress.sin_family = AF_INET;
  579. // It's entirely possible that there are two NIC cards.
  580. // We let the user specify which one the server runs on.
  581. // thanks to [TPG]P1aGu3 for the name
  582. const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
  583. // serverIP is guaranteed to be non-0.
  584. AssertFatal( serverIP, "serverIP is NULL!" );
  585. if( serverIP[0] != '\0' ) {
  586. // we're not empty
  587. socketAddress.sin_addr.s_addr = inet_addr( serverIP );
  588. if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
  589. Con::printf( "Binding server port to %s", serverIP );
  590. } else {
  591. Con::warnf( ConsoleLogEntry::General,
  592. "inet_addr() failed for %s while binding!",
  593. serverIP );
  594. socketAddress.sin_addr.s_addr = INADDR_ANY;
  595. }
  596. } else {
  597. Con::printf( "Binding server port to default IP" );
  598. socketAddress.sin_addr.s_addr = INADDR_ANY;
  599. }
  600. socketAddress.sin_port = htons(port);
  601. error = ::bind(socket, (PSOCKADDR) &socketAddress, sizeof(socketAddress));
  602. if(!error)
  603. return NoError;
  604. return getLastError();
  605. }
  606. Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
  607. {
  608. S32 error;
  609. error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufferSize, sizeof(bufferSize));
  610. if(!error)
  611. error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufferSize, sizeof(bufferSize));
  612. if(!error)
  613. return NoError;
  614. return getLastError();
  615. }
  616. Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
  617. {
  618. S32 bc = broadcast;
  619. S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc));
  620. if(!error)
  621. return NoError;
  622. return getLastError();
  623. }
  624. Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
  625. {
  626. DWORD notblock = !blockingIO;
  627. S32 error = ioctlsocket(socket, FIONBIO, &notblock);
  628. if(!error)
  629. return NoError;
  630. return getLastError();
  631. }
  632. Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
  633. {
  634. S32 error = ::send(socket, (const char*)buffer, bufferSize, 0);
  635. if(!error)
  636. return NoError;
  637. return getLastError();
  638. }
  639. Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead)
  640. {
  641. *bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
  642. if(*bytesRead == SOCKET_ERROR)
  643. return getLastError();
  644. return NoError;
  645. }
  646. bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
  647. {
  648. if((a1->type != a2->type) ||
  649. (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
  650. (a1->port != a2->port))
  651. return false;
  652. if(a1->type == NetAddress::IPAddress)
  653. return true;
  654. for(S32 i = 0; i < 6; i++)
  655. if(a1->nodeNum[i] != a2->nodeNum[i])
  656. return false;
  657. return true;
  658. }
  659. bool Net::stringToAddress(const char *addressString, NetAddress *address)
  660. {
  661. if(dStrnicmp(addressString, "ipx:", 4))
  662. {
  663. // assume IP if it doesn't have ipx: at the front.
  664. if(!dStrnicmp(addressString, "ip:", 3))
  665. addressString += 3; // eat off the ip:
  666. SOCKADDR_IN ipAddr;
  667. char remoteAddr[256];
  668. if(strlen(addressString) > 255)
  669. return false;
  670. dStrcpy(remoteAddr, addressString);
  671. char *portString = dStrchr(remoteAddr, ':');
  672. if(portString)
  673. *portString++ = 0;
  674. struct hostent *hp;
  675. if(!dStricmp(remoteAddr, "broadcast"))
  676. ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  677. else
  678. {
  679. ipAddr.sin_addr.s_addr = inet_addr(remoteAddr);
  680. if(ipAddr.sin_addr.s_addr == INADDR_NONE)
  681. {
  682. if((hp = gethostbyname(remoteAddr)) == NULL)
  683. return false;
  684. else
  685. memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
  686. }
  687. }
  688. if(portString)
  689. ipAddr.sin_port = htons(dAtoi(portString));
  690. else
  691. ipAddr.sin_port = htons(defaultPort);
  692. ipAddr.sin_family = AF_INET;
  693. IPSocketToNetAddress(&ipAddr, address);
  694. return true;
  695. }
  696. else
  697. {
  698. S32 i;
  699. S32 port;
  700. address->type = NetAddress::IPXAddress;
  701. for(i = 0; i < 6; i++)
  702. address->nodeNum[i] = 0xFF;
  703. // it's an IPX string
  704. addressString += 4;
  705. if(!dStricmp(addressString, "broadcast"))
  706. {
  707. address->port = defaultPort;
  708. return true;
  709. }
  710. else if(sscanf(addressString, "broadcast:%d", &port) == 1)
  711. {
  712. address->port = port;
  713. return true;
  714. }
  715. else
  716. {
  717. S32 nodeNum[6];
  718. S32 netNum[4];
  719. S32 count = dSscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d",
  720. &netNum[0], &netNum[1], &netNum[2], &netNum[3],
  721. &nodeNum[0], &nodeNum[1], &nodeNum[2], &nodeNum[3], &nodeNum[4], &nodeNum[5],
  722. &port);
  723. if(count == 10)
  724. {
  725. port = defaultPort;
  726. count++;
  727. }
  728. if(count != 11)
  729. return false;
  730. for(i = 0; i < 6; i++)
  731. address->nodeNum[i] = nodeNum[i];
  732. for(i = 0; i < 4; i++)
  733. address->netNum[i] = netNum[i];
  734. address->port = port;
  735. return true;
  736. }
  737. }
  738. }
  739. void Net::addressToString(const NetAddress *address, char addressString[256])
  740. {
  741. if(address->type == NetAddress::IPAddress)
  742. {
  743. SOCKADDR_IN ipAddr;
  744. netToIPSocketAddress(address, &ipAddr);
  745. if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
  746. dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
  747. else
  748. dSprintf(addressString, 256, "IP:%d.%d.%d.%d:%d", ipAddr.sin_addr.s_net,
  749. ipAddr.sin_addr.s_host, ipAddr.sin_addr.s_lh,
  750. ipAddr.sin_addr.s_impno, ntohs(ipAddr.sin_port));
  751. }
  752. else
  753. {
  754. dSprintf(addressString, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
  755. address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3],
  756. address->nodeNum[0], address->nodeNum[1], address->nodeNum[2], address->nodeNum[3], address->nodeNum[4], address->nodeNum[5],
  757. address->port);
  758. }
  759. }
  760. Net::Error getLastError()
  761. {
  762. S32 err = WSAGetLastError();
  763. switch(err)
  764. {
  765. case WSAEWOULDBLOCK:
  766. return Net::WouldBlock;
  767. default:
  768. return Net::UnknownError;
  769. }
  770. }