diff --git a/neighbours.cpp b/neighbours.cpp index 92cd130..a75a1ff 100644 --- a/neighbours.cpp +++ b/neighbours.cpp @@ -40,9 +40,9 @@ void Neighbours::fullUpdate() { fullCheck(); for(auto nei : unidirNei) - updateSendPackets(nei, proto); + updateSendPackets(nei); for(auto nei : symNei) - updateSendPackets(nei, proto); + updateSendPackets(nei); if(potentialNei.size() > 0 && symNei.size() < csts::SYM_COUNT_BEFORE_PEEK @@ -51,6 +51,7 @@ void Neighbours::fullUpdate() { auto it = potentialNei.begin(); for(int at=0; at < nPeerId; ++at, ++it); proto->sendEmpty(it->id); + lastPckSent[it->id] = time(NULL); lastPeerPeek = time(NULL); } } @@ -65,27 +66,28 @@ void Neighbours::addPotentialNei(const Neighbour& nei) { void Neighbours::receivedFrom(u64 id) { NeiType typ = neiType[id]; - lastRecv.insert({id, time(NULL)}); + lastRecv[id] = time(NULL); + if(typ == NEI_POTENTIAL) changeNeiType(id, NEI_UNIDIR); } void Neighbours::hadIHU(u64 id) { NeiType typ = neiType[id]; - lastRecv.insert({id, time(NULL)}); - lastIHU.insert({id, time(NULL)}); + lastRecv[id] = time(NULL); + lastIHU[id] = time(NULL); if(typ == NEI_POTENTIAL || typ == NEI_UNIDIR) changeNeiType(id, NEI_SYM); } -list& Neighbours::listOfType(NeiType typ) { +list* Neighbours::listOfType(NeiType typ) { switch(typ) { case NEI_POTENTIAL: - return potentialNei; + return &potentialNei; case NEI_UNIDIR: - return unidirNei; + return &unidirNei; case NEI_SYM: - return symNei; + return &symNei; default: break; } @@ -93,34 +95,55 @@ list& Neighbours::listOfType(NeiType typ) { } void Neighbours::changeNeiType(u64 id, NeiType nType) { + printf("TYPE %lX %d\n", id, neiType[id]); NeiType cType = neiType[id]; if(cType == nType) return; - list& fromList = listOfType(cType), toList = listOfType(nType); - neiType.insert({id, nType}); + list *fromList = listOfType(cType), + *toList = listOfType(nType); + neiType[id] = nType; bool wasSpliced=false; - for(auto it=fromList.begin(); it != fromList.end(); ++it) { + for(auto it=fromList->begin(); it != fromList->end(); ++it) { if(it->id == id) { - fromList.splice(it, toList); + printf("%ld %ld\n", fromList->size(), toList->size()); + toList->push_back(*it); // splice() doesn't work?! + fromList->erase(it); + printf("%ld %ld %d\n", fromList->size(), toList->size(), + toList == &unidirNei); wasSpliced=true; break; } } if(!wasSpliced) { - //TODO log error. + fprintf(stderr, "[ERROR] Node %lX wasn't found (type change)\n", id); } + printf("TYPE %lX %d\n", id, neiType[id]); } -void Neighbours::updateSendPackets(const Neighbour& nei, Protocol* proto) { - if(time(NULL) - lastIHUSent[nei.id] >= csts::TIME_RESEND_IHU) { - lastIHUSent[nei.id] = time(NULL); - lastPckSent[nei.id] = time(NULL); - proto->sendIHU(nei.id); - } - else if(time(NULL) - lastPckSent[nei.id] >= csts::TIME_RESEND_EMPTY) { - lastPckSent[nei.id] = time(NULL); - proto->sendEmpty(nei.id); - } +void Neighbours::updateSendPackets(const Neighbour& nei) { + if(!sendIHU(nei.id)) + sendEmpty(nei.id); +} + +bool Neighbours::sendEmpty(u64 id) { + if(time(NULL) - lastPckSent[id] >= csts::TIME_RESEND_EMPTY) { + printf("[DBG] sending empty packet to %lX.\n", id); + lastPckSent[id] = time(NULL); + proto->sendEmpty(id); + return true; + } + return false; +} + +bool Neighbours::sendIHU(u64 id) { + if(time(NULL) - lastIHUSent[id] >= csts::TIME_RESEND_IHU) { + printf("[DBG] sending IHU packet to %lX.\n", id); + lastIHUSent[id] = time(NULL); + lastPckSent[id] = time(NULL); + proto->sendIHU(id); + return true; + } + return false; } diff --git a/neighbours.h b/neighbours.h index 1c29bb7..b10f7f1 100644 --- a/neighbours.h +++ b/neighbours.h @@ -44,9 +44,12 @@ class Neighbours { NEI_UNDEF, NEI_POTENTIAL, NEI_UNIDIR, NEI_SYM }; - std::list& listOfType(NeiType typ); + std::list* listOfType(NeiType typ); void changeNeiType(u64 id, NeiType nType); - void updateSendPackets(const Neighbour& nei, Protocol* proto); + void updateSendPackets(const Neighbour& nei); + + bool sendEmpty(u64 id); + bool sendIHU(u64 id); private: Protocol* proto; diff --git a/protocol.cpp b/protocol.cpp index 68a46d7..83bb1d7 100644 --- a/protocol.cpp +++ b/protocol.cpp @@ -27,6 +27,7 @@ Protocol::Protocol(const SockAddr& listenAddr, u64 selfId) : } // Set socket reception timeout + /* struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; @@ -34,6 +35,7 @@ Protocol::Protocol(const SockAddr& listenAddr, u64 selfId) : perror("Cannot set socket timeout"); throw NwError(); } + */ startPollNetwork(); } @@ -159,14 +161,20 @@ void Protocol::startPollNetwork() { void Protocol::pollNetwork() { u8 buffer[MAX_MTU]; - SockAddr fromAddr6; - struct sockaddr* fromAddr = (struct sockaddr*)&fromAddr6; - socklen_t fromAddrLen; while(!terminating) { + struct sockaddr fromAddr; + memset(&fromAddr, 0, sizeof(fromAddr)); + socklen_t fromAddrLen=sizeof(fromAddr); ssize_t readDat = recvfrom(sock, buffer, MAX_MTU, 0, - fromAddr, &fromAddrLen); - if(readDat <= 0) + &fromAddr, &fromAddrLen); + if(readDat < 0) { + perror("[WARNING] Bad packet"); continue; + } + if(readDat <= 0) { + fprintf(stderr, "[WARNING] Empty packet.\n"); + continue; + } Bytes data(buffer, readDat); u8 magic, version; data >> magic >> version; @@ -181,7 +189,8 @@ void Protocol::pollNetwork() { u16 bodyLen; data >> bodyLen; if(data.size() < bodyLen + 8u) { - fprintf(stderr, "[WARNING] Body too short\n"); + fprintf(stderr, "[WARNING] Body too short (%lu < %d)\n", + data.size(), bodyLen+8u); continue; } else if(data.size() != bodyLen + 8u) { @@ -189,15 +198,24 @@ void Protocol::pollNetwork() { } SockAddr convFromAddr; - if(fromAddr->sa_family == AF_INET) - convFromAddr = addrOfV4(*(struct sockaddr_in*)fromAddr); - else if(fromAddr->sa_family == AF_INET6) - convFromAddr = *(SockAddr*)fromAddr; + if(fromAddr.sa_family == AF_INET) + convFromAddr = addrOfV4(*((struct sockaddr_in*)&fromAddr)); + else if(fromAddr.sa_family == AF_INET6) + convFromAddr = *(SockAddr*)&fromAddr; else { - fprintf(stderr, "ERROR: Unknown address family."); + fprintf(stderr, "[ERROR] Unknown address family %d.\n", + fromAddr.sa_family); + fprintf(stderr, "\t%hu\n", ((SockAddr*)&fromAddr)->sin6_port); + while(data.size() > 0) { + u8 c; + data >> c; + fprintf(stderr, "%02X|", c); + } + fprintf(stderr, "\n"); continue; } + puts("Received packet"); AvailPacket pck; pck.from = convFromAddr; pck.data = data;