Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }