diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-02-28 09:22:10 -0800 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-02-28 09:22:10 -0800 |
commit | 2b10a982e9c9aad4a6ed9b10f5d7bda93a55ffcf (patch) | |
tree | 95645d1d1868f40986c648fe6d3c910b03622d65 /node | |
parent | 31bece7fa076cf1c5f21743a9a936ade54c0fe1a (diff) | |
download | infinitytier-2b10a982e9c9aad4a6ed9b10f5d7bda93a55ffcf.tar.gz infinitytier-2b10a982e9c9aad4a6ed9b10f5d7bda93a55ffcf.zip |
Match on tag sender equals or tag recipient equals.
Diffstat (limited to 'node')
-rw-r--r-- | node/Capability.hpp | 8 | ||||
-rw-r--r-- | node/Network.cpp | 38 |
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. |