Browse Source

GitHub issue #67

Adam Ierymenko 11 years ago
parent
commit
31ddc49da2

+ 2 - 2
node/EthernetTap.hpp

@@ -170,8 +170,8 @@ public:
 	 * This populates a set or, if already populated, modifies it to contain
 	 * This populates a set or, if already populated, modifies it to contain
 	 * only multicast groups in which this device is interested.
 	 * only multicast groups in which this device is interested.
 	 *
 	 *
-	 * This should always include the blind wildcard MulticastGroup (MAC of
-	 * ff:ff:ff:ff:ff:ff and 0 ADI field).
+	 * This neither includes nor removes the broadcast (ff:ff:ff:ff:ff:ff / 0)
+	 * group.
 	 *
 	 *
 	 * @param groups Set to modify in place
 	 * @param groups Set to modify in place
 	 * @return True if set was changed since last call
 	 * @return True if set was changed since last call

+ 2 - 0
node/Network.cpp

@@ -48,6 +48,8 @@
 
 
 namespace ZeroTier {
 namespace ZeroTier {
 
 
+const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xff),0);
+
 const char *Network::statusString(const Status s)
 const char *Network::statusString(const Status s)
 	throw()
 	throw()
 {
 {

+ 21 - 3
node/Network.hpp

@@ -108,6 +108,11 @@ private:
 	inline void destroyOnDelete() throw() { _destroyOnDelete = true; }
 	inline void destroyOnDelete() throw() { _destroyOnDelete = true; }
 
 
 public:
 public:
+	/**
+	 * Broadcast multicast group: ff:ff:ff:ff:ff:ff / 0
+	 */
+	static const MulticastGroup BROADCAST;
+
 	/**
 	/**
 	 * Possible network states
 	 * Possible network states
 	 */
 	 */
@@ -157,9 +162,22 @@ public:
 	{
 	{
 		Mutex::Lock _l(_lock);
 		Mutex::Lock _l(_lock);
 		EthernetTap *t = _tap;
 		EthernetTap *t = _tap;
-		if (t)
-			return _tap->updateMulticastGroups(_multicastGroups);
-		return false;
+		if (t) {
+			bool updated = _tap->updateMulticastGroups(_multicastGroups);
+			if ((_config)&&(_config->enableBroadcast())) {
+				if (_multicastGroups.count(BROADCAST))
+					return updated;
+				else {
+					_multicastGroups.insert(BROADCAST);
+					return true;
+				}
+			} else {
+				if (_multicastGroups.count(BROADCAST)) {
+					_multicastGroups.erase(BROADCAST);
+					return true;
+				} else return updated;
+			}
+		} else return false;
 	}
 	}
 
 
 	/**
 	/**

+ 7 - 4
node/NetworkConfig.cpp

@@ -65,9 +65,11 @@ const NetworkConfig::MulticastRate &NetworkConfig::multicastRate(const Multicast
 	return r->second;
 	return r->second;
 }
 }
 
 
-static const std::string _zero("0");
 void NetworkConfig::_fromDictionary(const Dictionary &d)
 void NetworkConfig::_fromDictionary(const Dictionary &d)
 {
 {
+	static const std::string zero("0");
+	static const std::string one("1");
+
 	// NOTE: d.get(name) throws if not found, d.get(name,default) returns default
 	// NOTE: d.get(name) throws if not found, d.get(name,default) returns default
 
 
 	memset(_etWhitelist,0,sizeof(_etWhitelist));
 	memset(_etWhitelist,0,sizeof(_etWhitelist));
@@ -82,9 +84,10 @@ void NetworkConfig::_fromDictionary(const Dictionary &d)
 		throw std::invalid_argument("configuration contains zero network ID");
 		throw std::invalid_argument("configuration contains zero network ID");
 	_timestamp = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP).c_str());
 	_timestamp = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP).c_str());
 	_issuedTo = Address(d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO));
 	_issuedTo = Address(d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO));
-	_multicastPrefixBits = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_PREFIX_BITS,_zero).c_str());
-	_multicastDepth = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_DEPTH,_zero).c_str());
-	_private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,_zero).c_str()) != 0);
+	_multicastPrefixBits = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_PREFIX_BITS,zero).c_str());
+	_multicastDepth = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_DEPTH,zero).c_str());
+	_private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,zero).c_str()) != 0);
+	_enableBroadcast = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST,one).c_str()) != 0);
 	_name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME);
 	_name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME);
 	_description = d.get(ZT_NETWORKCONFIG_DICT_KEY_DESC,std::string());
 	_description = d.get(ZT_NETWORKCONFIG_DICT_KEY_DESC,std::string());
 
 

+ 4 - 1
node/NetworkConfig.hpp

@@ -61,6 +61,7 @@ namespace ZeroTier {
 #define ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC "v4s"
 #define ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC "v4s"
 #define ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC "v6s"
 #define ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC "v6s"
 #define ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP "com"
 #define ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP "com"
+#define ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST "eb"
 
 
 /**
 /**
  * Network configuration received from netconf master nodes
  * Network configuration received from netconf master nodes
@@ -117,13 +118,14 @@ public:
 	inline const Address &issuedTo() const throw() { return _issuedTo; }
 	inline const Address &issuedTo() const throw() { return _issuedTo; }
 	inline unsigned int multicastPrefixBits() const throw() { return _multicastPrefixBits; }
 	inline unsigned int multicastPrefixBits() const throw() { return _multicastPrefixBits; }
 	inline unsigned int multicastDepth() const throw() { return _multicastDepth; }
 	inline unsigned int multicastDepth() const throw() { return _multicastDepth; }
+	inline const std::map<MulticastGroup,MulticastRate> &multicastRates() const throw() { return _multicastRates; }
 	inline bool isOpen() const throw() { return (!_private); }
 	inline bool isOpen() const throw() { return (!_private); }
 	inline bool isPrivate() const throw() { return _private; }
 	inline bool isPrivate() const throw() { return _private; }
 	inline const std::string &name() const throw() { return _name; }
 	inline const std::string &name() const throw() { return _name; }
 	inline const std::string &description() const throw() { return _description; }
 	inline const std::string &description() const throw() { return _description; }
 	inline const std::set<InetAddress> &staticIps() const throw() { return _staticIps; }
 	inline const std::set<InetAddress> &staticIps() const throw() { return _staticIps; }
-	inline const std::map<MulticastGroup,MulticastRate> &multicastRates() const throw() { return _multicastRates; }
 	inline const CertificateOfMembership &com() const throw() { return _com; }
 	inline const CertificateOfMembership &com() const throw() { return _com; }
+	inline bool enableBroadcast() const throw() { return _enableBroadcast; }
 
 
 	/**
 	/**
 	 * @param fromPeer Peer attempting to bridge other Ethernet peers onto network
 	 * @param fromPeer Peer attempting to bridge other Ethernet peers onto network
@@ -155,6 +157,7 @@ private:
 	unsigned int _multicastPrefixBits;
 	unsigned int _multicastPrefixBits;
 	unsigned int _multicastDepth;
 	unsigned int _multicastDepth;
 	bool _private;
 	bool _private;
+	bool _enableBroadcast;
 	std::string _name;
 	std::string _name;
 	std::string _description;
 	std::string _description;
 	std::set<InetAddress> _staticIps;
 	std::set<InetAddress> _staticIps;

+ 2 - 6
node/UnixEthernetTap.cpp

@@ -710,8 +710,6 @@ bool UnixEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 
 
 	bool changed = false;
 	bool changed = false;
 
 
-	newGroups.insert(_blindWildcardMulticastGroup); // always join this
-
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 		if (!groups.count(*mg)) {
 		if (!groups.count(*mg)) {
 			groups.insert(*mg);
 			groups.insert(*mg);
@@ -719,7 +717,7 @@ bool UnixEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 		}
 		}
 	}
 	}
 	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
 	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
-		if (!newGroups.count(*mg)) {
+		if ((!newGroups.count(*mg))&&(*mg != _blindWildcardMulticastGroup)) {
 			groups.erase(mg++);
 			groups.erase(mg++);
 			changed = true;
 			changed = true;
 		} else ++mg;
 		} else ++mg;
@@ -934,8 +932,6 @@ bool UnixEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 
 
 	bool changed = false;
 	bool changed = false;
 
 
-	newGroups.insert(_blindWildcardMulticastGroup); // always join this
-
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 		if (!groups.count(*mg)) {
 		if (!groups.count(*mg)) {
 			groups.insert(*mg);
 			groups.insert(*mg);
@@ -943,7 +939,7 @@ bool UnixEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 		}
 		}
 	}
 	}
 	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
 	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
-		if (!newGroups.count(*mg)) {
+		if ((!newGroups.count(*mg))&&(*mg != _blindWildcardMulticastGroup)) {
 			groups.erase(mg++);
 			groups.erase(mg++);
 			changed = true;
 			changed = true;
 		} else ++mg;
 		} else ++mg;

+ 1 - 3
node/WindowsEthernetTap.cpp

@@ -616,8 +616,6 @@ bool WindowsEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 		}
 		}
 	}
 	}
 
 
-	newGroups.insert(_blindWildcardMulticastGroup); // always join this
-
 	bool changed = false;
 	bool changed = false;
 
 
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
@@ -627,7 +625,7 @@ bool WindowsEthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 		}
 		}
 	}
 	}
 	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
 	for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
-		if (!newGroups.count(*mg)) {
+		if ((!newGroups.count(*mg))&&(*mg != _blindWildcardMulticastGroup)) {
 			groups.erase(mg++);
 			groups.erase(mg++);
 			changed = true;
 			changed = true;
 		} else ++mg;
 		} else ++mg;