Browse Source

Add a recv timeout to root

Adam Ierymenko 5 years ago
parent
commit
9f5bccec30
3 changed files with 52 additions and 51 deletions
  1. 13 27
      node/Node.cpp
  2. 29 21
      node/Topology.hpp
  3. 10 3
      root/root.cpp

+ 13 - 27
node/Node.cpp

@@ -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);
-
-		const InetAddress *contactAddrs[2];
-		unsigned int contactAddrCount = 0;
-		if (v4SendCount == 0) {
-			if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET))))
-				++contactAddrCount;
-		}
-		if (v6SendCount == 0) {
-			if (*(contactAddrs[contactAddrCount] = &(root.pickPhysical(AF_INET6))))
-				++contactAddrCount;
+		for(std::vector<InetAddress>::const_iterator a(addrs.begin());a!=addrs.end();++a) {
+			if ( ((a->isV4())&&(v4SendCount == 0)) || ((a->isV6())&&(v6SendCount == 0)) )
+				peer->sendHELLO(tPtr,-1,*a,now);
 		}
 		}
-
-		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 (_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) {
 	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) {
-			//	_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 ( ... ) {
 		} catch ( ... ) {
 			return ZT_RESULT_FATAL_ERROR_INTERNAL;
 			return ZT_RESULT_FATAL_ERROR_INTERNAL;
 		}
 		}

+ 29 - 21
node/Topology.hpp

@@ -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.
-	 * 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 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;
 
 

+ 10 - 3
root/root.cpp

@@ -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;
 					}
 					}
 				}
 				}