|
|
- /**
- * @file Simulation.cpp
- *
- * Created on: 16.01.2017
- * @author Piotr Dergun
- */
-
- #include "Simulation.h"
- #include "Node.h"
- #include "NATRouter.h"
- #include "Peer.h"
- #include "P2PServer.h"
-
- Simulation::Simulation()
- {
- srand(time(NULL));
-
- this->rows = 0;
- this->cols = 0;
- #ifndef DEBUG
- // inicjalizacja ncurses
- initscr();
- curs_set(0);
- getmaxyx(stdscr, this->rows, this->cols);
-
- if (has_colors())
- {
- start_color();
- init_pair(0, COLOR_BLACK, COLOR_WHITE);
- init_pair(1, COLOR_RED, COLOR_BLACK);
- init_pair(2, COLOR_GREEN, COLOR_BLACK);
- init_pair(3, COLOR_YELLOW, COLOR_BLACK);
- init_pair(4, COLOR_BLUE, COLOR_BLACK);
- init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
- init_pair(6, COLOR_CYAN, COLOR_BLACK);
- init_pair(7, COLOR_WHITE, COLOR_BLACK);
- }
- #endif
- this->name = "Simulation";
- this->setLineNumber(rows -1);
- this->setDelimiter("\t");
- this->setObjectName(&this->name);
- this->setColor(WHITE);
- this->startTime = time(NULL);
-
- #ifndef DEBUG
- this->createThread("resizeWnd", SIM_RESIZE, this);
- #endif
-
- }
-
- Simulation::~Simulation()
- {
- //niestety nie dziala...
- endwin();
- }
-
- void Simulation::createThread(string name, THREAD_TYPE type, void* context)
- {
- struct threadParams params;
- params.type = type;
- params.context = context;
-
- this->threads.insert(pair<string, struct threadParams>(name, params));
- map<string, struct threadParams>::iterator it = threads.find(name);
-
-
- if (pthread_create(&it->second.thread_id, NULL, Simulation::threadWrapper, &it->second) == -1)
- {
- cerr << "pthread_create() failed" << endl;
- exit(1);
- }
-
- this->threads.insert(pair<string, struct threadParams>(name, params));
- usleep(3000); // 3ms
- }
-
- /*
- * przy niszczeniu watku niszczy sie ncurses :(
- * TODO poszukac rozwiazania w miare mozliwosci
- */
- void Simulation::destroyThread(string name)
- {
- void * state;
- map<string, struct threadParams>::iterator it = threads.find(name);
-
- if (it == threads.end())
- {
- cerr << "Thread: " << name << " does not exist!" << endl;
- exit(1);
- }
-
- if (pthread_cancel(it->second.thread_id) != 0)
- {
- cerr << "pthread_cancel() failed" << endl;
- exit(1);
- }
-
- if (pthread_join(it->second.thread_id, &state) == -1)
- {
- cerr << "pthread_cancel() failed" << endl;
- exit(1);
- }
-
- if (pthread_detach(it->second.thread_id) == -1)
- {
- cerr << "pthread_detach() failed" << endl;
- exit(1);
- }
-
- threads.erase(it);
- }
-
- /*
- * wrapper, w ktory trzeba opakowac metody do zastosowania w watku
- */
-
- void * Simulation::threadWrapper(void * context)
- {
- struct threadParams *params = (struct threadParams*)context;
-
- switch(params->type)
- {
- case NODE_RECV:
- ((Node *)params->context)->onRecv();
- break;
- case SIM_TIMER:
- ((Simulation *)params->context)->timer();
- break;
- case SIM_RESIZE:
- ((Simulation *)params->context)->resizeWnd();
- break;
- case NAT_FP:
- ((NATRouter *)params->context)->freePorts();
- break;
- }
- return 0;
- }
-
- void Simulation::resizeWnd()
- {
- while(true)
- {
- #ifndef DEBUG
- getmaxyx(stdscr, this->rows, this->cols);
- if (this->getLineNumber() != this->rows-1)
- this->setLineNumber(rows -1);
- //refresh();
- #endif
- }
- }
-
- void Simulation::timer()
- {
- #ifndef DEBUG
- char str[10];
- int h,m, s;
- unsigned long timeElapsed;
- pthread_mutex_t *mutex;
- #endif
- while(true)
- {
- #ifndef DEBUG
- refresh();
- timeElapsed = time(NULL) - this->startTime;
- h = timeElapsed / 3600;
- m = (timeElapsed % 3600) / 60;
- s = (timeElapsed % 3600) % 60;
- mutex = Log::getMutex();
- pthread_mutex_lock(mutex);
- sprintf(str, "%02d:%02d:%02d", h, m, s);
- move(0, this->cols-strlen(str));
- printw(str);
- pthread_mutex_unlock(mutex);
- #endif
- usleep(100000); // 100 ms
- //sleep(1);
- }
- }
-
- void Simulation::p2pSimulation()
- {
- this->print("Creating P2P peers");
- Peer seed("Seed", "192.168.1.2", "255.255.255.0", "192.168.1.1");
- seed.setSender(true);
- seed.setSim(this);
- seed.setLogParams(0, GREEN, "\t\t");
- Peer peer("Peer", "10.0.0.2", "255.255.255.0", "10.0.0.1");
- peer.setSim(this);
- peer.setLogParams(4, CYAN, "\t\t");
- seed.print("IP 192.168.1.2/24, Gateway: 192.168.1.1");
- peer.print("IP 10.0.0.2/24, Gateway: 10.0.0.1");
- sleep(1);
-
- this->print("Creating NAT devices");
- NATRouter r1("Router 1", "192.168.1.1", "255.255.255.0");
- NATRouter r2("Router 2", "10.0.0.1", "255.255.255.0");
- r1.setLogParams(1, RED, "\t");
- r2.setLogParams(3, MAGENTA, "\t");
- r1.print("IP 192.168.1.1/24");
- r2.print("IP 10.0.0.1/24");
- sleep(1);
-
- this->print("Setting WAN configuration");
- r1.setWanIp("41.42.43.44");
- r1.setWanMask("255.255.255.255");
- r2.setWanIp("45.46.47.48");
- r2.setWanMask("255.255.255.255");
- r1.print("WAN IP 41.42.43.44/32");
- r2.print("WAN IP 45.46.47.48/32");
- sleep(1);
-
- this->print("Creating P2P server");
- P2PServer server("Server", "80.80.90.91", "255.255.255.255");
- server.setSim(this);
- server.setLogParams(2, YELLOW, "\t\t");
- server.print("IP 80.80.90.91/32");
- sleep(1);
-
- this->print("Plugging Seed <---> Router 1");
- r1.connectNode(&seed);
- usleep(600000);
- this->print("Plugging Peer <---> Router 2");
- r2.connectNode(&peer);
- usleep(600000);
- this->print("Plugging Router 1 <---> Router 2");
- r1.connectNode(&r2, true);
- usleep(600000);
- this->print("Plugging Server <---> Router 1");
- server.connectNode(&r1);
- usleep(600000);
- this->print("Plugging Server <---> Router 2");
- server.connectNode(&r2);
- usleep(600000);
-
- this->print("Starting simulation...");
- sleep(1);
-
- this->createThread("r1", NODE_RECV, &r1);
- this->createThread("r2", NODE_RECV, &r2);
- this->createThread("s1", NODE_RECV, &server);
-
- this->print("Connecting peers to P2P server");
- seed.connectToServer("80.80.90.91", 6565);
- peer.connectToServer("80.80.90.91", 6565);
- sleep(3);
- this->createThread("p1", NODE_RECV, &seed);
- this->createThread("p2", NODE_RECV, &peer);
-
- while(true);
- }
-
- void Simulation::natOverflowSimulation(int nNodes)
- {
- int i = 0, srcPort;
- stringstream ss;
- string hostname;
-
- this->print("Creating server");
- Node server("Server", "93.92.91.90", "255.255.255.255");
- server.setLogParams(0, BLUE, "\t\t");
- server.print("IP 93.92.91.90/32");
- sleep(1);
-
- this->print("Creating NAT device");
- NATRouter router("Router", "10.13.12.254", "255.255.255.0");
- router.setLogParams(1, YELLOW, "\t\t");
- router.setDelay(0);
- router.print("IP 10.13.12.254/24", true);
- sleep(1);
-
- this->print("Setting WAN configuration");
- router.setWanIp("80.55.33.12");
- router.setWanMask("255.255.255.255");
- router.print("WAN IP 80.55.33.12/32", true);
- sleep(1);
-
- this->print("Creating and setting clients");
- Node *client = new Node[nNodes];
- for (i = 0; i < nNodes; ++i)
- {
- client[i].setLogParams(2, CYAN, "\t");
- ss.str("");
- ss << "Client " << (i + 1);
- client[i].setHostname(ss.str());
- ss.str("");
- ss << "10.13.12." << (i + 1);
- client[i].setIp(ss.str());
- client[i].setMask("255.255.255.0");
- client[i].setGatewayIp("10.13.12.254");
- ss.str("");
- ss << "IP 10.13.12." << (i + 1) << "/24, Gateway: 10.13.12.254";
- client[i].print(ss.str());
- usleep(12500);
- }
-
- for (i = 0; i < nNodes; ++i)
- {
- ss.str("");
- ss << "Plugging Client " << (i + 1) << " <---> Router";
- this->print(ss.str());
- router.connectNode(&client[i]);
- usleep(12500);
- }
-
- this->print("Plugging Server <---> Router");
- server.connectNode(&router);
- usleep(600000);
-
- this->print("Starting simulation...");
- sleep(2);
- this->createThread("router", NODE_RECV, &router);
- this->createThread("server", NODE_RECV, &server);
- this->createThread("nat", NAT_FP, &router);
-
- Packet p("test packet");
- p.setDstIp("93.92.91.90");
- p.setDstPort(80);
- i=0;
-
- Log clientLog;
- clientLog.setLogParams(5, MAGENTA, "\t");
- clientLog.setFirstLine(6);
- clientLog.setObjectName(&hostname);
-
- while(true)
- {
- i = (nNodes>1) ? rand()%nNodes : 0;
- ss.str("");
-
- //p.setSrcPort(0);
- srcPort = client[i].send(p);
- hostname = client[i].getHostname();
-
- ss << "Sent " << client[i].getIp() << ":" << srcPort << " to 93.92.91.90:80";
- clientLog.printLine(ss.str());
- this->delay(150);
- //usleep(1);
- }
- }
|