summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-09-04 13:53:48 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-09-04 13:53:48 -0700
commitd1341578d8dc7fd3e39b24dde1ac2dae4da7a632 (patch)
tree5d47db5666618eabd2317f6746640d11f7586192
parent7b8ce1605781f14d909e0aa099455b86d738c60a (diff)
downloadinfinitytier-d1341578d8dc7fd3e39b24dde1ac2dae4da7a632.tar.gz
infinitytier-d1341578d8dc7fd3e39b24dde1ac2dae4da7a632.zip
... and another one!
-rw-r--r--node/Network.cpp34
-rw-r--r--node/Network.hpp14
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?