Browse Source

More work on GitHub issue #666

Adam Ierymenko 7 years ago
parent
commit
384e5b66de
4 changed files with 27 additions and 39 deletions
  1. 0 1
      .gitignore
  2. 15 27
      node/Network.cpp
  3. 11 10
      node/NetworkConfig.hpp
  4. 1 1
      node/Node.cpp

+ 0 - 1
.gitignore

@@ -1,4 +1,3 @@
-<<<<<<< HEAD
 # Main binaries created in *nix builds
 /zerotier-one
 /zerotier-idtool

+ 15 - 27
node/Network.cpp

@@ -44,6 +44,8 @@
 #include "Peer.hpp"
 #include "Trace.hpp"
 
+#include <set>
+
 namespace ZeroTier {
 
 namespace {
@@ -1413,32 +1415,25 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
 		groups.push_back(*newMulticastGroup);
 	else groups = _allMulticastGroups();
 
+	std::vector<Address> alwaysAnnounceTo;
+
 	if ((newMulticastGroup)||((now - _lastAnnouncedMulticastGroupsUpstream) >= ZT_MULTICAST_ANNOUNCE_PERIOD)) {
 		if (!newMulticastGroup)
 			_lastAnnouncedMulticastGroupsUpstream = now;
 
-		// Announce multicast groups to upstream peers (roots, etc.) and also send
-		// them our COM so that MULTICAST_GATHER can be authenticated properly.
+		alwaysAnnounceTo = _config.alwaysContactAddresses();
+		if (std::find(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),controller()) == alwaysAnnounceTo.end())
+			alwaysAnnounceTo.push_back(controller());
 		const std::vector<Address> upstreams(RR->topology->upstreamAddresses());
 		for(std::vector<Address>::const_iterator a(upstreams.begin());a!=upstreams.end();++a) {
-			if (_config.com) {
-				Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
-				_config.com.serialize(outp);
-				outp.append((uint8_t)0x00);
-				outp.append((uint16_t)0); // no capabilities
-				outp.append((uint16_t)0); // no tags
-				outp.append((uint16_t)0); // no revocations
-				outp.append((uint16_t)0); // no certificates of ownership
-				RR->sw->send(tPtr,outp,true);
-			}
-			_announceMulticastGroupsTo(tPtr,*a,groups);
+			if (std::find(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),*a) == alwaysAnnounceTo.end())
+				alwaysAnnounceTo.push_back(*a);
 		}
+		std::sort(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end());
 
-		// Also announce to controller, and send COM to simplify and generalize behavior even though in theory it does not need it
-		const Address c(controller());
-		if ( (std::find(upstreams.begin(),upstreams.end(),c) == upstreams.end()) && (!_memberships.contains(c)) ) {
-			if (_config.com) {
-				Packet outp(c,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
+		for(std::vector<Address>::const_iterator a(alwaysAnnounceTo.begin());a!=alwaysAnnounceTo.end();++a) {
+			if ( (_config.com) && (!_memberships.contains(*a)) ) { // push COM to non-members so they can do multicast request auth
+				Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
 				_config.com.serialize(outp);
 				outp.append((uint8_t)0x00);
 				outp.append((uint16_t)0); // no capabilities
@@ -1447,24 +1442,17 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
 				outp.append((uint16_t)0); // no certificates of ownership
 				RR->sw->send(tPtr,outp,true);
 			}
-			_announceMulticastGroupsTo(tPtr,c,groups);
+			_announceMulticastGroupsTo(tPtr,*a,groups);
 		}
 	}
 
-	// Make sure that all "network anchors" have Membership records so we will
-	// push multicasts to them.
-	const std::vector<Address> anchors(_config.anchors());
-	for(std::vector<Address>::const_iterator a(anchors.begin());a!=anchors.end();++a)
-		_membership(*a);
-
-	// Send credentials and multicast LIKEs to members, upstreams, and controller
 	{
 		Address *a = (Address *)0;
 		Membership *m = (Membership *)0;
 		Hashtable<Address,Membership>::Iterator i(_memberships);
 		while (i.next(a,m)) {
 			m->pushCredentials(RR,tPtr,now,*a,_config,-1,false);
-			if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config)) )
+			if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config)) && (!std::binary_search(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),*a)) )
 				_announceMulticastGroupsTo(tPtr,*a,groups);
 		}
 	}

+ 11 - 10
node/NetworkConfig.hpp

@@ -292,9 +292,6 @@ public:
 		return r;
 	}
 
-	/**
-	 * @return ZeroTier addresses of "anchor" devices on this network
-	 */
 	inline std::vector<Address> anchors() const
 	{
 		std::vector<Address> r;
@@ -305,9 +302,6 @@ public:
 		return r;
 	}
 
-	/**
-	 * @return ZeroTier addresses of multicast replicators
-	 */
 	inline std::vector<Address> multicastReplicators() const
 	{
 		std::vector<Address> r;
@@ -318,10 +312,17 @@ public:
 		return r;
 	}
 
-	/**
-	 * Add addresses that we should attempt to stay connected to to a set
-	 */
-	inline void getAlwaysContactAddresses(Hashtable< Address,std::vector<InetAddress> > &a) const
+	inline std::vector<Address> alwaysContactAddresses() const
+	{
+		std::vector<Address> r;
+		for(unsigned int i=0;i<specialistCount;++i) {
+			if ((specialists[i] & (ZT_NETWORKCONFIG_SPECIALIST_TYPE_ANCHOR | ZT_NETWORKCONFIG_SPECIALIST_TYPE_MULTICAST_REPLICATOR)) != 0)
+				r.push_back(Address(specialists[i]));
+		}
+		return r;
+	}
+
+	inline void alwaysContactAddresses(Hashtable< Address,std::vector<InetAddress> > &a) const
 	{
 		for(unsigned int i=0;i<specialistCount;++i) {
 			if ((specialists[i] & (ZT_NETWORKCONFIG_SPECIALIST_TYPE_ANCHOR | ZT_NETWORKCONFIG_SPECIALIST_TYPE_MULTICAST_REPLICATOR)) != 0) {

+ 1 - 1
node/Node.cpp

@@ -290,7 +290,7 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,int64_t now,volatile int64
 				uint64_t *nwid = (uint64_t *)0;
 				SharedPtr<Network> *network = (SharedPtr<Network> *)0;
 				while (i.next(nwid,network)) {
-					(*network)->config().getAlwaysContactAddresses(alwaysContact);
+					(*network)->config().alwaysContactAddresses(alwaysContact);
 					networkConfigNeeded.push_back( std::pair< SharedPtr<Network>,bool >(*network,(((now - (*network)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!(*network)->hasConfig()))) );
 				}
 			}