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.

332 lines
7.5 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. #include "P2PServer.h"
  12. Simulation::Simulation()
  13. {
  14. srand(time(NULL));
  15. this->rows = 0;
  16. this->cols = 0;
  17. #ifndef DEBUG
  18. // inicjalizacja ncurses
  19. initscr();
  20. getmaxyx(stdscr, this->rows, this->cols);
  21. if (has_colors())
  22. {
  23. start_color();
  24. init_pair(0, COLOR_BLACK, COLOR_WHITE);
  25. init_pair(1, COLOR_RED, COLOR_BLACK);
  26. init_pair(2, COLOR_GREEN, COLOR_BLACK);
  27. init_pair(3, COLOR_YELLOW, COLOR_BLACK);
  28. init_pair(4, COLOR_BLUE, COLOR_BLACK);
  29. init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
  30. init_pair(6, COLOR_CYAN, COLOR_BLACK);
  31. init_pair(7, COLOR_WHITE, COLOR_BLACK);
  32. }
  33. #endif
  34. this->name = "Simulation";
  35. this->setLineNumber(rows -1);
  36. this->setDelimiter("\t");
  37. this->setObjectName(&this->name);
  38. this->setColor(WHITE);
  39. this->startTime = time(NULL);
  40. #ifndef DEBUG
  41. this->createThread("resizeWnd", SIM_RESIZE, this);
  42. #endif
  43. }
  44. Simulation::~Simulation()
  45. {
  46. //niestety nie dziala...
  47. endwin();
  48. }
  49. void Simulation::createThread(string name, THREAD_TYPE type, void* context)
  50. {
  51. struct threadParams params;
  52. params.type = type;
  53. params.context = context;
  54. this->threads.insert(pair<string, struct threadParams>(name, params));
  55. map<string, struct threadParams>::iterator it = threads.find(name);
  56. if (pthread_create(&it->second.thread_id, NULL, Simulation::threadWrapper, &it->second) == -1)
  57. {
  58. cerr << "pthread_create() failed" << endl;
  59. exit(1);
  60. }
  61. this->threads.insert(pair<string, struct threadParams>(name, params));
  62. usleep(3000); // 3ms
  63. }
  64. /*
  65. * przy niszczeniu watku niszczy sie ncurses :(
  66. * TODO poszukac rozwiazania w miare mozliwosci
  67. */
  68. void Simulation::destroyThread(string name)
  69. {
  70. void * state;
  71. map<string, struct threadParams>::iterator it = threads.find(name);
  72. if (it == threads.end())
  73. {
  74. cerr << "Thread: " << name << " does not exist!" << endl;
  75. exit(1);
  76. }
  77. if (pthread_cancel(it->second.thread_id) != 0)
  78. {
  79. cerr << "pthread_cancel() failed" << endl;
  80. exit(1);
  81. }
  82. if (pthread_join(it->second.thread_id, &state) == -1)
  83. {
  84. cerr << "pthread_cancel() failed" << endl;
  85. exit(1);
  86. }
  87. if (pthread_detach(it->second.thread_id) == -1)
  88. {
  89. cerr << "pthread_detach() failed" << endl;
  90. exit(1);
  91. }
  92. threads.erase(it);
  93. }
  94. /*
  95. * wrapper, w ktory trzeba opakowac metody do zastosowania w watku
  96. */
  97. void * Simulation::threadWrapper(void * context)
  98. {
  99. struct threadParams *params = (struct threadParams*)context;
  100. switch(params->type)
  101. {
  102. case NODE_RECV:
  103. ((Node *)params->context)->onRecv();
  104. break;
  105. case SIM_TIMER:
  106. ((Simulation *)params->context)->timer();
  107. break;
  108. case SIM_RESIZE:
  109. ((Simulation *)params->context)->resizeWnd();
  110. break;
  111. case NAT_FP:
  112. ((NATRouter *)params->context)->freePorts();
  113. break;
  114. }
  115. return 0;
  116. }
  117. void Simulation::resizeWnd()
  118. {
  119. while(true)
  120. {
  121. #ifndef DEBUG
  122. getmaxyx(stdscr, this->rows, this->cols);
  123. if (this->getLineNumber() != this->rows-1)
  124. this->setLineNumber(rows -1);
  125. //refresh();
  126. #endif
  127. }
  128. }
  129. void Simulation::timer()
  130. {
  131. #ifndef DEBUG
  132. char str[10];
  133. int h,m, s;
  134. unsigned long timeElapsed;
  135. #endif
  136. while(true)
  137. {
  138. #ifndef DEBUG
  139. refresh();
  140. timeElapsed = time(NULL) - this->startTime;
  141. h = timeElapsed / 3600;
  142. m = (timeElapsed % 3600) / 60;
  143. s = (timeElapsed % 3600) % 60;
  144. //refresh();
  145. sprintf(str, "%02d:%02d:%02d", h, m, s);
  146. move(0, this->cols-strlen(str));
  147. printw(str);
  148. #endif
  149. usleep(100000); // 100 ms
  150. //sleep(1);
  151. }
  152. }
  153. void Simulation::p2pSimulation()
  154. {
  155. this->print("Creating P2P peers");
  156. Peer seed("Seed", "192.168.1.2", "255.255.255.0", "192.168.1.1");
  157. seed.setSender(true);
  158. seed.setSim(this);
  159. seed.setLogParams(0, GREEN, "\t\t");
  160. Peer peer("Peer", "10.0.0.2", "255.255.255.0", "10.0.0.1");
  161. peer.setSim(this);
  162. peer.setLogParams(4, CYAN, "\t\t");
  163. seed.print("IP 192.168.1.2/24, Gateway: 192.168.1.1");
  164. peer.print("IP 10.0.0.2/24, Gateway: 10.0.0.1");
  165. sleep(1);
  166. this->print("Creating NAT devices");
  167. NATRouter r1("Router 1", "192.168.1.1", "255.255.255.0");
  168. NATRouter r2("Router 2", "10.0.0.1", "255.255.255.0");
  169. r1.setLogParams(1, RED, "\t");
  170. r2.setLogParams(3, MAGENTA, "\t");
  171. r1.print("IP 192.168.1.1/24");
  172. r2.print("IP 10.0.0.1/24");
  173. sleep(1);
  174. this->print("Setting WAN configuration");
  175. r1.setWanIp("41.42.43.44");
  176. r1.setWanMask("255.255.255.255");
  177. r2.setWanIp("45.46.47.48");
  178. r2.setWanMask("255.255.255.255");
  179. r1.print("WAN IP 41.42.43.44/32");
  180. r2.print("WAN IP 45.46.47.48/32");
  181. sleep(1);
  182. this->print("Creating P2P server");
  183. P2PServer server("Server", "80.80.90.91", "255.255.255.255");
  184. server.setSim(this);
  185. server.setLogParams(2, YELLOW, "\t\t");
  186. server.print("IP 80.80.90.91/32");
  187. sleep(1);
  188. this->print("Plugging Seed <---> Router 1");
  189. r1.connectNode(&seed);
  190. usleep(600000);
  191. this->print("Plugging Peer <---> Router 2");
  192. r2.connectNode(&peer);
  193. usleep(600000);
  194. this->print("Plugging Router 1 <---> Router 2");
  195. r1.connectNode(&r2, true);
  196. usleep(600000);
  197. this->print("Plugging Server <---> Router 1");
  198. server.connectNode(&r1);
  199. usleep(600000);
  200. this->print("Plugging Server <---> Router 2");
  201. server.connectNode(&r2);
  202. usleep(600000);
  203. this->print("Starting simulation...");
  204. sleep(1);
  205. this->createThread("r1", NODE_RECV, &r1);
  206. this->createThread("r2", NODE_RECV, &r2);
  207. this->createThread("s1", NODE_RECV, &server);
  208. this->print("Connecting peers to P2P server");
  209. seed.connectToServer("80.80.90.91", 6565);
  210. peer.connectToServer("80.80.90.91", 6565);
  211. sleep(3);
  212. this->createThread("p1", NODE_RECV, &seed);
  213. this->createThread("p2", NODE_RECV, &peer);
  214. this->createThread("nat", NAT_FP, &r1);
  215. while(true);
  216. }
  217. void Simulation::natOverflowSimulation(int nNodes)
  218. {
  219. int i = 0, srcPort;
  220. stringstream ss;
  221. this->print("Creating NAT device");
  222. NATRouter router("Router", "10.13.12.254", "255.255.255.0");
  223. router.setLogParams(1, YELLOW, "\t\t");
  224. router.setDelay(0);
  225. router.print("IP 10.13.12.254/24", true);
  226. sleep(1);
  227. this->print("Setting WAN configuration");
  228. router.setWanIp("80.55.33.12");
  229. router.setWanMask("255.255.255.255");
  230. router.print("WAN IP 80.55.33.12/32", true);
  231. sleep(1);
  232. this->print("Creating server");
  233. Node server("Server", "93.92.91.90", "255.255.255.255");
  234. server.setLogParams(2, BLUE, "\t\t");
  235. server.print("IP 93.92.91.90/32");
  236. sleep(1);
  237. this->print("Creating and setting clients");
  238. Node *client = new Node[nNodes];
  239. int *currentSrcPort = new int[nNodes];
  240. for (i = 0; i < nNodes; ++i)
  241. {
  242. currentSrcPort[i] = 0;
  243. client[i].setLogParams(0, CYAN, "\t");
  244. ss.str("");
  245. ss << "Client " << (i + 1);
  246. client[i].setHostname(ss.str());
  247. ss.str("");
  248. ss << "10.13.12." << (i + 1);
  249. client[i].setIp(ss.str());
  250. client[i].setMask("255.255.255.0");
  251. client[i].setGatewayIp("10.13.12.254");
  252. ss.str("");
  253. ss << "IP 10.13.12." << (i + 1) << "/24, Gateway: 10.0.0.1";
  254. client[i].print(ss.str());
  255. usleep(12500);
  256. }
  257. for (i = 0; i < nNodes; ++i)
  258. {
  259. ss.str("");
  260. ss << "Plugging Client " << (i + 1) << " <---> Router";
  261. this->print(ss.str());
  262. router.connectNode(&client[i]);
  263. usleep(12500);
  264. }
  265. this->print("Plugging Server <---> Router");
  266. server.connectNode(&router);
  267. usleep(600000);
  268. this->print("Starting simulation...");
  269. sleep(2);
  270. this->createThread("router", NODE_RECV, &router);
  271. this->createThread("server", NODE_RECV, &server);
  272. this->createThread("nat", NAT_FP, &router);
  273. Packet p("test packet");
  274. p.setDstIp("93.92.91.90");
  275. p.setDstPort(80);
  276. i=0;
  277. struct timespec ts, ts2;
  278. ts.tv_sec = 0;
  279. ts.tv_nsec = 100;
  280. while(true)
  281. {
  282. if (i==65535)
  283. i=1;
  284. p.setSrcPort(i++);
  285. client[0].send(p);
  286. //this->delay(10);
  287. //usleep(1);
  288. nanosleep(&ts, &ts2);
  289. }
  290. }