Clean up some routine stuff like pings, and stop keeping links open forever even if there are no frames passing between them.

This commit is contained in:
Adam Ierymenko 2013-10-02 16:12:10 -04:00
parent b8a9b42993
commit 58538500f2
7 changed files with 85 additions and 70 deletions

View File

@ -188,7 +188,7 @@ error_no_ZT_ARCH_defined;
* very unlikely, as the transfer rate would have to be fast enough to fill
* system memory in this time.
*/
#define ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT 1500
#define ZT_FRAGMENTED_PACKET_RECEIVE_TIMEOUT 1000
/**
* First byte of MAC addresses derived from ZeroTier addresses
@ -206,7 +206,7 @@ error_no_ZT_ARCH_defined;
/**
* Delay between WHOIS retries in ms
*/
#define ZT_WHOIS_RETRY_DELAY 500
#define ZT_WHOIS_RETRY_DELAY 350
/**
* Maximum identity WHOIS retries
@ -233,7 +233,7 @@ error_no_ZT_ARCH_defined;
/**
* Size of multicast deduplication ring buffer in 64-bit ints
*/
#define ZT_MULTICAST_DEDUP_HISTORY_LENGTH 1024
#define ZT_MULTICAST_DEDUP_HISTORY_LENGTH 512
/**
* Default number of bits in multicast propagation prefix
@ -247,6 +247,8 @@ error_no_ZT_ARCH_defined;
/**
* Global maximum for multicast propagation depth
*
* This is kind of an insane value, meant as a sanity check.
*/
#define ZT_MULTICAST_GLOBAL_MAX_DEPTH 500

View File

@ -496,34 +496,10 @@ Node::ReasonForTermination Node::run()
_r->sw->sendHELLO((*p)->address());
}
} else {
std::vector< SharedPtr<Peer> > needPing,needFirewallOpener;
if (resynchronize) {
_r->topology->eachPeer(Topology::CollectPeersWithDirectPath(needPing));
} else {
_r->topology->eachPeer(Topology::CollectPeersThatNeedPing(needPing));
}
for(std::vector< SharedPtr<Peer> >::iterator p(needPing.begin());p!=needPing.end();++p) {
try {
_r->sw->sendHELLO((*p)->address());
} catch (std::exception &exc) {
LOG("unexpected exception sending HELLO to %s: %s",(*p)->address().toString().c_str());
} catch ( ... ) {
LOG("unexpected exception sending HELLO to %s: (unknown)",(*p)->address().toString().c_str());
}
}
_r->topology->eachPeer(Topology::CollectPeersThatNeedFirewallOpener(needFirewallOpener));
for(std::vector< SharedPtr<Peer> >::iterator p(needFirewallOpener.begin());p!=needFirewallOpener.end();++p) {
try {
(*p)->sendFirewallOpener(_r,now);
} catch (std::exception &exc) {
LOG("unexpected exception sending firewall opener to %s: %s",(*p)->address().toString().c_str(),exc.what());
} catch ( ... ) {
LOG("unexpected exception sending firewall opener to %s: (unknown)",(*p)->address().toString().c_str());
}
}
if (resynchronize)
_r->topology->eachPeer(Topology::PingAllActivePeers(_r,now));
else _r->topology->eachPeer(Topology::PingPeersThatNeedPing(_r,now));
_r->topology->eachPeer(Topology::OpenPeersThatNeedFirewallOpener(_r,now));
}
} catch (std::exception &exc) {
LOG("unexpected exception running ping check cycle: %s",exc.what());

View File

@ -524,7 +524,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
// for the same frame would not be fair.
SharedPtr<Network> network(_r->nc->network(nwid));
if (network) {
maxDepth = network->multicastDepth(); // pull from network config if available
maxDepth = std::min((unsigned int)ZT_MULTICAST_GLOBAL_MAX_DEPTH,network->multicastDepth());
if (!network->isAllowed(origin)) {
TRACE("didn't inject MULTICAST_FRAME from %s(%s) into %.16llx: sender %s not allowed or we don't have a certificate",source().toString().c_str(),nwid,_remoteAddress.toString().c_str(),origin.toString().c_str());

View File

@ -126,6 +126,26 @@ bool Peer::sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now)
return sent;
}
bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now)
{
bool sent = false;
if (_ipv4p.addr) {
if (_r->sw->sendHELLO(SharedPtr<Peer>(this),_ipv4p.localPort,_ipv4p.addr)) {
_ipv4p.lastSend = now;
_dirty = true;
sent = true;
}
}
if (_ipv6p.addr) {
if (_r->sw->sendHELLO(SharedPtr<Peer>(this),_ipv6p.localPort,_ipv6p.addr)) {
_ipv6p.lastSend = now;
_dirty = true;
sent = true;
}
}
return sent;
}
void Peer::setPathAddress(const InetAddress &addr,bool fixed)
{
if (addr.isV4()) {

View File

@ -144,6 +144,15 @@ public:
*/
bool sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now);
/**
* Send HELLO to a peer using one or both active link types
*
* @param _r Runtime environment
* @param now Current time
* @return True if send appears successful for at least one address type
*/
bool sendPing(const RuntimeEnvironment *_r,uint64_t now);
/**
* Set an address to reach this peer
*
@ -222,18 +231,6 @@ public:
return _lastAnnouncedTo;
}
/**
* Set the time of last announcement
*
* @param t Time, typically current
*/
inline void setLastAnnouncedTo(const uint64_t t)
throw()
{
_lastAnnouncedTo = t;
_dirty = true;
}
/**
* @return Lowest of measured latencies of all paths or 0 if unknown
*/
@ -274,8 +271,9 @@ public:
}
/**
* @return True if this peer has at least one direct IP address path that looks active
*
* @param now Current time
* @return True if hasDirectPath() is true and at least one path is active
*/
inline bool hasActiveDirectPath(uint64_t now) const
throw()

