Browse Source

Merge branch 'adamierymenko-dev' into android-jni

Grant Limberg 10 years ago
parent
commit
b242886c33
5 changed files with 41 additions and 15 deletions
  1. 6 0
      node/Node.cpp
  2. 2 8
      node/Peer.cpp
  3. 3 4
      node/Peer.hpp
  4. 29 2
      node/SelfAwareness.cpp
  5. 1 1
      service/OneService.cpp

+ 6 - 0
node/Node.cpp

@@ -25,6 +25,12 @@
  * LLC. Start here: http://www.zerotier.com/
  * LLC. Start here: http://www.zerotier.com/
  */
  */
 
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdint.h>
+
 #include "../version.h"
 #include "../version.h"
 
 
 #include "Constants.hpp"
 #include "Constants.hpp"

+ 2 - 8
node/Peer.cpp

@@ -261,7 +261,7 @@ void Peer::clearPaths(bool fixedToo)
 	}
 	}
 }
 }
 
 
-void Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope scope,uint64_t now)
+bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope scope,uint64_t now)
 {
 {
 	unsigned int np = _numPaths;
 	unsigned int np = _numPaths;
 	unsigned int x = 0;
 	unsigned int x = 0;
@@ -278,13 +278,7 @@ void Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc
 		++x;
 		++x;
 	}
 	}
 	_numPaths = y;
 	_numPaths = y;
-
-	if ((y < np)&&(alive(now))) {
-		// Try to re-establish direct connectivity to this peer if it's alive
-		// and we have forgotten paths to it.
-		Packet outp(_id.address(),RR->identity.address(),Packet::VERB_NOP);
-		RR->sw->send(outp,true);
-	}
+	return (y < np);
 }
 }
 
 
 void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6,unsigned int maxDesperation) const
 void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6,unsigned int maxDesperation) const

+ 3 - 4
node/Peer.hpp

@@ -311,15 +311,14 @@ public:
 	 * Reset paths within a given scope
 	 * Reset paths within a given scope
 	 *
 	 *
 	 * For fixed paths in this scope, a packet is sent. Non-fixed paths in this
 	 * For fixed paths in this scope, a packet is sent. Non-fixed paths in this
-	 * scope are forgotten. If there are no paths remaining, a message is sent
-	 * indirectly to reestablish connectivity if we're actively exchanging
-	 * data with this peer (alive).
+	 * scope are forgotten.
 	 *
 	 *
 	 * @param RR Runtime environment
 	 * @param RR Runtime environment
 	 * @param scope IP scope of paths to reset
 	 * @param scope IP scope of paths to reset
 	 * @param now Current time
 	 * @param now Current time
+	 * @return True if at least one path was forgotten
 	 */
 	 */
-	void resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope scope,uint64_t now);
+	bool resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope scope,uint64_t now);
 
 
 	/**
 	/**
 	 * @return 256-bit secret symmetric encryption key
 	 * @return 256-bit secret symmetric encryption key

+ 29 - 2
node/SelfAwareness.cpp

@@ -46,7 +46,15 @@ public:
 		RR(renv),
 		RR(renv),
 		_now(now),
 		_now(now),
 		_scope(scope) {}
 		_scope(scope) {}
-	inline void operator()(Topology &t,const SharedPtr<Peer> &p) { p->resetWithinScope(RR,_scope,_now); }
+
+	inline void operator()(Topology &t,const SharedPtr<Peer> &p)
+	{
+		if (p->resetWithinScope(RR,_scope,_now))
+			peersReset.push_back(p);
+	}
+
+	std::vector< SharedPtr<Peer> > peersReset;
+
 private:
 private:
 	const RuntimeEnvironment *RR;
 	const RuntimeEnvironment *RR;
 	uint64_t _now;
 	uint64_t _now;
@@ -84,8 +92,27 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi
 			} else if (lastPhy != myPhysicalAddress) {
 			} else if (lastPhy != myPhysicalAddress) {
 				TRACE("learned physical address %s for scope %u from reporter %s(%s) (replaced %s, resetting within scope)",myPhysicalAddress.toString().c_str(),scope,reporter.toString().c_str(),reporterPhysicalAddress.toString().c_str(),lastPhy.toString().c_str());
 				TRACE("learned physical address %s for scope %u from reporter %s(%s) (replaced %s, resetting within scope)",myPhysicalAddress.toString().c_str(),scope,reporter.toString().c_str(),reporterPhysicalAddress.toString().c_str(),lastPhy.toString().c_str());
 				lastPhy = myPhysicalAddress;
 				lastPhy = myPhysicalAddress;
-				_ResetWithinScope rset(RR,RR->node->now(),(InetAddress::IpScope)scope);
+				uint64_t now = RR->node->now();
+
+				_ResetWithinScope rset(RR,now,(InetAddress::IpScope)scope);
 				RR->topology->eachPeer<_ResetWithinScope &>(rset);
 				RR->topology->eachPeer<_ResetWithinScope &>(rset);
+
+				// For all peers for whom we forgot an address, send a packet indirectly if
+				// they are still considered alive so that we will re-establish direct links.
+				SharedPtr<Peer> sn(RR->topology->getBestSupernode());
+				if (sn) {
+					Path *snp = sn->getBestPath(now);
+					if (snp) {
+						for(std::vector< SharedPtr<Peer> >::const_iterator p(rset.peersReset.begin());p!=rset.peersReset.end();++p) {
+							if ((*p)->alive(now)) {
+								TRACE("sending indirect NOP to %s via %s(%s) to re-establish link",(*p)->address().toString().c_str(),sn->address().toString().c_str(),snp->address().toString().c_str());
+								Packet outp((*p)->address(),RR->identity.address(),Packet::VERB_NOP);
+								outp.armor((*p)->key(),true);
+								snp->send(RR,outp.data(),outp.size(),now);
+							}
+						}
+					}
+				}
 			}
 			}
 		}
 		}
 	}
 	}

+ 1 - 1
service/OneService.cpp

@@ -508,7 +508,7 @@ public:
 			long sent = _phy.tcpSend(sock,tc->writeBuf.data(),tc->writeBuf.length(),true);
 			long sent = _phy.tcpSend(sock,tc->writeBuf.data(),tc->writeBuf.length(),true);
 			if (sent > 0) {
 			if (sent > 0) {
 				tc->lastActivity = OSUtils::now();
 				tc->lastActivity = OSUtils::now();
-				if (sent == tc->writeBuf.length()) {
+				if ((unsigned long)sent == (unsigned long)tc->writeBuf.length()) {
 					tc->writeBuf = "";
 					tc->writeBuf = "";
 					_phy.tcpSetNotifyWritable(sock,false);
 					_phy.tcpSetNotifyWritable(sock,false);
 					if (!tc->shouldKeepAlive)
 					if (!tc->shouldKeepAlive)