117 lines
2.6 KiB
C++
117 lines
2.6 KiB
C++
/***************************************************************************
|
|
* By Théophile Bastian, 2017
|
|
* M1 Network course project at ENS Cachan, Juliusz Chroboczek.
|
|
* License: WTFPL v2 <http://www.wtfpl.net/>
|
|
**************************************************************************/
|
|
|
|
#include "data.h"
|
|
#include "protocol.h"
|
|
#include "nw_constants.h"
|
|
#include "neighbours.h"
|
|
#include "packetParser.h"
|
|
#include "configFile.h"
|
|
#include "dataStore.h"
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
|
|
bool terminate=false;
|
|
|
|
char readStdin() {
|
|
fd_set fdSet;
|
|
FD_ZERO(&fdSet);
|
|
FD_SET(STDIN_FILENO, &fdSet);
|
|
struct timeval tv = {1, 0};
|
|
|
|
if(select(STDIN_FILENO+1, &fdSet, NULL, NULL, &tv) < 0) {
|
|
perror("[WARNING] Bad select");
|
|
return 0;
|
|
}
|
|
else {
|
|
if(FD_ISSET(STDIN_FILENO, &fdSet)) {
|
|
char c = getchar();
|
|
fflush(stdin);
|
|
return c;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
bool hasConfig = false;
|
|
char* configFilePath = nullptr;
|
|
if(argc > 1) {
|
|
hasConfig = true;
|
|
configFilePath = argv[1];
|
|
}
|
|
|
|
srand(time(NULL)+42);
|
|
|
|
signal(SIGINT, [](int) { terminate = true; });
|
|
|
|
ConfigFile cfg;
|
|
if(hasConfig) {
|
|
if(!cfg.read(configFilePath) || !cfg.write(configFilePath)) {
|
|
fprintf(stderr, "Could not read/write on '%s'.\n", configFilePath);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
SockAddr addr;
|
|
memset(&addr, 0, sizeof(addr));
|
|
addr.sin6_family = AF_INET6;
|
|
addr.sin6_port = htons(csts::DEFAULT_PORT);
|
|
|
|
fprintf(stderr, "[INFO] Starting with ID %lX\n", cfg.getSelfId());
|
|
|
|
Protocol proto(addr, cfg.getSelfId());
|
|
|
|
DataStore dataStore(&proto);
|
|
Bytes selfData;
|
|
for(auto dat : cfg.getData()) {
|
|
selfData << csts::TLV_DATA_TEXT << (u8)dat.size();
|
|
for(u8 chr : dat)
|
|
selfData << chr;
|
|
fprintf(stderr, "[INFO] Adding data `%s`\n",
|
|
dat.c_str());
|
|
}
|
|
dataStore.addData(selfData, time(NULL), cfg.getSelfId(), true);
|
|
|
|
Neighbours neighboursManager(&proto, &dataStore);
|
|
|
|
for(const Neighbour& nei : cfg.getBootstrapNodes()) {
|
|
char addr[54];
|
|
inet_ntop(AF_INET6, &nei.addr.sin6_addr, addr, 54);
|
|
fprintf(stderr, "[INFO] Bootstrap neighbour: %lX [%s]:%hu\n",
|
|
nei.id, addr, ntohs(nei.addr.sin6_port));
|
|
neighboursManager.addPotentialNei(nei);
|
|
}
|
|
|
|
PacketParser pckParser(&neighboursManager, &proto, &dataStore);
|
|
|
|
while(!terminate) {
|
|
neighboursManager.fullUpdate();
|
|
|
|
while(proto.readyRead()) {
|
|
SockAddr fromAddr;
|
|
Bytes pck = proto.getPacket(&fromAddr);
|
|
pckParser.parse(pck, fromAddr);
|
|
}
|
|
|
|
dataStore.update();
|
|
|
|
proto.sendAllNow();
|
|
// sleep(1);
|
|
char c = readStdin();
|
|
if(c != 0) {
|
|
dataStore.dump();
|
|
neighboursManager.dump();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|