Browse Source

Makefile changes, and make Topology::getBestSupernode() return the "next" supernode if I am a supernode. Also some comment cleanup.

Adam Ierymenko 11 years ago
parent
commit
282114e96c
4 changed files with 107 additions and 90 deletions
  1. 0 1
      make-linux.mk
  2. 26 22
      make-mac.mk
  3. 8 21
      node/Switch.cpp
  4. 73 46
      node/Topology.cpp

+ 0 - 1
make-linux.mk

@@ -35,7 +35,6 @@ endif
 #LDFLAGS=
 #STRIP=echo
 
-# Our code doesn't use rtti, so don't bloat the binary with it.
 CXXFLAGS=$(CFLAGS) -fno-rtti
 
 include objects.mk

+ 26 - 22
make-mac.mk

@@ -15,7 +15,6 @@ ifeq ($(ZT_OFFICIAL_RELEASE),1)
 	CODESIGN=codesign
 	CODESIGN_CERT="Developer ID Application: ZeroTier Networks LLC (8ZD9JUCZ4V)"
 endif
-
 ifeq ($(ZT_AUTO_UPDATE),1)
 	DEFS+=-DZT_AUTO_UPDATE 
 endif
@@ -23,34 +22,34 @@ endif
 # Enable SSE-optimized Salsa20
 DEFS+=-DZT_SALSA20_SSE
 
-# Uncomment to dump trace and log info to stdout (useful for debug/test)
-#DEFS+=-DZT_TRACE -DZT_LOG_STDOUT 
-
-# Uncomment for a release optimized universal binary build
-CFLAGS=-arch i386 -arch x86_64 -Wall -O3 -flto -fPIE -fvectorize -fstack-protector -pthread -mmacosx-version-min=10.6 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS)
-STRIP=strip
-
-# Uncomment for a debug build
-#CFLAGS=-Wall -g -pthread -DZT_TRACE -DZT_LOG_STDOUT $(INCLUDES) $(DEFS)
-#STRIP=echo
+# "make debug" is a shortcut for this
+ifeq ($(ZT_DEBUG),1)
+	CFLAGS=-Wall -g -pthread -DZT_TRACE -DZT_LOG_STDOUT $(INCLUDES) $(DEFS)
+	STRIP=echo
+	DEFS+=-DZT_TRACE -DZT_LOG_STDOUT 
+else
+	CFLAGS=-arch i386 -arch x86_64 -Wall -O3 -flto -fPIE -fvectorize -fstack-protector -pthread -mmacosx-version-min=10.6 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS)
+	STRIP=strip
+endif
 
 CXXFLAGS=$(CFLAGS) -fno-rtti
 
 include objects.mk
-OBJS+=osnet/BSDRoutingTable.o osnet/OSXEthernetTap.o osnet/OSXEthernetTapFactory.o
+OBJS+=main.o osnet/BSDRoutingTable.o osnet/OSXEthernetTap.o osnet/OSXEthernetTapFactory.o
 
 all: one
 
 one:	$(OBJS)
-	$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
+	$(CXX) $(CXXFLAGS) -o zerotier-one $(OBJS) $(LIBS)
 	$(STRIP) zerotier-one
 	ln -sf zerotier-one zerotier-cli
 	ln -sf zerotier-one zerotier-idtool
 
-selftest: $(OBJS)
-	$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.cpp $(OBJS) $(LIBS)
+selftest: $(OBJS) selftest.o
+	$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
 	$(STRIP) zerotier-selftest
 
+# Requires that ../Qt be symlinked to the Qt root to use for UI build
 mac-ui: FORCE
 	mkdir -p build-ZeroTierUI-release
 	cd build-ZeroTierUI-release ; ../../Qt/bin/qmake ../ZeroTierUI/ZeroTierUI.pro ; make -j 4
@@ -59,15 +58,13 @@ mac-ui: FORCE
 	$(CODESIGN) -f -s $(CODESIGN_CERT) "build-ZeroTierUI-release/ZeroTier One.app"
 	$(CODESIGN) -vvv "build-ZeroTierUI-release/ZeroTier One.app"
 
-install-mac-tap: FORCE
-	mkdir -p /Library/Application\ Support/ZeroTier/One
-	rm -rf /Library/Application\ Support/ZeroTier/One/tap.kext
-	cp -R ext/bin/tap-mac/tap.kext /Library/Application\ Support/ZeroTier/One
-	chown -R root:wheel /Library/Application\ Support/ZeroTier/One/tap.kext
-
 clean:
-	rm -rf *.dSYM build-* $(OBJS) zerotier-* ZeroTierOneInstaller-* "ZeroTier One.zip" "ZeroTier One.dmg"
+	rm -rf *.dSYM main.o selftest.o build-* $(OBJS) zerotier-* ZeroTierOneInstaller-* "ZeroTier One.zip" "ZeroTier One.dmg"
+
+debug:	FORCE
+	make -j 4 ZT_DEBUG=1
 
