Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Network.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /*!
  2. * \file src/Network.cpp
  3. * \brief Networking Singleton class
  4. *
  5. * \author Mongoose
  6. */
  7. #include <unistd.h>
  8. #include <signal.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #include <sys/time.h>
  12. #include <errno.h>
  13. #include <strings.h>
  14. #include <stdio.h>
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <netdb.h>
  19. #include <arpa/inet.h>
  20. #include <stdlib.h>
  21. #include "utils/math.h" // Random Number
  22. #include "Network.h"
  23. //#define LOCAL_BCAST
  24. #define MAX_CLIENTS 32
  25. typedef struct client_s {
  26. unsigned int uid;
  27. char active;
  28. unsigned int seq;
  29. unsigned int frameExpected;
  30. } client_t;
  31. #include <pthread.h>
  32. pthread_t gPThreadId[3];
  33. unsigned int gUID;
  34. client_t gClients[MAX_CLIENTS];
  35. unsigned int gNumClients = 0;
  36. network_frame_t gPiggyBack;
  37. ////////////////////////////////////////////////////////////
  38. // Constructors
  39. ////////////////////////////////////////////////////////////
  40. Network *Network::mInstance = 0x0;
  41. Network *Network::Instance()
  42. {
  43. if (mInstance == 0x0)
  44. {
  45. mInstance = new Network();
  46. }
  47. return mInstance;
  48. }
  49. void killNetworkSingleton()
  50. {
  51. printf("Shutting down Network...\n");
  52. // Requires public deconstructor
  53. delete Network::Instance();
  54. }
  55. Network::Network()
  56. {
  57. strncpy(mRemoteHost, "localhost", REMOTE_HOST_STR_SZ);
  58. memset(mBindHost, 0, BIND_HOST_STR_SZ);
  59. setPort(8080);
  60. mPiggyBack = true;
  61. mNetworkReliable = true;
  62. mSpawnedClient = false;
  63. mSpawnedServer = false;
  64. mKillClient = false;
  65. mKillServer = false;
  66. mDebug = false;
  67. gUID = getUID();
  68. printf("UID %u\n", gUID);
  69. for (gNumClients = MAX_CLIENTS; gNumClients > 0;)
  70. {
  71. --gNumClients;
  72. gClients[gNumClients].active = 0;
  73. gClients[gNumClients].uid = 0;
  74. gClients[gNumClients].seq = 0;
  75. }
  76. }
  77. Network::~Network()
  78. {
  79. killServerThread();
  80. killClientThread();
  81. }
  82. ////////////////////////////////////////////////////////////
  83. // Public Accessors
  84. ////////////////////////////////////////////////////////////
  85. network_frame_t &Network::getPiggyBack()
  86. {
  87. return gPiggyBack;
  88. }
  89. unsigned int Network::getUID()
  90. {
  91. struct timeval tv;
  92. struct timezone tz;
  93. gettimeofday(&tv, &tz);
  94. srand(tv.tv_usec);
  95. return ((unsigned int)(tv.tv_sec * helRandomNum(2.0f, 3.3f) -
  96. tv.tv_sec * helRandomNum(1.0f, 2.0f)) +
  97. (unsigned int)(tv.tv_usec * helRandomNum(2.0f, 3.3f) -
  98. tv.tv_usec * helRandomNum(1.0f, 2.0f)) +
  99. (unsigned int)helRandomNum(666.0f, 5000.0f));
  100. }
  101. int Network::getPort()
  102. {
  103. return mPort;
  104. }
  105. ////////////////////////////////////////////////////////////
  106. // Public Mutators
  107. ////////////////////////////////////////////////////////////
  108. void *client_thread(void *v)
  109. {
  110. Network &network = *Network::Instance();
  111. network.runClient();
  112. return NULL;
  113. }
  114. void *server_thread(void *v)
  115. {
  116. Network &network = *Network::Instance();
  117. network.runServer();
  118. return NULL;
  119. }
  120. void Network::setBindHost(char *s)
  121. {
  122. if (!s || !s[0])
  123. return;
  124. strncpy(mBindHost, s, BIND_HOST_STR_SZ);
  125. }
  126. void Network::setRemoteHost(char *s)
  127. {
  128. if (!s || !s[0])
  129. return;
  130. strncpy(mRemoteHost, s, REMOTE_HOST_STR_SZ);
  131. }
  132. void Network::setDebug(bool toggle)
  133. {
  134. mDebug = toggle;
  135. }
  136. void Network::setPort(unsigned int port)
  137. {
  138. mPort = port;
  139. }
  140. void Network::killServerThread()
  141. {
  142. mKillServer = true;
  143. // Remember for mutex
  144. // while (mKillServer)
  145. // {
  146. // }
  147. mSpawnedServer = false;
  148. }
  149. void Network::killClientThread()
  150. {
  151. mKillClient = true;
  152. // Remember for mutex
  153. // while (mKillClient)
  154. // {
  155. // }
  156. mSpawnedClient = false;
  157. }
  158. void Network::spawnServerThread()
  159. {
  160. // For now don't handle shutting down server to start client and vv
  161. if (!mSpawnedServer && !mSpawnedClient)
  162. {
  163. pthread_create(gPThreadId + 0, 0, server_thread, NULL);
  164. mSpawnedServer = true;
  165. }
  166. }
  167. void Network::spawnClientThread()
  168. {
  169. // For now don't handle shutting down server to start client and vv
  170. if (!mSpawnedServer && !mSpawnedClient)
  171. {
  172. pthread_create(gPThreadId + 1, 0, client_thread, NULL);
  173. mSpawnedClient = true;
  174. }
  175. }
  176. ////////////////////////////////////////////////////////////
  177. // Protected Mutators
  178. ////////////////////////////////////////////////////////////
  179. int Network::runServer()
  180. {
  181. unsigned int fsize;
  182. int socket_fd, cc, cip;
  183. struct sockaddr_in s_in, from;
  184. char hostid[64];
  185. network_frame_t f;
  186. unsigned int i;
  187. unsigned int packetsRecieved = 0;
  188. socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  189. if (socket_fd < 0)
  190. {
  191. perror("recv_udp:socket");
  192. return -1;
  193. }
  194. if (mBindHost[0])
  195. {
  196. strncpy(hostid, mBindHost, 64);
  197. }
  198. else
  199. {
  200. if (gethostname(hostid, 64) < 0)
  201. {
  202. perror("Server: recv_udp:gethostname");
  203. return -1;
  204. }
  205. printf("Server: gethostname returned '%s'\n", hostid);
  206. fflush(stdout);
  207. }
  208. // Setup for port binding
  209. memset(&s_in, 0, sizeof(s_in));
  210. s_in.sin_family = AF_INET;
  211. #ifdef LOCAL_BCAST
  212. // Replace deprecated gethostbyname() with getaddrinfo()
  213. //struct hostent *hostptr;
  214. //if ((hostptr = gethostbyname(hostid)) == NULL)
  215. //{
  216. // fprintf(stderr, "Server: recv_udp, Invalid host name '%s'\n", hostid);
  217. // return -1;
  218. //}
  219. //memcpy((void *)(&s_in.sin_addr), hostptr->h_addr, hostptr->h_length);
  220. struct addrinfo *result, *res;
  221. bool found = false;
  222. int error = getaddrinfo(hostid, NULL, NULL, &result);
  223. if (error != 0) {
  224. fprintf(stderr, "Server: %s\n", gai_strerror(error));
  225. return -1;
  226. }
  227. for (res = result; res != NULL; res = res->ai_next) {
  228. if (res->ss_family == AF_INET) {
  229. found = true;
  230. memcpy((void *)&s_in, res->ai_addr, res->ai_addrlen);
  231. break; // Found something suitable
  232. }
  233. }
  234. freeaddrinfo(result);
  235. if (!found) {
  236. fprintf(stderr, "Server: Can't bind to %s\n", hostid);
  237. return -1;
  238. }
  239. #else
  240. s_in.sin_addr.s_addr = htonl(INADDR_ANY);
  241. #endif
  242. int port = getPort();
  243. s_in.sin_port = htons(port); // htons new
  244. fflush(stdout);
  245. // Bind
  246. while (bind(socket_fd, (struct sockaddr *)&s_in, sizeof(s_in)) < 0)
  247. {
  248. if (s_in.sin_port++ > (port + 10))
  249. {
  250. perror("Server: recv_udp:bind exhausted");
  251. return -1;
  252. }
  253. }
  254. cip = ntohl(s_in.sin_addr.s_addr);
  255. printf("Server: Started on ( %i.%i.%i.%i:%i )\n",
  256. cip >> 24, cip << 8 >> 24,
  257. cip << 16 >> 24, cip << 24 >> 24, s_in.sin_port);
  258. for (; !mKillClient;)
  259. {
  260. fsize = sizeof(from);
  261. // 1. Wait for event
  262. // 2. Get inbound frame
  263. cc = recvfrom(socket_fd, &f, sizeof(network_frame_t), 0,
  264. (struct sockaddr *)&from, &fsize);
  265. if (cc < 0)
  266. {
  267. perror("Server: recv_udp:recvfrom");
  268. continue;
  269. }
  270. ++packetsRecieved;
  271. if (mDebug)
  272. {
  273. printf("=====================================================\n");
  274. printf("Packet %u\n", packetsRecieved);
  275. printf("Server: Recieved packet from %u\n",
  276. f.uid);
  277. }
  278. // A. Look and see if this client has connected before
  279. for (i = 0; i < gNumClients; ++i)
  280. {
  281. if (gClients[i].uid == f.uid)
  282. {
  283. break;
  284. }
  285. }
  286. // B. Collect client data if it's a new connection
  287. if (!gClients[i].active)
  288. {
  289. for (i = 0; i < gNumClients+1; ++i)
  290. {
  291. if ((i + 1) < MAX_CLIENTS && !gClients[i].active)
  292. {
  293. gClients[i].uid = f.uid;
  294. gClients[i].active = 1;
  295. gClients[i].frameExpected = 0;
  296. ++gNumClients;
  297. printf("Server: %u made connection, as client %u\n",
  298. gClients[i].uid, i);
  299. break;
  300. }
  301. }
  302. if (i == MAX_CLIENTS || !gClients[i].active)
  303. {
  304. if (mDebug)
  305. {
  306. printf("Server: Handshake packet from %u failed?\n",
  307. f.uid);
  308. }
  309. continue;
  310. }
  311. }
  312. cip = ntohl(from.sin_addr.s_addr);
  313. if (mDebug)
  314. {
  315. printf("Server: Client (Famliy %d, Address %i.%i.%i.%i:%d)\n",
  316. ntohs(from.sin_family), cip >> 24, cip << 8 >> 24,
  317. cip << 16 >> 24, cip << 24 >> 24,
  318. ntohs(from.sin_port));
  319. printf("Server: Datalink layer recieved: packet seq %u\n",
  320. f.seq);
  321. }
  322. if (mNetworkReliable)
  323. {
  324. if (f.seq == gClients[i].seq)
  325. {
  326. if (mDebug)
  327. {
  328. printf("SERVER> Msg from %u\n", f.uid);
  329. }
  330. to_network_layer(f.data);
  331. gClients[i].seq = f.seq;
  332. }
  333. else
  334. {
  335. continue;
  336. }
  337. }
  338. //! \fixme Combine with above, duh
  339. // 3. Send to network layer
  340. if (gClients[i].frameExpected == f.header)
  341. {
  342. f.data.cid = i;
  343. to_network_layer(f.data);
  344. gClients[i].frameExpected = !gClients[i].frameExpected;
  345. }
  346. fflush(stdout);
  347. #ifdef UNIT_TEST
  348. if ((rand() % 10 == 0))
  349. {
  350. printf("Server: Simulating a lost ack %u\n", f.seq);
  351. continue;
  352. }
  353. #endif
  354. // 4. Send ACK, w/ piggyback if requested
  355. if (mPiggyBack)
  356. {
  357. gPiggyBack.header = 0;
  358. gPiggyBack.seq = f.seq;
  359. gPiggyBack.uid = gUID;
  360. if (mDebug)
  361. {
  362. printf("SERVER> Sending data by piggyback\n");
  363. }
  364. cc = sendto(socket_fd, &gPiggyBack, sizeof(gPiggyBack), 0,
  365. (struct sockaddr *)&from, sizeof(from));
  366. }
  367. else
  368. {
  369. f.header = 0;
  370. f.seq = 0;
  371. f.uid = gUID;
  372. cc = sendto(socket_fd, &f, sizeof(f), 0,
  373. (struct sockaddr *)&from, sizeof(from));
  374. }
  375. if (cc < 0)
  376. {
  377. perror("Server: send_udp:sendto");
  378. }
  379. else
  380. {
  381. if (mDebug)
  382. {
  383. printf("Server: Ack sent to %u\n", gClients[i].uid);
  384. }
  385. }
  386. }
  387. mKillClient = false;
  388. return 0;
  389. }
  390. void Network::runClient()
  391. {
  392. unsigned int fsize, last_frame_sent = 0;
  393. int socket_fd, cc, done;
  394. struct sockaddr_in dest;
  395. struct addrinfo *addr;
  396. network_frame_t f;
  397. struct timeval timeout;
  398. fd_set readfds;
  399. unsigned int packetsSent = 0;
  400. unsigned int seq = 0;
  401. char timedOut = 1;
  402. if (!mRemoteHost || !mRemoteHost[0])
  403. {
  404. return;
  405. }
  406. memset((char*) &timeout, 0, sizeof(timeout));
  407. timeout.tv_sec = 5;
  408. socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
  409. if (socket_fd == -1)
  410. {
  411. perror("Client: send_udp: socket");
  412. exit(0);
  413. }
  414. //if ((hostptr = gethostbyname(mRemoteHost)) == NULL)
  415. //{
  416. // fprintf(stderr, "Client: send_udp: invalid host name, %s\n",
  417. // mRemoteHost);
  418. // exit(0);
  419. //}
  420. int error = getaddrinfo(mRemoteHost, NULL, NULL, &addr);
  421. if (error != 0) {
  422. fprintf(stderr, "Client: %s\n", gai_strerror(error));
  423. exit(0);
  424. }
  425. // Setup connection
  426. memset(&dest, 0, sizeof(dest));
  427. dest.sin_family = AF_INET;
  428. int port = getPort();
  429. dest.sin_port = htons(port);
  430. #ifdef LOCAL_BCAST
  431. //memcpy(hostptr->h_addr, (char *) &dest.sin_addr, hostptr->h_length);
  432. bool found = false;
  433. for (struct addrinfo *res = addr; res != NULL; res = res->ai_next) {
  434. if (res->ss_family == AF_INET) {
  435. found = true;
  436. memcpy((void *)&dest.sin_addr, res->ai_addr.sin_addr, sizeof(res->ai_addr.sin_addr));
  437. break; // Found something suitable
  438. }
  439. }
  440. freeaddrinfo(addr);
  441. if (!found) {
  442. fprintf(stderr, "Client: Can't connect to %s\n", hostid);
  443. return;
  444. }
  445. #else
  446. if (inet_pton(AF_INET, mRemoteHost, &dest.sin_addr) < 0)
  447. {
  448. perror("inet_pton");
  449. return;
  450. }
  451. #endif
  452. // init
  453. f.data.send = 0;
  454. f.seq = 0;
  455. for (; !mKillServer;)
  456. {
  457. ++packetsSent;
  458. if (mDebug)
  459. {
  460. printf("=====================================================\n");
  461. printf("Packet %u\n", packetsSent);
  462. }
  463. // 1. Get packet to send over wire
  464. if (mNetworkReliable && timedOut && f.seq != seq)
  465. {
  466. if (mDebug)
  467. {
  468. printf("Client: Resending packet\n");
  469. }
  470. }
  471. else
  472. {
  473. from_network_layer(&f.data, &last_frame_sent);
  474. if (!f.data.send)
  475. {
  476. struct timespec tmp;
  477. tmp.tv_sec = 0;
  478. tmp.tv_nsec = 20000;
  479. nanosleep(&tmp, NULL);
  480. continue;
  481. }
  482. }
  483. // 2. Copy to frame
  484. f.seq = 0;//seq; // 0 forces all packets to check out
  485. f.uid = gUID;
  486. // 3. Send over the wire
  487. done = 0;
  488. timedOut = 0;
  489. while (!done)
  490. {
  491. if (mDebug)
  492. {
  493. printf("Client: Sending packet %u\n", f.seq);
  494. }
  495. cc = sendto(socket_fd, &f, sizeof(f), 0,
  496. (struct sockaddr *)&dest, sizeof(dest));
  497. if (cc < 0)
  498. {
  499. perror("Client: send_udp:sendto");
  500. if (errno == EMSGSIZE)
  501. {
  502. printf("Client: packet was too large\n");
  503. }
  504. }
  505. else
  506. {
  507. f.data.send = 0;
  508. }
  509. // Comment out this to enable more reliable service
  510. done = 1;
  511. }
  512. // 4. Wait for +ack or resend
  513. FD_ZERO(&readfds);
  514. // Setup socket to listen on here
  515. FD_SET(socket_fd, &readfds);
  516. // Set timeout in milliseconds
  517. timeout.tv_usec = 850;
  518. cc = select(socket_fd + 1, &readfds, NULL, NULL, &timeout);
  519. if ((cc < 0) && (errno != EINTR))
  520. {
  521. // there was an local error with select
  522. }
  523. if (cc == 0)
  524. {
  525. if (mDebug)
  526. {
  527. printf("Client: Timeout detected on packet %u\n", f.seq);
  528. }
  529. timedOut = 1;
  530. continue;
  531. }
  532. // Clear header for recv use
  533. f.header = 0;
  534. fsize = sizeof(dest);
  535. cc = recvfrom(socket_fd, &f, sizeof(f), 0,
  536. (struct sockaddr *)&dest, &fsize);
  537. if (cc < 0)
  538. {
  539. perror("Client: recv_udp:recvfrom");
  540. }
  541. else
  542. {
  543. if (mDebug)
  544. {
  545. printf("Client: Datalink layer recieved: packet seq %u\n", f.seq);
  546. printf("CLIENT> Msg from %u\n", f.uid);
  547. }
  548. to_network_layer(f.data);
  549. }
  550. if (seq == f.seq)
  551. {
  552. if (mDebug)
  553. {
  554. printf("Client: Recieved ack %u\n", f.seq);
  555. }
  556. ++seq;
  557. }
  558. }
  559. mKillServer = false;
  560. }