/*************************************************************************** * By Théophile Bastian, 2017 * M1 Network course project at ENS Cachan, Juliusz Chroboczek. * License: WTFPL v2 **************************************************************************/ #pragma once #include #include #include #include #include #include #include "nw_constants.h" #include "Bytes.h" class Protocol { public: class NwError : public std::exception {}; class ThreadError : public std::exception {}; 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(); void addIdAddr(const sockaddr_in6& addr, u64 id); 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 SockAddr& to); void sendBody(const Bytes& body, const u64& id); /** Sends the given `body` (wrapped in headers) */ void sendEmpty(const SockAddr& to); void sendEmpty(u64 to); void sendIHU(const SockAddr& to, u64 id); void sendIHU(u64 id); /** Sends a IHU packet */ void sendNReq(const SockAddr& to); void sendNReq(u64 id); /** Sends a neighbour request packet */ void sendNeighbours(const SockAddr& to, const std::vector& neigh); void sendNeighbours(u64 id, const std::vector& neigh); /** Sends a neighbours list packet */ void sendIHave(const SockAddr& to, u64 datId, u32 seqno); void sendIHave(u64 id, u64 datId, u32 seqno); /** Sends a IHave packet for `datId` */ private: //meth void startPollNetwork(); void pollNetwork(); const SockAddr& addrOfId(u64 id); SockAddr addrOfV4(const sockaddr_in& addrv4); private: struct AvailPacket { SockAddr from; Bytes data; }; int sock; SockAddr listenAddr; u64 selfId; bool terminating; std::thread pollThread; std::mutex availPacketsMutex; std::queue availPackets; std::unordered_map addrMap; };