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.
 
 

246 lines
5.5 KiB

/*
* 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<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;
}
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 peer1("Peer 1", "192.168.1.2", "255.255.255.0", "192.168.1.1");
peer1.setSender(true);
peer1.setSim(this);
peer1.setLogParams(0, GREEN, "\t\t");
Peer peer2("Peer 2", "10.0.0.2", "255.255.255.0", "10.0.0.1");
peer2.setSim(this);
peer2.setLogParams(4, CYAN, "\t\t");
peer1.print("IP 192.168.1.2/24, Gateway: 192.168.1.1");
peer2.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 Peer1 <---> Router 1");
r1.connectNode(&peer1);
sleep(1);
this->print("Plugging Peer2 <---> Router 2");
r2.connectNode(&peer2);
sleep(1);
this->print("Plugging Router 1 <---> Router 2");
r1.connectNode(&r2, true);
sleep(1);
this->print("Plugging Server <---> Router 1");
server.connectNode(&r1);
sleep(1);
this->print("Plugging Server <---> Router 2");
server.connectNode(&r2);
sleep(1);
sleep(1);
this->print("Starting simulation...");
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");
peer1.connectToServer("80.80.90.91", 6565);
peer2.connectToServer("80.80.90.91", 6565);
sleep(1);
this->createThread("p1", NODE_RECV, &peer1);
this->createThread("p2", NODE_RECV, &peer2);
while(1);
}