diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-10-24 13:33:53 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-10-24 13:33:53 -0700 |
commit | 395d8b31392309d2861cd2d50377aaa8953f42cd (patch) | |
tree | dc348c4e9761eaea426971f68022dcec85d5c69b /node | |
parent | b92ef67e56f72b8eda9adfccef52a7d7f6642390 (diff) | |
download | infinitytier-395d8b31392309d2861cd2d50377aaa8953f42cd.tar.gz infinitytier-395d8b31392309d2861cd2d50377aaa8953f42cd.zip |
Full and clearer implementation of GitHub issue #588
Diffstat (limited to 'node')
-rw-r--r-- | node/Capability.hpp | 13 | ||||
-rw-r--r-- | node/Network.cpp | 29 |
2 files changed, 42 insertions, 0 deletions
diff --git a/node/Capability.hpp b/node/Capability.hpp index c0336243..407884ad 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -278,6 +278,13 @@ public: b.append((uint32_t)rules[i].v.tag.id); b.append((uint32_t)rules[i].v.tag.value); break; + case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: + b.append((uint8_t)19); + b.append((uint64_t)rules[i].v.intRange.start); + b.append((uint64_t)(rules[i].v.intRange.start + (uint64_t)rules[i].v.intRange.end)); // more future-proof + b.append((uint16_t)rules[i].v.intRange.idx); + b.append((uint8_t)rules[i].v.intRange.format); + break; } } } @@ -366,6 +373,12 @@ public: rules[ruleCount].v.tag.id = b.template at<uint32_t>(p); rules[ruleCount].v.tag.value = b.template at<uint32_t>(p + 4); break; + case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: + rules[ruleCount].v.intRange.start = b.template at<uint64_t>(p); + rules[ruleCount].v.intRange.end = (uint32_t)(b.template at<uint64_t>(p + 8) - rules[ruleCount].v.intRange.start); + rules[ruleCount].v.intRange.idx = b.template at<uint16_t>(p + 16); + rules[ruleCount].v.intRange.format = (uint8_t)b[p + 18]; + break; } p += fieldLen; ++ruleCount; diff --git a/node/Network.cpp b/node/Network.cpp index 111e4736..a9e8539e 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -493,6 +493,35 @@ static _doZtFilterResult _doZtFilter( } } } break; + case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: { + uint64_t integer = 0; + const unsigned int bits = (rules[rn].v.intRange.format & 63) + 1; + const unsigned int bytes = ((bits + 8 - 1) / 8); // integer ceiling of division by 8 + if ((rules[rn].v.intRange.format & 0x80) == 0) { + // Big-endian + unsigned int idx = rules[rn].v.intRange.idx + (8 - bytes); + const unsigned int eof = idx + bytes; + if (eof <= frameLen) { + while (idx < eof) { + integer <<= 8; + integer |= frameData[idx++]; + } + } + integer &= 0xffffffffffffffffULL >> (64 - bits); + } else { + // Little-endian + unsigned int idx = rules[rn].v.intRange.idx; + const unsigned int eof = idx + bytes; + if (eof <= frameLen) { + while (idx < eof) { + integer >>= 8; + integer |= ((uint64_t)frameData[idx++]) << 56; + } + } + integer >>= (64 - bits); + } + thisRuleMatches = (uint8_t)((integer >= rules[rn].v.intRange.start)&&(integer <= (rules[rn].v.intRange.start + (uint64_t)rules[rn].v.intRange.end))); + } break; // The result of an unsupported MATCH is configurable at the network // level via a flag. |