/***************************************************************************
* By Théophile Bastian, 2017
* M1 Network course project at ENS Cachan, Juliusz Chroboczek.
* License: WTFPL v2
**************************************************************************/
#pragma once
#include
#include
#include
#include
#include "data.h"
#include "protocol.h"
#include "flooder.h"
#include "dataStore.h"
class Neighbours {
public:
Neighbours(Protocol* proto, DataStore* dataStore);
~Neighbours();
void fullCheck();
/** Cleans the peers lists by removing the expired entries. */
void fullUpdate();
/** Triggers a full update of the peers lists: sends the appropriate
* packets to the peers (IHU, ...) when approaching expiracy, and
* performs a `fullCheck()`.
*/
void addPotentialNei(const Neighbour& nei);
/** Adds a `Neighbour` to the list of potential neighbours. */
void receivedFrom(u64 id, const SockAddr& addr);
/** Signals that a packet was received from `id`, performs the
* appropriate bookkeeping actions.
*/
void hadIHU(u64 id, const SockAddr& addr);
/** Signals that a IHU was received from `id`, performs the
* appropriate bookkeeping actions.
*/
void getNeighbours(std::vector& out, u64 except, int count);
/** Fills `out` with at most `count` symetric neighbours, not
* including `except`.
*/
void gotIHave(u64 from, u64 datId, u32 seqno);
/** Notifies the flooders that a `IHave` packet has been received for
* this data from the peer `from`.
*/
void dump();
/** Dumps everything to STDIN. */
private: //meth
class WrongNeiType : public std::exception {};
enum NeiType {
NEI_UNDEF, NEI_POTENTIAL, NEI_UNIDIR, NEI_SYM
};
void dumpNei(const Neighbour& nei, NeiType type);
std::list* listOfType(NeiType typ);
void changeNeiType(u64 id, NeiType nType);
void updateSendPackets(const Neighbour& nei);
bool sendEmpty(u64 id);
bool sendIHU(u64 id);
std::list::iterator randPeer(std::list* list);
void floodTo(u64 peer);
private:
Protocol* proto;
DataStore* dataStore;
std::list potentialNei, unidirNei, symNei;
std::unordered_map lastRecv, lastIHU;
std::unordered_map lastPckSent, lastIHUSent;
std::unordered_map neiType;
std::unordered_map dataFlooder;
time_t lastPeerPeek, lastSentNR;
};