/*************************************************************************** * By Théophile Bastian, 2017 * M1 Network course project at ENS Cachan, Juliusz Chroboczek. * License: WTFPL v2 **************************************************************************/ #include "packetParser.h" #include PacketParser::PacketParser(Neighbours* nei, Protocol* proto, DataStore* dataStore) : neighbours(nei), protocol(proto), dataStore(dataStore) {} void PacketParser::parse(Bytes pck, const SockAddr& addr) { u64 peerId; if(pck.size() < 8) { fprintf(stderr, "[WARNING] Bad packet size.\n"); return; } pck >> peerId; neighbours->receivedFrom(peerId, addr); while(pck.size() > 0) { readTLV(pck, peerId, addr); } } void PacketParser::readTLV(Bytes& pck, u64 nei, const SockAddr& addr) { u8 type, len; if(pck.size() < 2) { fprintf(stderr, "[WARNING] Bad packet size from %lX.\n", nei); return; } pck >> type >> len; fprintf(stderr, "[INFO] Parsing %d from %lX.\n", type, nei); if(pck.size() < len) { fprintf(stderr, "[WARNING] Advertised TLV does not fit in the packet" ".\n"); pck.extract(pck.size()); return; } Bytes subpacket = pck.extract(len); switch(type) { case csts::TLV_PAD1: case csts::TLV_PADN: break; case csts::TLV_IHU: { u64 ihuId; subpacket >> ihuId; if(ihuId != protocol->getSelfId()) break; neighbours->hadIHU(nei, addr); break; } case csts::TLV_NR: handleNR(nei); break; case csts::TLV_NEIGH: receiveNeigh(subpacket); break; case csts::TLV_DATA: receiveData(subpacket, nei); break; case csts::TLV_IHAVE: receiveIHave(subpacket, nei); break; } } void PacketParser::receiveNeigh(Bytes& pck) { while(pck.size() >= 8+16+2) { /* enough to read one peer */ u64 id; u16 port; SockAddr addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; pck >> id; for(int byte=0; byte < 16; byte++) pck >> addr.sin6_addr.s6_addr[byte]; pck >> port; addr.sin6_port = htons(port); if(id == protocol->getSelfId()) continue; Neighbour nei(id, addr); neighbours->addPotentialNei(nei); } } void PacketParser::receiveData(Bytes& pck, u64 from) { u32 seqNo; u64 datId; pck >> seqNo >> datId; neighbours->gotIHave(from, datId, seqNo); protocol->sendIHave(from, datId, seqNo); dataStore->addData(pck, seqNo, datId, false); } void PacketParser::receiveIHave(Bytes& pck, u64 from) { u32 seqno; u64 datId; if(pck.size() < 8+4) { fprintf(stderr, "[WARNING] IHave too short from %lX\n", from); return; } pck >> seqno >> datId; neighbours->gotIHave(from, datId, seqno); } void PacketParser::handleNR(u64 from) { std::vector neigh; neighbours->getNeighbours(neigh, from, csts::NB_NEIGH_PER_NR); protocol->sendNeighbours(from, neigh); }