diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-09-04 13:53:48 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-09-04 13:53:48 -0700 |
commit | d1341578d8dc7fd3e39b24dde1ac2dae4da7a632 (patch) | |
tree | 5d47db5666618eabd2317f6746640d11f7586192 | |
parent | 7b8ce1605781f14d909e0aa099455b86d738c60a (diff) | |
download | infinitytier-d1341578d8dc7fd3e39b24dde1ac2dae4da7a632.tar.gz infinitytier-d1341578d8dc7fd3e39b24dde1ac2dae4da7a632.zip |
... and another one!
-rw-r--r-- | node/Network.cpp | 34 | ||||
-rw-r--r-- | node/Network.hpp | 14 |
2 files changed, 30 insertions, 18 deletions
diff --git a/node/Network.cpp b/node/Network.cpp index 8317cad9..b0c2627b 100644 --- a/node/Network.cpp +++ b/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); + } } } } diff --git a/node/Network.hpp b/node/Network.hpp index 47d2efc0..d8ffd612 100644 --- a/node/Network.hpp +++ b/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? |