summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2017-02-28 09:22:10 -0800
committerAdam Ierymenko <adam.ierymenko@gmail.com>2017-02-28 09:22:10 -0800
commit2b10a982e9c9aad4a6ed9b10f5d7bda93a55ffcf (patch)
tree95645d1d1868f40986c648fe6d3c910b03622d65 /node
parent31bece7fa076cf1c5f21743a9a936ade54c0fe1a (diff)
downloadinfinitytier-2b10a982e9c9aad4a6ed9b10f5d7bda93a55ffcf.tar.gz
infinitytier-2b10a982e9c9aad4a6ed9b10f5d7bda93a55ffcf.zip
Match on tag sender equals or tag recipient equals.
Diffstat (limited to 'node')
-rw-r--r--node/Capability.hpp8
-rw-r--r--node/Network.cpp38
2 files changed, 42 insertions, 4 deletions
diff --git a/node/Capability.hpp b/node/Capability.hpp
index d884625e..1ad6ea42 100644
--- a/node/Capability.hpp
+++ b/node/Capability.hpp
@@ -167,9 +167,6 @@ public:
// rules to be ignored but still parsed.
b.append((uint8_t)rules[i].t);
switch((ZT_VirtualNetworkRuleType)(rules[i].t & 0x3f)) {
- //case ZT_NETWORK_RULE_ACTION_DROP:
- //case ZT_NETWORK_RULE_ACTION_ACCEPT:
- //case ZT_NETWORK_RULE_ACTION_DEBUG_LOG:
default:
b.append((uint8_t)0);
break;
@@ -258,6 +255,9 @@ public:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
+ case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
+ case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
+ case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
b.append((uint8_t)8);
b.append((uint32_t)rules[i].v.tag.id);
b.append((uint32_t)rules[i].v.tag.value);
@@ -345,6 +345,8 @@ public:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
+ case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
+ case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
rules[ruleCount].v.tag.id = b.template at<uint32_t>(p);
rules[ruleCount].v.tag.value = b.template at<uint32_t>(p + 4);
break;
diff --git a/node/Network.cpp b/node/Network.cpp
index aad6e716..dc976f03 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -515,7 +515,6 @@ static _doZtFilterResult _doZtFilter(
src.set((const void *)(frameData + 12),4,0);
} else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
// IPv6 NDP requires special handling, since the src and dest IPs in the packet are empty or link-local.
- unsigned int pos = 0,proto = 0;
if ( (frameLen >= (40 + 8 + 16)) && (frameData[6] == 0x3a) && ((frameData[40] == 0x87)||(frameData[40] == 0x88)) ) {
if (frameData[40] == 0x87) {
// Neighbor solicitations contain no reliable source address, so we implement a small
@@ -609,6 +608,11 @@ static _doZtFilterResult _doZtFilter(
thisRuleMatches = 0;
FILTER_TRACE("%u %s %c remote tag %u not found -> 0 (inbound side is strict)",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id);
} else {
+ // Outbound side is not strict since if we have to match both tags and
+ // we are sending a first packet to a recipient, we probably do not know
+ // about their tags yet. They will filter on inbound and we will filter
+ // once we get their tag. If we are a tee/redirect target we are also
+ // not strict since we likely do not have these tags.
thisRuleMatches = 1;
FILTER_TRACE("%u %s %c remote tag %u not found -> 1 (outbound side and TEE/REDIRECT targets are not strict)",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id);
}
@@ -618,6 +622,38 @@ static _doZtFilterResult _doZtFilter(
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);
}
} break;
+ case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
+ case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: {
+ if (superAccept) {
+ thisRuleMatches = 1;
+ FILTER_TRACE("%u %s %c we are a TEE/REDIRECT target -> 1",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='));
+ } else if ( ((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER)&&(inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER)&&(!inbound)) ) {
+ const Tag *const remoteTag = ((membership) ? membership->getTag(nconf,rules[rn].v.tag.id) : (const Tag *)0);
+ if (remoteTag) {
+ thisRuleMatches = (uint8_t)(remoteTag->value() == rules[rn].v.tag.value);
+ FILTER_TRACE("%u %s %c TAG %u %.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,remoteTag->value(),(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches);
+ } else {
+ if (rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) {
+ // If we are checking the receiver and this is an outbound packet, we
+ // can't be strict since we may not yet know the receiver's tag.
+ thisRuleMatches = 1;
+ FILTER_TRACE("%u %s %c (inbound) remote tag %u not found -> 1 (outbound receiver match is not strict)",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id);
+ } else {
+ thisRuleMatches = 0;
+ FILTER_TRACE("%u %s %c (inbound) remote tag %u not found -> 0",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id);
+ }
+ }
+ } else { // sender and outbound or receiver and inbound
+ const Tag *const localTag = std::lower_bound(&(nconf.tags[0]),&(nconf.tags[nconf.tagCount]),rules[rn].v.tag.id,Tag::IdComparePredicate());
+ if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) {
+ thisRuleMatches = (uint8_t)(localTag->value() == rules[rn].v.tag.value);
+ FILTER_TRACE("%u %s %c TAG %u %.8x == %.8x -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)rules[rn].v.tag.id,remoteTag->value(),(unsigned int)rules[rn].v.tag.value,(unsigned int)thisRuleMatches);
+ } else {
+ 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);
+ }
+ }
+ } break;
// The result of an unsupported MATCH is configurable at the network
// level via a flag.