Browse Source

... and another one!

Adam Ierymenko 10 năm trước cách đây
mục cha
commit
d1341578d8
2 tập tin đã thay đổi với 30 bổ sung18 xóa
  1. 23 11
      node/Network.cpp
  2. 7 7
      node/Network.hpp

+ 23 - 11
node/Network.cpp

@@ -389,22 +389,34 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
 	Mutex::Lock _l(_lock);
 	_remoteBridgeRoutes[mac] = addr;
 
-	// If _remoteBridgeRoutes exceeds sanity limit, trim worst offenders until below -- denial of service circuit breaker
+	// Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes
 	while (_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
-		std::map<Address,unsigned long> counts;
+		Hashtable< Address,unsigned long > counts;
 		Address maxAddr;
 		unsigned long maxCount = 0;
-		for(std::map<MAC,Address>::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();++br) {
-			unsigned long c = ++counts[br->second];
-			if (c > maxCount) {
-				maxCount = c;
-				maxAddr = br->second;
+
+		MAC *m = (MAC *)0;
+		Address *a = (Address *)0;
+
+		// Find the address responsible for the most entries
+		{
+			Hashtable<MAC,Address>::Iterator i(_remoteBridgeRoutes);
+			while (i.next(m,a)) {
+				const unsigned long c = ++counts[*a];
+				if (c > maxCount) {
+					maxCount = c;
+					maxAddr = *a;
+				}
 			}
 		}
-		for(std::map<MAC,Address>::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();) {
-			if (br->second == maxAddr)
-				_remoteBridgeRoutes.erase(br++);
-			else ++br;
+
+		// Kill this address from our table, since it's most likely spamming us
+		{
+			Hashtable<MAC,Address>::Iterator i(_remoteBridgeRoutes);
+			while (i.next(m,a)) {
+				if (*a == maxAddr)
+					_remoteBridgeRoutes.erase(*m);
+			}
 		}
 	}
 }

+ 7 - 7
node/Network.hpp

@@ -298,10 +298,10 @@ public:
 	inline Address findBridgeTo(const MAC &mac) const
 	{
 		Mutex::Lock _l(_lock);
-		std::map<MAC,Address>::const_iterator br(_remoteBridgeRoutes.find(mac));
-		if (br == _remoteBridgeRoutes.end())
-			return Address();
-		return br->second;
+		const Address *const br = _remoteBridgeRoutes.get(mac);
+		if (br)
+			return *br;
+		return Address();
 	}
 
 	/**
@@ -359,10 +359,10 @@ private:
 	volatile bool _enabled;
 	volatile bool _portInitialized;
 
-	std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to including those behind us (updated periodically)
-	Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups bridged to us and when we last saw activity on each
+	std::vector< MulticastGroup > _myMulticastGroups; // multicast groups that we belong to (according to tap)
+	Hashtable< MulticastGroup,uint64_t > _multicastGroupsBehindMe; // multicast groups that seem to be behind us and when we last saw them (if we are a bridge)
 
-	std::map<MAC,Address> _remoteBridgeRoutes; // remote addresses where given MACs are reachable
+	Hashtable< MAC,Address > _remoteBridgeRoutes; // remote addresses where given MACs are reachable (for remote bridges)
 
 	std::map<Address,CertificateOfMembership> _membershipCertificates; // Other members' certificates of membership
 	std::map<Address,uint64_t> _lastPushedMembershipCertificate; // When did we last push our certificate to each remote member?