M1-nw-project/packetParser.cpp

130 lines
2.8 KiB
C++
Raw Normal View History

2016-11-24 14:39:03 +01:00
/***************************************************************************
* 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>
2016-11-26 16:20:20 +01:00
PacketParser::PacketParser(Neighbours* nei, Protocol* proto,
DataStore* dataStore) :
neighbours(nei), protocol(proto), dataStore(dataStore)
2016-11-24 14:39:03 +01:00
{}
2016-11-26 16:20:20 +01:00
void PacketParser::parse(Bytes pck, const SockAddr& addr) {
2016-11-24 14:39:03 +01:00
u64 peerId;
if(pck.size() < 8) {
fprintf(stderr, "[WARNING] Bad packet size.\n");
return;
}
2016-11-24 14:39:03 +01:00
pck >> peerId;
2016-11-26 16:20:20 +01:00
neighbours->receivedFrom(peerId, addr);
2016-11-24 14:39:03 +01:00
while(pck.size() > 0) {
2016-11-26 16:20:20 +01:00
readTLV(pck, peerId, addr);
2016-11-24 14:39:03 +01:00
}
}
2016-11-26 16:20:20 +01:00
void PacketParser::readTLV(Bytes& pck, u64 nei, const SockAddr& addr) {
2016-11-24 14:39:03 +01:00
u8 type, len;
if(pck.size() < 2) {
fprintf(stderr, "[WARNING] Bad packet size from %lX.\n", nei);
return;
}
2016-11-24 14:39:03 +01:00
pck >> type >> len;
2016-11-26 19:17:56 +01:00
fprintf(stderr, "[INFO] Parsing %d from %lX.\n", type, nei);
2016-11-26 16:20:20 +01:00
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);
2016-11-24 14:39:03 +01:00
switch(type) {
case csts::TLV_PAD1:
case csts::TLV_PADN:
break;
case csts::TLV_IHU: {
u64 ihuId;
2016-11-26 16:20:20 +01:00
subpacket >> ihuId;
2016-11-24 14:39:03 +01:00
if(ihuId != protocol->getSelfId())
break;
2016-11-26 16:20:20 +01:00
neighbours->hadIHU(nei, addr);
2016-11-24 14:39:03 +01:00
break;
}
case csts::TLV_NR:
2016-11-26 16:20:20 +01:00
handleNR(nei);
2016-11-24 14:39:03 +01:00
break;
case csts::TLV_NEIGH:
2016-11-26 16:20:20 +01:00
receiveNeigh(subpacket);
2016-11-24 14:39:03 +01:00
break;
case csts::TLV_DATA:
2016-11-26 16:20:20 +01:00
receiveData(subpacket, nei);
2016-11-24 14:39:03 +01:00
break;
case csts::TLV_IHAVE:
2016-11-26 16:20:20 +01:00
receiveIHave(subpacket, nei);
2016-11-24 14:39:03 +01:00
break;
}
}
2016-11-26 16:20:20 +01:00
void PacketParser::receiveNeigh(Bytes& pck) {
while(pck.size() >= 8+16+2) { /* enough to read one peer */
2016-11-24 14:39:03 +01:00
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);
2016-11-26 16:20:20 +01:00
if(id == protocol->getSelfId())
continue;
2016-11-24 14:39:03 +01:00
Neighbour nei(id, addr);
neighbours->addPotentialNei(nei);
}
}
2016-11-26 16:20:20 +01:00
void PacketParser::receiveData(Bytes& pck, u64 from) {
2016-11-24 14:39:03 +01:00
u32 seqNo;
u64 datId;
pck >> seqNo >> datId;
2016-11-26 16:20:20 +01:00
neighbours->gotIHave(from, datId, seqNo);
2016-11-24 14:39:03 +01:00
protocol->sendIHave(from, datId, seqNo);
2016-11-26 16:20:20 +01:00
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);
2016-11-24 14:39:03 +01:00
}