|
@@ -33,14 +33,14 @@ namespace ZeroTier {
|
|
namespace {
|
|
namespace {
|
|
|
|
|
|
// Returns true if packet appears valid; pos and proto will be set
|
|
// Returns true if packet appears valid; pos and proto will be set
|
|
-bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsigned int &pos,unsigned int &proto) noexcept
|
|
|
|
|
|
+bool _ipv6GetPayload(const uint8_t *frameData, unsigned int frameLen, unsigned int &pos, unsigned int &proto) noexcept
|
|
{
|
|
{
|
|
if (frameLen < 40)
|
|
if (frameLen < 40)
|
|
return false;
|
|
return false;
|
|
pos = 40;
|
|
pos = 40;
|
|
proto = frameData[6];
|
|
proto = frameData[6];
|
|
while (pos <= frameLen) {
|
|
while (pos <= frameLen) {
|
|
- switch(proto) {
|
|
|
|
|
|
+ switch (proto) {
|
|
case 0: // hop-by-hop options
|
|
case 0: // hop-by-hop options
|
|
case 43: // routing
|
|
case 43: // routing
|
|
case 60: // destination options
|
|
case 60: // destination options
|
|
@@ -51,9 +51,9 @@ bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsigned int
|
|
pos += ((unsigned int)frameData[pos + 1] * 8) + 8;
|
|
pos += ((unsigned int)frameData[pos + 1] * 8) + 8;
|
|
break;
|
|
break;
|
|
|
|
|
|
- //case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway
|
|
|
|
- //case 50:
|
|
|
|
- //case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff
|
|
|
|
|
|
+ //case 44: // fragment -- we currently can't parse these and they are deprecated in IPv6 anyway
|
|
|
|
+ //case 50:
|
|
|
|
+ //case 51: // IPSec ESP and AH -- we have to stop here since this is encrypted stuff
|
|
default:
|
|
default:
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -100,13 +100,13 @@ _doZtFilterResult _doZtFilter(
|
|
|
|
|
|
rrl.clear();
|
|
rrl.clear();
|
|
|
|
|
|
- for(unsigned int rn=0;rn<ruleCount;++rn) {
|
|
|
|
|
|
+ for (unsigned int rn = 0; rn < ruleCount; ++rn) {
|
|
const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rules[rn].t & 0x3fU);
|
|
const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rules[rn].t & 0x3fU);
|
|
|
|
|
|
// First check if this is an ACTION
|
|
// First check if this is an ACTION
|
|
if ((unsigned int)rt <= (unsigned int)ZT_NETWORK_RULE_ACTION__MAX_ID) {
|
|
if ((unsigned int)rt <= (unsigned int)ZT_NETWORK_RULE_ACTION__MAX_ID) {
|
|
if (thisSetMatches) {
|
|
if (thisSetMatches) {
|
|
- switch(rt) {
|
|
|
|
|
|
+ switch (rt) {
|
|
case ZT_NETWORK_RULE_ACTION_PRIORITY:
|
|
case ZT_NETWORK_RULE_ACTION_PRIORITY:
|
|
qosBucket = (rules[rn].v.qosBucket >= 0 && rules[rn].v.qosBucket <= 8) ? rules[rn].v.qosBucket : 4; // 4 = default bucket (no priority)
|
|
qosBucket = (rules[rn].v.qosBucket >= 0 && rules[rn].v.qosBucket <= 8) ? rules[rn].v.qosBucket : 4; // 4 = default bucket (no priority)
|
|
return DOZTFILTER_ACCEPT;
|
|
return DOZTFILTER_ACCEPT;
|
|
@@ -117,10 +117,10 @@ _doZtFilterResult _doZtFilter(
|
|
case ZT_NETWORK_RULE_ACTION_ACCEPT:
|
|
case ZT_NETWORK_RULE_ACTION_ACCEPT:
|
|
return (superAccept ? DOZTFILTER_SUPER_ACCEPT : DOZTFILTER_ACCEPT); // match, accept packet
|
|
return (superAccept ? DOZTFILTER_SUPER_ACCEPT : DOZTFILTER_ACCEPT); // match, accept packet
|
|
|
|
|
|
- // These are initially handled together since preliminary logic is common
|
|
|
|
|
|
+ // These are initially handled together since preliminary logic is common
|
|
case ZT_NETWORK_RULE_ACTION_TEE:
|
|
case ZT_NETWORK_RULE_ACTION_TEE:
|
|
case ZT_NETWORK_RULE_ACTION_WATCH:
|
|
case ZT_NETWORK_RULE_ACTION_WATCH:
|
|
- case ZT_NETWORK_RULE_ACTION_REDIRECT: {
|
|
|
|
|
|
+ case ZT_NETWORK_RULE_ACTION_REDIRECT: {
|
|
const Address fwdAddr(rules[rn].v.fwd.address);
|
|
const Address fwdAddr(rules[rn].v.fwd.address);
|
|
if (fwdAddr == ztSource) {
|
|
if (fwdAddr == ztSource) {
|
|
// Skip as no-op since source is target
|
|
// Skip as no-op since source is target
|
|
@@ -140,12 +140,13 @@ _doZtFilterResult _doZtFilter(
|
|
ccWatch = (rt == ZT_NETWORK_RULE_ACTION_WATCH);
|
|
ccWatch = (rt == ZT_NETWORK_RULE_ACTION_WATCH);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } continue;
|
|
|
|
|
|
+ }
|
|
|
|
+ continue;
|
|
|
|
|
|
case ZT_NETWORK_RULE_ACTION_BREAK:
|
|
case ZT_NETWORK_RULE_ACTION_BREAK:
|
|
return DOZTFILTER_NO_MATCH;
|
|
return DOZTFILTER_NO_MATCH;
|
|
|
|
|
|
- // Unrecognized ACTIONs are ignored as no-ops
|
|
|
|
|
|
+ // Unrecognized ACTIONs are ignored as no-ops
|
|
default:
|
|
default:
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
@@ -154,7 +155,7 @@ _doZtFilterResult _doZtFilter(
|
|
// super-accept if we accept at all. This will cause us to accept redirected or
|
|
// super-accept if we accept at all. This will cause us to accept redirected or
|
|
// tee'd packets in spite of MAC and ZT addressing checks.
|
|
// tee'd packets in spite of MAC and ZT addressing checks.
|
|
if (inbound) {
|
|
if (inbound) {
|
|
- switch(rt) {
|
|
|
|
|
|
+ switch (rt) {
|
|
case ZT_NETWORK_RULE_ACTION_TEE:
|
|
case ZT_NETWORK_RULE_ACTION_TEE:
|
|
case ZT_NETWORK_RULE_ACTION_WATCH:
|
|
case ZT_NETWORK_RULE_ACTION_WATCH:
|
|
case ZT_NETWORK_RULE_ACTION_REDIRECT:
|
|
case ZT_NETWORK_RULE_ACTION_REDIRECT:
|
|
@@ -173,15 +174,15 @@ _doZtFilterResult _doZtFilter(
|
|
|
|
|
|
// Circuit breaker: no need to evaluate an AND if the set's match state
|
|
// Circuit breaker: no need to evaluate an AND if the set's match state
|
|
// is currently false since anything AND false is false.
|
|
// is currently false since anything AND false is false.
|
|
- if ((!thisSetMatches)&&(!(rules[rn].t & 0x40U))) {
|
|
|
|
- rrl.logSkipped(rn,thisSetMatches);
|
|
|
|
|
|
+ if ((!thisSetMatches) && (!(rules[rn].t & 0x40U))) {
|
|
|
|
+ rrl.logSkipped(rn, thisSetMatches);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
// If this was not an ACTION evaluate next MATCH and update thisSetMatches with (AND [result])
|
|
// If this was not an ACTION evaluate next MATCH and update thisSetMatches with (AND [result])
|
|
uint8_t thisRuleMatches = 0;
|
|
uint8_t thisRuleMatches = 0;
|
|
uint64_t ownershipVerificationMask = 1; // this magic value means it hasn't been computed yet -- this is done lazily the first time it's needed
|
|
uint64_t ownershipVerificationMask = 1; // this magic value means it hasn't been computed yet -- this is done lazily the first time it's needed
|
|
- switch(rt) {
|
|
|
|
|
|
+ switch (rt) {
|
|
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
|
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.zt == ztSource.toInt());
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.zt == ztSource.toInt());
|
|
break;
|
|
break;
|
|
@@ -206,50 +207,50 @@ _doZtFilterResult _doZtFilter(
|
|
thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac) == macDest);
|
|
thisRuleMatches = (uint8_t)(MAC(rules[rn].v.mac) == macDest);
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
|
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
|
- 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)));
|
|
|
|
|
|
+ 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)));
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
|
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
|
- 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)));
|
|
|
|
|
|
+ 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)));
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
|
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
|
- 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)));
|
|
|
|
|
|
+ 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)));
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
|
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
|
- 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)));
|
|
|
|
|
|
+ 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)));
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
|
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
|
- if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
|
|
|
|
|
+ if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
|
const uint8_t tosMasked = frameData[1] & rules[rn].v.ipTos.mask;
|
|
const uint8_t tosMasked = frameData[1] & rules[rn].v.ipTos.mask;
|
|
- thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1]));
|
|
|
|
- } else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
|
|
|
|
|
|
+ thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0]) && (tosMasked <= rules[rn].v.ipTos.value[1]));
|
|
|
|
+ } else if ((etherType == ZT_ETHERTYPE_IPV6) && (frameLen >= 40)) {
|
|
const uint8_t tosMasked = (((frameData[0] << 4U) & 0xf0U) | ((frameData[1] >> 4U) & 0x0fU)) & rules[rn].v.ipTos.mask;
|
|
const uint8_t tosMasked = (((frameData[0] << 4U) & 0xf0U) | ((frameData[1] >> 4U) & 0x0fU)) & rules[rn].v.ipTos.mask;
|
|
- thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0])&&(tosMasked <= rules[rn].v.ipTos.value[1]));
|
|
|
|
|
|
+ thisRuleMatches = (uint8_t)((tosMasked >= rules[rn].v.ipTos.value[0]) && (tosMasked <= rules[rn].v.ipTos.value[1]));
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
|
|
case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
|
|
- if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
|
|
|
|
|
+ if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == frameData[9]);
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == frameData[9]);
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
- unsigned int pos = 0,proto = 0;
|
|
|
|
- if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
|
|
|
|
|
|
+ unsigned int pos = 0, proto = 0;
|
|
|
|
+ if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == (uint8_t)proto);
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.ipProtocol == (uint8_t)proto);
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
@@ -262,13 +263,13 @@ _doZtFilterResult _doZtFilter(
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.etherType == (uint16_t)etherType);
|
|
thisRuleMatches = (uint8_t)(rules[rn].v.etherType == (uint16_t)etherType);
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_ICMP:
|
|
case ZT_NETWORK_RULE_MATCH_ICMP:
|
|
- if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
|
|
|
|
|
+ if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
|
if (frameData[9] == 0x01) { // IP protocol == ICMP
|
|
if (frameData[9] == 0x01) { // IP protocol == ICMP
|
|
const unsigned int ihl = (frameData[0] & 0xfU) * 4;
|
|
const unsigned int ihl = (frameData[0] & 0xfU) * 4;
|
|
if (frameLen >= (ihl + 2)) {
|
|
if (frameLen >= (ihl + 2)) {
|
|
if (rules[rn].v.icmp.type == frameData[ihl]) {
|
|
if (rules[rn].v.icmp.type == frameData[ihl]) {
|
|
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
|
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
|
- thisRuleMatches = (uint8_t)(frameData[ihl+1] == rules[rn].v.icmp.code);
|
|
|
|
|
|
+ thisRuleMatches = (uint8_t)(frameData[ihl + 1] == rules[rn].v.icmp.code);
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 1;
|
|
thisRuleMatches = 1;
|
|
}
|
|
}
|
|
@@ -282,12 +283,12 @@ _doZtFilterResult _doZtFilter(
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
- unsigned int pos = 0,proto = 0;
|
|
|
|
- if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
|
|
|
|
- if ((proto == 0x3a)&&(frameLen >= (pos+2))) {
|
|
|
|
|
|
+ unsigned int pos = 0, proto = 0;
|
|
|
|
+ if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
|
|
|
+ if ((proto == 0x3a) && (frameLen >= (pos + 2))) {
|
|
if (rules[rn].v.icmp.type == frameData[pos]) {
|
|
if (rules[rn].v.icmp.type == frameData[pos]) {
|
|
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
|
if ((rules[rn].v.icmp.flags & 0x01) != 0) {
|
|
- thisRuleMatches = (uint8_t)(frameData[pos+1] == rules[rn].v.icmp.code);
|
|
|
|
|
|
+ thisRuleMatches = (uint8_t)(frameData[pos + 1] == rules[rn].v.icmp.code);
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 1;
|
|
thisRuleMatches = 1;
|
|
}
|
|
}
|
|
@@ -306,10 +307,10 @@ _doZtFilterResult _doZtFilter(
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
|
|
case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
|
|
case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
|
|
case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
|
|
- if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
|
|
|
|
|
+ if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
|
const unsigned int headerLen = 4 * (frameData[0] & 0xfU);
|
|
const unsigned int headerLen = 4 * (frameData[0] & 0xfU);
|
|
int p = -1;
|
|
int p = -1;
|
|
- switch(frameData[9]) { // IP protocol number
|
|
|
|
|
|
+ switch (frameData[9]) { // IP protocol number
|
|
// All these start with 16-bit source and destination port in that order
|
|
// All these start with 16-bit source and destination port in that order
|
|
case 0x06: // TCP
|
|
case 0x06: // TCP
|
|
case 0x11: // UDP
|
|
case 0x11: // UDP
|
|
@@ -323,12 +324,12 @@ _doZtFilterResult _doZtFilter(
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- 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;
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
- unsigned int pos = 0,proto = 0;
|
|
|
|
- if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
|
|
|
|
|
|
+ unsigned int pos = 0, proto = 0;
|
|
|
|
+ if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
|
int p = -1;
|
|
int p = -1;
|
|
- switch(proto) { // IP protocol number
|
|
|
|
|
|
+ switch (proto) { // IP protocol number
|
|
// All these start with 16-bit source and destination port in that order
|
|
// All these start with 16-bit source and destination port in that order
|
|
case 0x06: // TCP
|
|
case 0x06: // TCP
|
|
case 0x11: // UDP
|
|
case 0x11: // UDP
|
|
@@ -341,7 +342,7 @@ _doZtFilterResult _doZtFilter(
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- 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;
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
@@ -356,11 +357,11 @@ _doZtFilterResult _doZtFilter(
|
|
if (ownershipVerificationMask == 1) {
|
|
if (ownershipVerificationMask == 1) {
|
|
ownershipVerificationMask = 0;
|
|
ownershipVerificationMask = 0;
|
|
InetAddress src;
|
|
InetAddress src;
|
|
- if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)) {
|
|
|
|
- src.set((const void *)(frameData + 12),4,0);
|
|
|
|
- } else if ((etherType == ZT_ETHERTYPE_IPV6)&&(frameLen >= 40)) {
|
|
|
|
|
|
+ if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20)) {
|
|
|
|
+ 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.
|
|
// IPv6 NDP requires special handling, since the src and dest IPs in the packet are empty or link-local.
|
|
- if ( (frameLen >= (40 + 8 + 16)) && (frameData[6] == 0x3a) && ((frameData[40] == 0x87)||(frameData[40] == 0x88)) ) {
|
|
|
|
|
|
+ if ((frameLen >= (40 + 8 + 16)) && (frameData[6] == 0x3a) && ((frameData[40] == 0x87) || (frameData[40] == 0x88))) {
|
|
if (frameData[40] == 0x87) {
|
|
if (frameData[40] == 0x87) {
|
|
// Neighbor solicitations contain no reliable source address, so we implement a small
|
|
// Neighbor solicitations contain no reliable source address, so we implement a small
|
|
// hack by considering them authenticated. Otherwise you would pretty much have to do
|
|
// hack by considering them authenticated. Otherwise you would pretty much have to do
|
|
@@ -368,25 +369,25 @@ _doZtFilterResult _doZtFilter(
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
|
} else {
|
|
} else {
|
|
// Neighbor advertisements on the other hand can absolutely be authenticated.
|
|
// Neighbor advertisements on the other hand can absolutely be authenticated.
|
|
- src.set((const void *)(frameData + 40 + 8),16,0);
|
|
|
|
|
|
+ src.set((const void *)(frameData + 40 + 8), 16, 0);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
// Other IPv6 packets can be handled normally
|
|
// Other IPv6 packets can be handled normally
|
|
- src.set((const void *)(frameData + 8),16,0);
|
|
|
|
|
|
+ src.set((const void *)(frameData + 8), 16, 0);
|
|
}
|
|
}
|
|
- } else if ((etherType == ZT_ETHERTYPE_ARP)&&(frameLen >= 28)) {
|
|
|
|
- src.set((const void *)(frameData + 14),4,0);
|
|
|
|
|
|
+ } else if ((etherType == ZT_ETHERTYPE_ARP) && (frameLen >= 28)) {
|
|
|
|
+ src.set((const void *)(frameData + 14), 4, 0);
|
|
}
|
|
}
|
|
if (inbound) {
|
|
if (inbound) {
|
|
if (membership) {
|
|
if (membership) {
|
|
- if ((src)&&(membership->peerOwnsAddress<InetAddress>(nconf,src)))
|
|
|
|
|
|
+ if ((src) && (membership->peerOwnsAddress< InetAddress >(nconf, src)))
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
|
- if (membership->peerOwnsAddress<MAC>(nconf,macSource))
|
|
|
|
|
|
+ if (membership->peerOwnsAddress< MAC >(nconf, macSource))
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- for(unsigned int i=0;i<nconf.certificateOfOwnershipCount;++i) {
|
|
|
|
- if ((src)&&(nconf.certificatesOfOwnership[i].owns(src)))
|
|
|
|
|
|
+ for (unsigned int i = 0; i < nconf.certificateOfOwnershipCount; ++i) {
|
|
|
|
+ if ((src) && (nconf.certificatesOfOwnership[i].owns(src)))
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
|
|
if (nconf.certificatesOfOwnership[i].owns(macSource))
|
|
if (nconf.certificatesOfOwnership[i].owns(macSource))
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
|
|
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
|
|
@@ -394,23 +395,24 @@ _doZtFilterResult _doZtFilter(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cf |= ownershipVerificationMask;
|
|
cf |= ownershipVerificationMask;
|
|
- if ((etherType == ZT_ETHERTYPE_IPV4)&&(frameLen >= 20)&&(frameData[9] == 0x06)) {
|
|
|
|
|
|
+ if ((etherType == ZT_ETHERTYPE_IPV4) && (frameLen >= 20) && (frameData[9] == 0x06)) {
|
|
const unsigned int headerLen = 4 * (frameData[0] & 0xfU);
|
|
const unsigned int headerLen = 4 * (frameData[0] & 0xfU);
|
|
cf |= (uint64_t)frameData[headerLen + 13];
|
|
cf |= (uint64_t)frameData[headerLen + 13];
|
|
cf |= (((uint64_t)(frameData[headerLen + 12] & 0x0fU)) << 8U);
|
|
cf |= (((uint64_t)(frameData[headerLen + 12] & 0x0fU)) << 8U);
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
} else if (etherType == ZT_ETHERTYPE_IPV6) {
|
|
- unsigned int pos = 0,proto = 0;
|
|
|
|
- if (_ipv6GetPayload(frameData,frameLen,pos,proto)) {
|
|
|
|
- if ((proto == 0x06)&&(frameLen > (pos + 14))) {
|
|
|
|
|
|
+ unsigned int pos = 0, proto = 0;
|
|
|
|
+ if (_ipv6GetPayload(frameData, frameLen, pos, proto)) {
|
|
|
|
+ if ((proto == 0x06) && (frameLen > (pos + 14))) {
|
|
cf |= (uint64_t)frameData[pos + 13];
|
|
cf |= (uint64_t)frameData[pos + 13];
|
|
cf |= (((uint64_t)(frameData[pos + 12] & 0x0fU)) << 8U);
|
|
cf |= (((uint64_t)(frameData[pos + 12] & 0x0fU)) << 8U);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
thisRuleMatches = (uint8_t)((cf & rules[rn].v.characteristics) != 0);
|
|
thisRuleMatches = (uint8_t)((cf & rules[rn].v.characteristics) != 0);
|
|
- } break;
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
|
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
|
- thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0])&&(frameLen <= (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]));
|
|
break;
|
|
break;
|
|
case ZT_NETWORK_RULE_MATCH_RANDOM:
|
|
case ZT_NETWORK_RULE_MATCH_RANDOM:
|
|
thisRuleMatches = (uint8_t)((uint32_t)(Utils::random() & 0xffffffffULL) <= rules[rn].v.randomProbability);
|
|
thisRuleMatches = (uint8_t)((uint32_t)(Utils::random() & 0xffffffffULL) <= rules[rn].v.randomProbability);
|
|
@@ -421,7 +423,7 @@ _doZtFilterResult _doZtFilter(
|
|
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
|
|
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
|
|
case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: {
|
|
case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL: {
|
|
const TagCredential *const localTag = std::lower_bound(&(nconf.tags[0]), &(nconf.tags[nconf.tagCount]), rules[rn].v.tag.id, TagCredential::IdComparePredicate());
|
|
const TagCredential *const localTag = std::lower_bound(&(nconf.tags[0]), &(nconf.tags[nconf.tagCount]), rules[rn].v.tag.id, TagCredential::IdComparePredicate());
|
|
- if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) {
|
|
|
|
|
|
+ if ((localTag != &(nconf.tags[nconf.tagCount])) && (localTag->id() == rules[rn].v.tag.id)) {
|
|
const TagCredential *const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const TagCredential *)0);
|
|
const TagCredential *const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const TagCredential *)0);
|
|
if (remoteTag) {
|
|
if (remoteTag) {
|
|
const uint32_t ltv = localTag->value();
|
|
const uint32_t ltv = localTag->value();
|
|
@@ -436,12 +438,12 @@ _doZtFilterResult _doZtFilter(
|
|
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) {
|
|
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR) {
|
|
thisRuleMatches = (uint8_t)((ltv ^ rtv) == rules[rn].v.tag.value);
|
|
thisRuleMatches = (uint8_t)((ltv ^ rtv) == rules[rn].v.tag.value);
|
|
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) {
|
|
} else if (rt == ZT_NETWORK_RULE_MATCH_TAGS_EQUAL) {
|
|
- thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value)&&(rtv == rules[rn].v.tag.value));
|
|
|
|
|
|
+ thisRuleMatches = (uint8_t)((ltv == rules[rn].v.tag.value) && (rtv == rules[rn].v.tag.value));
|
|
} else { // sanity check, can't really happen
|
|
} else { // sanity check, can't really happen
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- if ((inbound)&&(!superAccept)) {
|
|
|
|
|
|
+ if ((inbound) && (!superAccept)) {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
} else {
|
|
} else {
|
|
// Outbound side is not strict since if we have to match both tags and
|
|
// Outbound side is not strict since if we have to match both tags and
|
|
@@ -455,12 +457,13 @@ _doZtFilterResult _doZtFilter(
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
- } break;
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
|
|
case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
|
|
case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: {
|
|
case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER: {
|
|
if (superAccept) {
|
|
if (superAccept) {
|
|
thisRuleMatches = 1;
|
|
thisRuleMatches = 1;
|
|
- } else if ( ((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER)&&(inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER)&&(!inbound)) ) {
|
|
|
|
|
|
+ } else if (((rt == ZT_NETWORK_RULE_MATCH_TAG_SENDER) && (inbound)) || ((rt == ZT_NETWORK_RULE_MATCH_TAG_RECEIVER) && (!inbound))) {
|
|
const TagCredential *const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const TagCredential *)0);
|
|
const TagCredential *const remoteTag = ((membership) ? membership->getTag(nconf, rules[rn].v.tag.id) : (const TagCredential *)0);
|
|
if (remoteTag) {
|
|
if (remoteTag) {
|
|
thisRuleMatches = (uint8_t)(remoteTag->value() == rules[rn].v.tag.value);
|
|
thisRuleMatches = (uint8_t)(remoteTag->value() == rules[rn].v.tag.value);
|
|
@@ -475,13 +478,14 @@ _doZtFilterResult _doZtFilter(
|
|
}
|
|
}
|
|
} else { // sender and outbound or receiver and inbound
|
|
} else { // sender and outbound or receiver and inbound
|
|
const TagCredential *const localTag = std::lower_bound(&(nconf.tags[0]), &(nconf.tags[nconf.tagCount]), rules[rn].v.tag.id, TagCredential::IdComparePredicate());
|
|
const TagCredential *const localTag = std::lower_bound(&(nconf.tags[0]), &(nconf.tags[nconf.tagCount]), rules[rn].v.tag.id, TagCredential::IdComparePredicate());
|
|
- if ((localTag != &(nconf.tags[nconf.tagCount]))&&(localTag->id() == rules[rn].v.tag.id)) {
|
|
|
|
|
|
+ if ((localTag != &(nconf.tags[nconf.tagCount])) && (localTag->id() == rules[rn].v.tag.id)) {
|
|
thisRuleMatches = (uint8_t)(localTag->value() == rules[rn].v.tag.value);
|
|
thisRuleMatches = (uint8_t)(localTag->value() == rules[rn].v.tag.value);
|
|
} else {
|
|
} else {
|
|
thisRuleMatches = 0;
|
|
thisRuleMatches = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } break;
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: {
|
|
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE: {
|
|
uint64_t integer = 0;
|
|
uint64_t integer = 0;
|
|
const unsigned int bits = (rules[rn].v.intRange.format & 63U) + 1;
|
|
const unsigned int bits = (rules[rn].v.intRange.format & 63U) + 1;
|
|
@@ -509,17 +513,18 @@ _doZtFilterResult _doZtFilter(
|
|
}
|
|
}
|
|
integer >>= (64 - bits);
|
|
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;
|
|
|
|
|
|
+ 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.
|
|
|
|
|
|
+ // The result of an unsupported MATCH is configurable at the network
|
|
|
|
+ // level via a flag.
|
|
default:
|
|
default:
|
|
thisRuleMatches = (uint8_t)((nconf.flags & ZT_NETWORKCONFIG_FLAG_RULES_RESULT_OF_UNSUPPORTED_MATCH) != 0);
|
|
thisRuleMatches = (uint8_t)((nconf.flags & ZT_NETWORKCONFIG_FLAG_RULES_RESULT_OF_UNSUPPORTED_MATCH) != 0);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- rrl.log(rn,thisRuleMatches,thisSetMatches);
|
|
|
|
|
|
+ rrl.log(rn, thisRuleMatches, thisSetMatches);
|
|
|
|
|
|
if ((rules[rn].t & 0x40U))
|
|
if ((rules[rn].t & 0x40U))
|
|
thisSetMatches |= (thisRuleMatches ^ ((rules[rn].t >> 7U) & 1U));
|
|
thisSetMatches |= (thisRuleMatches ^ ((rules[rn].t >> 7U) & 1U));
|
|
@@ -531,9 +536,9 @@ _doZtFilterResult _doZtFilter(
|
|
|
|
|
|
} // anonymous namespace
|
|
} // anonymous namespace
|
|
|
|
|
|
-const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL),0);
|
|
|
|
|
|
+const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL), 0);
|
|
|
|
|
|
-Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const Fingerprint &controllerFingerprint,void *uptr,const NetworkConfig *nconf) :
|
|
|
|
|
|
+Network::Network(const RuntimeEnvironment *renv, void *tPtr, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr, const NetworkConfig *nconf) :
|
|
RR(renv),
|
|
RR(renv),
|
|
m_uPtr(uptr),
|
|
m_uPtr(uptr),
|
|
m_id(nwid),
|
|
m_id(nwid),
|
|
@@ -547,33 +552,34 @@ Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,const F
|
|
m_controllerFingerprint = controllerFingerprint;
|
|
m_controllerFingerprint = controllerFingerprint;
|
|
|
|
|
|
if (nconf) {
|
|
if (nconf) {
|
|
- this->setConfiguration(tPtr,*nconf,false);
|
|
|
|
|
|
+ this->setConfiguration(tPtr, *nconf, false);
|
|
m_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
|
|
m_lastConfigUpdate = 0; // still want to re-request since it's likely outdated
|
|
} else {
|
|
} else {
|
|
uint64_t tmp[2];
|
|
uint64_t tmp[2];
|
|
- tmp[0] = nwid; tmp[1] = 0;
|
|
|
|
|
|
+ tmp[0] = nwid;
|
|
|
|
+ tmp[1] = 0;
|
|
|
|
|
|
bool got = false;
|
|
bool got = false;
|
|
try {
|
|
try {
|
|
Dictionary dict;
|
|
Dictionary dict;
|
|
- Vector<uint8_t> nconfData(RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp));
|
|
|
|
|
|
+ Vector< uint8_t > nconfData(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp));
|
|
if (nconfData.size() > 2) {
|
|
if (nconfData.size() > 2) {
|
|
nconfData.push_back(0);
|
|
nconfData.push_back(0);
|
|
- if (dict.decode(nconfData.data(),(unsigned int)nconfData.size())) {
|
|
|
|
|
|
+ if (dict.decode(nconfData.data(), (unsigned int)nconfData.size())) {
|
|
try {
|
|
try {
|
|
- ScopedPtr<NetworkConfig> nconf2(new NetworkConfig());
|
|
|
|
|
|
+ ScopedPtr< NetworkConfig > nconf2(new NetworkConfig());
|
|
if (nconf2->fromDictionary(dict)) {
|
|
if (nconf2->fromDictionary(dict)) {
|
|
- this->setConfiguration(tPtr,*nconf2,false);
|
|
|
|
|
|
+ this->setConfiguration(tPtr, *nconf2, false);
|
|
m_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
|
|
m_lastConfigUpdate = 0; // still want to re-request an update since it's likely outdated
|
|
got = true;
|
|
got = true;
|
|
}
|
|
}
|
|
} catch (...) {}
|
|
} catch (...) {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } catch ( ... ) {}
|
|
|
|
|
|
+ } catch (...) {}
|
|
|
|
|
|
if (!got)
|
|
if (!got)
|
|
- RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,"\n",1);
|
|
|
|
|
|
+ RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, "\n", 1);
|
|
}
|
|
}
|
|
|
|
|
|
if (!m_portInitialized) {
|
|
if (!m_portInitialized) {
|
|
@@ -615,7 +621,7 @@ bool Network::filterOutgoingPacket(
|
|
const unsigned int vlanId,
|
|
const unsigned int vlanId,
|
|
uint8_t &qosBucket)
|
|
uint8_t &qosBucket)
|
|
{
|
|
{
|
|
- Trace::RuleResultLog rrl,crrl;
|
|
|
|
|
|
+ Trace::RuleResultLog rrl, crrl;
|
|
Address ztFinalDest(ztDest);
|
|
Address ztFinalDest(ztDest);
|
|
int localCapabilityIndex = -1;
|
|
int localCapabilityIndex = -1;
|
|
int accept = 0;
|
|
int accept = 0;
|
|
@@ -626,12 +632,19 @@ bool Network::filterOutgoingPacket(
|
|
Mutex::Lock l1(m_memberships_l);
|
|
Mutex::Lock l1(m_memberships_l);
|
|
Mutex::Lock l2(m_config_l);
|
|
Mutex::Lock l2(m_config_l);
|
|
|
|
|
|
- Member *const membership = (ztDest) ? m_memberships.get(ztDest) : nullptr;
|
|
|
|
|
|
+ Member *membership;
|
|
|
|
+ if (ztDest) {
|
|
|
|
+ Map<Address, Member>::iterator mm(m_memberships.find(ztDest));
|
|
|
|
+ if (mm != m_memberships.end())
|
|
|
|
+ membership = &(mm->second);
|
|
|
|
+ } else {
|
|
|
|
+ membership = nullptr;
|
|
|
|
+ }
|
|
|
|
|
|
- switch(_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
|
|
|
|
|
+ switch (_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, cc, ccLength, ccWatch, qosBucket)) {
|
|
|
|
|
|
case DOZTFILTER_NO_MATCH: {
|
|
case DOZTFILTER_NO_MATCH: {
|
|
- for(unsigned int c=0;c < m_config.capabilityCount;++c) {
|
|
|
|
|
|
+ for (unsigned int c = 0; c < m_config.capabilityCount; ++c) {
|
|
ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match
|
|
ztFinalDest = ztDest; // sanity check, shouldn't be possible if there was no match
|
|
Address cc2;
|
|
Address cc2;
|
|
unsigned int ccLength2 = 0;
|
|
unsigned int ccLength2 = 0;
|
|
@@ -647,7 +660,7 @@ bool Network::filterOutgoingPacket(
|
|
localCapabilityIndex = (int)c;
|
|
localCapabilityIndex = (int)c;
|
|
accept = 1;
|
|
accept = 1;
|
|
|
|
|
|
- if ((!noTee)&&(cc2)) {
|
|
|
|
|
|
+ if ((!noTee) && (cc2)) {
|
|
// TODO
|
|
// TODO
|
|
/*
|
|
/*
|
|
Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
@@ -667,7 +680,8 @@ bool Network::filterOutgoingPacket(
|
|
if (accept)
|
|
if (accept)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- } break;
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
|
|
case DOZTFILTER_DROP:
|
|
case DOZTFILTER_DROP:
|
|
RR->t->networkFilter(tPtr, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
|
|
RR->t->networkFilter(tPtr, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
|
|
@@ -684,7 +698,7 @@ bool Network::filterOutgoingPacket(
|
|
}
|
|
}
|
|
|
|
|
|
if (accept != 0) {
|
|
if (accept != 0) {
|
|
- if ((!noTee)&&(cc)) {
|
|
|
|
|
|
+ if ((!noTee) && (cc)) {
|
|
// TODO
|
|
// TODO
|
|
/*
|
|
/*
|
|
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
@@ -699,7 +713,7 @@ bool Network::filterOutgoingPacket(
|
|
*/
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
- if ((ztDest != ztFinalDest)&&(ztFinalDest)) {
|
|
|
|
|
|
+ if ((ztDest != ztFinalDest) && (ztFinalDest)) {
|
|
// TODO
|
|
// TODO
|
|
/*
|
|
/*
|
|
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
@@ -730,7 +744,7 @@ bool Network::filterOutgoingPacket(
|
|
|
|
|
|
int Network::filterIncomingPacket(
|
|
int Network::filterIncomingPacket(
|
|
void *tPtr,
|
|
void *tPtr,
|
|
- const SharedPtr<Peer> &sourcePeer,
|
|
|
|
|
|
+ const SharedPtr< Peer > &sourcePeer,
|
|
const Address &ztDest,
|
|
const Address &ztDest,
|
|
const MAC &macSource,
|
|
const MAC &macSource,
|
|
const MAC &macDest,
|
|
const MAC &macDest,
|
|
@@ -740,7 +754,7 @@ int Network::filterIncomingPacket(
|
|
const unsigned int vlanId)
|
|
const unsigned int vlanId)
|
|
{
|
|
{
|
|
Address ztFinalDest(ztDest);
|
|
Address ztFinalDest(ztDest);
|
|
- Trace::RuleResultLog rrl,crrl;
|
|
|
|
|
|
+ Trace::RuleResultLog rrl, crrl;
|
|
int accept = 0;
|
|
int accept = 0;
|
|
Address cc;
|
|
Address cc;
|
|
unsigned int ccLength = 0;
|
|
unsigned int ccLength = 0;
|
|
@@ -763,7 +777,7 @@ int Network::filterIncomingPacket(
|
|
Address cc2;
|
|
Address cc2;
|
|
unsigned int ccLength2 = 0;
|
|
unsigned int ccLength2 = 0;
|
|
bool ccWatch2 = false;
|
|
bool ccWatch2 = false;
|
|
- switch(_doZtFilter(RR, crrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, c->rules(), c->ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
|
|
|
|
|
|
+ switch (_doZtFilter(RR, crrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, c->rules(), c->ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
|
|
case DOZTFILTER_NO_MATCH:
|
|
case DOZTFILTER_NO_MATCH:
|
|
case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
|
|
case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
|
|
break;
|
|
break;
|
|
@@ -794,7 +808,8 @@ int Network::filterIncomingPacket(
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } break;
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
|
|
case DOZTFILTER_DROP:
|
|
case DOZTFILTER_DROP:
|
|
//if (_config.remoteTraceTarget)
|
|
//if (_config.remoteTraceTarget)
|
|
@@ -826,7 +841,7 @@ int Network::filterIncomingPacket(
|
|
*/
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
- if ((ztDest != ztFinalDest)&&(ztFinalDest)) {
|
|
|
|
|
|
+ if ((ztDest != ztFinalDest) && (ztFinalDest)) {
|
|
// TODO
|
|
// TODO
|
|
/*
|
|
/*
|
|
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
|
|
@@ -851,7 +866,7 @@ int Network::filterIncomingPacket(
|
|
return accept;
|
|
return accept;
|
|
}
|
|
}
|
|
|
|
|
|
-void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg)
|
|
|
|
|
|
+void Network::multicastSubscribe(void *tPtr, const MulticastGroup &mg)
|
|
{
|
|
{
|
|
Mutex::Lock l(m_myMulticastGroups_l);
|
|
Mutex::Lock l(m_myMulticastGroups_l);
|
|
if (!std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg)) {
|
|
if (!std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg)) {
|
|
@@ -864,12 +879,12 @@ void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg)
|
|
void Network::multicastUnsubscribe(const MulticastGroup &mg)
|
|
void Network::multicastUnsubscribe(const MulticastGroup &mg)
|
|
{
|
|
{
|
|
Mutex::Lock l(m_myMulticastGroups_l);
|
|
Mutex::Lock l(m_myMulticastGroups_l);
|
|
- Vector<MulticastGroup>::iterator i(std::lower_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg));
|
|
|
|
- if ((i != m_myMulticastGroups.end()) && (*i == mg) )
|
|
|
|
|
|
+ Vector< MulticastGroup >::iterator i(std::lower_bound(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg));
|
|
|
|
+ if ((i != m_myMulticastGroups.end()) && (*i == mg))
|
|
m_myMulticastGroups.erase(i);
|
|
m_myMulticastGroups.erase(i);
|
|
}
|
|
}
|
|
|
|
|
|
-uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr<Peer> &source,const Buf &chunk,int ptr,int size)
|
|
|
|
|
|
+uint64_t Network::handleConfigChunk(void *tPtr, uint64_t packetId, const SharedPtr< Peer > &source, const Buf &chunk, int ptr, int size)
|
|
{
|
|
{
|
|
// If the controller's full fingerprint is known or was explicitly specified on join(),
|
|
// If the controller's full fingerprint is known or was explicitly specified on join(),
|
|
// require that the controller's identity match. Otherwise learn it.
|
|
// require that the controller's identity match. Otherwise learn it.
|
|
@@ -1013,16 +1028,16 @@ uint64_t Network::handleConfigChunk(void *tPtr,uint64_t packetId,const SharedPtr
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk)
|
|
|
|
|
|
+int Network::setConfiguration(void *tPtr, const NetworkConfig &nconf, bool saveToDisk)
|
|
{
|
|
{
|
|
if (m_destroyed)
|
|
if (m_destroyed)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
// _lock is NOT locked when this is called
|
|
// _lock is NOT locked when this is called
|
|
try {
|
|
try {
|
|
- if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != m_id))
|
|
|
|
|
|
+ if ((nconf.issuedTo != RR->identity.address()) || (nconf.networkId != m_id))
|
|
return 0; // invalid config that is not for us or not for this network
|
|
return 0; // invalid config that is not for us or not for this network
|
|
- if ((!Utils::allZero(nconf.issuedToFingerprintHash,ZT_FINGERPRINT_HASH_SIZE)) && (memcmp(nconf.issuedToFingerprintHash,RR->identity.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE) != 0))
|
|
|
|
|
|
+ if ((!Utils::allZero(nconf.issuedToFingerprintHash, ZT_FINGERPRINT_HASH_SIZE)) && (memcmp(nconf.issuedToFingerprintHash, RR->identity.fingerprint().hash, ZT_FINGERPRINT_HASH_SIZE) != 0))
|
|
return 0; // full identity hash is present and does not match
|
|
return 0; // full identity hash is present and does not match
|
|
|
|
|
|
if (m_config == nconf)
|
|
if (m_config == nconf)
|
|
@@ -1030,7 +1045,7 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
|
|
|
|
|
|
ZT_VirtualNetworkConfig ctmp;
|
|
ZT_VirtualNetworkConfig ctmp;
|
|
bool oldPortInitialized;
|
|
bool oldPortInitialized;
|
|
- { // do things that require lock here, but unlock before calling callbacks
|
|
|
|
|
|
+ { // do things that require lock here, but unlock before calling callbacks
|
|
Mutex::Lock l1(m_config_l);
|
|
Mutex::Lock l1(m_config_l);
|
|
|
|
|
|
m_config = nconf;
|
|
m_config = nconf;
|
|
@@ -1050,20 +1065,21 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
|
|
Dictionary d;
|
|
Dictionary d;
|
|
if (nconf.toDictionary(d)) {
|
|
if (nconf.toDictionary(d)) {
|
|
uint64_t tmp[2];
|
|
uint64_t tmp[2];
|
|
- tmp[0] = m_id; tmp[1] = 0;
|
|
|
|
- Vector<uint8_t> d2;
|
|
|
|
|
|
+ tmp[0] = m_id;
|
|
|
|
+ tmp[1] = 0;
|
|
|
|
+ Vector< uint8_t > d2;
|
|
d.encode(d2);
|
|
d.encode(d2);
|
|
- RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_NETWORK_CONFIG,tmp,d2.data(),(unsigned int)d2.size());
|
|
|
|
|
|
+ RR->node->stateObjectPut(tPtr, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, d2.data(), (unsigned int)d2.size());
|
|
}
|
|
}
|
|
- } catch ( ... ) {}
|
|
|
|
|
|
+ } catch (...) {}
|
|
}
|
|
}
|
|
|
|
|
|
return 2; // OK and configuration has changed
|
|
return 2; // OK and configuration has changed
|
|
- } catch ( ... ) {} // ignore invalid configs
|
|
|
|
|
|
+ } catch (...) {} // ignore invalid configs
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer) noexcept
|
|
|
|
|
|
+bool Network::gate(void *tPtr, const SharedPtr< Peer > &peer) noexcept
|
|
{
|
|
{
|
|
Mutex::Lock lc(m_config_l);
|
|
Mutex::Lock lc(m_config_l);
|
|
|
|
|
|
@@ -1074,21 +1090,13 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer) noexcept
|
|
|
|
|
|
try {
|
|
try {
|
|
Mutex::Lock l(m_memberships_l);
|
|
Mutex::Lock l(m_memberships_l);
|
|
- Member *m = m_memberships.get(peer->address());
|
|
|
|
- if (m) {
|
|
|
|
- // SECURITY: this method in CertificateOfMembership does a full fingerprint check as well as
|
|
|
|
- // checking certificate agreement. See Membership.hpp.
|
|
|
|
- return m->certificateOfMembershipAgress(m_config.com, peer->identity());
|
|
|
|
- } else {
|
|
|
|
- m = &(m_memberships[peer->address()]);
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- } catch ( ... ) {}
|
|
|
|
|
|
+ return m_memberships[peer->address()].certificateOfMembershipAgress(m_config.com, peer->identity());
|
|
|
|
+ } catch (...) {}
|
|
|
|
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-void Network::doPeriodicTasks(void *tPtr,const int64_t now)
|
|
|
|
|
|
+void Network::doPeriodicTasks(void *tPtr, const int64_t now)
|
|
{
|
|
{
|
|
if (m_destroyed)
|
|
if (m_destroyed)
|
|
return;
|
|
return;
|
|
@@ -1099,8 +1107,8 @@ void Network::doPeriodicTasks(void *tPtr,const int64_t now)
|
|
{
|
|
{
|
|
Mutex::Lock l1(m_memberships_l);
|
|
Mutex::Lock l1(m_memberships_l);
|
|
|
|
|
|
- for(Map<Address,Member>::iterator i(m_memberships.begin()); i != m_memberships.end(); ++i)
|
|
|
|
- i->second.clean(now, m_config);
|
|
|
|
|
|
+ for (Map< Address, Member >::iterator i(m_memberships.begin()); i != m_memberships.end(); ++i)
|
|
|
|
+ i->second.clean(m_config);
|
|
|
|
|
|
{
|
|
{
|
|
Mutex::Lock l2(m_myMulticastGroups_l);
|
|
Mutex::Lock l2(m_myMulticastGroups_l);
|
|
@@ -1121,19 +1129,19 @@ void Network::doPeriodicTasks(void *tPtr,const int64_t now)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
|
|
|
|
|
|
+void Network::learnBridgeRoute(const MAC &mac, const Address &addr)
|
|
{
|
|
{
|
|
Mutex::Lock _l(m_remoteBridgeRoutes_l);
|
|
Mutex::Lock _l(m_remoteBridgeRoutes_l);
|
|
m_remoteBridgeRoutes[mac] = addr;
|
|
m_remoteBridgeRoutes[mac] = addr;
|
|
|
|
|
|
// Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes
|
|
// Anti-DOS circuit breaker to prevent nodes from spamming us with absurd numbers of bridge routes
|
|
while (m_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
|
|
while (m_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
|
|
- Map< Address,unsigned long > counts;
|
|
|
|
|
|
+ Map< Address, unsigned long > counts;
|
|
Address maxAddr;
|
|
Address maxAddr;
|
|
unsigned long maxCount = 0;
|
|
unsigned long maxCount = 0;
|
|
|
|
|
|
// Find the address responsible for the most entries
|
|
// Find the address responsible for the most entries
|
|
- for(Map<MAC,Address>::iterator i(m_remoteBridgeRoutes.begin());i != m_remoteBridgeRoutes.end();++i) {
|
|
|
|
|
|
+ for (Map< MAC, Address >::iterator i(m_remoteBridgeRoutes.begin()); i != m_remoteBridgeRoutes.end(); ++i) {
|
|
const unsigned long c = ++counts[i->second];
|
|
const unsigned long c = ++counts[i->second];
|
|
if (c > maxCount) {
|
|
if (c > maxCount) {
|
|
maxCount = c;
|
|
maxCount = c;
|
|
@@ -1142,7 +1150,7 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
|
|
}
|
|
}
|
|
|
|
|
|
// Kill this address from our table, since it's most likely spamming us
|
|
// Kill this address from our table, since it's most likely spamming us
|
|
- for(Map<MAC,Address>::iterator i(m_remoteBridgeRoutes.begin());i != m_remoteBridgeRoutes.end();) {
|
|
|
|
|
|
+ for (Map< MAC, Address >::iterator i(m_remoteBridgeRoutes.begin()); i != m_remoteBridgeRoutes.end();) {
|
|
if (i->second == maxAddr)
|
|
if (i->second == maxAddr)
|
|
m_remoteBridgeRoutes.erase(i++);
|
|
m_remoteBridgeRoutes.erase(i++);
|
|
else ++i;
|
|
else ++i;
|
|
@@ -1216,7 +1224,7 @@ Member::AddCredentialResult Network::addCredential(void *tPtr, const Identity &s
|
|
return m_memberships[coo.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, coo);
|
|
return m_memberships[coo.issuedTo()].addCredential(RR, tPtr, sourcePeerIdentity, m_config, coo);
|
|
}
|
|
}
|
|
|
|
|
|
-void Network::pushCredentials(void *tPtr,const SharedPtr<Peer> &to,const int64_t now)
|
|
|
|
|
|
+void Network::pushCredentials(void *tPtr, const SharedPtr< Peer > &to, const int64_t now)
|
|
{
|
|
{
|
|
const int64_t tout = std::min(m_config.credentialTimeMaxDelta, m_config.com.timestampMaxDelta());
|
|
const int64_t tout = std::min(m_config.credentialTimeMaxDelta, m_config.com.timestampMaxDelta());
|
|
Mutex::Lock _l(m_memberships_l);
|
|
Mutex::Lock _l(m_memberships_l);
|
|
@@ -1251,7 +1259,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
const uint16_t startPortRange = (uint16_t)((m_id >> 40U) & 0xffff);
|
|
const uint16_t startPortRange = (uint16_t)((m_id >> 40U) & 0xffff);
|
|
const uint16_t endPortRange = (uint16_t)((m_id >> 24U) & 0xffff);
|
|
const uint16_t endPortRange = (uint16_t)((m_id >> 24U) & 0xffff);
|
|
if (endPortRange >= startPortRange) {
|
|
if (endPortRange >= startPortRange) {
|
|
- ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
|
|
|
|
|
|
+ ScopedPtr< NetworkConfig > nconf(new NetworkConfig());
|
|
|
|
|
|
nconf->networkId = m_id;
|
|
nconf->networkId = m_id;
|
|
nconf->timestamp = RR->node->now();
|
|
nconf->timestamp = RR->node->now();
|
|
@@ -1307,12 +1315,12 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
nconf->name[3] = 'o';
|
|
nconf->name[3] = 'o';
|
|
nconf->name[4] = 'c';
|
|
nconf->name[4] = 'c';
|
|
nconf->name[5] = '-';
|
|
nconf->name[5] = '-';
|
|
- Utils::hex((uint16_t)startPortRange,nconf->name + 6);
|
|
|
|
|
|
+ Utils::hex((uint16_t)startPortRange, nconf->name + 6);
|
|
nconf->name[10] = '-';
|
|
nconf->name[10] = '-';
|
|
- Utils::hex((uint16_t)endPortRange,nconf->name + 11);
|
|
|
|
|
|
+ Utils::hex((uint16_t)endPortRange, nconf->name + 11);
|
|
nconf->name[15] = (char)0;
|
|
nconf->name[15] = (char)0;
|
|
|
|
|
|
- this->setConfiguration(tPtr,*nconf,false);
|
|
|
|
|
|
+ this->setConfiguration(tPtr, *nconf, false);
|
|
} else {
|
|
} else {
|
|
this->setNotFound();
|
|
this->setNotFound();
|
|
}
|
|
}
|
|
@@ -1328,9 +1336,9 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
ipv4[3] = (uint8_t)myAddress;
|
|
ipv4[3] = (uint8_t)myAddress;
|
|
|
|
|
|
char v4ascii[24];
|
|
char v4ascii[24];
|
|
- Utils::decimal(ipv4[0],v4ascii);
|
|
|
|
|
|
+ Utils::decimal(ipv4[0], v4ascii);
|
|
|
|
|
|
- ScopedPtr<NetworkConfig> nconf(new NetworkConfig());
|
|
|
|
|
|
+ ScopedPtr< NetworkConfig > nconf(new NetworkConfig());
|
|
|
|
|
|
nconf->networkId = m_id;
|
|
nconf->networkId = m_id;
|
|
nconf->timestamp = RR->node->now();
|
|
nconf->timestamp = RR->node->now();
|
|
@@ -1348,7 +1356,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
nconf->specialists[0] = networkHub;
|
|
nconf->specialists[0] = networkHub;
|
|
|
|
|
|
nconf->staticIps[0] = InetAddress::makeIpv66plane(m_id, myAddress);
|
|
nconf->staticIps[0] = InetAddress::makeIpv66plane(m_id, myAddress);
|
|
- nconf->staticIps[1].set(ipv4,4,8);
|
|
|
|
|
|
+ nconf->staticIps[1].set(ipv4, 4, 8);
|
|
|
|
|
|
nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT;
|
|
nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_ACTION_ACCEPT;
|
|
|
|
|
|
@@ -1370,7 +1378,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
nconf->name[nn++] = '0';
|
|
nconf->name[nn++] = '0';
|
|
nconf->name[nn] = (char)0;
|
|
nconf->name[nn] = (char)0;
|
|
|
|
|
|
- this->setConfiguration(tPtr,*nconf,false);
|
|
|
|
|
|
+ this->setConfiguration(tPtr, *nconf, false);
|
|
}
|
|
}
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -1378,17 +1386,17 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
const Address ctrl(controller());
|
|
const Address ctrl(controller());
|
|
|
|
|
|
Dictionary rmd;
|
|
Dictionary rmd;
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)1); // 1 == ZeroTier, no other vendors at the moment
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_VERSION_MAJOR);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_VERSION_MINOR);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,(uint64_t)ZEROTIER_VERSION_REVISION);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES,(uint64_t)ZT_MAX_NETWORK_RULES);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES,(uint64_t)ZT_MAX_NETWORK_CAPABILITIES);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES,(uint64_t)ZT_MAX_CAPABILITY_RULES);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
|
|
|
|
- rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
|
|
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR, (uint64_t)1); // 1 == ZeroTier, no other vendors at the moment
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION, (uint64_t)ZT_PROTO_VERSION);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION, (uint64_t)ZEROTIER_VERSION_MAJOR);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION, (uint64_t)ZEROTIER_VERSION_MINOR);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION, (uint64_t)ZEROTIER_VERSION_REVISION);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_RULES, (uint64_t)ZT_MAX_NETWORK_RULES);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_CAPABILITIES, (uint64_t)ZT_MAX_NETWORK_CAPABILITIES);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_CAPABILITY_RULES, (uint64_t)ZT_MAX_CAPABILITY_RULES);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS, (uint64_t)ZT_MAX_NETWORK_TAGS);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS, (uint64_t)0);
|
|
|
|
+ rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV, (uint64_t)ZT_RULES_ENGINE_REVISION);
|
|
|
|
|
|
RR->t->networkConfigRequestSent(tPtr, 0x335bb1a2, m_id);
|
|
RR->t->networkConfigRequestSent(tPtr, 0x335bb1a2, m_id);
|
|
|
|
|
|
@@ -1422,7 +1430,7 @@ void Network::m_requestConfiguration(void *tPtr)
|
|
|
|
|
|
ZT_VirtualNetworkStatus Network::m_status() const
|
|
ZT_VirtualNetworkStatus Network::m_status() const
|
|
{
|
|
{
|
|
- switch(_netconfFailure) {
|
|
|
|
|
|
+ switch (_netconfFailure) {
|
|
case NETCONF_FAILURE_ACCESS_DENIED:
|
|
case NETCONF_FAILURE_ACCESS_DENIED:
|
|
return ZT_NETWORK_STATUS_ACCESS_DENIED;
|
|
return ZT_NETWORK_STATUS_ACCESS_DENIED;
|
|
case NETCONF_FAILURE_NOT_FOUND:
|
|
case NETCONF_FAILURE_NOT_FOUND:
|
|
@@ -1445,32 +1453,32 @@ void Network::m_externalConfig(ZT_VirtualNetworkConfig *ec) const
|
|
ec->status = m_status();
|
|
ec->status = m_status();
|
|
ec->type = (m_config) ? (m_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE;
|
|
ec->type = (m_config) ? (m_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE;
|
|
ec->mtu = (m_config) ? m_config.mtu : ZT_DEFAULT_MTU;
|
|
ec->mtu = (m_config) ? m_config.mtu : ZT_DEFAULT_MTU;
|
|
- Vector<Address> ab;
|
|
|
|
- for(unsigned int i=0;i < m_config.specialistCount;++i) {
|
|
|
|
|
|
+ Vector< Address > ab;
|
|
|
|
+ for (unsigned int i = 0; i < m_config.specialistCount; ++i) {
|
|
if ((m_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
|
|
if ((m_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
|
|
ab.push_back(Address(m_config.specialists[i]));
|
|
ab.push_back(Address(m_config.specialists[i]));
|
|
}
|
|
}
|
|
- ec->bridge = (std::find(ab.begin(),ab.end(),RR->identity.address()) != ab.end()) ? 1 : 0;
|
|
|
|
|
|
+ ec->bridge = (std::find(ab.begin(), ab.end(), RR->identity.address()) != ab.end()) ? 1 : 0;
|
|
ec->broadcastEnabled = (m_config) ? (m_config.enableBroadcast() ? 1 : 0) : 0;
|
|
ec->broadcastEnabled = (m_config) ? (m_config.enableBroadcast() ? 1 : 0) : 0;
|
|
ec->netconfRevision = (m_config) ? (unsigned long)m_config.revision : 0;
|
|
ec->netconfRevision = (m_config) ? (unsigned long)m_config.revision : 0;
|
|
|
|
|
|
ec->assignedAddressCount = 0;
|
|
ec->assignedAddressCount = 0;
|
|
- for(unsigned int i=0;i<ZT_MAX_ZT_ASSIGNED_ADDRESSES;++i) {
|
|
|
|
|
|
+ for (unsigned int i = 0; i < ZT_MAX_ZT_ASSIGNED_ADDRESSES; ++i) {
|
|
if (i < m_config.staticIpCount) {
|
|
if (i < m_config.staticIpCount) {
|
|
- Utils::copy<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]),&(m_config.staticIps[i]));
|
|
|
|
|
|
+ Utils::copy< sizeof(struct sockaddr_storage) >(&(ec->assignedAddresses[i]), &(m_config.staticIps[i]));
|
|
++ec->assignedAddressCount;
|
|
++ec->assignedAddressCount;
|
|
} else {
|
|
} else {
|
|
- Utils::zero<sizeof(struct sockaddr_storage)>(&(ec->assignedAddresses[i]));
|
|
|
|
|
|
+ Utils::zero< sizeof(struct sockaddr_storage) >(&(ec->assignedAddresses[i]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ec->routeCount = 0;
|
|
ec->routeCount = 0;
|
|
- for(unsigned int i=0;i<ZT_MAX_NETWORK_ROUTES;++i) {
|
|
|
|
|
|
+ for (unsigned int i = 0; i < ZT_MAX_NETWORK_ROUTES; ++i) {
|
|
if (i < m_config.routeCount) {
|
|
if (i < m_config.routeCount) {
|
|
- Utils::copy<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]),&(m_config.routes[i]));
|
|
|
|
|
|
+ Utils::copy< sizeof(ZT_VirtualNetworkRoute) >(&(ec->routes[i]), &(m_config.routes[i]));
|
|
++ec->routeCount;
|
|
++ec->routeCount;
|
|
} else {
|
|
} else {
|
|
- Utils::zero<sizeof(ZT_VirtualNetworkRoute)>(&(ec->routes[i]));
|
|
|
|
|
|
+ Utils::zero< sizeof(ZT_VirtualNetworkRoute) >(&(ec->routes[i]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1478,26 +1486,26 @@ void Network::m_externalConfig(ZT_VirtualNetworkConfig *ec) const
|
|
void Network::m_announceMulticastGroups(void *tPtr, bool force)
|
|
void Network::m_announceMulticastGroups(void *tPtr, bool force)
|
|
{
|
|
{
|
|
// Assumes _myMulticastGroups_l and _memberships_l are locked
|
|
// Assumes _myMulticastGroups_l and _memberships_l are locked
|
|
- const Vector<MulticastGroup> groups(m_allMulticastGroups());
|
|
|
|
|
|
+ const Vector< MulticastGroup > groups(m_allMulticastGroups());
|
|
m_announceMulticastGroupsTo(tPtr, controller(), groups);
|
|
m_announceMulticastGroupsTo(tPtr, controller(), groups);
|
|
|
|
|
|
- // TODO
|
|
|
|
- /*
|
|
|
|
- Address *a = nullptr;
|
|
|
|
- Membership *m = nullptr;
|
|
|
|
- Hashtable<Address,Membership>::Iterator i(_memberships);
|
|
|
|
- while (i.next(a,m)) {
|
|
|
|
- bool announce = m->multicastLikeGate(now); // force this to be called even if 'force' is true since it updates last push time
|
|
|
|
- if ((!announce)&&(force))
|
|
|
|
- announce = true;
|
|
|
|
- if ((announce)&&(m->isAllowedOnNetwork(_config)))
|
|
|
|
- _announceMulticastGroupsTo(tPtr,*a,groups);
|
|
|
|
- }
|
|
|
|
- */
|
|
|
|
|
|
+ // TODO
|
|
|
|
+ /*
|
|
|
|
+Address *a = nullptr;
|
|
|
|
+Membership *m = nullptr;
|
|
|
|
+Hashtable<Address,Membership>::Iterator i(_memberships);
|
|
|
|
+while (i.next(a,m)) {
|
|
|
|
+ bool announce = m->multicastLikeGate(now); // force this to be called even if 'force' is true since it updates last push time
|
|
|
|
+ if ((!announce)&&(force))
|
|
|
|
+ announce = true;
|
|
|
|
+ if ((announce)&&(m->isAllowedOnNetwork(_config)))
|
|
|
|
+ _announceMulticastGroupsTo(tPtr,*a,groups);
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector<MulticastGroup> &allMulticastGroups)
|
|
|
|
|
|
+void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector< MulticastGroup > &allMulticastGroups)
|
|
{
|
|
{
|
|
#if 0
|
|
#if 0
|
|
// Assumes _myMulticastGroups_l and _memberships_l are locked
|
|
// Assumes _myMulticastGroups_l and _memberships_l are locked
|
|
@@ -1523,18 +1531,18 @@ void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-Vector<MulticastGroup> Network::m_allMulticastGroups() const
|
|
|
|
|
|
+Vector< MulticastGroup > Network::m_allMulticastGroups() const
|
|
{
|
|
{
|
|
// Assumes _myMulticastGroups_l is locked
|
|
// Assumes _myMulticastGroups_l is locked
|
|
- Vector<MulticastGroup> mgs;
|
|
|
|
|
|
+ Vector< MulticastGroup > mgs;
|
|
mgs.reserve(m_myMulticastGroups.size() + m_multicastGroupsBehindMe.size() + 1);
|
|
mgs.reserve(m_myMulticastGroups.size() + m_multicastGroupsBehindMe.size() + 1);
|
|
mgs.insert(mgs.end(), m_myMulticastGroups.begin(), m_myMulticastGroups.end());
|
|
mgs.insert(mgs.end(), m_myMulticastGroups.begin(), m_myMulticastGroups.end());
|
|
- for(Map<MulticastGroup,int64_t>::const_iterator i(m_multicastGroupsBehindMe.begin());i != m_multicastGroupsBehindMe.end();++i)
|
|
|
|
|
|
+ for (Map< MulticastGroup, int64_t >::const_iterator i(m_multicastGroupsBehindMe.begin()); i != m_multicastGroupsBehindMe.end(); ++i)
|
|
mgs.push_back(i->first);
|
|
mgs.push_back(i->first);
|
|
if ((m_config) && (m_config.enableBroadcast()))
|
|
if ((m_config) && (m_config.enableBroadcast()))
|
|
mgs.push_back(Network::BROADCAST);
|
|
mgs.push_back(Network::BROADCAST);
|
|
- std::sort(mgs.begin(),mgs.end());
|
|
|
|
- mgs.erase(std::unique(mgs.begin(),mgs.end()),mgs.end());
|
|
|
|
|
|
+ std::sort(mgs.begin(), mgs.end());
|
|
|
|
+ mgs.erase(std::unique(mgs.begin(), mgs.end()), mgs.end());
|
|
return mgs;
|
|
return mgs;
|
|
}
|
|
}
|
|
|
|
|