View File

@ -379,7 +379,7 @@ unsigned long Switch::doTimerTasks()
void Switch::announceMulticastGroups(const std::map< SharedPtr<Network>,std::set<MulticastGroup> > &allMemberships)
{
std::vector< SharedPtr<Peer> > directPeers;
_r->topology->eachPeer(Topology::CollectPeersWithActiveDirectPath(directPeers));
_r->topology->eachPeer(Topology::CollectPeersWithActiveDirectPath(directPeers,Utils::now()));
#ifdef ZT_TRACE
unsigned int totalMulticastGroups = 0;

View File

@ -190,90 +190,109 @@ public:
/**
* Function object to collect peers that need a firewall opener sent
*/
class CollectPeersThatNeedFirewallOpener
class OpenPeersThatNeedFirewallOpener
{
public:
CollectPeersThatNeedFirewallOpener(std::vector< SharedPtr<Peer> > &v) :
_now(Utils::now()),
_v(v)
OpenPeersThatNeedFirewallOpener(const RuntimeEnvironment *renv,uint64_t now) throw() :
_now(now),
_r(renv)
{
}
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
if ((p->hasDirectPath())&&((_now - std::max(p->lastFirewallOpener(),p->lastDirectSend())) >= ZT_FIREWALL_OPENER_DELAY))
_v.push_back(p);
p->sendFirewallOpener(_r,_now);
}
private:
uint64_t _now;
std::vector< SharedPtr<Peer> > &_v;
const RuntimeEnvironment *_r;
};
/**
* Function object to collect peers that need a ping sent
*/
class CollectPeersThatNeedPing
class PingPeersThatNeedPing
{
public:
CollectPeersThatNeedPing(std::vector< SharedPtr<Peer> > &v) :
_now(Utils::now()),
_v(v)
PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) throw() :
_now(now),
_r(renv)
{
}
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
if ( ((t.isSupernode(p->address()))&&((_now - p->lastDirectReceive()) >= ZT_PEER_DIRECT_PING_DELAY)) || ((p->hasActiveDirectPath(_now))&&((_now - p->lastDirectSend()) >= ZT_PEER_DIRECT_PING_DELAY)) )
_v.push_back(p);
if (
((_now - p->lastDirectReceive()) >= ZT_PEER_DIRECT_PING_DELAY) &&
(
(
(p->hasDirectPath())&&
((_now - p->lastFrame()) < ZT_PEER_LINK_ACTIVITY_TIMEOUT)
) ||
(t.isSupernode(p->address()))
)
) {
p->sendPing(_r,_now);
}
}
private:
uint64_t _now;
std::vector< SharedPtr<Peer> > &_v;
const RuntimeEnvironment *_r;
};
/**
* Function object to collect peers with active links (and supernodes)
* Function object to collect peers that we're talking to
*/
class CollectPeersWithActiveDirectPath
class PingAllActivePeers
{
public:
CollectPeersWithActiveDirectPath(std::vector< SharedPtr<Peer> > &v) :
_now(Utils::now()),
_v(v)
PingAllActivePeers(const RuntimeEnvironment *renv,uint64_t now) throw() :
_now(now),
_r(renv)
{
}
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
if ((p->hasActiveDirectPath(_now))||(t.isSupernode(p->address())))
_v.push_back(p);
if (
(
(p->hasDirectPath())&&
((_now - p->lastFrame()) < ZT_PEER_LINK_ACTIVITY_TIMEOUT)
) ||
(t.isSupernode(p->address()))
) {
p->sendPing(_r,_now);
}
}
private:
uint64_t _now;
std::vector< SharedPtr<Peer> > &_v;
const RuntimeEnvironment *_r;
};
/**
* Function object to collect peers with any known direct path
*/
class CollectPeersWithDirectPath
class CollectPeersWithActiveDirectPath
{
public:
CollectPeersWithDirectPath(std::vector< SharedPtr<Peer> > &v) :
CollectPeersWithActiveDirectPath(std::vector< SharedPtr<Peer> > &v,uint64_t now) throw() :
_now(now),
_v(v)
{
}
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
if (p->hasDirectPath())
if (p->hasActiveDirectPath(_now))
_v.push_back(p);
}
private:
uint64_t _now;
std::vector< SharedPtr<Peer> > &_v;
};