Add a recv timeout to root

This commit is contained in:
Adam Ierymenko 2019-09-16 18:03:17 -07:00
parent ade52bf81e
commit 9f5bccec30
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3
3 changed files with 52 additions and 51 deletions

@ -173,7 +173,6 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND; } else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
} }
#if 0
struct _processBackgroundTasks_ping_eachRoot struct _processBackgroundTasks_ping_eachRoot
{ {
Hashtable< void *,bool > roots; Hashtable< void *,bool > roots;
@ -181,32 +180,19 @@ struct _processBackgroundTasks_ping_eachRoot
void *tPtr; void *tPtr;
bool online; bool online;
ZT_ALWAYS_INLINE void operator()(const Root &root,const SharedPtr<Peer> &peer) ZT_ALWAYS_INLINE void operator()(const SharedPtr<Peer> &peer,const std::vector<InetAddress> &addrs)
{ {
unsigned int v4SendCount = 0,v6SendCount = 0; unsigned int v4SendCount = 0,v6SendCount = 0;
peer->ping(tPtr,now,v4SendCount,v6SendCount); peer->ping(tPtr,now,v4SendCount,v6SendCount);
for(std::vector<InetAddress>::const_iterator a(addrs.begin());a!=addrs.end();++a) {
const InetAddress *contactAddrs[2]; if ( ((a->isV4())&&(v4SendCount == 0)) || ((a->isV6())&&(v6SendCount == 0)) )
unsigned int contactAddrCount = 0; peer->sendHELLO(tPtr,-1,*a,now);
if (v4SendCount == 0) {
if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET))))
++contactAddrCount;
} }
if (v6SendCount == 0) {
if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET6))))
++contactAddrCount;
}
for(unsigned int i=0;i<contactAddrCount;++i)
peer->sendHELLO(tPtr,-1,*contactAddrs[i],now);
if (!online) if (!online)
online = ((now - peer->lastReceive()) <= ((ZT_PEER_PING_PERIOD * 2) + 5000)); online = ((now - peer->lastReceive()) <= ((ZT_PEER_PING_PERIOD * 2) + 5000));
roots.set((void *)peer.ptr(),true); roots.set((void *)peer.ptr(),true);
} }
}; };
#endif
struct _processBackgroundTasks_ping_eachPeer 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 // 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 // startup, since right at startup things are likely to not be ready to communicate
// at all yet. // at all yet.
if (_lastNetworkHousekeepingRun <= 0) _lastNetworkHousekeepingRun = now - (ZT_NETWORK_HOUSEKEEPING_PERIOD / 3); if (_lastNetworkHousekeepingRun <= 0)
if (_lastHousekeepingRun <= 0) _lastHousekeepingRun = now; _lastNetworkHousekeepingRun = now - (ZT_NETWORK_HOUSEKEEPING_PERIOD / 3);
if (_lastHousekeepingRun <= 0)
_lastHousekeepingRun = now;
if ((now - _lastPing) >= ZT_PEER_PING_PERIOD) { if ((now - _lastPing) >= ZT_PEER_PING_PERIOD) {
_lastPing = now; _lastPing = now;
try { try {
#if 0
_processBackgroundTasks_ping_eachRoot rf; _processBackgroundTasks_ping_eachRoot rf;
rf.now = now; rf.now = now;
rf.tPtr = tptr; rf.tPtr = tptr;
rf.online = false; rf.online = false;
RR->topology->eachRoot(rf); RR->topology->eachRoot(rf);
#endif
_processBackgroundTasks_ping_eachPeer pf; _processBackgroundTasks_ping_eachPeer pf;
pf.now = now; pf.now = now;
pf.tPtr = tptr; pf.tPtr = tptr;
//pf.roots = &rf.roots; pf.roots = &rf.roots;
RR->topology->eachPeer(pf); RR->topology->eachPeer(pf);
//if (rf.online != _online) { if (rf.online != _online) {
// _online = rf.online; _online = rf.online;
// postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE); postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
//} }
} catch ( ... ) { } catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL; return ZT_RESULT_FATAL_ERROR_INTERNAL;
} }

@ -64,6 +64,19 @@ private:
unsigned int bestRootLatency; 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: public:
ZT_ALWAYS_INLINE Topology(const RuntimeEnvironment *renv,const Identity &myId) : ZT_ALWAYS_INLINE Topology(const RuntimeEnvironment *renv,const Identity &myId) :
RR(renv), RR(renv),
@ -244,7 +257,7 @@ public:
* @tparam F function or function object type * @tparam F function or function object type
*/ */
template<typename F> template<typename F>
inline void eachRoot(F f) ZT_ALWAYS_INLINE void eachRoot(F f)
{ {
{ {
Mutex::Lock l(_dynamicRoots_l); Mutex::Lock l(_dynamicRoots_l);
@ -343,6 +356,15 @@ public:
_staticRoots.erase(id); _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 * @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. * This does not check signatures or internal validity of the locator.
* It does not check any DNS signatures.
* *
* @param dnsName DNS name used to retrive root * @param dnsName DNS name used to retrive root
* @param latestLocator Latest locator * @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) ZT_ALWAYS_INLINE bool setDynamicRoot(const Str &dnsName,const Locator &latestLocator)
{ {
@ -389,7 +410,7 @@ public:
/** /**
* Remove all dynamic roots * Remove all dynamic roots
*/ */
ZT_ALWAYS_INLINE bool clearDynamicRoots(const Str &dnsName) ZT_ALWAYS_INLINE bool clearDynamicRoots()
{ {
Mutex::Lock l(_dynamicRoots_l); Mutex::Lock l(_dynamicRoots_l);
_dynamicRoots.clear(); _dynamicRoots.clear();
@ -406,13 +427,13 @@ public:
ZT_ALWAYS_INLINE SharedPtr<Peer> findRelayTo(const int64_t now,const Address &toAddr) ZT_ALWAYS_INLINE SharedPtr<Peer> 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) // 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 * @param allPeers vector to fill with all current peers
*/ */
inline void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const ZT_ALWAYS_INLINE void getAllPeers(std::vector< SharedPtr<Peer> > &allPeers) const
{ {
Mutex::Lock l(_peers_l); Mutex::Lock l(_peers_l);
allPeers.clear(); allPeers.clear();
@ -528,19 +549,6 @@ public:
} }
private: 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 RuntimeEnvironment *const RR;
const Identity _myIdentity; const Identity _myIdentity;

@ -671,13 +671,20 @@ static int bindSocket(struct sockaddr *const bindAddr)
#endif #endif
*/ */
#if defined(SO_REUSEPORT) #ifdef SO_REUSEPORT
f = 1; setsockopt(s,SOL_SOCKET,SO_REUSEPORT,(void *)&f,sizeof(f)); f = 1; setsockopt(s,SOL_SOCKET,SO_REUSEPORT,(void *)&f,sizeof(f));
#endif #endif
#ifndef __LINUX__ // linux wants just SO_REUSEPORT #ifndef __LINUX__ // linux wants just SO_REUSEPORT
f = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); f = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f));
#endif #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))) { if (bind(s,bindAddr,(bindAddr->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))) {
close(s); close(s);
//printf("%s\n",strerror(errno)); //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<const InetAddress *>(&in6)->toString(ipstr)); printf("WARNING: unexpected exception handling packet from %s: unknown exception" ZT_EOL_S,reinterpret_cast<const InetAddress *>(&in6)->toString(ipstr));
} }
} }
} else { } else if ((errno != EAGAIN)&&(errno != EWOULDBLOCK)) {
break; 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<const InetAddress *>(&in4)->toString(ipstr)); printf("WARNING: unexpected exception handling packet from %s: unknown exception" ZT_EOL_S,reinterpret_cast<const InetAddress *>(&in4)->toString(ipstr));
} }
} }
} else { } else if ((errno != EAGAIN)&&(errno != EWOULDBLOCK)) {
break; break;
} }
} }