/*************************************************************************** * 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 DataTooLongError : 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& addr, u64 id); /** Maps internally `id` to `addr` for future use. */ 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); /** Sends the given `body` (wrapped in headers) * Actually, this puts the `body` in an aggregated TLVs bytes and * waits up to 500ms before sending. */ 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& neigh); /** Sends a neighbours list packet */ void sendData(u64 id, const Bytes& data, u32 seqno, u64 datId); void sendIHave(u64 id, u64 datId, u32 seqno); /** Sends a IHave packet for `datId` */ u64 getSelfId() const { return selfId; } /** Returns the ID of this node. */ void sendAllNow(); /** Notifies the object that it should send every waiting packet now. */ private: //meth void startPollNetwork(); void pollNetwork(); const SockAddr& addrOfId(u64 id); SockAddr addrOfV4(const sockaddr_in& addrv4); void sendNow(u64 id, bool erase=true); /** Sends the aggregated TLVs right now. */ 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; std::unordered_map aggregatedTLVs; };