Tons of refactoring, change to desperation algorithm to use max of core or link, porting over core loop code from old Node.cpp to new CAPI version, etc.

This commit is contained in:
Adam Ierymenko 2015-04-07 19:31:11 -07:00
parent 9e55f882d3
commit 49f031ccb4
14 changed files with 277 additions and 254 deletions

View file

@ -188,100 +188,6 @@ public:
f(*this,p->second);
}
#if 0
/**
* Apply a function or function object to all supernode peers
*
* Note: explicitly template this by reference if you want the object
* passed by reference instead of copied.
*
* Warning: be careful not to use features in these that call any other
* methods of Topology that may lock _lock, otherwise a recursive lock
* and deadlock or lock corruption may occur.
*
* @param f Function to apply
* @tparam F Function or function object type
*/
template<typename F>
inline void eachSupernodePeer(F f)
{
Mutex::Lock _l(_lock);
for(std::vector< SharedPtr<Peer> >::const_iterator p(_supernodePeers.begin());p!=_supernodePeers.end();++p)
f(*this,*p);
}
/**
* Pings all peers that need a ping sent, excluding supernodes
*
* Ordinary peers are pinged if we haven't heard from them recently. Receive
* time rather than send time as OK is returned on success and we want to
* keep trying if a packet is lost. Ordinary peers are subject to a frame
* inactivity timeout. We give up if we haven't actually transferred any
* data to them recently, and eventually Topology purges them from memory.
*/
class PingPeersThatNeedPing
{
public:
PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) throw() :
_now(now),
_supernodeAddresses(renv->topology->supernodeAddresses()),
RR(renv) {}
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
/* For ordinary nodes we ping if they've sent us a frame recently,
* otherwise they are stale and we let the link die.
*
* Note that we measure ping time from time of last receive rather
* than time of last send in order to only count full round trips. */
if ( (std::find(_supernodeAddresses.begin(),_supernodeAddresses.end(),p->address()) == _supernodeAddresses.end()) &&
((_now - p->lastFrame()) < ZT_PEER_PATH_ACTIVITY_TIMEOUT) &&
((_now - p->lastDirectReceive()) >= ZT_PEER_DIRECT_PING_DELAY) ) {
p->sendPing(RR,_now);
}
}
private:
uint64_t _now;
std::vector<Address> _supernodeAddresses;
const RuntimeEnvironment *RR;
};
/**
* Ping peers that need ping according to supernode rules
*
* Supernodes ping aggressively if a ping is unanswered and they are not
* subject to the activity timeout. In other words: we assume they are
* always there and always try to reach them.
*
* The ultimate rate limit for this is controlled up in the Node main loop.
*/
class PingSupernodesThatNeedPing
{
public:
PingSupernodesThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) throw() :
_now(now),
RR(renv) {}
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
/* For supernodes we always ping even if no frames have been seen, and
* we ping aggressively if pings are unanswered. The limit to this
* frequency is set in the main loop to no more than ZT_STARTUP_AGGRO. */
uint64_t lp = 0;
uint64_t lr = 0;
p->lastPingAndDirectReceive(lp,lr);
if ( ((lr < lp)&&((lp - lr) >= ZT_PING_UNANSWERED_AFTER)) || ((_now - lr) >= ZT_PEER_DIRECT_PING_DELAY) )
p->sendPing(RR,_now);
}
private:
uint64_t _now;
const RuntimeEnvironment *RR;
};
#endif
/**
* Validate a root topology dictionary against the identities specified in Defaults
*