Browse Source

Some adjustments to TCP logic for GitHub issue #60

Adam Ierymenko 11 years ago
parent
commit
28a6d328a5
3 changed files with 32 additions and 32 deletions
  1. 15 22
      node/Constants.hpp
  2. 7 3
      node/Node.cpp
  3. 10 7
      node/Peer.cpp

+ 15 - 22
node/Constants.hpp

@@ -255,7 +255,7 @@ error_no_byte_order_defined;
 /**
  * Delay between scans of the topology active peer DB for peers that need ping
  */
-#define ZT_PING_CHECK_DELAY 7000
+#define ZT_PING_CHECK_DELAY 10000
 
 /**
  * Delay between checks of network configuration fingerprint
@@ -283,52 +283,45 @@ error_no_byte_order_defined;
 /**
  * Delay in core loop between checks of network autoconf newness
  */
-#define ZT_NETWORK_AUTOCONF_CHECK_DELAY 7000
+#define ZT_NETWORK_AUTOCONF_CHECK_DELAY 10000
 
 /**
- * Minimum delay in Node service loop
- * 
- * This is the shortest of the check delays/periods.
+ * Time since a ping was sent to be considered unanswered
  */
-#define ZT_MIN_SERVICE_LOOP_INTERVAL 5000
+#define ZT_PING_UNANSWERED_AFTER 1500
 
 /**
- * Activity timeout for links
- * 
- * A link that hasn't spoken in this long is simply considered inactive.
+ * Try to ping supernodes this often until we get something from somewhere
  */
-#define ZT_PEER_PATH_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 2) + 10000)
+#define ZT_STARTUP_AGGRO (ZT_PING_UNANSWERED_AFTER * 2)
 
 /**
- * Close TCP tunnels if unused for this long
+ * Maximum delay between runs of the main service loop
+ * 
+ * This is the shortest of the check delays/periods.
  */
-#define ZT_TCP_TUNNEL_ACTIVITY_TIMEOUT (ZT_PEER_PATH_ACTIVITY_TIMEOUT + 10000)
+#define ZT_MAX_SERVICE_LOOP_INTERVAL ZT_STARTUP_AGGRO
 
 /**
  * Try TCP tunnels if nothing received for this long
  */
-#define ZT_TCP_TUNNEL_FAILOVER_TIMEOUT 5000
+#define ZT_TCP_TUNNEL_FAILOVER_TIMEOUT (ZT_STARTUP_AGGRO * 5)
 
 /**
- * Try to ping supernodes this often until we get something from somewhere
+ * Path activity timeout
  */
-#define ZT_STARTUP_AGGRO 5000
+#define ZT_PEER_PATH_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 2) + ZT_PING_CHECK_DELAY)
 
 /**
- * Time since a ping was sent to be considered unanswered
+ * Close TCP tunnels if unused for this long
  */
-#define ZT_PING_UNANSWERED_AFTER 2500
+#define ZT_TCP_TUNNEL_ACTIVITY_TIMEOUT ZT_PEER_PATH_ACTIVITY_TIMEOUT
 
 /**
  * Stop relaying via peers that have not responded to direct sends in this long
  */
 #define ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD 10000
 
-/**
- * Number of outgoing verb/packetId pairs to keep for sends expecting responses
- */
-#define ZT_PEER_REQUEST_HISTORY_LENGTH 8
-
 /**
  * IP hops (a.k.a. TTL) to set for firewall opener packets
  *

+ 7 - 3
node/Node.cpp

@@ -546,14 +546,18 @@ Node::ReasonForTermination Node::run()
 		_r->timeOfLastResynchronize = Utils::now();
 
 		while (impl->reasonForTermination == NODE_RUNNING) {
-			//TRACE("--- BEGIN main I/O loop");
-
+			/* This is how the service automatically shuts down when the OSX .app is
+			 * thrown in the trash. It's not used on any other platform for now but
+			 * could do similar things. It's disabled on Windows since it doesn't really
+			 * work there. */
+#ifdef __UNIX_LIKE__
 			if (Utils::fileExists(shutdownIfUnreadablePath.c_str(),false)) {
 				FILE *tmpf = fopen(shutdownIfUnreadablePath.c_str(),"r");
 				if (!tmpf)
 					return impl->terminateBecause(Node::NODE_NORMAL_TERMINATION,"shutdownIfUnreadable exists but is not readable");
 				fclose(tmpf);
 			}
+#endif
 
 			uint64_t now = Utils::now();
 			bool resynchronize = false;
@@ -664,7 +668,7 @@ Node::ReasonForTermination Node::run()
 
 			// Sleep for loop interval or until something interesting happens.
 			try {
-				unsigned long delay = std::min((unsigned long)ZT_MIN_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks());
+				unsigned long delay = std::min((unsigned long)ZT_MAX_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks());
 				uint64_t start = Utils::now();
 				_r->sm->poll(delay);
 				lastDelayDelta = (long)(Utils::now() - start) - (long)delay; // used to detect sleep/wake

+ 10 - 7
node/Peer.cpp

@@ -117,25 +117,28 @@ void Peer::receive(
 		_lastMulticastFrame = now;
 }
 
-
 bool Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int len,uint64_t now)
 {
 	Mutex::Lock _l(_lock);
-	bool useTcp = _isTcpFailoverTime(_r,now);
+	bool useTcpOut = _isTcpFailoverTime(_r,now);
 
 	std::vector<Path>::iterator p(_paths.begin());
-	if (useTcp) {
-		while ((p->tcp())&&(p != _paths.end()))
+	if (!useTcpOut) {
+		// If we don't want to initiate TCP, seek past TCP paths if they are at the front
+		// to find the first UDP path as our default.
+		while ((p != _paths.end())&&(p->type() == Path::PATH_TYPE_TCP_OUT))
 			++p;
 	}
 	if (p == _paths.end())
 		return false;
 
-	uint64_t bestPathLastReceived = p->lastReceived();
+	// Treat first path as default and look for a better one based on time of
+	// last packet received.
 	std::vector<Path>::iterator bestPath = p;
+	uint64_t bestPathLastReceived = p->lastReceived();
 	while (++p != _paths.end()) {
 		uint64_t lr = p->lastReceived();
-		if ( (lr > bestPathLastReceived) && ((useTcp)||(!p->tcp())) ) {
+		if ( (lr > bestPathLastReceived) && ((useTcpOut)||(p->type() != Path::PATH_TYPE_TCP_OUT)) ) {
 			bestPathLastReceived = lr;
 			bestPath = p;
 		}
@@ -215,7 +218,7 @@ bool Peer::_isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
 			}
 		}
 
-		return ( (lastUdpPingSent > lastResync) && (lastUdpPingSent > lastUdpReceive) && ((now - lastUdpPingSent) >= ZT_TCP_TUNNEL_FAILOVER_TIMEOUT) );
+		return ( (lastUdpPingSent > lastResync) && ((now - lastUdpReceive) >= ZT_TCP_TUNNEL_FAILOVER_TIMEOUT) );
 	}
 	return false;
 }