2016-11-20 00:15:52 +01:00
|
|
|
/***************************************************************************
|
|
|
|
* By Théophile Bastian, 2017
|
|
|
|
* M1 Network course project at ENS Cachan, Juliusz Chroboczek.
|
|
|
|
* License: WTFPL v2 <http://www.wtfpl.net/>
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <queue>
|
|
|
|
#include <thread>
|
|
|
|
#include <mutex>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include "nw_constants.h"
|
|
|
|
#include "Bytes.h"
|
|
|
|
|
|
|
|
class Protocol {
|
|
|
|
public:
|
|
|
|
class NwError : public std::exception {};
|
|
|
|
class ThreadError : public std::exception {};
|
2016-11-23 23:49:48 +01:00
|
|
|
class DataTooLongError : public std::exception {};
|
2016-11-20 00:15:52 +01:00
|
|
|
class UnknownId : public std::exception {
|
|
|
|
public:
|
|
|
|
UnknownId(u64 id) : _id(id) {}
|
|
|
|
u64 id() const { return _id; }
|
|
|
|
private:
|
|
|
|
u64 _id;
|
|
|
|
};
|
|
|
|
|
|
|
|
Protocol(const SockAddr& dest, u64 selfId);
|
|
|
|
~Protocol();
|
|
|
|
|
2016-11-23 23:49:48 +01:00
|
|
|
void addIdAddr(const SockAddr& addr, u64 id);
|
|
|
|
/** Maps internally `id` to `addr` for future use. */
|
2016-11-20 00:15:52 +01:00
|
|
|
|
|
|
|
bool readyRead() const;
|
|
|
|
/** Returns whether a packet is available. */
|
|
|
|
|
|
|
|
Bytes getPacket(SockAddr* from);
|
|
|
|
/** Appends the body of a full packet to `out`. */
|
|
|
|
|
|
|
|
void sendBody(const Bytes& body, const u64& id);
|
2016-11-27 09:49:28 +01:00
|
|
|
/** Sends the given `body` (wrapped in headers)
|
|
|
|
* Actually, this puts the `body` in an aggregated TLVs bytes and
|
|
|
|
* waits up to 500ms before sending. */
|
2016-11-20 00:15:52 +01:00
|
|
|
|
|
|
|
void sendEmpty(u64 to);
|
|
|
|
|
|
|
|
void sendIHU(u64 id);
|
|
|
|
/** Sends a IHU packet */
|
|
|
|
|
|
|
|
void sendNReq(u64 id);
|
|
|
|
/** Sends a neighbour request packet */
|
|
|
|
|
|
|
|
void sendNeighbours(u64 id,
|
|
|
|
const std::vector<Neighbour>& neigh);
|
|
|
|
/** Sends a neighbours list packet */
|
|
|
|
|
2016-11-26 16:20:20 +01:00
|
|
|
void sendData(u64 id, const Bytes& data, u32 seqno, u64 datId);
|
2016-11-23 23:49:48 +01:00
|
|
|
|
2016-11-20 00:15:52 +01:00
|
|
|
void sendIHave(u64 id, u64 datId, u32 seqno);
|
|
|
|
/** Sends a IHave packet for `datId` */
|
|
|
|
|
2016-11-24 14:39:12 +01:00
|
|
|
u64 getSelfId() const { return selfId; }
|
|
|
|
/** Returns the ID of this node. */
|
|
|
|
|
2016-11-27 09:49:28 +01:00
|
|
|
void sendAllNow();
|
|
|
|
/** Notifies the object that it should send every waiting packet now.
|
|
|
|
*/
|
|
|
|
|
2016-11-20 00:15:52 +01:00
|
|
|
private: //meth
|
|
|
|
void startPollNetwork();
|
|
|
|
void pollNetwork();
|
|
|
|
const SockAddr& addrOfId(u64 id);
|
|
|
|
SockAddr addrOfV4(const sockaddr_in& addrv4);
|
|
|
|
|
2016-11-27 12:16:56 +01:00
|
|
|
void sendNow(u64 id, bool erase=true);
|
2016-11-27 09:49:28 +01:00
|
|
|
/** Sends the aggregated TLVs right now. */
|
|
|
|
|
2016-11-20 00:15:52 +01:00
|
|
|
private:
|
|
|
|
struct AvailPacket {
|
|
|
|
SockAddr from;
|
|
|
|
Bytes data;
|
|
|
|
};
|
|
|
|
|
|
|
|
int sock;
|
|
|
|
SockAddr listenAddr;
|
|
|
|
u64 selfId;
|
|
|
|
bool terminating;
|
|
|
|
|
|
|
|
std::thread pollThread;
|
|
|
|
std::mutex availPacketsMutex;
|
|
|
|
std::queue<AvailPacket> availPackets;
|
|
|
|
std::unordered_map<u64, SockAddr> addrMap;
|
2016-11-27 09:49:28 +01:00
|
|
|
|
|
|
|
std::unordered_map<u64, Bytes> aggregatedTLVs;
|
2016-11-20 00:15:52 +01:00
|
|
|
};
|
|
|
|
|