+# For our use -- builds official signed binary, packages in installer and download DMG
 official: FORCE
 	make -j 4 ZT_OFFICIAL_RELEASE=1
 	make mac-ui ZT_OFFICIAL_RELEASE=1
@@ -80,4 +77,11 @@ official: FORCE
 	hdiutil convert /tmp/tmp.dmg -format UDZO -o "ZeroTier One.dmg"
 	rm -f /tmp/tmp.dmg
 
+# For those building from source -- installs signed binary tap driver in system ZT home
+install-mac-tap: FORCE
+	mkdir -p /Library/Application\ Support/ZeroTier/One
+	rm -rf /Library/Application\ Support/ZeroTier/One/tap.kext
+	cp -R ext/bin/tap-mac/tap.kext /Library/Application\ Support/ZeroTier/One
+	chown -R root:wheel /Library/Application\ Support/ZeroTier/One/tap.kext
+
 FORCE:

+ 8 - 21
node/Switch.cpp

@@ -639,12 +639,12 @@ void Switch::cancelWhoisRequest(const Address &addr)
 
 void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer)
 {
-	{
+	{	// cancel pending WHOIS since we now know this peer
 		Mutex::Lock _l(_outstandingWhoisRequests_m);
 		_outstandingWhoisRequests.erase(peer->address());
 	}
 
-	{
+	{	// finish processing any packets waiting on peer's public key / identity
 		Mutex::Lock _l(_rxQueue_m);
 		for(std::list< SharedPtr<PacketDecoder> >::iterator rxi(_rxQueue.begin());rxi!=_rxQueue.end();) {
 			if ((*rxi)->tryDecode(_r))
@@ -653,7 +653,7 @@ void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer)
 		}
 	}
 
-	{
+	{	// finish sending any packets waiting on peer's public key / identity
 		Mutex::Lock _l(_txQueue_m);
 		std::pair< std::multimap< Address,TXQueueEntry >::iterator,std::multimap< Address,TXQueueEntry >::iterator > waitingTxQueueItems(_txQueue.equal_range(peer->address()));
 		for(std::multimap< Address,TXQueueEntry >::iterator txi(waitingTxQueueItems.first);txi!=waitingTxQueueItems.second;) {
@@ -690,8 +690,11 @@ void Switch::_handleRemotePacketFragment(const SharedPtr<Socket> &fromSock,const
 		if (fragment.hops() < ZT_RELAY_MAX_HOPS) {
 			fragment.incrementHops();
 
+			// Note: we don't bother initiating NAT-t for fragments, since heads will set that off.
+			// It wouldn't hurt anything, just redundant and unnecessary.
 			SharedPtr<Peer> relayTo = _r->topology->getPeer(destination);
 			if ((!relayTo)||(relayTo->send(_r,fragment.data(),fragment.size(),Utils::now()) == Path::PATH_TYPE_NULL)) {
+				// Don't know peer or no direct path -- so relay via supernode
 				relayTo = _r->topology->getBestSupernode();
 				if (relayTo)
 					relayTo->send(_r,fragment.data(),fragment.size(),Utils::now());
@@ -772,11 +775,7 @@ void Switch::_handleRemotePacketHead(const SharedPtr<Socket> &fromSock,const Ine
 				if ((fromSock->udp())&&(relayedVia == Path::PATH_TYPE_UDP))
 					unite(source,destination,false);
 			} else {
-				// If we've received a packet not for us and we don't have
-				// a direct path to its recipient, pass it to (another)
-				// supernode. This can happen due to Internet weather -- the
-				// most direct supernode may not be reachable, yet another
-				// further away may be.
+				// Don't know peer or no direct path -- so relay via supernode
 				relayTo = _r->topology->getBestSupernode(&source,1,true);
 				if (relayTo)
 					relayTo->send(_r,packet->data(),packet->size(),Utils::now());
@@ -903,21 +902,9 @@ bool Switch::_trySend(const Packet &packet,bool encrypt)
 					remaining -= chunkSize;
 				}
 			}
-
-/* #ifdef ZT_TRACE
-			if (via != peer) {
-				TRACE(">> %s to %s via %s (%d)",Packet::verbString(packet.verb()),peer->address().toString().c_str(),via->address().toString().c_str(),(int)packet.size());
-			} else {
-				TRACE(">> %s to %s (%d)",Packet::verbString(packet.verb()),peer->address().toString().c_str(),(int)packet.size());
-			}
-#endif */
-
 			return true;
 		}
-		return false;
-	}
-
-	requestWhois(packet.destination());
+	} else requestWhois(packet.destination());
 	return false;
 }
 

+ 73 - 46
node/Topology.cpp

@@ -161,65 +161,92 @@ void Topology::saveIdentity(const Identity &id)
 SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const
 {
 	SharedPtr<Peer> bestSupernode;
-	unsigned int l,bestSupernodeLatency = 65536;
 	uint64_t now = Utils::now();
-	uint64_t lds,ldr;
-
 	Mutex::Lock _l(_supernodes_m);
 
-	// First look for a best supernode by comparing latencies, but exclude
-	// supernodes that have not responded to direct messages in order to
-	// try to exclude any that are dead or unreachable.
-	for(std::vector< SharedPtr<Peer> >::const_iterator sn(_supernodePeers.begin());sn!=_supernodePeers.end();) {
-		// Skip explicitly avoided relays
-		for(unsigned int i=0;i<avoidCount;++i) {
-			if (avoid[i] == (*sn)->address())
-				goto keep_searching_for_supernodes;
+	if (_amSupernode) {
+		/* If I am a supernode, the "best" supernode is the one whose address
+		 * is numerically greater than mine (with wrap at top of list). This
+		 * causes packets searching for a route to pretty much literally
+		 * circumnavigate the globe rather than bouncing between just two. */
+
+		if (_supernodeAddresses.size() > 1) { // gotta be one other than me for this to work
+			std::set<Address>::const_iterator sna(_supernodeAddresses.find(_r->identity.address()));
+			if (sna != _supernodeAddresses.end()) { // sanity check -- _amSupernode should've been false in this case
+				for(;;) {
+					if (++sna == _supernodeAddresses.end())
+						sna = _supernodeAddresses.begin(); // wrap around at end
+					if (*sna != _r->identity.address()) { // pick one other than us -- starting from me+1 in sorted set order
+						SharedPtr<Peer> p(getPeer(*sna));
+						if ((p)&&(p->hasActiveDirectPath(now))) {
+							bestSupernode = p;
+							break;
+						}
+					}
+				}
+			}
 		}
+	} else {
+		/* If I am not a supernode, the best supernode is the active one with
+		 * the lowest latency. */
+
+		unsigned int l,bestSupernodeLatency = 65536;
+		uint64_t lds,ldr;
+
+		// First look for a best supernode by comparing latencies, but exclude
+		// supernodes that have not responded to direct messages in order to
+		// try to exclude any that are dead or unreachable.
+		for(std::vector< SharedPtr<Peer> >::const_iterator sn(_supernodePeers.begin());sn!=_supernodePeers.end();) {
+			// Skip explicitly avoided relays
+			for(unsigned int i=0;i<avoidCount;++i) {
+				if (avoid[i] == (*sn)->address())
+					goto keep_searching_for_supernodes;
+			}
+
+			// Skip possibly comatose or unreachable relays
+			lds = (*sn)->lastDirectSend();
+			ldr = (*sn)->lastDirectReceive();
+			if ((lds)&&(lds > ldr)&&((lds - ldr) > ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD))
+				goto keep_searching_for_supernodes;
 
-		// Skip possibly comatose or unreachable relays
-		lds = (*sn)->lastDirectSend();
-		ldr = (*sn)->lastDirectReceive();
-		if ((lds)&&(lds > ldr)&&((lds - ldr) > ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD))
-			goto keep_searching_for_supernodes;
-
-		if ((*sn)->hasActiveDirectPath(now)) {
-			l = (*sn)->latency();
-			if (bestSupernode) {
-				if ((l)&&(l < bestSupernodeLatency)) {
-					bestSupernodeLatency = l;
+			if ((*sn)->hasActiveDirectPath(now)) {
+				l = (*sn)->latency();
+				if (bestSupernode) {
+					if ((l)&&(l < bestSupernodeLatency)) {
+						bestSupernodeLatency = l;
+						bestSupernode = *sn;
+					}
+				} else {
+					if (l)
+						bestSupernodeLatency = l;
 					bestSupernode = *sn;
 				}
-			} else {
-				if (l)
-					bestSupernodeLatency = l;
-				bestSupernode = *sn;
 			}
-		}
 
 keep_searching_for_supernodes:
-		++sn;
-	}
-
-	if (bestSupernode) {
-		bestSupernode->use(now);
-		return bestSupernode;
-	} else if (strictAvoid)
-		return SharedPtr<Peer>();
+			++sn;
+		}
 
-	// If we have nothing from above, just pick one without avoidance criteria.
-	for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();++sn) {
-		if ((*sn)->hasActiveDirectPath(now)) {
-			unsigned int l = (*sn)->latency();
-			if (bestSupernode) {
-				if ((l)&&(l < bestSupernodeLatency)) {
-					bestSupernodeLatency = l;
+		if (bestSupernode) {
+			bestSupernode->use(now);
+			return bestSupernode;
+		} else if (strictAvoid)
+			return SharedPtr<Peer>();
+
+		// If we have nothing from above, just pick one without avoidance criteria.
+		for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();++sn) {
+			if ((*sn)->hasActiveDirectPath(now)) {
+				unsigned int l = (*sn)->latency();
+				if (bestSupernode) {
+					if ((l)&&(l < bestSupernodeLatency)) {
+						bestSupernodeLatency = l;
+						bestSupernode = *sn;
+					}
+				} else {
+					if (l)
+						bestSupernodeLatency = l;
 					bestSupernode = *sn;
 				}
-			} else {
-				if (l)
-					bestSupernodeLatency = l;
-				bestSupernode = *sn;
 			}
 		}
 	}