From 9f5bccec302cd6c738f564d5dda8919db245d010 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 16 Sep 2019 18:03:17 -0700 Subject: [PATCH] Add a recv timeout to root --- node/Node.cpp | 40 ++++++++++++------------------------- node/Topology.hpp | 50 +++++++++++++++++++++++++++-------------------- root/root.cpp | 13 +++++++++--- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/node/Node.cpp b/node/Node.cpp index 0d102a71a..af9cff8cd 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -173,7 +173,6 @@ ZT_ResultCode Node::processVirtualNetworkFrame( } else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } -#if 0 struct _processBackgroundTasks_ping_eachRoot { Hashtable< void *,bool > roots; @@ -181,32 +180,19 @@ struct _processBackgroundTasks_ping_eachRoot void *tPtr; bool online; - ZT_ALWAYS_INLINE void operator()(const Root &root,const SharedPtr &peer) + ZT_ALWAYS_INLINE void operator()(const SharedPtr &peer,const std::vector &addrs) { unsigned int v4SendCount = 0,v6SendCount = 0; peer->ping(tPtr,now,v4SendCount,v6SendCount); - - const InetAddress *contactAddrs[2]; - unsigned int contactAddrCount = 0; - if (v4SendCount == 0) { - if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET)))) - ++contactAddrCount; + for(std::vector::const_iterator a(addrs.begin());a!=addrs.end();++a) { + if ( ((a->isV4())&&(v4SendCount == 0)) || ((a->isV6())&&(v6SendCount == 0)) ) + peer->sendHELLO(tPtr,-1,*a,now); } - if (v6SendCount == 0) { - if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET6)))) - ++contactAddrCount; - } - - for(unsigned int i=0;isendHELLO(tPtr,-1,*contactAddrs[i],now); - if (!online) online = ((now - peer->lastReceive()) <= ((ZT_PEER_PING_PERIOD * 2) + 5000)); - roots.set((void *)peer.ptr(),true); } }; -#endif struct _processBackgroundTasks_ping_eachPeer { @@ -231,30 +217,30 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64 // Initialize these on first call so these things happen just a few seconds after // startup, since right at startup things are likely to not be ready to communicate // at all yet. - if (_lastNetworkHousekeepingRun <= 0) _lastNetworkHousekeepingRun = now - (ZT_NETWORK_HOUSEKEEPING_PERIOD / 3); - if (_lastHousekeepingRun <= 0) _lastHousekeepingRun = now; + if (_lastNetworkHousekeepingRun <= 0) + _lastNetworkHousekeepingRun = now - (ZT_NETWORK_HOUSEKEEPING_PERIOD / 3); + if (_lastHousekeepingRun <= 0) + _lastHousekeepingRun = now; if ((now - _lastPing) >= ZT_PEER_PING_PERIOD) { _lastPing = now; try { -#if 0 _processBackgroundTasks_ping_eachRoot rf; rf.now = now; rf.tPtr = tptr; rf.online = false; RR->topology->eachRoot(rf); -#endif _processBackgroundTasks_ping_eachPeer pf; pf.now = now; pf.tPtr = tptr; - //pf.roots = &rf.roots; + pf.roots = &rf.roots; RR->topology->eachPeer(pf); - //if (rf.online != _online) { - // _online = rf.online; - // postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); - //} + if (rf.online != _online) { + _online = rf.online; + postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); + } } catch ( ... ) { return ZT_RESULT_FATAL_ERROR_INTERNAL; } diff --git a/node/Topology.hpp b/node/Topology.hpp index ef7e546df..83a4ae447 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -64,6 +64,19 @@ private: unsigned int bestRootLatency; }; + ZT_ALWAYS_INLINE void _updateDynamicRootIdentities() + { + // assumes _dynamicRoots_l is locked + _dynamicRootIdentities.clear(); + Hashtable< Str,Locator >::Iterator i(_dynamicRoots); + Str *k = (Str *)0; + Locator *v = (Locator *)0; + while (i.next(k,v)) { + if (v->id()) + _dynamicRootIdentities.set(v->id(),true); + } + } + public: ZT_ALWAYS_INLINE Topology(const RuntimeEnvironment *renv,const Identity &myId) : RR(renv), @@ -244,7 +257,7 @@ public: * @tparam F function or function object type */ template - inline void eachRoot(F f) + ZT_ALWAYS_INLINE void eachRoot(F f) { { Mutex::Lock l(_dynamicRoots_l); @@ -343,6 +356,15 @@ public: _staticRoots.erase(id); } + /** + * Clear all static roots + */ + ZT_ALWAYS_INLINE void removeStaticRoot() + { + Mutex::Lock l(_staticRoots_l); + _staticRoots.clear(); + } + /** * @return Names of dynamic roots currently known by the system */ @@ -353,14 +375,13 @@ public: } /** - * Set or update dynamic root if new locator is newer and valid + * Set or update dynamic root if new locator is newer * - * This checks internal validity of the new locator including its internal self-signature. - * It does not check any DNS signatures. + * This does not check signatures or internal validity of the locator. * * @param dnsName DNS name used to retrive root * @param latestLocator Latest locator - * @return True if latest locator is internally valid and newer + * @return True if locator is newer */ ZT_ALWAYS_INLINE bool setDynamicRoot(const Str &dnsName,const Locator &latestLocator) { @@ -389,7 +410,7 @@ public: /** * Remove all dynamic roots */ - ZT_ALWAYS_INLINE bool clearDynamicRoots(const Str &dnsName) + ZT_ALWAYS_INLINE bool clearDynamicRoots() { Mutex::Lock l(_dynamicRoots_l); _dynamicRoots.clear(); @@ -406,13 +427,13 @@ public: ZT_ALWAYS_INLINE SharedPtr findRelayTo(const int64_t now,const Address &toAddr) { // TODO: in the future this will check 'mesh-like' relays and if enabled consult LF for other roots (for if this is a root) - //return root(now); + return root(now); } /** * @param allPeers vector to fill with all current peers */ - inline void getAllPeers(std::vector< SharedPtr > &allPeers) const + ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr > &allPeers) const { Mutex::Lock l(_peers_l); allPeers.clear(); @@ -528,19 +549,6 @@ public: } private: - inline void _updateDynamicRootIdentities() - { - // assumes _dynamicRoots_l is locked - _dynamicRootIdentities.clear(); - Hashtable< Str,Locator >::Iterator i(_dynamicRoots); - Str *k = (Str *)0; - Locator *v = (Locator *)0; - while (i.next(k,v)) { - if (v->id()) - _dynamicRootIdentities.set(v->id(),true); - } - } - const RuntimeEnvironment *const RR; const Identity _myIdentity; diff --git a/root/root.cpp b/root/root.cpp index 5275bdbad..83dc82b2c 100644 --- a/root/root.cpp +++ b/root/root.cpp @@ -671,13 +671,20 @@ static int bindSocket(struct sockaddr *const bindAddr) #endif */ -#if defined(SO_REUSEPORT) +#ifdef SO_REUSEPORT f = 1; setsockopt(s,SOL_SOCKET,SO_REUSEPORT,(void *)&f,sizeof(f)); #endif #ifndef __LINUX__ // linux wants just SO_REUSEPORT f = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); #endif +#ifdef __LINUX__ + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(const void *)&tv,sizeof(tv)); +#endif + if (bind(s,bindAddr,(bindAddr->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))) { close(s); //printf("%s\n",strerror(errno)); @@ -911,7 +918,7 @@ int main(int argc,char **argv) printf("WARNING: unexpected exception handling packet from %s: unknown exception" ZT_EOL_S,reinterpret_cast(&in6)->toString(ipstr)); } } - } else { + } else if ((errno != EAGAIN)&&(errno != EWOULDBLOCK)) { break; } } @@ -940,7 +947,7 @@ int main(int argc,char **argv) printf("WARNING: unexpected exception handling packet from %s: unknown exception" ZT_EOL_S,reinterpret_cast(&in4)->toString(ipstr)); } } - } else { + } else if ((errno != EAGAIN)&&(errno != EWOULDBLOCK)) { break; } }