mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-09 04:04:13 +00:00
Full and clearer implementation of GitHub issue #588
This commit is contained in:
parent
b92ef67e56
commit
395d8b3139
@ -227,6 +227,16 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
|
||||
r["id"] = rule.v.tag.id;
|
||||
r["value"] = rule.v.tag.value;
|
||||
break;
|
||||
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
|
||||
r["type"] = "INTEGER_RANGE";
|
||||
OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start);
|
||||
r["start"] = tmp;
|
||||
OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start + (uint64_t)rule.v.intRange.end);
|
||||
r["end"] = tmp;
|
||||
r["idx"] = rule.v.intRange.idx;
|
||||
r["little"] = ((rule.v.intRange.format & 0x80) != 0);
|
||||
r["bits"] = (rule.v.intRange.format & 63) + 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -417,7 +427,26 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
|
||||
} else if (t == "MATCH_TAG_RECEIVER") {
|
||||
rule.t |= ZT_NETWORK_RULE_MATCH_TAG_RECEIVER;
|
||||
tag = true;
|
||||
} else if (t == "INTEGER_RANGE") {
|
||||
json &s = r["start"];
|
||||
if (s.is_string()) {
|
||||
std::string tmp = s;
|
||||
rule.v.intRange.start = Utils::hexStrToU64(tmp.c_str());
|
||||
} else {
|
||||
rule.v.intRange.start = OSUtils::jsonInt(s,0ULL);
|
||||
}
|
||||
json &e = r["end"];
|
||||
if (e.is_string()) {
|
||||
std::string tmp = e;
|
||||
rule.v.intRange.end = (uint32_t)(Utils::hexStrToU64(tmp.c_str()) - rule.v.intRange.start);
|
||||
} else {
|
||||
rule.v.intRange.end = (uint32_t)(OSUtils::jsonInt(e,0ULL) - rule.v.intRange.start);
|
||||
}
|
||||
rule.v.intRange.idx = (uint16_t)OSUtils::jsonInt(r["idx"],0ULL);
|
||||
rule.v.intRange.format = (OSUtils::jsonBool(r["little"],false)) ? 0x80 : 0x00;
|
||||
rule.v.intRange.format |= (uint8_t)((OSUtils::jsonInt(r["bits"],1ULL) - 1) & 63);
|
||||
}
|
||||
|
||||
if (tag) {
|
||||
rule.v.tag.id = (uint32_t)(OSUtils::jsonInt(r["id"],0ULL) & 0xffffffffULL);
|
||||
rule.v.tag.value = (uint32_t)(OSUtils::jsonInt(r["value"],0ULL) & 0xffffffffULL);
|
||||
|
@ -52,13 +52,13 @@
|
||||
#else
|
||||
#define ZT_SDK_API __declspec(dllimport)
|
||||
#ifdef _DEBUG
|
||||
#ifdef _WIN64
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "ZeroTierOne_x64d.lib")
|
||||
#else
|
||||
#pragma comment(lib, "ZeroTierOne_x86d.lib")
|
||||
#endif
|
||||
#else
|
||||
#ifdef _WIN64
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "ZeroTierOne_x64.lib")
|
||||
#else
|
||||
#pragma comment(lib, "ZeroTierOne_x86.lib")
|
||||
@ -750,6 +750,7 @@ enum ZT_VirtualNetworkRuleType
|
||||
ZT_NETWORK_RULE_MATCH_TAGS_EQUAL = 48,
|
||||
ZT_NETWORK_RULE_MATCH_TAG_SENDER = 49,
|
||||
ZT_NETWORK_RULE_MATCH_TAG_RECEIVER = 50,
|
||||
ZT_NETWORK_RULE_MATCH_INTEGER_RANGE = 51,
|
||||
|
||||
/**
|
||||
* Maximum ID allowed for a MATCH entry in the rules table
|
||||
@ -770,7 +771,7 @@ enum ZT_VirtualNetworkRuleType
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Type and flags
|
||||
*
|
||||
* Bits are: NOTTTTTT
|
||||
@ -812,10 +813,9 @@ typedef struct
|
||||
*/
|
||||
struct {
|
||||
uint64_t start; // integer range start
|
||||
int32_t delta; // +/- offset from start of integer range end
|
||||
uint32_t end; // end of integer range (relative to start, inclusive, 0 for equality w/start)
|
||||
uint16_t idx; // index in packet of integer
|
||||
uint8_t bits; // number of bits in integer (range: 1-64)
|
||||
uint8_t endian; // endianness of integer in packet (0 == big, 1 == little)
|
||||
uint8_t format; // bits in integer (range 1-64, ((format&63)+1)) and endianness (MSB 1 for little, 0 for big)
|
||||
} intRange;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user