Browse Source

Fix for GitHub issue #38: compute whether we are ONLINE a little differently

Adam Ierymenko 11 years ago
parent
commit
4ec7cd2760
3 changed files with 13 additions and 3 deletions
  1. 3 2
      node/Node.cpp
  2. 6 1
      node/NodeConfig.cpp
  3. 4 0
      node/RuntimeEnvironment.hpp

+ 3 - 2
node/Node.cpp

@@ -511,8 +511,7 @@ Node::ReasonForTermination Node::run()
 		 * in the natural Mac way. */
 		std::string shutdownIfUnreadablePath(_r->homePath + ZT_PATH_SEPARATOR_S + "shutdownIfUnreadable");
 
-		// TODO: persist some of this stuff between restarts
-		uint64_t lastNetworkAutoconfCheck = Utils::now() - 5000; // check autoconf again after 5s for startup
+		uint64_t lastNetworkAutoconfCheck = Utils::now() - 5000ULL; // check autoconf again after 5s for startup
 		uint64_t lastPingCheck = 0;
 		uint64_t lastSupernodePing = 0;
 		uint64_t lastClean = Utils::now(); // don't need to do this immediately
@@ -520,6 +519,7 @@ Node::ReasonForTermination Node::run()
 		uint64_t lastMulticastCheck = 0;
 
 		uint64_t networkConfigurationFingerprint = _r->sysEnv->getNetworkConfigurationFingerprint(_r->nc->networkTapDeviceNames());
+		_r->timeOfLastNetworkEnvironmentChange = Utils::now();
 		long lastDelayDelta = 0;
 
 		while (impl->reasonForTermination == NODE_RUNNING) {
@@ -551,6 +551,7 @@ Node::ReasonForTermination Node::run()
 				if (fp != networkConfigurationFingerprint) {
 					LOG("netconf fingerprint change: %.16llx != %.16llx, resyncing with network",networkConfigurationFingerprint,fp);
 					networkConfigurationFingerprint = fp;
+					_r->timeOfLastNetworkEnvironmentChange = now;
 					resynchronize = true;
 				}
 			}

+ 6 - 1
node/NodeConfig.cpp

@@ -195,15 +195,20 @@ std::vector<std::string> NodeConfig::execute(const char *command)
 		_P("200 help terminate [<reason>]");
 		_P("200 help updatecheck");
 	} else if (cmd[0] == "info") {
+		// We are online if at least one supernode has spoken to us since the last time our
+		// network environment changed and also less than ZT_PEER_LINK_ACTIVITY_TIMEOUT ago.
 		bool isOnline = false;
 		uint64_t now = Utils::now();
+		uint64_t since = _r->timeOfLastNetworkEnvironmentChange;
 		std::vector< SharedPtr<Peer> > snp(_r->topology->supernodePeers());
 		for(std::vector< SharedPtr<Peer> >::const_iterator sn(snp.begin());sn!=snp.end();++sn) {
-			if ((*sn)->hasActiveDirectPath(now)) {
+			uint64_t lastRec = (*sn)->lastDirectReceive();
+			if ((lastRec)&&(lastRec > since)&&((now - lastRec) < ZT_PEER_LINK_ACTIVITY_TIMEOUT)) {
 				isOnline = true;
 				break;
 			}
 		}
+
 		_P("200 info %s %s %s",_r->identity.address().toString().c_str(),(isOnline ? "ONLINE" : "OFFLINE"),Node::versionString());
 	} else if (cmd[0] == "listpeers") {
 		_P("200 listpeers <ztaddr> <ipv4> <ipv6> <latency> <version>");

+ 4 - 0
node/RuntimeEnvironment.hpp

@@ -65,6 +65,7 @@ class RuntimeEnvironment
 public:
 	RuntimeEnvironment() :
 		shutdownInProgress(false),
+		timeOfLastNetworkEnvironmentChange(0),
 		log((Logger *)0),
 		prng((CMWC4096 *)0),
 		mc((Multicaster *)0),
@@ -93,6 +94,9 @@ public:
 	// Indicates that we are shutting down -- this is hacky, want to factor out
 	volatile bool shutdownInProgress;
 
+	// Time network environment (e.g. fingerprint) last changed -- used to determine online-ness
+	volatile uint64_t timeOfLastNetworkEnvironmentChange;
+
 	/*
 	 * Order matters a bit here. These are constructed in this order
 	 * and then deleted in the opposite order on Node exit. The order ensures