Symulacja NAT na przedmiot Symulacje Komputerowe
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.

232 lines
5.2 KiB

  1. /*
  2. * Simulation.cpp
  3. *
  4. * Created on: 16.01.2017
  5. * Author: piotrek
  6. */
  7. #include "Simulation.h"
  8. #include "Node.h"
  9. #include "NATRouter.h"
  10. #include "Peer.h"
  11. Simulation::Simulation()
  12. {
  13. this->rows = 0;
  14. this->cols = 0;
  15. #ifndef DEBUG
  16. // inicjalizacja ncurses
  17. initscr();
  18. getmaxyx(stdscr, this->rows, this->cols);
  19. if (has_colors())
  20. {
  21. start_color();
  22. init_pair(0, COLOR_BLACK, COLOR_WHITE);
  23. init_pair(1, COLOR_RED, COLOR_BLACK);
  24. init_pair(2, COLOR_GREEN, COLOR_BLACK);
  25. init_pair(3, COLOR_YELLOW, COLOR_BLACK);
  26. init_pair(4, COLOR_BLUE, COLOR_BLACK);
  27. init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
  28. init_pair(6, COLOR_CYAN, COLOR_BLACK);
  29. init_pair(7, COLOR_WHITE, COLOR_BLACK);
  30. }
  31. #endif
  32. this->name = "Simulation";
  33. this->setLineNumber(rows -1);
  34. this->setDelimiter("\t");
  35. this->setObjectName(&this->name);
  36. this->setColor(WHITE);
  37. this->startTime = time(NULL);
  38. #ifndef DEBUG
  39. this->createThread("resizeWnd", SIM_RESIZE, this);
  40. #endif
  41. }
  42. Simulation::~Simulation()
  43. {
  44. //niestety nie dziala...
  45. endwin();
  46. }
  47. void Simulation::createThread(string name, THREAD_TYPE type, void* context)
  48. {
  49. struct threadParams params;
  50. params.type = type;
  51. params.context = context;
  52. this->threads.insert(pair<string, struct threadParams>(name, params));
  53. map<string, struct threadParams>::iterator it = threads.find(name);
  54. if (pthread_create(&it->second.thread_id, NULL, Simulation::threadWrapper, &it->second) == -1)
  55. {
  56. cerr << "pthread_create() failed" << endl;
  57. exit(1);
  58. }
  59. this->threads.insert(pair<string, struct threadParams>(name, params));
  60. usleep(3000); // 3ms
  61. }
  62. /*
  63. * przy niszczeniu watku niszczy sie ncurses :(
  64. * TODO poszukac rozwiazania w miare mozliwosci
  65. */
  66. void Simulation::destroyThread(string name)
  67. {
  68. void * state;
  69. map<string, struct threadParams>::iterator it = threads.find(name);
  70. if (it == threads.end())
  71. {
  72. cerr << "Thread: " << name << " does not exist!" << endl;
  73. exit(1);
  74. }
  75. if (pthread_cancel(it->second.thread_id) != 0)
  76. {
  77. cerr << "pthread_cancel() failed" << endl;
  78. exit(1);
  79. }
  80. if (pthread_join(it->second.thread_id, &state) == -1)
  81. {
  82. cerr << "pthread_cancel() failed" << endl;
  83. exit(1);
  84. }
  85. if (pthread_detach(it->second.thread_id) == -1)
  86. {
  87. cerr << "pthread_detach() failed" << endl;
  88. exit(1);
  89. }
  90. threads.erase(it);
  91. }
  92. /*
  93. * wrapper, w ktory trzeba opakowac metody do zastosowania w watku
  94. */
  95. void * Simulation::threadWrapper(void * context)
  96. {
  97. struct threadParams *params = (struct threadParams*)context;
  98. switch(params->type)
  99. {
  100. case NODE_RECV:
  101. ((Node *)params->context)->onRecv();
  102. break;
  103. case SIM_TIMER:
  104. ((Simulation *)params->context)->timer();
  105. break;
  106. case SIM_RESIZE:
  107. ((Simulation *)params->context)->resizeWnd();
  108. break;
  109. }
  110. return 0;
  111. }
  112. void Simulation::resizeWnd()
  113. {
  114. while(true)
  115. {
  116. #ifndef DEBUG
  117. getmaxyx(stdscr, this->rows, this->cols);
  118. if (this->getLineNumber() != this->rows-1)
  119. this->setLineNumber(rows -1);
  120. //refresh();
  121. #endif
  122. }
  123. }
  124. void Simulation::timer()
  125. {
  126. char str[10];
  127. int h,m, s;
  128. unsigned long timeElapsed;
  129. while(true)
  130. {
  131. refresh();
  132. timeElapsed = time(NULL) - this->startTime;
  133. h = timeElapsed / 3600;
  134. m = (timeElapsed % 3600) / 60;
  135. s = (timeElapsed % 3600) % 60;
  136. //refresh();
  137. sprintf(str, "%02d:%02d:%02d", h, m, s);
  138. move(0, this->cols-strlen(str));
  139. printw(str);
  140. usleep(100000); // 100 ms
  141. //sleep(1);
  142. }
  143. }
  144. void Simulation::p2pSimulation()
  145. {
  146. this->print("Creating P2P peers");
  147. Peer peer1("Peer 1", "192.168.1.2", "255.255.255.0", "192.168.1.1");
  148. peer1.setLogParams(0, GREEN, "\t\t");
  149. Peer peer2("Peer 2", "10.0.0.2", "255.255.255.0", "10.0.0.1");
  150. peer2.setLogParams(4, CYAN, "\t\t");
  151. peer1.print("IP 192.168.1.2/24, Gateway: 192.168.1.1");
  152. peer2.print("IP 10.0.0.2/24, Gateway: 10.0.0.1");
  153. sleep(1);
  154. this->print("Creating NAT devices");
  155. NATRouter r1("Router 1", "192.168.1.1", "255.255.255.0");
  156. NATRouter r2("Router 2", "10.0.0.1", "255.255.255.0");
  157. r1.setLogParams(1, RED, "\t");
  158. r2.setLogParams(3, MAGENTA, "\t");
  159. r1.print("IP 192.168.1.1/24");
  160. r2.print("IP 10.0.0.1/24");
  161. sleep(1);
  162. this->print("Setting WAN configuration");
  163. r1.setWanIp("41.42.43.44");
  164. r1.setWanMask("255.255.255.255");
  165. r2.setWanIp("45.46.47.48");
  166. r2.setWanMask("255.255.255.255");
  167. r1.print("WAN IP 41.42.43.44/32");
  168. r2.print("WAN IP 45.46.47.48/32");
  169. sleep(1);
  170. this->print("Creating P2P server");
  171. Node server("Server", "80.80.90.91", "255.255.255.255");
  172. server.setLogParams(2, YELLOW, "\t\t");
  173. server.print("IP 80.80.90.91/32");
  174. sleep(1);
  175. this->print("Plugging Peer1 <---> Router 1");
  176. r1.connectNode(&peer1);
  177. sleep(1);
  178. this->print("Plugging Peer2 <---> Router 2");
  179. r2.connectNode(&peer2);
  180. sleep(1);
  181. this->print("Plugging Router 1 <---> Router 2");
  182. r1.connectNode(&r2, true);
  183. sleep(1);
  184. this->print("Plugging Server <---> Router 1");
  185. server.connectNode(&r1);
  186. sleep(1);
  187. this->print("Plugging Server <---> Router 2");
  188. server.connectNode(&r2);
  189. sleep(1);
  190. sleep(1);
  191. this->print("Starting simulation...");
  192. this->createThread("r1", NODE_RECV, &r1);
  193. this->createThread("r2", NODE_RECV, &r2);
  194. this->createThread("s1", NODE_RECV, &server);
  195. this->createThread("p2", NODE_RECV, &peer2);
  196. peer1.connectToServer("80.80.90.91", 6565);
  197. sleep(1);
  198. this->createThread("p1", NODE_RECV, &peer1);
  199. while(1);
  200. }