x86UNIXNet.cc 28 KB

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