/* * Simulation.cpp * * Created on: 16.01.2017 * Author: piotrek */ #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(); 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(name, params)); map::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(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::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; } 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; #endif while(true) { #ifndef DEBUG refresh(); timeElapsed = time(NULL) - this->startTime; h = timeElapsed / 3600; m = (timeElapsed % 3600) / 60; s = (timeElapsed % 3600) % 60; //refresh(); sprintf(str, "%02d:%02d:%02d", h, m, s); move(0, this->cols-strlen(str)); printw(str); #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; Node *client = new Node[nNodes]; while(true); }