Browse Source

Always ping / contact network preferred relays (if any).

Adam Ierymenko 10 years ago
parent
commit
5bc89034bc
3 changed files with 37 additions and 5 deletions
  1. 32 3
      node/Node.cpp
  2. 3 1
      node/Peer.cpp
  3. 2 1
      node/Peer.hpp

+ 32 - 3
node/Node.cpp

@@ -188,24 +188,53 @@ public:
 		lastReceiveFromUpstream(0),
 		RR(renv),
 		_now(now),
-		_supernodes(RR->topology->supernodeAddresses()) {}
+		_supernodes(RR->topology->supernodeAddresses()),
+		_networkRelays()
+	{
+		std::vector< SharedPtr<Network> > nws(renv->node->allNetworks());
+		for(std::vector< SharedPtr<Network> >::const_iterator nw(nws.begin());nw!=nws.end();++nw) {
+			SharedPtr<NetworkConfig> nc((*nw)->config2());
+			if (nc)
+				_networkRelays.insert(_networkRelays.end(),nc->relays().begin(),nc->relays().end());
+		}
+		std::sort(_networkRelays.begin(),_networkRelays.end());
+		std::unique(_networkRelays.begin(),_networkRelays.end());
+	}
 
 	uint64_t lastReceiveFromUpstream;
 
 	inline void operator()(Topology &t,const SharedPtr<Peer> &p)
 	{
 		if (std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end()) {
+			// Supernodes have fixed addresses and are always pinged
 			p->doPingAndKeepalive(RR,_now);
 			if (p->lastReceive() > lastReceiveFromUpstream)
 				lastReceiveFromUpstream = p->lastReceive();
-		} else if (p->alive(_now)) {
-			p->doPingAndKeepalive(RR,_now);
+		} else {
+			// Ping regular peers if they are alive, or if they are network
+			// designated relays with suggested IP address endpoints in a
+			// network config.
+			bool ison;
+			if (p->alive(_now))
+				ison = p->doPingAndKeepalive(RR,_now);
+			else ison = false;
+
+			if (!ison) {
+				// Note that multiple networks might designate the same peer as
+				// a preferred relay, so try all suggested endpoints.
+				for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(_networkRelays.begin());r!=_networkRelays.end();++r) {
+					if (r->first == p->address())
+						p->attemptToContactAt(RR,r->second,_now);
+				}
+			}
 		}
 	}
+
 private:
 	const RuntimeEnvironment *RR;
 	uint64_t _now;
 	std::vector<Address> _supernodes;
+	std::vector< std::pair<Address,InetAddress> > _networkRelays;
 };
 
 ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)

+ 3 - 1
node/Peer.cpp

@@ -191,7 +191,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at
 	RR->node->putPacket(atAddress,outp.data(),outp.size());
 }
 
-void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
+bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
 {
 	Path *const bestPath = getBestPath(now);
 	if ((bestPath)&&(bestPath->active(now))) {
@@ -204,7 +204,9 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
 			RR->node->putPacket(bestPath->address(),"",0);
 			bestPath->sent(now);
 		}
+		return true;
 	}
+	return false;
 }
 
 void Peer::addPath(const Path &newp)

+ 2 - 1
node/Peer.hpp

@@ -179,8 +179,9 @@ public:
 	 *
 	 * @param RR Runtime environment
 	 * @param now Current time
+	 * @return True if there is an active best path (regardless of whether it needed a ping or keepalive), false if no paths
 	 */
-	void doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now);
+	bool doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now);
 
 	/**
 	 * @return All known direct paths to this peer