AndroidNet.cpp 26 KB

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