x86UNIXNet.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 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. #if 0
  23. #include "platformX86UNIX/platformX86UNIX.h"
  24. #include "platform/platform.h"
  25. #include "platform/event.h"
  26. #include "platform/platformNetAsync.h"
  27. #include <unistd.h>
  28. #include <sys/types.h>
  29. #include <sys/socket.h>
  30. #include <sys/poll.h>
  31. #include <arpa/inet.h>
  32. #include <netdb.h>
  33. #include <netinet/in.h>
  34. #include <errno.h>
  35. /* for PROTO_IPX */
  36. #if defined(__linux__)
  37. #include <net/if_ppp.h>
  38. #include <sys/ioctl.h> /* ioctl() */
  39. #include <net/ppp_defs.h>
  40. #elif defined(__OpenBSD__) || defined(__FreeBSD__)
  41. #include <sys/ioctl.h> /* ioctl() */
  42. #include <net/ppp_defs.h>
  43. #endif
  44. #include <netipx/ipx.h>
  45. #include <stdlib.h>
  46. #include "console/console.h"
  47. #include "platform/gameInterface.h"
  48. #include "core/fileStream.h"
  49. #include "core/tVector.h"
  50. static Net::Error getLastError();
  51. static S32 defaultPort = 28000;
  52. static S32 netPort = 0;
  53. static int ipxSocket = InvalidSocket;
  54. static int udpSocket = InvalidSocket;
  55. // local enum for socket states for polled sockets
  56. enum SocketState
  57. {
  58. InvalidState,
  59. Connected,
  60. ConnectionPending,
  61. Listening,
  62. NameLookupRequired
  63. };
  64. // the Socket structure helps us keep track of the
  65. // above states
  66. struct Socket
  67. {
  68. Socket()
  69. {
  70. fd = InvalidSocket;
  71. state = InvalidState;
  72. remoteAddr[0] = 0;
  73. remotePort = -1;
  74. }
  75. NetSocket fd;
  76. S32 state;
  77. char remoteAddr[256];
  78. S32 remotePort;
  79. };
  80. // list of polled sockets
  81. static Vector<Socket*> gPolledSockets;
  82. static Socket* addPolledSocket(NetSocket& fd, S32 state,
  83. char* remoteAddr = NULL, S32 port = -1)
  84. {
  85. Socket* sock = new Socket();
  86. sock->fd = fd;
  87. sock->state = state;
  88. if (remoteAddr)
  89. dStrcpy(sock->remoteAddr, remoteAddr, 256);
  90. if (port != -1)
  91. sock->remotePort = port;
  92. gPolledSockets.push_back(sock);
  93. return sock;
  94. }
  95. enum {
  96. MaxConnections = 1024,
  97. };
  98. S32 Poll(NetSocket fd, S32 eventMask, S32 timeoutMs)
  99. {
  100. pollfd pfd;
  101. S32 retVal;
  102. pfd.fd = fd;
  103. pfd.events = eventMask;
  104. retVal = poll(&pfd, 1, timeoutMs);
  105. return retVal;
  106. if (retVal <= 0)
  107. return retVal;
  108. else
  109. return pfd.revents;
  110. }
  111. bool Net::init()
  112. {
  113. NetAsync::startAsync();
  114. return(true);
  115. }
  116. void Net::shutdown()
  117. {
  118. while (gPolledSockets.size() > 0)
  119. closeConnectTo(gPolledSockets[0]->fd);
  120. closePort();
  121. NetAsync::stopAsync();
  122. }
  123. static void netToIPSocketAddress(const NetAddress *address, struct sockaddr_in *sockAddr)
  124. {
  125. dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
  126. sockAddr->sin_family = AF_INET;
  127. sockAddr->sin_port = htons(address->port);
  128. char tAddr[20];
  129. dSprintf(tAddr, 20, "%d.%d.%d.%d\n", address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3]);
  130. //fprintf(stdout,"netToIPSocketAddress(): %s\n",tAddr);fflush(NULL);
  131. sockAddr->sin_addr.s_addr = inet_addr(tAddr);
  132. // sockAddr->sin_addr.s_addr = address->netNum[0]; // hopefully this will work.
  133. }
  134. static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address)
  135. {
  136. address->type = NetAddress::IPAddress;
  137. address->port = htons(sockAddr->sin_port);
  138. char *tAddr;
  139. tAddr = inet_ntoa(sockAddr->sin_addr);
  140. //fprintf(stdout,"IPSocketToNetAddress(): %s\n",tAddr);fflush(NULL);
  141. U8 nets[4];
  142. nets[0] = atoi(strtok(tAddr, "."));
  143. nets[1] = atoi(strtok(NULL, "."));
  144. nets[2] = atoi(strtok(NULL, "."));
  145. nets[3] = atoi(strtok(NULL, "."));
  146. //fprintf(stdout,"0 = %d, 1 = %d, 2 = %d, 3 = %d\n", nets[0], nets[1], nets[2], nets[3]);
  147. address->netNum[0] = nets[0];
  148. address->netNum[1] = nets[1];
  149. address->netNum[2] = nets[2];
  150. address->netNum[3] = nets[3];
  151. }
  152. static void netToIPXSocketAddress(const NetAddress *address, sockaddr_ipx *sockAddr)
  153. {
  154. #if !defined(__FreeBSD__)
  155. dMemset(sockAddr, 0, sizeof(sockaddr_ipx));
  156. sockAddr->sipx_family = AF_INET;
  157. sockAddr->sipx_port = htons(address->port);
  158. sockAddr->sipx_network = address->netNum[0];
  159. sockAddr->sipx_node[0] = address->nodeNum[0];
  160. sockAddr->sipx_node[1] = address->nodeNum[1];
  161. sockAddr->sipx_node[2] = address->nodeNum[2];
  162. sockAddr->sipx_node[3] = address->nodeNum[3];
  163. sockAddr->sipx_node[4] = address->nodeNum[4];
  164. sockAddr->sipx_node[5] = address->nodeNum[5];
  165. #endif
  166. }
  167. static void IPXSocketToNetAddress(const sockaddr_ipx *sockAddr, NetAddress *address)
  168. {
  169. #if !defined(__FreeBSD__)
  170. address->type = NetAddress::IPXAddress;
  171. address->port = htons(sockAddr->sipx_port);
  172. address->netNum[0] = sockAddr->sipx_network;
  173. address->nodeNum[0] = sockAddr->sipx_node[0];
  174. address->nodeNum[1] = sockAddr->sipx_node[1];
  175. address->nodeNum[2] = sockAddr->sipx_node[2];
  176. address->nodeNum[3] = sockAddr->sipx_node[3];
  177. address->nodeNum[4] = sockAddr->sipx_node[4];
  178. address->nodeNum[5] = sockAddr->sipx_node[5];
  179. #endif
  180. }
  181. NetSocket Net::openListenPort(U16 port)
  182. {
  183. if(Game->isJournalReading())
  184. {
  185. U32 ret;
  186. Game->journalRead(&ret);
  187. return NetSocket(ret);
  188. }
  189. NetSocket sock = openSocket();
  190. if (sock == InvalidSocket)
  191. {
  192. Con::errorf("Unable to open listen socket: %s", strerror(errno));
  193. return InvalidSocket;
  194. }
  195. if (bind(sock, port) != NoError)
  196. {
  197. Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
  198. ::close(sock);
  199. return InvalidSocket;
  200. }
  201. if (listen(sock, 4) != NoError)
  202. {
  203. Con::errorf("Unable to listen on port %d: %s", port, strerror(errno));
  204. ::close(sock);
  205. return InvalidSocket;
  206. }
  207. setBlocking(sock, false);
  208. addPolledSocket(sock, Listening);
  209. if (Game->isJournalWriting())
  210. Game->journalWrite(U32(sock));
  211. return sock;
  212. }
  213. NetSocket Net::openConnectTo(const char *addressString)
  214. {
  215. if(!dStrnicmp(addressString, "ipx:", 4))
  216. return InvalidSocket;
  217. if(!dStrnicmp(addressString, "ip:", 3))
  218. addressString += 3; // eat off the ip:
  219. char remoteAddr[256];
  220. dStrcpy(remoteAddr, addressString, 256);
  221. char *portString = dStrchr(remoteAddr, ':');
  222. U16 port;
  223. if(portString)
  224. {
  225. *portString++ = 0;
  226. port = htons(dAtoi(portString));
  227. }
  228. else
  229. port = htons(defaultPort);
  230. if(!dStricmp(remoteAddr, "broadcast"))
  231. return InvalidSocket;
  232. if(Game->isJournalReading())
  233. {
  234. U32 ret;
  235. Game->journalRead(&ret);
  236. return NetSocket(ret);
  237. }
  238. NetSocket sock = openSocket();
  239. setBlocking(sock, false);
  240. sockaddr_in ipAddr;
  241. dMemset(&ipAddr, 0, sizeof(ipAddr));
  242. if (inet_aton(remoteAddr, &ipAddr.sin_addr) != 0)
  243. {
  244. ipAddr.sin_port = port;
  245. ipAddr.sin_family = AF_INET;
  246. if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) == -1 &&
  247. errno != EINPROGRESS)
  248. {
  249. Con::errorf("Error connecting %s: %s",
  250. addressString, strerror(errno));
  251. ::close(sock);
  252. sock = InvalidSocket;
  253. }
  254. if(sock != InvalidSocket) {
  255. // add this socket to our list of polled sockets
  256. addPolledSocket(sock, ConnectionPending);
  257. }
  258. }
  259. else
  260. {
  261. // need to do an asynchronous name lookup. first, add the socket
  262. // to the polled list
  263. addPolledSocket(sock, NameLookupRequired, remoteAddr, port);
  264. // queue the lookup
  265. gNetAsync.queueLookup(remoteAddr, sock);
  266. }
  267. if(Game->isJournalWriting())
  268. Game->journalWrite(U32(sock));
  269. return sock;
  270. }
  271. void Net::closeConnectTo(NetSocket sock)
  272. {
  273. if(Game->isJournalReading())
  274. return;
  275. // if this socket is in the list of polled sockets, remove it
  276. for (int i = 0; i < gPolledSockets.size(); ++i)
  277. if (gPolledSockets[i]->fd == sock)
  278. {
  279. delete gPolledSockets[i];
  280. gPolledSockets.erase(i);
  281. break;
  282. }
  283. closeSocket(sock);
  284. }
  285. Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int bufferSize)
  286. {
  287. if(Game->isJournalReading())
  288. {
  289. U32 e;
  290. Game->journalRead(&e);
  291. return (Net::Error) e;
  292. }
  293. Net::Error e = send(socket, buffer, bufferSize);
  294. if(Game->isJournalWriting())
  295. Game->journalWrite(U32(e));
  296. return e;
  297. }
  298. bool Net::openPort(S32 port)
  299. {
  300. if(udpSocket != InvalidSocket)
  301. close(udpSocket);
  302. if(ipxSocket != InvalidSocket)
  303. close(ipxSocket);
  304. udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
  305. ipxSocket = socket(AF_IPX, SOCK_DGRAM, 0);
  306. if(udpSocket != InvalidSocket)
  307. {
  308. Net::Error error;
  309. error = bind(udpSocket, port);
  310. if(error == NoError)
  311. error = setBufferSize(udpSocket, 32768);
  312. if(error == NoError)
  313. error = setBroadcast(udpSocket, true);
  314. if(error == NoError)
  315. error = setBlocking(udpSocket, false);
  316. if(error == NoError)
  317. Con::printf("UDP initialized on port %d", port);
  318. else
  319. {
  320. close(udpSocket);
  321. udpSocket = InvalidSocket;
  322. Con::printf("Unable to initialize UDP - error %d", error);
  323. }
  324. }
  325. if(ipxSocket != InvalidSocket)
  326. {
  327. Net::Error error = NoError;
  328. sockaddr_ipx ipxAddress;
  329. memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
  330. ipxAddress.sipx_family = AF_IPX;
  331. ipxAddress.sipx_port = htons(port);
  332. S32 err = ::bind(ipxSocket, (struct sockaddr *)&ipxAddress, sizeof(ipxAddress));
  333. if(err)
  334. error = getLastError();
  335. if(error == NoError)
  336. error = setBufferSize(ipxSocket, 32768);
  337. if(error == NoError)
  338. error = setBroadcast(ipxSocket, true);
  339. if(error == NoError)
  340. error = setBlocking(ipxSocket, false);
  341. if(error == NoError)
  342. Con::printf("IPX initialized on port %d", port);
  343. else
  344. {
  345. close(ipxSocket);
  346. ipxSocket = InvalidSocket;
  347. Con::printf("Unable to initialize IPX - error %d", error);
  348. }
  349. }
  350. netPort = port;
  351. return ipxSocket != InvalidSocket || udpSocket != InvalidSocket;
  352. }
  353. void Net::closePort()
  354. {
  355. if(ipxSocket != InvalidSocket)
  356. close(ipxSocket);
  357. if(udpSocket != InvalidSocket)
  358. close(udpSocket);
  359. }
  360. Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize)
  361. {
  362. if(Game->isJournalReading())
  363. return NoError;
  364. if(address->type == NetAddress::IPXAddress)
  365. {
  366. sockaddr_ipx ipxAddr;
  367. netToIPXSocketAddress(address, &ipxAddr);
  368. if(::sendto(ipxSocket, (const char*)buffer, bufferSize, 0,
  369. (sockaddr *) &ipxAddr, sizeof(sockaddr_ipx)) == -1)
  370. return getLastError();
  371. else
  372. return NoError;
  373. }
  374. else
  375. {
  376. sockaddr_in ipAddr;
  377. netToIPSocketAddress(address, &ipAddr);
  378. if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
  379. (sockaddr *) &ipAddr, sizeof(sockaddr_in)) == -1)
  380. return getLastError();
  381. else
  382. return NoError;
  383. }
  384. }
  385. void Net::process()
  386. {
  387. sockaddr sa;
  388. PacketReceiveEvent receiveEvent;
  389. for(;;)
  390. {
  391. U32 addrLen = sizeof(sa);
  392. S32 bytesRead = -1;
  393. if(udpSocket != InvalidSocket)
  394. bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
  395. if(bytesRead == -1 && ipxSocket != InvalidSocket)
  396. {
  397. addrLen = sizeof(sa);
  398. bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
  399. }
  400. if(bytesRead == -1)
  401. break;
  402. if(sa.sa_family == AF_INET)
  403. IPSocketToNetAddress((sockaddr_in *) &sa, &receiveEvent.sourceAddress);
  404. else if(sa.sa_family == AF_IPX)
  405. IPXSocketToNetAddress((sockaddr_ipx *) &sa, &receiveEvent.sourceAddress);
  406. else
  407. continue;
  408. NetAddress &na = receiveEvent.sourceAddress;
  409. if(na.type == NetAddress::IPAddress &&
  410. na.netNum[0] == 127 &&
  411. na.netNum[1] == 0 &&
  412. na.netNum[2] == 0 &&
  413. na.netNum[3] == 1 &&
  414. na.port == netPort)
  415. continue;
  416. if(bytesRead <= 0)
  417. continue;
  418. receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
  419. Game->postEvent(receiveEvent);
  420. }
  421. // process the polled sockets. This blob of code performs functions
  422. // similar to WinsockProc in winNet.cc
  423. if (gPolledSockets.size() == 0)
  424. return;
  425. static ConnectedNotifyEvent notifyEvent;
  426. static ConnectedAcceptEvent acceptEvent;
  427. static ConnectedReceiveEvent cReceiveEvent;
  428. S32 optval;
  429. socklen_t optlen = sizeof(S32);
  430. S32 bytesRead;
  431. Net::Error err;
  432. bool removeSock = false;
  433. Socket *currentSock = NULL;
  434. sockaddr_in ipAddr;
  435. NetSocket incoming = InvalidSocket;
  436. char out_h_addr[1024];
  437. int out_h_length = 0;
  438. for (S32 i = 0; i < gPolledSockets.size();
  439. /* no increment, this is done at end of loop body */)
  440. {
  441. removeSock = false;
  442. currentSock = gPolledSockets[i];
  443. switch (currentSock->state)
  444. {
  445. case InvalidState:
  446. Con::errorf("Error, InvalidState socket in polled sockets list");
  447. break;
  448. case ConnectionPending:
  449. notifyEvent.tag = currentSock->fd;
  450. // see if it is now connected
  451. if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR,
  452. &optval, &optlen) == -1)
  453. {
  454. Con::errorf("Error getting socket options: %s", strerror(errno));
  455. notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
  456. Game->postEvent(notifyEvent);
  457. removeSock = true;
  458. }
  459. else
  460. {
  461. if (optval == EINPROGRESS)
  462. // still connecting...
  463. break;
  464. if (optval == 0)
  465. {
  466. // connected
  467. notifyEvent.state = ConnectedNotifyEvent::Connected;
  468. Game->postEvent(notifyEvent);
  469. currentSock->state = Connected;
  470. }
  471. else
  472. {
  473. // some kind of error
  474. Con::errorf("Error connecting: %s", strerror(errno));
  475. notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
  476. Game->postEvent(notifyEvent);
  477. removeSock = true;
  478. }
  479. }
  480. break;
  481. case Connected:
  482. bytesRead = 0;
  483. // try to get some data
  484. err = Net::recv(currentSock->fd, cReceiveEvent.data,
  485. MaxPacketDataSize, &bytesRead);
  486. if(err == Net::NoError)
  487. {
  488. if (bytesRead > 0)
  489. {
  490. // got some data, post it
  491. cReceiveEvent.tag = currentSock->fd;
  492. cReceiveEvent.size = ConnectedReceiveEventHeaderSize +
  493. bytesRead;
  494. Game->postEvent(cReceiveEvent);
  495. }
  496. else
  497. {
  498. // zero bytes read means EOF
  499. if (bytesRead < 0)
  500. // ack! this shouldn't happen
  501. Con::errorf("Unexpected error on socket: %s",
  502. strerror(errno));
  503. notifyEvent.tag = currentSock->fd;
  504. notifyEvent.state = ConnectedNotifyEvent::Disconnected;
  505. Game->postEvent(notifyEvent);
  506. removeSock = true;
  507. }
  508. }
  509. else if (err != Net::NoError && err != Net::WouldBlock)
  510. {
  511. Con::errorf("Error reading from socket: %s", strerror(errno));
  512. notifyEvent.tag = currentSock->fd;
  513. notifyEvent.state = ConnectedNotifyEvent::Disconnected;
  514. Game->postEvent(notifyEvent);
  515. removeSock = true;
  516. }
  517. break;
  518. case NameLookupRequired:
  519. // is the lookup complete?
  520. if (!gNetAsync.checkLookup(
  521. currentSock->fd, out_h_addr, &out_h_length,
  522. sizeof(out_h_addr)))
  523. break;
  524. notifyEvent.tag = currentSock->fd;
  525. if (out_h_length == -1)
  526. {
  527. Con::errorf("DNS lookup failed: %s", currentSock->remoteAddr);
  528. notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
  529. removeSock = true;
  530. }
  531. else
  532. {
  533. // try to connect
  534. dMemcpy(&(ipAddr.sin_addr.s_addr), out_h_addr, out_h_length);
  535. ipAddr.sin_port = currentSock->remotePort;
  536. ipAddr.sin_family = AF_INET;
  537. if(::connect(currentSock->fd, (struct sockaddr *)&ipAddr,
  538. sizeof(ipAddr)) == -1)
  539. {
  540. if (errno == EINPROGRESS)
  541. {
  542. notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
  543. currentSock->state = ConnectionPending;
  544. }
  545. else
  546. {
  547. Con::errorf("Error connecting to %s: %s",
  548. currentSock->remoteAddr, strerror(errno));
  549. notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
  550. removeSock = true;
  551. }
  552. }
  553. else
  554. {
  555. notifyEvent.state = ConnectedNotifyEvent::Connected;
  556. currentSock->state = Connected;
  557. }
  558. }
  559. Game->postEvent(notifyEvent);
  560. break;
  561. case Listening:
  562. incoming =
  563. Net::accept(currentSock->fd, &acceptEvent.address);
  564. if(incoming != InvalidSocket)
  565. {
  566. acceptEvent.portTag = currentSock->fd;
  567. acceptEvent.connectionTag = incoming;
  568. setBlocking(incoming, false);
  569. addPolledSocket(incoming, Connected);
  570. Game->postEvent(acceptEvent);
  571. }
  572. break;
  573. }
  574. // only increment index if we're not removing the connection, since
  575. // the removal will shift the indices down by one
  576. if (removeSock)
  577. closeConnectTo(currentSock->fd);
  578. else
  579. i++;
  580. }
  581. }
  582. NetSocket Net::openSocket()
  583. {
  584. int retSocket;
  585. retSocket = socket(AF_INET, SOCK_STREAM, 0);
  586. if(retSocket == InvalidSocket)
  587. return InvalidSocket;
  588. else
  589. return retSocket;
  590. }
  591. Net::Error Net::closeSocket(NetSocket socket)
  592. {
  593. if(socket != InvalidSocket)
  594. {
  595. if(!close(socket))
  596. return NoError;
  597. else
  598. return getLastError();
  599. }
  600. else
  601. return NotASocket;
  602. }
  603. Net::Error Net::connect(NetSocket socket, const NetAddress *address)
  604. {
  605. if(address->type != NetAddress::IPAddress)
  606. return WrongProtocolType;
  607. sockaddr_in socketAddress;
  608. netToIPSocketAddress(address, &socketAddress);
  609. if(!::connect(socket, (sockaddr *) &socketAddress, sizeof(socketAddress)))
  610. return NoError;
  611. return getLastError();
  612. }
  613. Net::Error Net::listen(NetSocket socket, S32 backlog)
  614. {
  615. if(!::listen(socket, backlog))
  616. return NoError;
  617. return getLastError();
  618. }
  619. NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
  620. {
  621. sockaddr_in socketAddress;
  622. U32 addrLen = sizeof(socketAddress);
  623. int retVal = ::accept(acceptSocket, (sockaddr *) &socketAddress, &addrLen);
  624. if(retVal != InvalidSocket)
  625. {
  626. IPSocketToNetAddress(&socketAddress, remoteAddress);
  627. return retVal;
  628. }
  629. return InvalidSocket;
  630. }
  631. Net::Error Net::bind(NetSocket socket, U16 port)
  632. {
  633. S32 error;
  634. sockaddr_in socketAddress;
  635. dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
  636. socketAddress.sin_family = AF_INET;
  637. // It's entirely possible that there are two NIC cards.
  638. // We let the user specify which one the server runs on.
  639. // thanks to [TPG]P1aGu3 for the name
  640. const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
  641. // serverIP is guaranteed to be non-0.
  642. AssertFatal( serverIP, "serverIP is NULL!" );
  643. if( serverIP[0] != '\0' ) {
  644. // we're not empty
  645. socketAddress.sin_addr.s_addr = inet_addr( serverIP );
  646. if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
  647. Con::printf( "Binding server port to %s", serverIP );
  648. } else {
  649. Con::warnf( ConsoleLogEntry::General,
  650. "inet_addr() failed for %s while binding!",
  651. serverIP );
  652. socketAddress.sin_addr.s_addr = INADDR_ANY;
  653. }
  654. } else {
  655. Con::printf( "Binding server port to default IP" );
  656. socketAddress.sin_addr.s_addr = INADDR_ANY;
  657. }
  658. socketAddress.sin_port = htons(port);
  659. error = ::bind(socket, (sockaddr *) &socketAddress, sizeof(socketAddress));
  660. if(!error)
  661. return NoError;
  662. return getLastError();
  663. }
  664. Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
  665. {
  666. S32 error;
  667. error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufferSize, sizeof(bufferSize));
  668. if(!error)
  669. error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufferSize, sizeof(bufferSize));
  670. if(!error)
  671. return NoError;
  672. return getLastError();
  673. }
  674. Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
  675. {
  676. S32 bc = broadcast;
  677. S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc));
  678. if(!error)
  679. return NoError;
  680. return getLastError();
  681. }
  682. Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
  683. {
  684. int notblock = !blockingIO;
  685. S32 error = ioctl(socket, FIONBIO, &notblock);
  686. if(!error)
  687. return NoError;
  688. return getLastError();
  689. }
  690. Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
  691. {
  692. // Poll for write status. this blocks. should really
  693. // do this in a separate thread or set it up so that the data can
  694. // get queued and sent later
  695. // JMQTODO
  696. Poll(socket, POLLOUT, 10000);
  697. S32 error = ::send(socket, (const char*)buffer, bufferSize, 0);
  698. if(error != -1)
  699. return NoError;
  700. return getLastError();
  701. }
  702. Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead)
  703. {
  704. *bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
  705. if(*bytesRead == -1)
  706. return getLastError();
  707. return NoError;
  708. }
  709. bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
  710. {
  711. if((a1->type != a2->type) ||
  712. (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
  713. (a1->port != a2->port))
  714. return false;
  715. if(a1->type == NetAddress::IPAddress)
  716. return true;
  717. for(S32 i = 0; i < 6; i++)
  718. if(a1->nodeNum[i] != a2->nodeNum[i])
  719. return false;
  720. return true;
  721. }
  722. bool Net::stringToAddress(const char *addressString, NetAddress *address)
  723. {
  724. if(dStrnicmp(addressString, "ipx:", 4))
  725. {
  726. // assume IP if it doesn't have ipx: at the front.
  727. if(!dStrnicmp(addressString, "ip:", 3))
  728. addressString += 3; // eat off the ip:
  729. sockaddr_in ipAddr;
  730. char remoteAddr[256];
  731. if(strlen(addressString) > 255)
  732. return false;
  733. dStrcpy(remoteAddr, addressString, 256);
  734. char *portString = dStrchr(remoteAddr, ':');
  735. if(portString)
  736. *portString++ = '\0';
  737. struct hostent *hp;
  738. if(!dStricmp(remoteAddr, "broadcast"))
  739. ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  740. else
  741. {
  742. if (inet_aton(remoteAddr,&ipAddr.sin_addr) == 0) // error
  743. {
  744. if((hp = gethostbyname(remoteAddr)) == 0)
  745. return false;
  746. else
  747. memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(in_addr));
  748. }
  749. }
  750. if(portString)
  751. ipAddr.sin_port = htons(dAtoi(portString));
  752. else
  753. ipAddr.sin_port = htons(defaultPort);
  754. ipAddr.sin_family = AF_INET;
  755. IPSocketToNetAddress(&ipAddr, address);
  756. return true;
  757. }
  758. else
  759. {
  760. S32 i;
  761. S32 port;
  762. address->type = NetAddress::IPXAddress;
  763. for(i = 0; i < 6; i++)
  764. address->nodeNum[i] = 0xFF;
  765. // it's an IPX string
  766. addressString += 4;
  767. if(!dStricmp(addressString, "broadcast"))
  768. {
  769. address->port = defaultPort;
  770. return true;
  771. }
  772. else if(sscanf(addressString, "broadcast:%d", &port) == 1)
  773. {
  774. address->port = port;
  775. return true;
  776. }
  777. else
  778. {
  779. S32 nodeNum[6];
  780. S32 netNum[4];
  781. S32 count = dSscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d",
  782. &netNum[0], &netNum[1], &netNum[2], &netNum[3],
  783. &nodeNum[0], &nodeNum[1], &nodeNum[2], &nodeNum[3], &nodeNum[4], &nodeNum[5],
  784. &port);
  785. if(count == 10)
  786. {
  787. port = defaultPort;
  788. count++;
  789. }
  790. if(count != 11)
  791. return false;
  792. for(i = 0; i < 6; i++)
  793. address->nodeNum[i] = nodeNum[i];
  794. for(i = 0; i < 4; i++)
  795. address->netNum[i] = netNum[i];
  796. address->port = port;
  797. return true;
  798. }
  799. }
  800. }
  801. void Net::addressToString(const NetAddress *address, char addressString[256])
  802. {
  803. if(address->type == NetAddress::IPAddress)
  804. {
  805. sockaddr_in ipAddr;
  806. netToIPSocketAddress(address, &ipAddr);
  807. if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
  808. dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
  809. else
  810. dSprintf(addressString, 256, "IP:%s:%d", inet_ntoa(ipAddr.sin_addr),
  811. ntohs(ipAddr.sin_port));
  812. // dSprintf(addressString, 256, "IP:%d:%d", ipAddr.sin_addr.s_addr,
  813. // ntohs(ipAddr.sin_port));
  814. }
  815. else
  816. {
  817. return;
  818. dSprintf(addressString, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
  819. address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3],
  820. address->nodeNum[0], address->nodeNum[1], address->nodeNum[2], address->nodeNum[3], address->nodeNum[4], address->nodeNum[5],
  821. address->port);
  822. }
  823. }
  824. Net::Error getLastError()
  825. {
  826. if (errno == EAGAIN)
  827. return Net::WouldBlock;
  828. return Net::UnknownError;
  829. }
  830. #endif