summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2016-08-25 18:21:20 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2016-08-25 18:21:20 -0700
commitd637988ccf5c62c1f20233cf5704329daff61c67 (patch)
treee1c6590673f470083b3b6396086eab0e9433eed8
parent858e8c52171f2d4d95d78222bdfe28052fb3afec (diff)
downloadinfinitytier-d637988ccf5c62c1f20233cf5704329daff61c67.tar.gz
infinitytier-d637988ccf5c62c1f20233cf5704329daff61c67.zip
Fix chicken or egg problem in tags, and better filter debug instrumentation.
-rw-r--r--controller/EmbeddedNetworkController.cpp2
-rw-r--r--include/ZeroTierOne.h6
-rw-r--r--node/Membership.cpp25
-rw-r--r--node/Membership.hpp10
-rw-r--r--node/Network.cpp136
5 files changed, 96 insertions, 83 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp
index 8f013464..45af30be 100644
--- a/controller/EmbeddedNetworkController.cpp
+++ b/controller/EmbeddedNetworkController.cpp
@@ -50,7 +50,7 @@ using json = nlohmann::json;
#define ZT_NETCONF_CONTROLLER_API_VERSION 3
// Number of requests to remember in member history
-#define ZT_NETCONF_DB_MEMBER_HISTORY_LENGTH 16
+#define ZT_NETCONF_DB_MEMBER_HISTORY_LENGTH 32
// Min duration between requests for an address/nwid combo to prevent floods
#define ZT_NETCONF_MIN_REQUEST_PERIOD 1000
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h
index 1d7620d4..a3d82adb 100644
--- a/include/ZeroTierOne.h
+++ b/include/ZeroTierOne.h
@@ -107,14 +107,14 @@ extern "C" {
#define ZT_MAX_NETWORK_RULES 1024
/**
- * Maximum number of per-node capabilities per network
+ * Maximum number of per-member capabilities per network
*/
#define ZT_MAX_NETWORK_CAPABILITIES 128
/**
- * Maximum number of per-node tags per network
+ * Maximum number of per-member tags per network
*/
-#define ZT_MAX_NETWORK_TAGS 128
+#define ZT_MAX_NETWORK_TAGS 16
/**
* Maximum number of direct network paths to a given peer
diff --git a/node/Membership.cpp b/node/Membership.cpp
index 8bf5b784..7ced9dcf 100644
--- a/node/Membership.cpp
+++ b/node/Membership.cpp
@@ -28,8 +28,12 @@
namespace ZeroTier {
-bool Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const CertificateOfMembership &com,const Capability *cap,const Tag **tags,const unsigned int tagCount)
+bool Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,const Capability *cap)
{
+ if ((now - _lastPushAttempt) < 1000ULL)
+ return false;
+ _lastPushAttempt = now;
+
try {
Buffer<ZT_PROTO_MAX_PACKET_LENGTH> capsAndTags;
@@ -50,27 +54,29 @@ bool Membership::sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint
unsigned int appendedTags = 0;
const unsigned int tagCountPos = capsAndTags.size();
capsAndTags.addSize(2);
- for(unsigned int i=0;i<tagCount;++i) {
- TState *const ts = _tags.get(tags[i]->id());
+ for(unsigned int i=0;i<nconf.tagCount;++i) {
+ TState *const ts = _tags.get(nconf.tags[i].id());
if ((now - ts->lastPushed) >= ZT_CREDENTIAL_PUSH_EVERY) {
if ((capsAndTags.size() + sizeof(Tag)) > (ZT_PROTO_MAX_PACKET_LENGTH - sizeof(CertificateOfMembership)))
break;
- tags[i]->serialize(capsAndTags);
+ nconf.tags[i].serialize(capsAndTags);
ts->lastPushed = now;
++appendedTags;
}
}
capsAndTags.setAt<uint16_t>(tagCountPos,(uint16_t)appendedTags);
- if ( ((com)&&((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY)) || (appendedCaps) || (appendedTags) ) {
+ const bool needCom = ((nconf.isPrivate())&&(nconf.com)&&((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY));
+ if ( (needCom) || (appendedCaps) || (appendedTags) ) {
Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
- if (com)
- com.serialize(outp);
+ if (needCom) {
+ nconf.com.serialize(outp);
+ _lastPushedCom = now;
+ }
outp.append((uint8_t)0x00);
outp.append(capsAndTags.data(),capsAndTags.size());
outp.compress();
RR->sw->send(outp,true);
- _lastPushedCom = now;
return true;
}
} catch ( ... ) {
@@ -88,8 +94,9 @@ int Membership::addCredential(const RuntimeEnvironment *RR,const CertificateOfMe
const int vr = com.verify(RR);
if (vr == 0) {
TRACE("addCredential(CertificateOfMembership) for %s on %.16llx ACCEPTED (new)",com.issuedTo().toString().c_str(),com.networkId());
- if (com.timestamp().first > _com.timestamp().first)
+ if (com.timestamp().first > _com.timestamp().first) {
_com = com;
+ }
} else {
TRACE("addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (%d)",com.issuedTo().toString().c_str(),com.networkId(),vr);
}
diff --git a/node/Membership.hpp b/node/Membership.hpp
index bb356902..580aa529 100644
--- a/node/Membership.hpp
+++ b/node/Membership.hpp
@@ -107,6 +107,7 @@ public:
friend class CapabilityIterator;
Membership() :
+ _lastPushAttempt(0),
_lastPushedCom(0),
_blacklistBefore(0),
_com(),
@@ -124,13 +125,11 @@ public:
* @param RR Runtime environment
* @param now Current time
* @param peerAddress Address of member peer
- * @param com My network certificate of membership (if any) (not the one here, but ours -- in NetworkConfig)
+ * @param nconf My network config
* @param cap Capability to send or 0 if none
- * @param tags Tags that this peer might need
- * @param tagCount Number of tag IDs
* @return True if we pushed something
*/
- bool sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const CertificateOfMembership &com,const Capability *cap,const Tag **tags,const unsigned int tagCount);
+ bool sendCredentialsIfNeeded(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,const Capability *cap);
/**
* @param nconf Our network config
@@ -270,6 +269,9 @@ public:
}
private:
+ // Last time we checked if credential push was needed
+ uint64_t _lastPushAttempt;
+
// Last time we pushed our COM to this peer
uint64_t _lastPushedCom;
diff --git a/node/Network.cpp b/node/Network.cpp
index 5293e2f0..1267f99c 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -143,7 +143,7 @@ static int _doZtFilter(
const Address &ztDest,
const MAC &macSource,
const MAC &macDest,
- const uint8_t *frameData,
+ const uint8_t *const frameData,
const unsigned int frameLen,
const unsigned int etherType,
const unsigned int vlanId,
@@ -151,11 +151,9 @@ static int _doZtFilter(
const unsigned int ruleCount,
const Tag *localTags,
const unsigned int localTagCount,
- const uint32_t *remoteTagIds,
- const uint32_t *remoteTagValues,
- const unsigned int remoteTagCount,
- const Tag **relevantLocalTags, // pointer array must be at least [localTagCount] in size
- unsigned int &relevantLocalTagCount)
+ const uint32_t *const remoteTagIds,
+ const uint32_t *const remoteTagValues,
+ const unsigned int remoteTagCount)
{
// For each set of rules we start by assuming that they match (since no constraints
// yields a 'match all' rule).
@@ -168,30 +166,22 @@ static int _doZtFilter(
for(unsigned int rn=0;rn<ruleCount;++rn) {
const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rules[rn].t & 0x7f);
- uint8_t thisRuleMatches = 0;
switch(rt) {
- // Actions -------------------------------------------------------------
-
- // An action is performed if thisSetMatches is true, and if not
- // (or if the action is non-terminating) we start a new set of rules.
-
case ZT_NETWORK_RULE_ACTION_DROP:
if (thisSetMatches) {
return -1; // match, drop packet
} else {
- thisRuleMatches = 1;
thisSetMatches = 1; // no match, evaluate next set
}
- break;
+ continue;
case ZT_NETWORK_RULE_ACTION_ACCEPT:
if (thisSetMatches) {
return 1; // match, accept packet
} else {
- thisRuleMatches = 1;
thisSetMatches = 1; // no match, evaluate next set
}
- break;
+ continue;
case ZT_NETWORK_RULE_ACTION_TEE:
case ZT_NETWORK_RULE_ACTION_REDIRECT: {
if (!noRedirect) {
@@ -209,10 +199,9 @@ static int _doZtFilter(
if (rt == ZT_NETWORK_RULE_ACTION_REDIRECT) {
return -1; // match, drop packet (we redirected it)
} else {
- thisRuleMatches = 1;
thisSetMatches = 1; // TEE does not terminate evaluation
}
- } break;
+ } continue;
case ZT_NETWORK_RULE_ACTION_DEBUG_LOG:
#ifdef ZT_RULES_ENGINE_DEBUGGING
if (thisSetMatches) {
@@ -241,104 +230,118 @@ static int _doZtFilter(
dlog.clear();
}
#endif // ZT_RULES_ENGINE_DEBUGGING
- thisRuleMatches = 1;
thisSetMatches = 1; // DEBUG_LOG does not terminate evaluation
- break;
+ continue;
+
+ default: break;
+ }
- // Rules ---------------------------------------------------------------
+ // No need to evaluate MATCH entries beyond where thisSetMatches is no longer still true
+ if (!thisSetMatches)
+ continue;
- // thisSetMatches is the binary AND of the result of all rules in a set
+ uint8_t thisRuleMatches = 0;
+ switch(rt) {
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
- FILTER_TRACE("%u %s param0=%.10llx",rn,_rtn(rt),rules[rn].v.zt);
thisRuleMatches = (uint8_t)(rules[rn].v.zt == ztSource.toInt());
+ FILTER_TRACE("%u %s %c %.10llx==%.10llx -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),rules[rn].v.zt,ztSource.toInt(),(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
- FILTER_TRACE("%u %s param0=%.10llx",rn,_rtn(rt),rules[rn].v.zt);
thisRuleMatches = (uint8_t)(rules[rn].v.zt == ztDest.toInt());
+ FILTER_TRACE("%u %s %c %.10llx==%.10llx -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),rules[rn].v.zt,ztDest.toInt(),(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_VLAN_ID:
- FILTER_TRACE("%u %s param0=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.vlanId);
thisRuleMatches = (uint8_t)(rules[rn].v.vlanId == (uint16_t)vlanId);
+ FILTER_TRACE("%u %s %c %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.vlanId,(unsigned int)vlanId,(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
// NOT SUPPORTED YET
- FILTER_TRACE("%u %s param0=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.vlanPcp);
thisRuleMatches = (uint8_t)(rules[rn].v.vlanPcp == 0);
+ FILTER_TRACE("%u %s %c %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.vlanPcp,0,(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_VLAN_DEI:
// NOT SUPPORTED YET
- FILTER_TRACE("%u %s param0=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.vlanDei);
thisRuleMatches = (uint8_t)(rules[rn].v.vlanDei == 0);
+ FILTER_TRACE("%u %s %c %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.vlanDei,0,(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
- FILTER_TRACE("%u %s param0=%u etherType=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.etherType,etherType);
thisRuleMatches = (uint8_t)(rules[rn].v.etherType == (uint16_t)etherType);
+ FILTER_TRACE("%u %s %c %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.etherType,etherType,(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
- FILTER_TRACE("%u %s param0=%.12llx",rn,_rtn(rt),rules[rn].v.mac);
thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac,6) == macSource);
+ FILTER_TRACE("%u %s %c %.12llx=%.12llx -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),rules[rn].v.mac,macSource.toInt(),(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
- FILTER_TRACE("%u %s param0=%.12llx",rn,_rtn(rt),rules[rn].v.mac);
thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac,6) == macDest);
+ FILTER_TRACE("%u %s %c %.12llx=%.12llx -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),rules[rn].v.mac,macDest.toInt(),(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
- FILTER_TRACE("%u %s param0=%s",rn,_rtn(rt),InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).toString().c_str());
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
thisRuleMatches = (uint8_t)(InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void *)(frameData + 12),4,0)));
+ FILTER_TRACE("%u %s %c %s contains %s -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).toString().c_str(),InetAddress((const void *)(frameData + 12),4,0).toIpString().c_str(),(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IPv4] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
- FILTER_TRACE("%u %s param0=%s",rn,_rtn(rt),InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).toString().c_str());
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
thisRuleMatches = (uint8_t)(InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).containsAddress(InetAddress((const void *)(frameData + 16),4,0)));
+ FILTER_TRACE("%u %s %c %s contains %s -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),InetAddress((const void *)&(rules[rn].v.ipv4.ip),4,rules[rn].v.ipv4.mask).toString().c_str(),InetAddress((const void *)(frameData + 16),4,0).toIpString().c_str(),(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IPv4] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
- FILTER_TRACE("%u %s param0=%s",rn,_rtn(rt),InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).toString().c_str());
if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
thisRuleMatches = (uint8_t)(InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void *)(frameData + 8),16,0)));
+ FILTER_TRACE("%u %s %c %s contains %s -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).toString().c_str(),InetAddress((const void *)(frameData + 8),16,0).toIpString().c_str(),(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IPv6] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
- FILTER_TRACE("%u %s param0=%s",rn,_rtn(rt),InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).toString().c_str());
if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
thisRuleMatches = (uint8_t)(InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).containsAddress(InetAddress((const void *)(frameData + 24),16,0)));
+ FILTER_TRACE("%u %s %c %s contains %s -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),InetAddress((const void *)rules[rn].v.ipv6.ip,16,rules[rn].v.ipv6.mask).toString().c_str(),InetAddress((const void *)(frameData + 24),16,0).toIpString().c_str(),(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IPv6] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:
- FILTER_TRACE("%u %s param0=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.ipTos);
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
thisRuleMatches = (uint8_t)(rules[rn].v.ipTos == ((frameData[1] & 0xfc) >> 2));
+ FILTER_TRACE("%u %s %c (IPv4) %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.ipTos,(unsigned int)((frameData[1] & 0xfc) >> 2),(unsigned int)thisRuleMatches);
} else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
const uint8_t trafficClass = ((frameData[0] << 4) & 0xf0) | ((frameData[1] >> 4) & 0x0f);
thisRuleMatches = (uint8_t)(rules[rn].v.ipTos == ((trafficClass & 0xfc) >> 2));
+ FILTER_TRACE("%u %s %c (IPv6) %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.ipTos,(unsigned int)((trafficClass & 0xfc) >> 2),(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IP] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
- FILTER_TRACE("%u %s param0=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.ipProtocol);
if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == frameData[9]);
+ FILTER_TRACE("%u %s %c (IPv4) %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.ipProtocol,(unsigned int)frameData[9],(unsigned int)thisRuleMatches);
} else if (etherType == ZT_ETHERTYPE_IPV6) {
unsigned int pos = 0,proto = 0;
if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == (uint8_t)proto);
+ FILTER_TRACE("%u %s %c (IPv6) %u==%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.ipProtocol,proto,(unsigned int)thisRuleMatches);
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [invalid IPv6] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
} else {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IP] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
@@ -359,8 +362,9 @@ static int _doZtFilter(
}
break;
}
- FILTER_TRACE("%u %s param0=%u param1=%u port==%u proto==%u etherType=%u (IPv4)",rn,_rtn(rt),(unsigned int)rules[rn].v.port[0],(unsigned int)rules[rn].v.port[1],p,(unsigned int)frameData[9],etherType);
- thisRuleMatches = (p > 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0])&&(p <= (int)rules[rn].v.port[1])) : (uint8_t)0;
+
+ thisRuleMatches = (p >= 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0])&&(p <= (int)rules[rn].v.port[1])) : (uint8_t)0;
+ FILTER_TRACE("%u %s %c (IPv4) %d in %d-%d -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),p,(int)rules[rn].v.port[0],(int)rules[rn].v.port[1],(unsigned int)thisRuleMatches);
} else if (etherType == ZT_ETHERTYPE_IPV6) {
unsigned int pos = 0,proto = 0;
if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
@@ -378,15 +382,15 @@ static int _doZtFilter(
}
break;
}
- FILTER_TRACE("%u %s param0=%u param1=%u port==%u proto=%u etherType=%u (IPv6)",rn,_rtn(rt),(unsigned int)rules[rn].v.port[0],(unsigned int)rules[rn].v.port[1],p,proto,etherType);
thisRuleMatches = (p > 0) ? (uint8_t)((p >= (int)rules[rn].v.port[0])&&(p <= (int)rules[rn].v.port[1])) : (uint8_t)0;
+ FILTER_TRACE("%u %s %c (IPv6) %d in %d-%d -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),p,(int)rules[rn].v.port[0],(int)rules[rn].v.port[1],(unsigned int)thisRuleMatches);
} else {
- FILTER_TRACE("%u %s param0=%u param1=%u port=0 proto=0 etherType=%u (IPv6 parse failed)",rn,_rtn(rt),(unsigned int)rules[rn].v.port[0],(unsigned int)rules[rn].v.port[1],etherType);
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [invalid IPv6] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
} else {
- FILTER_TRACE("%u %s param0=%u param1=%u port=0 proto=0 etherType=%u (not IPv4 or IPv6)",rn,_rtn(rt),(unsigned int)rules[rn].v.port[0],(unsigned int)rules[rn].v.port[1],etherType);
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c [frame not IP] -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
}
break;
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS: {
@@ -406,18 +410,17 @@ static int _doZtFilter(
}
}
}
- FILTER_TRACE("%u %s param0=%.16llx param1=%.16llx actual=%.16llx",rn,_rtn(rt),rules[rn].v.characteristics[0],rules[rn].v.characteristics[1],cf);
thisRuleMatches = (uint8_t)((cf & rules[rn].v.characteristics[0]) == rules[rn].v.characteristics[1]);
+ FILTER_TRACE("%u %s %c (%.16llx & %.16llx)==%.16llx -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),cf,rules[rn].v.characteristics[0],rules[rn].v.characteristics[1],(unsigned int)thisRuleMatches);
} break;
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
- FILTER_TRACE("%u %s param0=%u param1=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.frameSize[0],(unsigned int)rules[rn].v.frameSize[1]);
thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0])&&(frameLen <= (unsigned int)rules[rn].v.frameSize[1]));
+ FILTER_TRACE("%u %s %c %u in %u-%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),frameLen,(unsigned int)rules[rn].v.frameSize[0],(unsigned int)rules[rn].v.frameSize[1],(unsigned int)thisRuleMatches);
break;
case ZT_NETWORK_RULE_MATCH_TAGS_SAMENESS:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: {
- FILTER_TRACE("%u %s param0=%u",rn,_rtn(rt),(unsigned int)rules[rn].v.tag.value);
const Tag *lt = (const Tag *)0;
for(unsigned int i=0;i<localTagCount;++i) {
if (rules[rn].v.tag.id == localTags[i].id()) {
@@ -427,6 +430,7 @@ static int _doZtFilter(
}
if (!lt) {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c local tag %u not found -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id);
} else {
const uint32_t *rtv = (const uint32_t *)0;
for(unsigned int i=0;i<remoteTagCount;++i) {
@@ -437,31 +441,33 @@ static int _doZtFilter(
}
if (!rtv) {
thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c remote tag %u not found -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id);
} else {
if (rt == ZT_NETWORK_RULE_MATCH_TAGS_SAMENESS) {
const uint32_t sameness = (lt->value() > *rtv) ? (lt->value() - *rtv) : (*rtv - lt->value());
thisRuleMatches = (uint8_t)(sameness <= rules[rn].v.tag.value);
+ FILTER_TRACE("%u %s %c TAG %u local:%u remote:%u sameness:%u <= %u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,lt->value(),*rtv,sameness,(unsigned int)rules[rn].v.tag.value,thisRuleMatches);
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND) {
- thisRuleMatches = (uint8_t)((lt->value() & *rtv) <= rules[rn].v.tag.value);
+ thisRuleMatches = (uint8_t)((lt->value() & *rtv) == rules[rn].v.tag.value);
+ FILTER_TRACE("%u %s %c TAG %u local:%.8x & remote:%.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,lt->value(),*rtv,(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches);
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR) {
- thisRuleMatches = (uint8_t)((lt->value() | *rtv) <= rules[rn].v.tag.value);
+ thisRuleMatches = (uint8_t)((lt->value() | *rtv) == rules[rn].v.tag.value);
+ FILTER_TRACE("%u %s %c TAG %u local:%.8x | remote:%.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,lt->value(),*rtv,(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches);
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) {
- thisRuleMatches = (uint8_t)((lt->value() ^ *rtv) <= rules[rn].v.tag.value);
+ thisRuleMatches = (uint8_t)((lt->value() ^ *rtv) == rules[rn].v.tag.value);
+ FILTER_TRACE("%u %s %c TAG %u local:%.8x ^ remote:%.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,lt->value(),*rtv,(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches);
} else { // sanity check, can't really happen
thisRuleMatches = 0;
}
- if (thisRuleMatches) {
- relevantLocalTags[relevantLocalTagCount++] = lt;
- }
}
}
} break;
+
+ default: continue;
}
// thisSetMatches remains true if the current rule matched (or did NOT match if NOT bit is set)
- thisSetMatches &= (thisRuleMatches ^ ((rules[rn].t & 0x80) >> 7));
-
- FILTER_TRACE("%u %s/%u thisRuleMatches==%u thisSetMatches==%u",rn,_rtn(rt),(unsigned int)rt,(unsigned int)thisRuleMatches,(unsigned int)thisSetMatches);
+ thisSetMatches &= (thisRuleMatches ^ ((rules[rn].t >> 7) & 1));
}
return 0;
@@ -543,31 +549,32 @@ bool Network::filterOutgoingPacket(
{
uint32_t remoteTagIds[ZT_MAX_NETWORK_TAGS];
uint32_t remoteTagValues[ZT_MAX_NETWORK_TAGS];
- const Tag *relevantLocalTags[ZT_MAX_NETWORK_TAGS];
- unsigned int relevantLocalTagCount = 0;
Mutex::Lock _l(_lock);
Membership &m = _memberships[ztDest];
const unsigned int remoteTagCount = m.getAllTags(_config,remoteTagIds,remoteTagValues,ZT_MAX_NETWORK_TAGS);
- switch(_doZtFilter(RR,noRedirect,_config,false,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount,relevantLocalTags,relevantLocalTagCount)) {
+ switch(_doZtFilter(RR,noRedirect,_config,false,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount)) {
case -1:
+ if (ztDest)
+ m.sendCredentialsIfNeeded(RR,RR->node->now(),ztDest,_config,(const Capability *)0);
return false;
case 1:
if (ztDest)
- m.sendCredentialsIfNeeded(RR,RR->node->now(),ztDest,_config.com,(const Capability *)0,relevantLocalTags,relevantLocalTagCount);
+ m.sendCredentialsIfNeeded(RR,RR->node->now(),ztDest,_config,(const Capability *)0);
return true;
}
for(unsigned int c=0;c<_config.capabilityCount;++c) {
- relevantLocalTagCount = 0;
- switch (_doZtFilter(RR,noRedirect,_config,false,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.capabilities[c].rules(),_config.capabilities[c].ruleCount(),_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount,relevantLocalTags,relevantLocalTagCount)) {
+ switch (_doZtFilter(RR,noRedirect,_config,false,ztSource,ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.capabilities[c].rules(),_config.capabilities[c].ruleCount(),_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount)) {
case -1:
+ if (ztDest)
+ m.sendCredentialsIfNeeded(RR,RR->node->now(),ztDest,_config,(const Capability *)0);
return false;
case 1:
if (ztDest)
- m.sendCredentialsIfNeeded(RR,RR->node->now(),ztDest,_config.com,&(_config.capabilities[c]),relevantLocalTags,relevantLocalTagCount);
+ m.sendCredentialsIfNeeded(RR,RR->node->now(),ztDest,_config,&(_config.capabilities[c]));
return true;
}
}
@@ -587,15 +594,13 @@ bool Network::filterIncomingPacket(
{
uint32_t remoteTagIds[ZT_MAX_NETWORK_TAGS];
uint32_t remoteTagValues[ZT_MAX_NETWORK_TAGS];
- const Tag *relevantLocalTags[ZT_MAX_NETWORK_TAGS];
- unsigned int relevantLocalTagCount = 0;
Mutex::Lock _l(_lock);
Membership &m = _memberships[ztDest];
const unsigned int remoteTagCount = m.getAllTags(_config,remoteTagIds,remoteTagValues,ZT_MAX_NETWORK_TAGS);
- switch (_doZtFilter(RR,false,_config,true,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount,relevantLocalTags,relevantLocalTagCount)) {
+ switch (_doZtFilter(RR,false,_config,true,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,_config.rules,_config.ruleCount,_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount)) {
case -1:
return false;
case 1:
@@ -605,8 +610,7 @@ bool Network::filterIncomingPacket(
Membership::CapabilityIterator mci(m);
const Capability *c;
while ((c = mci.next(_config))) {
- relevantLocalTagCount = 0;
- switch(_doZtFilter(RR,false,_config,false,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,c->rules(),c->ruleCount(),_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount,relevantLocalTags,relevantLocalTagCount)) {
+ switch(_doZtFilter(RR,false,_config,false,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,c->rules(),c->ruleCount(),_config.tags,_config.tagCount,remoteTagIds,remoteTagValues,remoteTagCount)) {
case -1:
return false;
case 1:
@@ -1030,7 +1034,7 @@ void Network::_announceMulticastGroupsTo(const SharedPtr<Peer> &peer,const std::
{
Membership *m = _memberships.get(peer->address());
if (m)
- m->sendCredentialsIfNeeded(RR,RR->node->now(),peer->address(),_config.com,(const Capability *)0,(const Tag **)0,0);
+ m->sendCredentialsIfNeeded(RR,RR->node->now(),peer->address(),_config,(const Capability *)0);
}
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);