diff options
Diffstat (limited to 'node/Node.cpp')
| -rw-r--r-- | node/Node.cpp | 100 |
1 files changed, 65 insertions, 35 deletions
diff --git a/node/Node.cpp b/node/Node.cpp index c5c9873c..9f195a10 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -184,27 +184,41 @@ ZT1_ResultCode Node::processVirtualNetworkFrame( class _PingPeersThatNeedPing { public: - _PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) : + _PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now,const std::vector< std::pair<Address,InetAddress> > &relays) : lastReceiveFromUpstream(0), RR(renv), _now(now), - _supernodes(RR->topology->supernodeAddresses()) {} + _relays(relays), + _supernodes(RR->topology->supernodeAddresses()) + { + } uint64_t lastReceiveFromUpstream; inline void operator()(Topology &t,const SharedPtr<Peer> &p) { - if (std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end()) { + bool isRelay = false; + for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(_relays.begin());r!=_relays.end();++r) { + if (r->first == p->address()) { + isRelay = true; + break; + } + } + + if ((isRelay)||(std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end())) { p->doPingAndKeepalive(RR,_now); if (p->lastReceive() > lastReceiveFromUpstream) lastReceiveFromUpstream = p->lastReceive(); - } else if (p->alive(_now)) { - p->doPingAndKeepalive(RR,_now); + } else { + if (p->alive(_now)) + p->doPingAndKeepalive(RR,_now); } } + private: const RuntimeEnvironment *RR; uint64_t _now; + const std::vector< std::pair<Address,InetAddress> > &_relays; std::vector<Address> _supernodes; }; @@ -214,54 +228,70 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next Mutex::Lock bl(_backgroundTasksLock); if ((now - _lastPingCheck) >= ZT_PING_CHECK_INVERVAL) { - _lastPingCheck = now; - try { - _PingPeersThatNeedPing pfunc(RR,now); + _lastPingCheck = now; + + // Get relays and networks that need config without leaving the mutex locked + std::vector< std::pair<Address,InetAddress> > networkRelays; + std::vector< SharedPtr<Network> > needConfig; + { + Mutex::Lock _l(_networks_m); + for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) { + SharedPtr<NetworkConfig> nc(n->second->config2()); + if (((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!nc)) + needConfig.push_back(n->second); + if (nc) + networkRelays.insert(networkRelays.end(),nc->relays().begin(),nc->relays().end()); + } + } + + // Request updated configuration for networks that need it + for(std::vector< SharedPtr<Network> >::const_iterator n(needConfig.begin());n!=needConfig.end();++n) + (*n)->requestConfiguration(); + + // Attempt to contact network preferred relays that we don't have direct links to + std::sort(networkRelays.begin(),networkRelays.end()); + std::unique(networkRelays.begin(),networkRelays.end()); + for(std::vector< std::pair<Address,InetAddress> >::const_iterator nr(networkRelays.begin());nr!=networkRelays.end();++nr) { + if (nr->second) { + SharedPtr<Peer> rp(RR->topology->getPeer(nr->first)); + if ((rp)&&(!rp->hasActiveDirectPath(now))) + rp->attemptToContactAt(RR,nr->second,now); + } + } + + // Ping living or supernode/relay peers + _PingPeersThatNeedPing pfunc(RR,now,networkRelays); RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc); + // Update online status, post status change as event bool oldOnline = _online; _online = ((now - pfunc.lastReceiveFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT); if (oldOnline != _online) postEvent(_online ? ZT1_EVENT_ONLINE : ZT1_EVENT_OFFLINE); - } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; - } - try { - Mutex::Lock _l(_networks_m); - for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) { - if ((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY) - n->second->requestConfiguration(); + // Send LAN beacons + if ((now - _lastBeacon) >= ZT_BEACON_INTERVAL) { + _lastBeacon = now; + char beacon[13]; + void *p = beacon; + *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32(); + p = beacon + 4; + *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32(); + RR->identity.address().copyTo(beacon + 8,5); + RR->antiRec->logOutgoingZT(beacon,13); + putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13); } } catch ( ... ) { return ZT1_RESULT_FATAL_ERROR_INTERNAL; } - - if ((now - _lastBeacon) >= ZT_BEACON_INTERVAL) { - _lastBeacon = now; - char beacon[13]; - void *p = beacon; - *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32(); - p = beacon + 4; - *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32(); - RR->identity.address().copyTo(beacon + 8,5); - RR->antiRec->logOutgoingZT(beacon,13); - putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13); - } } if ((now - _lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) { - _lastHousekeepingRun = now; - try { + _lastHousekeepingRun = now; RR->topology->clean(now); RR->sa->clean(now); - } catch ( ... ) { - return ZT1_RESULT_FATAL_ERROR_INTERNAL; - } - - try { RR->mc->clean(now); } catch ( ... ) { return ZT1_RESULT_FATAL_ERROR_INTERNAL; |
