From 914b34070e89b578eeba99bd89d76655a375c839 Mon Sep 17 00:00:00 2001 From: PioDer Date: Tue, 17 Jan 2017 15:31:00 +0100 Subject: [PATCH] przebijanie NAT working 100% --- Log.cpp | 17 ++++++ Log.h | 2 + Makefile | 2 +- NATRouter.cpp | 16 +++++- Node.cpp | 24 +++++++-- Node.h | 4 +- P2PServer.cpp | 79 ++++++++++++++++++++++++++++ P2PServer.h | 26 ++++++++++ Peer.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++++++ Peer.h | 37 +++++++++++++ Simulation.cpp | 14 ++++- common.h | 2 +- 12 files changed, 350 insertions(+), 10 deletions(-) create mode 100644 P2PServer.cpp create mode 100644 P2PServer.h create mode 100644 Peer.cpp create mode 100644 Peer.h diff --git a/Log.cpp b/Log.cpp index af6e1eb..882d5d1 100644 --- a/Log.cpp +++ b/Log.cpp @@ -13,6 +13,8 @@ Log::Log() this->delimiter = ""; this->lineNumber = 0; this->objectName = NULL; + + this->writeMutex = Log::getMutex(); } LOG_COLOR Log::getColor() const @@ -61,6 +63,7 @@ void Log::print(string msg) if (this->getObjectName() == NULL) return; + pthread_mutex_lock(this->writeMutex); move(this->getLineNumber(), 0); clrtoeol(); @@ -73,6 +76,8 @@ void Log::print(string msg) attroff(COLOR_PAIR(this->getColor())); move(0, 0); + pthread_mutex_unlock(this->writeMutex); + #else cout << this->getObjectName()->c_str() << ": " << this->getDelimiter() << msg << endl; #endif @@ -84,3 +89,15 @@ void Log::setLogParams(int lineNumber, LOG_COLOR color, string delimiter) this->setColor(color); this->setDelimiter(delimiter); } + +pthread_mutex_t* Log::getMutex() +{ + static pthread_mutex_t m; + static int mutex_initalized; + if (mutex_initalized != 0) + { + pthread_mutex_init(&m, NULL); + } + + return &m; +} diff --git a/Log.h b/Log.h index 0cfc8e8..f9a1cc9 100644 --- a/Log.h +++ b/Log.h @@ -27,6 +27,7 @@ class Log LOG_COLOR color; string delimiter; string *objectName; + pthread_mutex_t *writeMutex; protected: string* getObjectName() const; void setObjectName(string* objectName); @@ -41,6 +42,7 @@ public: int getLineNumber() const; void setLineNumber(int lineNumber); void setLogParams(int lineNumber, LOG_COLOR color, string delimiter); + static pthread_mutex_t * getMutex(); }; #endif /* LOG_H_ */ diff --git a/Makefile b/Makefile index c2798ce..27d4892 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CXX = g++ CXXFLAGS = -Wall -std=c++11 LDFLAGS = -pthread -lncurses -OBJ = Log.o Packet.o Node.o NATItem.o NATRouter.o Peer.o Simulation.o +OBJ = Log.o Packet.o Node.o NATItem.o NATRouter.o Peer.o P2PServer.o Simulation.o all: +@make simulation diff --git a/NATRouter.cpp b/NATRouter.cpp index 47a008d..0b094aa 100644 --- a/NATRouter.cpp +++ b/NATRouter.cpp @@ -62,6 +62,10 @@ void NATRouter::onRecv() Packet p = this->recv(); stringstream s; + /*if (this->getHostname() == "Router 2") { + s << "src: " << p.getSrcIp() << ":" << p.getSrcPort() << "dst: " << p.getDstIp() << ":" << p.getDstPort(); + this->print(s.str()); + }*/ if (p.getSrcPort() != 0) { // jezeli pakiet idzie z jednego wezla do drugiego w danej possieci to odeslij mu "jak switch" @@ -87,7 +91,10 @@ void NATRouter::onRecv() } else { +#ifndef DEBUG + this->print("onRecv() sleeping..."); +#endif } sleep(1); @@ -148,7 +155,7 @@ void NATRouter::sNAT(Packet *packet) natItem = &this->natTable[port]; natItem->setIp(packet->getSrcIp()); natItem->setPort(packet->getSrcPort()); - natItem->setTimeout(5); + natItem->setTimeout(/*5*/10); stringstream ss; ss << "SNAT " << packet->getSrcIp() << ":" << packet->getSrcPort() << " --> " << this->getWanIp() << ":" << port; @@ -157,7 +164,7 @@ void NATRouter::sNAT(Packet *packet) packet->setSrcPort(port); // zamieniam port lokalny na WAN'owy - z tablicy NAT this->print(ss.str()); - + sleep(1); this->send(*packet, true); // wysylam dalej natItem = NULL; } @@ -172,11 +179,16 @@ void NATRouter::dNAT(Packet* packet) { NATItem *natItem = &this->natTable[packet->getDstPort()]; + stringstream ss; + ss << "DNAT " << packet->getDstIp() << ":" << packet->getDstPort() << " --> " << natItem->getIp() << ":" << natItem->getPort(); + packet->setDstIp(natItem->getIp()); // zamieniam IP lokalne na WAN'owe packet->setDstPort(natItem->getPort()); // zamieniam port NAT na lokalny wezla //natItem->free(); // zwalniam port w routerze natItem->increaseTimeout(5); // podbijam o kolejne 5 sekund skoro transmisja trwa + this->print(ss.str()); + sleep(1); this->send(*packet, true); // wysylam dalej natItem = NULL; diff --git a/Node.cpp b/Node.cpp index 7443b59..6062962 100644 --- a/Node.cpp +++ b/Node.cpp @@ -152,7 +152,7 @@ bool Node::connectNode(Node *node, bool isExternal, bool firstConnected) * funkcja wysyla, czyli przekazuje kopie pakietu kolejnemu wezlowi - docelowemu lub bramie domyslnej * o ile jest skonfigurowana i istnieje do niej sciezka */ -bool Node::send(Packet packet, bool isRouter) +int Node::send(Packet packet, bool isRouter) { Node *node; node = this->findConnection(packet.getDstIp()); // znajdz bezposrednia trase @@ -172,13 +172,13 @@ bool Node::send(Packet packet, bool isRouter) if (packet.getSrcPort() == 0) { // ustaw port zrodlowy na port losowy z zakresu [32768,61000] - zob. empheral port (port emferyczny) - srand(time(NULL)); + packet.setSrcPort(rand() % 32768 + 28233); } } node->putPacket(packet); - return true; + return packet.getSrcPort(); } /* @@ -264,3 +264,21 @@ string Node::getNetwork() { return this->netConf.network; } + +void Node::split(const std::string &s, char delim, vector &elems) +{ + stringstream ss; + ss.str(s); + string item; + while (getline(ss, item, delim)) + { + elems.push_back(item); + } +} + +vector Node::split(const string &s, char delim) +{ + vector elems; + split(s, delim, elems); + return elems; +} diff --git a/Node.h b/Node.h index c24709d..c7ec587 100644 --- a/Node.h +++ b/Node.h @@ -33,6 +33,8 @@ protected: string ipToString(unsigned int ip); unsigned int stringToIp(string ip); string calculateNetwork(string ip, string mask); + void split(const string &s, char delim, vector &elems); + vector split(const string &s, char delim); public: Node(); @@ -42,7 +44,7 @@ public: virtual ~Node(); bool connectNode(Node *node, bool isExternal = false, bool firstConnected = false); - bool send(Packet packet, bool isRouter = false); + int send(Packet packet, bool isRouter = false); void putPacket(Packet packet); // settery diff --git a/P2PServer.cpp b/P2PServer.cpp new file mode 100644 index 0000000..0577065 --- /dev/null +++ b/P2PServer.cpp @@ -0,0 +1,79 @@ +/* + * P2PServer.cpp + * + * Created on: 17.01.2017 + * Author: Piotr Dergun + */ + +#include "P2PServer.h" + +P2PServer::P2PServer() +{ + this->seedIp = ""; + this->peerIp = ""; + this->seedPort = 0; + this->peerPort = 0; +} + +P2PServer::P2PServer(string hostname, string ip, string mask) : Node(hostname, ip, mask) +{ + this->seedIp = ""; + this->peerIp = ""; + this->seedPort = 0; + this->peerPort = 0; +} + +P2PServer::~P2PServer() +{ +} + +void P2PServer::onRecv() +{ + stringstream ss; + while (true) + { + ss.str(""); + Packet p = this->recv(); + + if (p.getSrcPort() != 0) + { + ss << "onRecv() Received \"" << p.getMsg() << "\" from " << p.getSrcIp() << ":" << p.getSrcPort(); + this->print(ss.str()); + sleep(1); + + if (p.getMsg() == "getRemoteIPPort") + { + this->seedIp = p.getSrcIp(); + this->seedPort = p.getSrcPort(); + } + else if (p.getMsg() == "helloDownload") + { + this->peerIp = p.getSrcIp(); + this->peerPort = p.getSrcPort(); + } + + if (this->seedPort != 0 && this->peerPort != 0) + { + ss.str(""); + ss << "peerConnectionInfo:" << this->peerIp << ":" << this->peerPort; + Packet pp(ss.str()); + pp.setDstIp(this->seedIp); + pp.setDstPort(this->seedPort); + pp.setSrcPort(p.getDstPort()); + ss.str(""); + + ss << "Sending \"" << pp.getMsg() << "\" to " << pp.getDstIp() << ":" << pp.getDstPort(); + this->print(ss.str()); + this->send(pp); + sleep(1); + } + } + else + { +#ifndef DEBUG + this->print("onRecv() sleeping..."); +#endif + sleep(1); + } + } +} diff --git a/P2PServer.h b/P2PServer.h new file mode 100644 index 0000000..cdd760a --- /dev/null +++ b/P2PServer.h @@ -0,0 +1,26 @@ +/* + * P2PServer.h + * + * Created on: 17.01.2017 + * Author: Piotr Dergun + */ + +#ifndef P2PSERVER_H_ +#define P2PSERVER_H_ + +#include "common.h" +#include "Node.h" + +class P2PServer : public Node +{ + string seedIp, peerIp; + int seedPort, peerPort; +public: + P2PServer(); + P2PServer(string hostname, string ip, string mask); + virtual ~P2PServer(); + + virtual void onRecv(); +}; + +#endif /* P2PSERVER_H_ */ diff --git a/Peer.cpp b/Peer.cpp new file mode 100644 index 0000000..496e08a --- /dev/null +++ b/Peer.cpp @@ -0,0 +1,137 @@ +/* + * Peer.cpp + * + * Created on: 17.01.2017 + * Author: piotrek + */ + +#include "Peer.h" + +Peer::Peer() +{ + this->partId = 1; + this->srcPort = 0; + this->remotePort = 0; + this->sender = false; +} + +Peer::Peer(string hostname, string ip, string mask, string gatewayIp) : Node(hostname, ip, mask, gatewayIp) +{ + this->partId = 1; + this->srcPort = 0; + this->remotePort = 0; + this->sender = false; +} + +void Peer::onRecv() +{ + stringstream ss; + while (true) + { + ss.str(""); + Packet p = this->recv(); + + if (p.getSrcPort() != 0) + { + // jezeli informacje o drugiej stronie + if (this->isSender() && this->remotePort == 0) + { + vector x = split(p.getMsg(), ':'); + this->remoteIp = x[1]; + this->remotePort = atoi(x[2].c_str()); + ss << "onRecv() REMOTE peer is " << this->remoteIp << ":" << this->remotePort; + this->print(ss.str()); + sleep(1); + + this->sendData(); + } + else if (!this->isSender() && p.getMsg().find("data") != string::npos) + { + ss << "onRecv() Received \"" << p.getMsg() << "\" from " << p.getSrcIp() << ":" << p.getSrcPort(); + this->print(ss.str()); + sleep(1); + + this->sendAck(p.getSrcIp(), p.getSrcPort()); + } + else if (this->isSender() && p.getMsg().find("Ack") != string::npos) + { + ss << "onRecv() Received \"" << p.getMsg() << "\" from " << p.getSrcIp() << ":" << p.getSrcPort(); + this->print(ss.str()); + sleep(1); + + this->sendData(); + } + } + else + { +#ifndef DEBUG + this->print("onRecv() sleeping..."); +#endif + } + sleep(1); + } +} + +void Peer::connectToServer(string serverIp, int serverPort) +{ + stringstream ss; + ss << "Connecting to " << serverIp << ":" << serverPort; + + Packet p; + if (this->isSender()) + p.setMsg("getRemoteIPPort"); + else + p.setMsg("helloDownload"); + + p.setDstIp(serverIp); + p.setDstPort(serverPort); + this->srcPort = this->send(p); + ss << "\t RESULT: " << this->srcPort; + + this->print(ss.str()); +} + +void Peer::sendData() +{ + stringstream ss; + Packet p; + ss << "data-Part" << this->partId++; + p.setDstIp(this->remoteIp); + p.setDstPort(this->remotePort); + p.setSrcPort(this->srcPort); + p.setMsg(ss.str()); + ss.str(""); + + ss << "Sending \"" << p.getMsg() << "\" to " << p.getDstIp() << ":" << p.getDstPort(); + this->print(ss.str()); + this->send(p); +} + +bool Peer::isSender() const +{ + return sender; +} + +void Peer::setSender(bool sender) +{ + this->sender = sender; +} + +void Peer::sendAck(string dstIp, int dstPort) +{ + stringstream ss; + Packet p; + ss << "data-Ack" << this->partId++; + p.setDstIp(dstIp); + p.setDstPort(dstPort); + p.setSrcPort(this->srcPort); + p.setMsg(ss.str()); + ss.str(""); + + ss << "Sending \"" << p.getMsg() << "\" to " << p.getDstIp() << ":" << p.getDstPort(); + this->print(ss.str()); + this->send(p); +} + + + diff --git a/Peer.h b/Peer.h new file mode 100644 index 0000000..4410aa3 --- /dev/null +++ b/Peer.h @@ -0,0 +1,37 @@ +/* + * Peer.h + * + * Created on: 17.01.2017 + * Author: piotrek + */ + +#ifndef PEER_H_ +#define PEER_H_ + +#include "common.h" +#include "Node.h" + +class Peer : public Node +{ + bool sender; + int srcPort; + string remoteIp; + int remotePort; + int partId; + +public: + Peer(); + Peer(string hostname, string ip, string mask, string gatewayIp); + virtual ~Peer() {}; + + virtual void onRecv(); + void connectToServer(string serverIp, int serverPort); + bool isSender() const; + void setSender(bool sender); + +protected: + void sendData(); + void sendAck(string dstIp, int dstPort); +}; + +#endif /* PEER_H_ */ diff --git a/Simulation.cpp b/Simulation.cpp index fad1857..d484c87 100644 --- a/Simulation.cpp +++ b/Simulation.cpp @@ -9,9 +9,12 @@ #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 @@ -145,11 +148,14 @@ void Simulation::resizeWnd() 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; @@ -159,6 +165,7 @@ void Simulation::timer() sprintf(str, "%02d:%02d:%02d", h, m, s); move(0, this->cols-strlen(str)); printw(str); +#endif usleep(100000); // 100 ms //sleep(1); } @@ -168,6 +175,7 @@ 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.setLogParams(0, GREEN, "\t\t"); Peer peer2("Peer 2", "10.0.0.2", "255.255.255.0", "10.0.0.1"); peer2.setLogParams(4, CYAN, "\t\t"); @@ -194,7 +202,7 @@ void Simulation::p2pSimulation() sleep(1); this->print("Creating P2P server"); - Node server("Server", "80.80.90.91", "255.255.255.255"); + P2PServer server("Server", "80.80.90.91", "255.255.255.255"); server.setLogParams(2, YELLOW, "\t\t"); server.print("IP 80.80.90.91/32"); sleep(1); @@ -221,11 +229,13 @@ void Simulation::p2pSimulation() this->createThread("r1", NODE_RECV, &r1); this->createThread("r2", NODE_RECV, &r2); this->createThread("s1", NODE_RECV, &server); - this->createThread("p2", NODE_RECV, &peer2); 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); diff --git a/common.h b/common.h index 5e1bb78..186f040 100644 --- a/common.h +++ b/common.h @@ -2,7 +2,7 @@ * common.h * * Created on: 10.01.2017 - * Author: piotrek + * Author: Piotr Dergun */ #ifndef COMMON_H_