diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-06-10 17:18:59 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-06-10 17:18:59 -0700 |
commit | d44e1349d8e83b875b1a102b2b1ce31613a10924 (patch) | |
tree | 2fa63ef794fadd2d4abce1f20f997b0da4e98736 /node | |
parent | 6f831d53700249fb723d3d88dd9b4d90e4272239 (diff) | |
download | infinitytier-d44e1349d8e83b875b1a102b2b1ce31613a10924.tar.gz infinitytier-d44e1349d8e83b875b1a102b2b1ce31613a10924.zip |
Bridge routing table - GitHub issue #68
Diffstat (limited to 'node')
-rw-r--r-- | node/Constants.hpp | 11 | ||||
-rw-r--r-- | node/Network.cpp | 25 | ||||
-rw-r--r-- | node/Network.hpp | 36 |
3 files changed, 69 insertions, 3 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp index 37a3b3a9..6634836f 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -396,4 +396,15 @@ error_no_byte_order_defined; */ #define ZT_UPDATE_HTTP_TIMEOUT 30 +/** + * Sanity limit on maximum bridge routes + * + * If the number of bridge routes exceeds this, we cull routes from the + * bridges with the most MACs behind them until it doesn't. This is a + * sanity limit to prevent memory-filling DOS attacks, nothing more. No + * physical LAN has anywhere even close to this many nodes. Note that this + * does not limit the size of ZT virtual LANs, only bridge routing. + */ +#define ZT_MAX_BRIDGE_ROUTES 67108864 + #endif diff --git a/node/Network.cpp b/node/Network.cpp index d55101c2..3091638a 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -333,6 +333,31 @@ void Network::threadMain() } } +void Network::learnBridgeRoute(const MAC &mac,const Address &addr) +{ + Mutex::Lock _l(_lock); + _bridgeRoutes[mac] = addr; + + // If _bridgeRoutes exceeds sanity limit, trim worst offenders until below -- denial of service circuit breaker + while (_bridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) { + std::map<Address,unsigned long> counts; + Address maxAddr; + unsigned long maxCount = 0; + for(std::map<MAC,Address>::iterator br(_bridgeRoutes.begin());br!=_bridgeRoutes.end();++br) { + unsigned long c = ++counts[br->second]; + if (c > maxCount) { + maxCount = c; + maxAddr = br->second; + } + } + for(std::map<MAC,Address>::iterator br(_bridgeRoutes.begin());br!=_bridgeRoutes.end();) { + if (br->second == maxAddr) + _bridgeRoutes.erase(br++); + else ++br; + } + } +} + void Network::_restoreState() { if (!_id) diff --git a/node/Network.hpp b/node/Network.hpp index 26766ffb..b40afd45 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -416,6 +416,27 @@ public: return std::set<InetAddress>(); } + /** + * @param mac MAC address + * @return ZeroTier address of bridge to this MAC or null address if not found + */ + inline Address findBridgeTo(const MAC &mac) const + { + Mutex::Lock _l(_lock); + std::map<MAC,Address>::const_iterator br(_bridgeRoutes.find(mac)); + if (br == _bridgeRoutes.end()) + return Address(); + return br->second; + } + + /** + * Set a bridge route + * + * @param mac MAC address of destination + * @param addr Bridge this MAC is reachable behind + */ + void learnBridgeRoute(const MAC &mac,const Address &addr); + private: static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data); @@ -424,24 +445,33 @@ private: void _dumpMulticastCerts(); uint64_t _id; - NodeConfig *_nc; - MAC _mac; + NodeConfig *_nc; // parent NodeConfig object + MAC _mac; // local MAC address const RuntimeEnvironment *_r; - EthernetTap *volatile _tap; + EthernetTap *volatile _tap; // tap device or NULL if not initialized yet + std::set<MulticastGroup> _multicastGroups; std::map< std::pair<Address,MulticastGroup>,BandwidthAccount > _multicastRateAccounts; + std::map<Address,CertificateOfMembership> _membershipCertificates; std::map<Address,uint64_t> _lastPushedMembershipCertificate; + + std::map<MAC,Address> _bridgeRoutes; + SharedPtr<NetworkConfig> _config; volatile uint64_t _lastConfigUpdate; + volatile bool _destroyOnDelete; + volatile enum { NETCONF_FAILURE_NONE, NETCONF_FAILURE_ACCESS_DENIED, NETCONF_FAILURE_NOT_FOUND, NETCONF_FAILURE_INIT_FAILED } _netconfFailure; + Thread _setupThread; + Mutex _lock; AtomicCounter __refCount; |