/*************************************************************************** * By Théophile Bastian, 2017 * M1 Network course project at ENS Cachan, Juliusz Chroboczek. * License: WTFPL v2 **************************************************************************/ #include "data.h" #include "protocol.h" #include "nw_constants.h" #include "neighbours.h" #include "packetParser.h" #include "configFile.h" #include "dataStore.h" #include #include #include #include #include #include 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; }