122 lines
2.7 KiB
C++
122 lines
2.7 KiB
C++
/***************************************************************************
|
|
* By Théophile Bastian, 2017
|
|
* M1 Network course project at ENS Cachan, Juliusz Chroboczek.
|
|
* License: WTFPL v2 <http://www.wtfpl.net/>
|
|
**************************************************************************/
|
|
|
|
#include "packetParser.h"
|
|
#include <cstring>
|
|
|
|
PacketParser::PacketParser(Neighbours* nei, Protocol* proto,
|
|
DataStore* dataStore) :
|
|
neighbours(nei), protocol(proto), dataStore(dataStore)
|
|
{}
|
|
|
|
void PacketParser::parse(Bytes pck, const SockAddr& addr) {
|
|
u64 peerId;
|
|
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;
|
|
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;
|
|
|
|
fprintf(stderr, "[INFO] Adding neighbour %lX\n", id);
|
|
|
|
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<Neighbour> neigh;
|
|
neighbours->getNeighbours(neigh, from, csts::NB_NEIGH_PER_NR);
|
|
|
|
protocol->sendNeighbours(from, neigh);
|
|
}
|
|
|