From 102b0865cb4a4c2d17dea7ba4e9717a7a6a6049f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 16 Jul 2013 15:00:15 -0400 Subject: Filter work, adding toString() and main evaluation function. --- node/Filter.hpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 12 deletions(-) (limited to 'node/Filter.hpp') diff --git a/node/Filter.hpp b/node/Filter.hpp index 861603f0..0af52864 100644 --- a/node/Filter.hpp +++ b/node/Filter.hpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "Mutex.hpp" #include "Range.hpp" @@ -129,6 +130,14 @@ class RuntimeEnvironment; class Filter { public: + /** + * Value returned by etherTypeName, etc. on unknown + * + * These static methods return precisely this, so a pointer equality + * check will work. + */ + static const char *const UNKNOWN_NAME; + /** * A filter rule * @@ -171,8 +180,15 @@ public: * @param data Ethernet frame data * @param len Length of ethernet frame * @return True if rule matches + * @throws std::invalid_argument Frame invalid or not parseable + */ + bool operator()(unsigned int etype,const void *data,unsigned int len) const + throw(std::invalid_argument); + + /** + * @return Human readable representation of rule */ - bool operator()(unsigned int etype,const void *data,unsigned int len) const; + std::string toString() const; inline bool operator==(const Rule &r) const throw() { return ((_etherType == r._etherType)&&(_protocol == r._protocol)&&(_port == r._port)); } inline bool operator!=(const Rule &r) const throw() { return !(*this == r); } @@ -206,9 +222,10 @@ public: */ enum Action { - ACTION_DENY = 0, - ACTION_ALLOW = 1, - ACTION_LOG = 2 + ACTION_DENY = 1, + ACTION_ALLOW = 2, + ACTION_LOG = 3, + ACTION_UNPARSEABLE = 4 }; /** @@ -227,8 +244,27 @@ public: Action action; }; - Filter(const RuntimeEnvironment *renv); - ~Filter(); + Filter() : + _chain(), + _chain_m() + { + } + + Filter(const Filter &f) : + _chain(), + _chain_m() + { + Mutex::Lock _l(f._chain_m); + _chain = f._chain; + } + + inline Filter &operator=(const Filter &f) + { + Mutex::Lock _l1(_chain_m); + Mutex::Lock _l2(f._chain_m); + _chain = f._chain; + return *this; + } /** * Remove all filter entries @@ -281,16 +317,31 @@ public: */ std::string toString(const char *sep = (const char *)0) const; - /** - * @param etherType Ethernet type ID - * @return Name of Ethernet protocol (e.g. ARP, IPV4) - */ static const char *etherTypeName(const unsigned int etherType) throw(); + static const char *ipProtocolName(const unsigned int ipp) + throw(); + static const char *icmpTypeName(const unsigned int icmpType) + throw(); + static const char *icmp6TypeName(const unsigned int icmp6Type) + throw(); -private: - const RuntimeEnvironment *_r; + /** + * Match against an Ethernet frame + * + * Note that ACTION_LOG rules do not terminate rule evaluation and + * ACTION_LOG is never returned here as a result. It's primarily for + * debugging and rule testing. + * + * @param _r Runtime environment + * @param etherType Ethernet frame type + * @param frame Ethernet frame data + * @param len Length of frame in bytes + * @return Action if matched or ACTION_ALLOW if not matched + */ + Action operator()(const RuntimeEnvironment *_r,unsigned int etherType,const void *frame,unsigned int len) const; +private: std::vector _chain; Mutex _chain_m; }; -- cgit v1.2.3 From 557cc359b30aacff372f1b92a8f0f621fcd9c50f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 17 Jul 2013 10:01:46 -0400 Subject: More filter work. --- node/Defaults.cpp | 7 +------ node/Defaults.hpp | 6 ------ node/Filter.cpp | 9 +++++++-- node/Filter.hpp | 16 ++++++++-------- node/NodeConfig.cpp | 8 ++++++++ node/NodeConfig.hpp | 8 +------- 6 files changed, 25 insertions(+), 29 deletions(-) (limited to 'node/Filter.hpp') diff --git a/node/Defaults.cpp b/node/Defaults.cpp index d5990600..f1454796 100644 --- a/node/Defaults.cpp +++ b/node/Defaults.cpp @@ -66,16 +66,11 @@ static inline std::map< Identity,std::vector > _mkSupernodeMap() return sn; } -static inline Filter _mkDefaultNodeFilter() -{ -} - Defaults::Defaults() throw(std::runtime_error) : supernodes(_mkSupernodeMap()), configUrlPrefix("http://api.zerotier.com/one/nc/"), - configAuthority("f9f34184ac:1:AwGgrWjb8dARXzruqxiy1+Qf+gz4iM5IMfQTCWrJXkwERdvbvxTPZvtIyitw4gS90TGIxW+e7uJxweg9Vyq5lZJBrg==:QeEQLm9ymLC3EcnIw2OUqufUwb2wgHSAg6wQOXKyhT779p/8Hz5485PZLJCbr/aVHjwzop8APJk9B45Zm0Mb/LEhQTBMH2jvc7qqoYnMCNCO9jpADeMJwMW5e1VFgIObWl9uNjhRbf5/m8dZcn0pKKGwjSoP1QTeVWOC8GkZhE25bUWj"), - defaultNodeFilter(_mkDefaultNodeFilter()) + configAuthority("f9f34184ac:1:AwGgrWjb8dARXzruqxiy1+Qf+gz4iM5IMfQTCWrJXkwERdvbvxTPZvtIyitw4gS90TGIxW+e7uJxweg9Vyq5lZJBrg==:QeEQLm9ymLC3EcnIw2OUqufUwb2wgHSAg6wQOXKyhT779p/8Hz5485PZLJCbr/aVHjwzop8APJk9B45Zm0Mb/LEhQTBMH2jvc7qqoYnMCNCO9jpADeMJwMW5e1VFgIObWl9uNjhRbf5/m8dZcn0pKKGwjSoP1QTeVWOC8GkZhE25bUWj") { } diff --git a/node/Defaults.hpp b/node/Defaults.hpp index 3493c5a8..b9c8ecf5 100644 --- a/node/Defaults.hpp +++ b/node/Defaults.hpp @@ -34,7 +34,6 @@ #include #include "Identity.hpp" #include "InetAddress.hpp" -#include "Filter.hpp" namespace ZeroTier { @@ -66,11 +65,6 @@ public: * Identity used to encrypt and authenticate configuration from URL */ const std::string configAuthority; - - /** - * Default node filter for this platform - */ - const Filter defaultNodeFilter; }; extern const Defaults ZT_DEFAULTS; diff --git a/node/Filter.cpp b/node/Filter.cpp index d7d177b1..a0412173 100644 --- a/node/Filter.cpp +++ b/node/Filter.cpp @@ -38,6 +38,7 @@ namespace ZeroTier { const char *const Filter::UNKNOWN_NAME = "(unknown)"; +const Range Filter::ANY; bool Filter::Rule::operator()(unsigned int etype,const void *data,unsigned int len) const throw(std::invalid_argument) @@ -338,19 +339,23 @@ Filter::Action Filter::operator()(const RuntimeEnvironment *_r,unsigned int ethe { Mutex::Lock _l(_chain_m); + TRACE("starting match against %d rules",(int)_chain.size()); + int ruleNo = 0; for(std::vector::const_iterator r(_chain.begin());r!=_chain.end();++r,++ruleNo) { try { if (r->rule(etherType,frame,len)) { + TRACE("match: %s",r->rule.toString().c_str()); + switch(r->action) { case ACTION_ALLOW: case ACTION_DENY: return r->action; - case ACTION_LOG: - break; default: break; } + } else { + TRACE("no match: %s",r->rule.toString().c_str()); } } catch (std::invalid_argument &exc) { LOG("filter: unable to parse packet on rule %s (%d): %s",r->rule.toString().c_str(),ruleNo,exc.what()); diff --git a/node/Filter.hpp b/node/Filter.hpp index 0af52864..8b86b48f 100644 --- a/node/Filter.hpp +++ b/node/Filter.hpp @@ -138,6 +138,11 @@ public: */ static const char *const UNKNOWN_NAME; + /** + * An empty range as a more idiomatic way of specifying a wildcard match + */ + static const Range ANY; + /** * A filter rule * @@ -222,10 +227,9 @@ public: */ enum Action { - ACTION_DENY = 1, - ACTION_ALLOW = 2, - ACTION_LOG = 3, - ACTION_UNPARSEABLE = 4 + ACTION_DENY = 0, + ACTION_ALLOW = 1, + ACTION_UNPARSEABLE = 2 }; /** @@ -329,10 +333,6 @@ public: /** * Match against an Ethernet frame * - * Note that ACTION_LOG rules do not terminate rule evaluation and - * ACTION_LOG is never returned here as a result. It's primarily for - * debugging and rule testing. - * * @param _r Runtime environment * @param etherType Ethernet frame type * @param frame Ethernet frame data diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index fcbbc6bd..763a5899 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -57,6 +57,14 @@ NodeConfig::~NodeConfig() _autoconfigureLock.unlock(); } +void NodeConfig::whackAllTaps() +{ + std::vector< SharedPtr > nwlist; + Mutex::Lock _l(_networks_m); + for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) + n->second->tap().whack(); +} + void NodeConfig::refreshConfiguration() { _autoconfigureLock.lock(); // unlocked when handler gets called diff --git a/node/NodeConfig.hpp b/node/NodeConfig.hpp index 5caf18ab..5c412c9b 100644 --- a/node/NodeConfig.hpp +++ b/node/NodeConfig.hpp @@ -81,13 +81,7 @@ public: /** * Call whack() on all networks' tap devices */ - inline void whackAllTaps() - { - std::vector< SharedPtr > nwlist; - Mutex::Lock _l(_networks_m); - for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) - n->second->tap().whack(); - } + void whackAllTaps(); /** * @param nwid Network ID -- cgit v1.2.3