M1-nw-project/protocol.h
Théophile Bastian a31d9e29eb Dump data on RETURN ; FIX sending
Packet sending was broken: active iterators could be invalidated.
2016-11-27 12:16:56 +01:00

99 lines
2.5 KiB
C++

/***************************************************************************
* 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 {};
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<Neighbour>& 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<AvailPacket> availPackets;
std::unordered_map<u64, SockAddr> addrMap;
std::unordered_map<u64, Bytes> aggregatedTLVs;
};