mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
A bunch of boring formattings stuff, etc.
This commit is contained in:
parent
52e1f5502d
commit
d3777b3eb4
21 changed files with 611 additions and 788 deletions
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
#define ZT_ADDRESS_STRING_SIZE_MAX (ZT_ADDRESS_LENGTH_HEX + 1)
|
#define ZT_ADDRESS_STRING_SIZE_MAX (ZT_ADDRESS_LENGTH_HEX + 1)
|
||||||
|
|
||||||
static_assert(ZT_ADDRESS_LENGTH == 5,"parts of Address will need modification for any change in ZT_ADDRESS_LENGTH");
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -394,9 +394,12 @@ public:
|
||||||
{
|
{
|
||||||
const char *const s = (const char *)(unsafeData + ii);
|
const char *const s = (const char *)(unsafeData + ii);
|
||||||
const int sii = ii;
|
const int sii = ii;
|
||||||
while (likely(ii < ZT_BUF_MEM_SIZE)) {
|
while (ii < ZT_BUF_MEM_SIZE) {
|
||||||
if (unsafeData[ii++] == 0) {
|
if (unsafeData[ii++] == 0) {
|
||||||
Utils::copy(buf,s,ii - sii);
|
const int l = ii - sii;
|
||||||
|
if (unlikely((unsigned int)l > bufSize))
|
||||||
|
return nullptr;
|
||||||
|
Utils::copy(buf,s,l);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ set(core_headers
|
||||||
SelfAwareness.hpp
|
SelfAwareness.hpp
|
||||||
SHA512.hpp
|
SHA512.hpp
|
||||||
SharedPtr.hpp
|
SharedPtr.hpp
|
||||||
Speck128.hpp
|
|
||||||
SymmetricKey.hpp
|
SymmetricKey.hpp
|
||||||
Tag.hpp
|
Tag.hpp
|
||||||
Topology.hpp
|
Topology.hpp
|
||||||
|
|
|
@ -36,11 +36,15 @@ int Capability::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],const bool
|
||||||
data[p++] = 0x7f;
|
data[p++] = 0x7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::storeBigEndian<uint64_t>(data + p, m_nwid); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, m_nwid);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)m_ts); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint32_t>(data + p, m_id); p += 4;
|
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_ts);
|
||||||
|
p += 8;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p, m_id);
|
||||||
|
p += 4;
|
||||||
|
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)m_ruleCount); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_ruleCount);
|
||||||
|
p += 2;
|
||||||
p += Capability::marshalVirtualNetworkRules(data + p, m_rules, m_ruleCount);
|
p += Capability::marshalVirtualNetworkRules(data + p, m_rules, m_ruleCount);
|
||||||
|
|
||||||
// LEGACY: older versions supported multiple records with this being a maximum custody
|
// LEGACY: older versions supported multiple records with this being a maximum custody
|
||||||
|
@ -48,11 +52,15 @@ int Capability::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],const bool
|
||||||
data[p++] = (uint8_t) 1;
|
data[p++] = (uint8_t) 1;
|
||||||
|
|
||||||
if (!forSign) {
|
if (!forSign) {
|
||||||
m_issuedTo.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
m_issuedTo.copyTo(data + p);
|
||||||
m_signedBy.copyTo(data + 0); p += ZT_ADDRESS_LENGTH;
|
p += ZT_ADDRESS_LENGTH;
|
||||||
|
m_signedBy.copyTo(data + 0);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
data[p++] = 1; // LEGACY: old versions require a reserved byte here
|
data[p++] = 1; // LEGACY: old versions require a reserved byte here
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)m_signatureLength); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_signatureLength);
|
||||||
Utils::copy(data + p, m_signature, m_signatureLength); p += (int)m_signatureLength;
|
p += 2;
|
||||||
|
Utils::copy(data + p, m_signature, m_signatureLength);
|
||||||
|
p += (int) m_signatureLength;
|
||||||
|
|
||||||
// LEGACY: older versions supported more than one record terminated by a zero address.
|
// LEGACY: older versions supported more than one record terminated by a zero address.
|
||||||
for (int k = 0;k < ZT_ADDRESS_LENGTH;++k)
|
for (int k = 0;k < ZT_ADDRESS_LENGTH;++k)
|
||||||
|
@ -98,7 +106,8 @@ int Capability::unmarshal(const uint8_t *data,int len) noexcept
|
||||||
for (unsigned int i = 0;;++i) {
|
for (unsigned int i = 0;;++i) {
|
||||||
if ((p + ZT_ADDRESS_LENGTH) > len)
|
if ((p + ZT_ADDRESS_LENGTH) > len)
|
||||||
return -1;
|
return -1;
|
||||||
const Address to(data + p); p += ZT_ADDRESS_LENGTH;
|
const Address to(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
|
|
||||||
if (!to)
|
if (!to)
|
||||||
break;
|
break;
|
||||||
|
@ -106,14 +115,17 @@ int Capability::unmarshal(const uint8_t *data,int len) noexcept
|
||||||
m_issuedTo = to;
|
m_issuedTo = to;
|
||||||
if ((p + ZT_ADDRESS_LENGTH) > len)
|
if ((p + ZT_ADDRESS_LENGTH) > len)
|
||||||
return -1;
|
return -1;
|
||||||
m_signedBy.setTo(data + p); p += ZT_ADDRESS_LENGTH + 1; // LEGACY: +1 to skip reserved field
|
m_signedBy.setTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH + 1; // LEGACY: +1 to skip reserved field
|
||||||
|
|
||||||
if ((p + 2) > len)
|
if ((p + 2) > len)
|
||||||
return -1;
|
return -1;
|
||||||
m_signatureLength = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
m_signatureLength = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
if ((m_signatureLength > sizeof(m_signature)) || ((p + (int) m_signatureLength) > len))
|
if ((m_signatureLength > sizeof(m_signature)) || ((p + (int) m_signatureLength) > len))
|
||||||
return -1;
|
return -1;
|
||||||
Utils::copy(m_signature, data + p, m_signatureLength); p += (int)m_signatureLength;
|
Utils::copy(m_signature, data + p, m_signatureLength);
|
||||||
|
p += (int) m_signatureLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p + 2) > len)
|
if ((p + 2) > len)
|
||||||
|
@ -139,18 +151,23 @@ int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetwork
|
||||||
case ZT_NETWORK_RULE_ACTION_WATCH:
|
case ZT_NETWORK_RULE_ACTION_WATCH:
|
||||||
case ZT_NETWORK_RULE_ACTION_REDIRECT:
|
case ZT_NETWORK_RULE_ACTION_REDIRECT:
|
||||||
data[p++] = 14;
|
data[p++] = 14;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.fwd.address); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.fwd.address);
|
||||||
Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.fwd.flags); p += 4;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.fwd.length); p += 2;
|
Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.fwd.flags);
|
||||||
|
p += 4;
|
||||||
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.fwd.length);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
||||||
case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
|
case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
|
||||||
data[p++] = 5;
|
data[p++] = 5;
|
||||||
Address(rules[i].v.zt).copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
Address(rules[i].v.zt).copyTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_VLAN_ID:
|
case ZT_NETWORK_RULE_MATCH_VLAN_ID:
|
||||||
data[p++] = 2;
|
data[p++] = 2;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.vlanId); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.vlanId);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
|
case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
|
||||||
data[p++] = 1;
|
data[p++] = 1;
|
||||||
|
@ -163,7 +180,8 @@ int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetwork
|
||||||
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
|
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
|
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
|
||||||
data[p++] = 6;
|
data[p++] = 6;
|
||||||
MAC(rules[i].v.mac).copyTo(data + p); p += 6;
|
MAC(rules[i].v.mac).copyTo(data + p);
|
||||||
|
p += 6;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
||||||
|
@ -177,7 +195,8 @@ int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetwork
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
||||||
data[p++] = 17;
|
data[p++] = 17;
|
||||||
Utils::copy<16>(data + p,rules[i].v.ipv6.ip); p += 16;
|
Utils::copy<16>(data + p, rules[i].v.ipv6.ip);
|
||||||
|
p += 16;
|
||||||
data[p++] = rules[i].v.ipv6.mask;
|
data[p++] = rules[i].v.ipv6.mask;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
||||||
|
@ -192,7 +211,8 @@ int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetwork
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
|
case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
|
||||||
data[p++] = 2;
|
data[p++] = 2;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.etherType); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.etherType);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_ICMP:
|
case ZT_NETWORK_RULE_MATCH_ICMP:
|
||||||
data[p++] = 3;
|
data[p++] = 3;
|
||||||
|
@ -203,21 +223,27 @@ int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetwork
|
||||||
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:
|
||||||
data[p++] = 4;
|
data[p++] = 4;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.port[0]); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.port[0]);
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.port[1]); p += 2;
|
p += 2;
|
||||||
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.port[1]);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
|
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
|
||||||
data[p++] = 8;
|
data[p++] = 8;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.characteristics); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.characteristics);
|
||||||
|
p += 8;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
||||||
data[p++] = 4;
|
data[p++] = 4;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.frameSize[0]); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.frameSize[0]);
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.frameSize[1]); p += 2;
|
p += 2;
|
||||||
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.frameSize[1]);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_RANDOM:
|
case ZT_NETWORK_RULE_MATCH_RANDOM:
|
||||||
data[p++] = 4;
|
data[p++] = 4;
|
||||||
Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.randomProbability); p += 4;
|
Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.randomProbability);
|
||||||
|
p += 4;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
|
case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
|
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
|
||||||
|
@ -227,14 +253,19 @@ int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetwork
|
||||||
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:
|
||||||
data[p++] = 8;
|
data[p++] = 8;
|
||||||
Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.tag.id); p += 4;
|
Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.tag.id);
|
||||||
Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.tag.value); p += 4;
|
p += 4;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.tag.value);
|
||||||
|
p += 4;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
|
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
|
||||||
data[p++] = 19;
|
data[p++] = 19;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.intRange.start); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.intRange.start);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.intRange.start + (uint64_t)rules[i].v.intRange.end); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.intRange.idx); p += 2;
|
Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.intRange.start + (uint64_t) rules[i].v.intRange.end);
|
||||||
|
p += 8;
|
||||||
|
Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.intRange.idx);
|
||||||
|
p += 2;
|
||||||
data[p++] = rules[i].v.intRange.format;
|
data[p++] = rules[i].v.intRange.format;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -260,18 +291,23 @@ int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int
|
||||||
case ZT_NETWORK_RULE_ACTION_WATCH:
|
case ZT_NETWORK_RULE_ACTION_WATCH:
|
||||||
case ZT_NETWORK_RULE_ACTION_REDIRECT:
|
case ZT_NETWORK_RULE_ACTION_REDIRECT:
|
||||||
if ((p + 14) > len) return -1;
|
if ((p + 14) > len) return -1;
|
||||||
rules[ruleCount].v.fwd.address = Utils::loadBigEndian<uint64_t>(data + p); p += 8;
|
rules[ruleCount].v.fwd.address = Utils::loadBigEndian<uint64_t>(data + p);
|
||||||
rules[ruleCount].v.fwd.flags = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
|
p += 8;
|
||||||
rules[ruleCount].v.fwd.length = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
rules[ruleCount].v.fwd.flags = Utils::loadBigEndian<uint32_t>(data + p);
|
||||||
|
p += 4;
|
||||||
|
rules[ruleCount].v.fwd.length = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
|
||||||
case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
|
case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
|
||||||
if ((p + ZT_ADDRESS_LENGTH) > len) return -1;
|
if ((p + ZT_ADDRESS_LENGTH) > len) return -1;
|
||||||
rules[ruleCount].v.zt = Address(data + p).toInt(); p += ZT_ADDRESS_LENGTH;
|
rules[ruleCount].v.zt = Address(data + p).toInt();
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_VLAN_ID:
|
case ZT_NETWORK_RULE_MATCH_VLAN_ID:
|
||||||
if ((p + 2) > len) return -1;
|
if ((p + 2) > len) return -1;
|
||||||
rules[ruleCount].v.vlanId = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
rules[ruleCount].v.vlanId = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
|
case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
|
||||||
if ((p + 1) > len) return -1;
|
if ((p + 1) > len) return -1;
|
||||||
|
@ -284,18 +320,21 @@ int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int
|
||||||
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
|
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
|
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
|
||||||
if ((p + 6) > len) return -1;
|
if ((p + 6) > len) return -1;
|
||||||
Utils::copy<6>(rules[ruleCount].v.mac,data + p); p += 6;
|
Utils::copy<6>(rules[ruleCount].v.mac, data + p);
|
||||||
|
p += 6;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
|
||||||
if ((p + 5) > len) return -1;
|
if ((p + 5) > len) return -1;
|
||||||
Utils::copy<4>(&(rules[ruleCount].v.ipv4.ip),data + p); p += 4;
|
Utils::copy<4>(&(rules[ruleCount].v.ipv4.ip), data + p);
|
||||||
|
p += 4;
|
||||||
rules[ruleCount].v.ipv4.mask = data[p++];
|
rules[ruleCount].v.ipv4.mask = data[p++];
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
|
||||||
if ((p + 17) > len) return -1;
|
if ((p + 17) > len) return -1;
|
||||||
Utils::copy<16>(rules[ruleCount].v.ipv6.ip,data + p); p += 16;
|
Utils::copy<16>(rules[ruleCount].v.ipv6.ip, data + p);
|
||||||
|
p += 16;
|
||||||
rules[ruleCount].v.ipv6.mask = data[p++];
|
rules[ruleCount].v.ipv6.mask = data[p++];
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
case ZT_NETWORK_RULE_MATCH_IP_TOS:
|
||||||
|
@ -310,7 +349,8 @@ int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
|
case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
|
||||||
if ((p + 2) > len) return -1;
|
if ((p + 2) > len) return -1;
|
||||||
rules[ruleCount].v.etherType = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
rules[ruleCount].v.etherType = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_ICMP:
|
case ZT_NETWORK_RULE_MATCH_ICMP:
|
||||||
if ((p + 3) > len) return -1;
|
if ((p + 3) > len) return -1;
|
||||||
|
@ -321,21 +361,27 @@ int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int
|
||||||
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 ((p + 4) > len) return -1;
|
if ((p + 4) > len) return -1;
|
||||||
rules[ruleCount].v.port[0] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
rules[ruleCount].v.port[0] = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
rules[ruleCount].v.port[1] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
p += 2;
|
||||||
|
rules[ruleCount].v.port[1] = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
|
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
|
||||||
if ((p + 8) > len) return -1;
|
if ((p + 8) > len) return -1;
|
||||||
rules[ruleCount].v.characteristics = Utils::loadBigEndian<uint64_t>(data + p); p += 8;
|
rules[ruleCount].v.characteristics = Utils::loadBigEndian<uint64_t>(data + p);
|
||||||
|
p += 8;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
|
||||||
if ((p + 4) > len) return -1;
|
if ((p + 4) > len) return -1;
|
||||||
rules[ruleCount].v.frameSize[0] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
rules[ruleCount].v.frameSize[0] = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
rules[ruleCount].v.frameSize[1] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
p += 2;
|
||||||
|
rules[ruleCount].v.frameSize[1] = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_RANDOM:
|
case ZT_NETWORK_RULE_MATCH_RANDOM:
|
||||||
if ((p + 4) > len) return -1;
|
if ((p + 4) > len) return -1;
|
||||||
rules[ruleCount].v.randomProbability = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
|
rules[ruleCount].v.randomProbability = Utils::loadBigEndian<uint32_t>(data + p);
|
||||||
|
p += 4;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
|
case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
|
||||||
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
|
case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
|
||||||
|
@ -345,14 +391,19 @@ int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int
|
||||||
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 ((p + 4) > len) return -1;
|
if ((p + 4) > len) return -1;
|
||||||
rules[ruleCount].v.tag.id = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
|
rules[ruleCount].v.tag.id = Utils::loadBigEndian<uint32_t>(data + p);
|
||||||
rules[ruleCount].v.tag.value = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
|
p += 4;
|
||||||
|
rules[ruleCount].v.tag.value = Utils::loadBigEndian<uint32_t>(data + p);
|
||||||
|
p += 4;
|
||||||
break;
|
break;
|
||||||
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
|
case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
|
||||||
if ((p + 19) > len) return -1;
|
if ((p + 19) > len) return -1;
|
||||||
rules[ruleCount].v.intRange.start = Utils::loadBigEndian<uint64_t>(data + p); p += 8;
|
rules[ruleCount].v.intRange.start = Utils::loadBigEndian<uint64_t>(data + p);
|
||||||
rules[ruleCount].v.intRange.end = (uint32_t)(Utils::loadBigEndian<uint64_t>(data + p) - rules[ruleCount].v.intRange.start); p += 8;
|
p += 8;
|
||||||
rules[ruleCount].v.intRange.idx = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
|
rules[ruleCount].v.intRange.end = (uint32_t) (Utils::loadBigEndian<uint64_t>(data + p) - rules[ruleCount].v.intRange.start);
|
||||||
|
p += 8;
|
||||||
|
rules[ruleCount].v.intRange.idx = Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
p += 2;
|
||||||
rules[ruleCount].v.intRange.format = data[p++];
|
rules[ruleCount].v.intRange.format = data[p++];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ CertificateOfMembership::CertificateOfMembership(const int64_t timestamp,const i
|
||||||
m_timestampMaxDelta(timestampMaxDelta),
|
m_timestampMaxDelta(timestampMaxDelta),
|
||||||
m_networkId(nwid),
|
m_networkId(nwid),
|
||||||
m_issuedTo(issuedTo.fingerprint()),
|
m_issuedTo(issuedTo.fingerprint()),
|
||||||
m_signatureLength(0) {}
|
m_signatureLength(0)
|
||||||
|
{}
|
||||||
|
|
||||||
bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) const noexcept
|
bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) const noexcept
|
||||||
{
|
{
|
||||||
|
@ -100,15 +101,24 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
|
||||||
// All formats start with the standard three qualifiers: timestamp with delta, network ID as a strict
|
// All formats start with the standard three qualifiers: timestamp with delta, network ID as a strict
|
||||||
// equality compare, and the address of the issued-to node as an informational tuple.
|
// equality compare, and the address of the issued-to node as an informational tuple.
|
||||||
int p = 3;
|
int p = 3;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,0); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, 0);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)m_timestamp); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)m_timestampMaxDelta); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_timestamp);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,1); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p, m_networkId); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_timestampMaxDelta);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,0); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,2); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, 1);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p, m_issuedTo.address().toInt()); p += 8;
|
p += 8;
|
||||||
Utils::storeAsIsEndian<uint64_t>(data + p,0xffffffffffffffffULL); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, m_networkId);
|
||||||
|
p += 8;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p, 0);
|
||||||
|
p += 8;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p, 2);
|
||||||
|
p += 8;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p, m_issuedTo.address().toInt());
|
||||||
|
p += 8;
|
||||||
|
Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
|
||||||
|
p += 8;
|
||||||
|
|
||||||
if (v2) {
|
if (v2) {
|
||||||
// V2 marshal format will have three tuples followed by the fingerprint hash.
|
// V2 marshal format will have three tuples followed by the fingerprint hash.
|
||||||
|
@ -119,17 +129,22 @@ int CertificateOfMembership::marshal(uint8_t data[ZT_CERTIFICATEOFMEMBERSHIP_MAR
|
||||||
// V1 marshal format must shove everything into tuples, resulting in nine.
|
// V1 marshal format must shove everything into tuples, resulting in nine.
|
||||||
Utils::storeBigEndian<uint16_t>(data + 1, 9);
|
Utils::storeBigEndian<uint16_t>(data + 1, 9);
|
||||||
for (int k = 0;k < 6;++k) {
|
for (int k = 0;k < 6;++k) {
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)k + 3); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) k + 3);
|
||||||
Utils::storeAsIsEndian<uint64_t>(data + p,Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + (k * 8))); p += 8;
|
p += 8;
|
||||||
Utils::storeAsIsEndian<uint64_t>(data + p,0xffffffffffffffffULL); p += 8;
|
Utils::storeAsIsEndian<uint64_t>(data + p, Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash() + (k * 8)));
|
||||||
|
p += 8;
|
||||||
|
Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
|
||||||
|
p += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_signedBy.copyTo(data + p); p += 5;
|
m_signedBy.copyTo(data + p);
|
||||||
|
p += 5;
|
||||||
|
|
||||||
if (v2) {
|
if (v2) {
|
||||||
// V2 marshal format prefixes signatures with a 16-bit length to support future signature types.
|
// V2 marshal format prefixes signatures with a 16-bit length to support future signature types.
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)m_signatureLength); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_signatureLength);
|
||||||
|
p += 2;
|
||||||
Utils::copy(data + p, m_signature, m_signatureLength);
|
Utils::copy(data + p, m_signature, m_signatureLength);
|
||||||
p += (int) m_signatureLength;
|
p += (int) m_signatureLength;
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,9 +170,12 @@ int CertificateOfMembership::unmarshal(const uint8_t *data,int len) noexcept
|
||||||
for (unsigned int q = 0;q < numq;++q) {
|
for (unsigned int q = 0;q < numq;++q) {
|
||||||
if ((p + 24) > len)
|
if ((p + 24) > len)
|
||||||
return -1;
|
return -1;
|
||||||
const uint64_t id = Utils::loadBigEndian<uint64_t>(data + p); p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
|
const uint64_t id = Utils::loadBigEndian<uint64_t>(data + p);
|
||||||
const uint64_t value = Utils::loadBigEndian<uint64_t>(data + p); p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
|
p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||||
const uint64_t delta = Utils::loadBigEndian<uint64_t>(data + p); p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
|
const uint64_t value = Utils::loadBigEndian<uint64_t>(data + p);
|
||||||
|
p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||||
|
const uint64_t delta = Utils::loadBigEndian<uint64_t>(data + p);
|
||||||
|
p += 8; // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case 0:
|
case 0:
|
||||||
m_timestamp = (int64_t) value;
|
m_timestamp = (int64_t) value;
|
||||||
|
|
|
@ -68,12 +68,16 @@ int CertificateOfOwnership::marshal(uint8_t data[ZT_CERTIFICATEOFOWNERSHIP_MARSH
|
||||||
Utils::copy<ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE>(data + p, m_thingValues[i]);
|
Utils::copy<ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE>(data + p, m_thingValues[i]);
|
||||||
p += ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE;
|
p += ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE;
|
||||||
}
|
}
|
||||||
m_issuedTo.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
m_issuedTo.copyTo(data + p);
|
||||||
m_signedBy.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
p += ZT_ADDRESS_LENGTH;
|
||||||
|
m_signedBy.copyTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
if (!forSign) {
|
if (!forSign) {
|
||||||
data[p++] = 1;
|
data[p++] = 1;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)m_signatureLength); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_signatureLength);
|
||||||
Utils::copy(data + p, m_signature, m_signatureLength); p += (int)m_signatureLength;
|
p += 2;
|
||||||
|
Utils::copy(data + p, m_signature, m_signatureLength);
|
||||||
|
p += (int) m_signatureLength;
|
||||||
}
|
}
|
||||||
data[p++] = 0;
|
data[p++] = 0;
|
||||||
data[p++] = 0;
|
data[p++] = 0;
|
||||||
|
@ -108,8 +112,10 @@ int CertificateOfOwnership::unmarshal(const uint8_t *data,int len) noexcept
|
||||||
|
|
||||||
if ((p + ZT_ADDRESS_LENGTH + ZT_ADDRESS_LENGTH + 1 + 2) > len)
|
if ((p + ZT_ADDRESS_LENGTH + ZT_ADDRESS_LENGTH + 1 + 2) > len)
|
||||||
return -1;
|
return -1;
|
||||||
m_issuedTo.setTo(data + p); p += ZT_ADDRESS_LENGTH;
|
m_issuedTo.setTo(data + p);
|
||||||
m_signedBy.setTo(data + p); p += ZT_ADDRESS_LENGTH + 1;
|
p += ZT_ADDRESS_LENGTH;
|
||||||
|
m_signedBy.setTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH + 1;
|
||||||
|
|
||||||
p += 2 + Utils::loadBigEndian<uint16_t>(data + p);
|
p += 2 + Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
if (p > len)
|
if (p > len)
|
||||||
|
|
|
@ -16,10 +16,8 @@
|
||||||
#include "SHA512.hpp"
|
#include "SHA512.hpp"
|
||||||
#include "Salsa20.hpp"
|
#include "Salsa20.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Speck128.hpp"
|
#include "AES.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
@ -78,74 +76,34 @@ struct identityV0ProofOfWorkCriteria
|
||||||
// It's not quite as heavy as the V0 frankenhash, is a little more orderly in
|
// It's not quite as heavy as the V0 frankenhash, is a little more orderly in
|
||||||
// its design, but remains relatively resistant to GPU acceleration due to memory
|
// its design, but remains relatively resistant to GPU acceleration due to memory
|
||||||
// requirements for efficient computation.
|
// requirements for efficient computation.
|
||||||
#define ZT_IDENTITY_V1_POW_MEMORY_SIZE 98304
|
#define ZT_IDENTITY_V1_POW_MEMORY_SIZE 1048576
|
||||||
|
#define ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64 131072
|
||||||
bool identityV1ProofOfWorkCriteria(const void *in,const unsigned int len,uint64_t *const b)
|
bool identityV1ProofOfWorkCriteria(const void *in,const unsigned int len,uint64_t *const b)
|
||||||
{
|
{
|
||||||
SHA512(b,in,len);
|
SHA512(b,in,len);
|
||||||
|
|
||||||
// This treats hash output as little-endian, so swap on BE machines.
|
AES c(b);
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
for(unsigned int i=8;i<ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64;i+=8) {
|
||||||
b[0] = Utils::swapBytes(b[0]);
|
SHA512(b + i,b + (i - 8),64);
|
||||||
b[1] = Utils::swapBytes(b[1]);
|
if (unlikely((b[i] % 31337ULL) == (b[i] >> 49U)))
|
||||||
b[2] = Utils::swapBytes(b[2]);
|
c.encrypt(b + i,b + i);
|
||||||
b[3] = Utils::swapBytes(b[3]);
|
|
||||||
b[4] = Utils::swapBytes(b[4]);
|
|
||||||
b[5] = Utils::swapBytes(b[5]);
|
|
||||||
b[6] = Utils::swapBytes(b[6]);
|
|
||||||
b[7] = Utils::swapBytes(b[7]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Memory-intensive work: fill 'b' with pseudo-random bits generated from
|
|
||||||
// a reduced-round instance of Speck128 using a CBC-like construction.
|
|
||||||
// Then sort the resulting integer array in ascending numerical order.
|
|
||||||
// The sort requires that we compute and cache the whole data set, or at
|
|
||||||
// least that this is the most efficient implementation.
|
|
||||||
Speck128<24> s16;
|
|
||||||
s16.initXY(b[4],b[5]);
|
|
||||||
for(unsigned long i=0;i<(ZT_IDENTITY_V1_POW_MEMORY_SIZE-8);) {
|
|
||||||
// Load four 128-bit blocks.
|
|
||||||
uint64_t x0 = b[i];
|
|
||||||
uint64_t y0 = b[i + 1];
|
|
||||||
uint64_t x1 = b[i + 2];
|
|
||||||
uint64_t y1 = b[i + 3];
|
|
||||||
uint64_t x2 = b[i + 4];
|
|
||||||
uint64_t y2 = b[i + 5];
|
|
||||||
uint64_t x3 = b[i + 6];
|
|
||||||
uint64_t y3 = b[i + 7];
|
|
||||||
|
|
||||||
// Advance by 512 bits / 64 bytes (its a uint64_t array).
|
|
||||||
i += 8;
|
|
||||||
|
|
||||||
// Ensure that mixing happens across blocks.
|
|
||||||
x0 += x1;
|
|
||||||
x1 += x2;
|
|
||||||
x2 += x3;
|
|
||||||
x3 += y0;
|
|
||||||
|
|
||||||
// Encrypt 4X blocks. Speck is used for this PoW function because
|
|
||||||
// its performance is similar on all architectures while AES is much
|
|
||||||
// faster on some than others.
|
|
||||||
s16.encryptXYXYXYXY(x0,y0,x1,y1,x2,y2,x3,y3);
|
|
||||||
|
|
||||||
// Store four 128-bit blocks at new position.
|
|
||||||
b[i] = x0;
|
|
||||||
b[i + 1] = y0;
|
|
||||||
b[i + 2] = x1;
|
|
||||||
b[i + 3] = y1;
|
|
||||||
b[i + 4] = x2;
|
|
||||||
b[i + 5] = y2;
|
|
||||||
b[i + 6] = x3;
|
|
||||||
b[i + 7] = y3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort array, something that can't efficiently be done unless we have
|
|
||||||
// computed the whole array and have it in memory. This also involves
|
|
||||||
// branching which is less efficient on GPUs.
|
|
||||||
std::sort(b,b + ZT_IDENTITY_V1_POW_MEMORY_SIZE);
|
|
||||||
|
|
||||||
// Swap byte order back on BE machines.
|
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
for(unsigned int i=0;i<98304;i+=8) {
|
for(unsigned int i=0;i<ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64;i+=8) {
|
||||||
|
b[i] = Utils::swapBytes(b[i]);
|
||||||
|
b[i + 1] = Utils::swapBytes(b[i + 1]);
|
||||||
|
b[i + 2] = Utils::swapBytes(b[i + 2]);
|
||||||
|
b[i + 3] = Utils::swapBytes(b[i + 3]);
|
||||||
|
b[i + 4] = Utils::swapBytes(b[i + 4]);
|
||||||
|
b[i + 5] = Utils::swapBytes(b[i + 5]);
|
||||||
|
b[i + 6] = Utils::swapBytes(b[i + 6]);
|
||||||
|
b[i + 7] = Utils::swapBytes(b[i + 7]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
std::sort(b,b + ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64);
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
for(unsigned int i=0;i<ZT_IDENTITY_V1_POW_MEMORY_SIZE_U64;i+=8) {
|
||||||
b[i] = Utils::swapBytes(b[i]);
|
b[i] = Utils::swapBytes(b[i]);
|
||||||
b[i + 1] = Utils::swapBytes(b[i + 1]);
|
b[i + 1] = Utils::swapBytes(b[i + 1]);
|
||||||
b[i + 2] = Utils::swapBytes(b[i + 2]);
|
b[i + 2] = Utils::swapBytes(b[i + 2]);
|
||||||
|
@ -158,6 +116,9 @@ bool identityV1ProofOfWorkCriteria(const void *in,const unsigned int len,uint64_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Hash resulting sorted array to get final result for PoW criteria test.
|
// Hash resulting sorted array to get final result for PoW criteria test.
|
||||||
|
// We also include the original input after so that cryptographically this
|
||||||
|
// is exactly like SHA384(in). This should make any FIPS types happy as
|
||||||
|
// this means the identity hash is SHA384 and not some weird construction.
|
||||||
SHA384(b,b,sizeof(b),in,len);
|
SHA384(b,b,sizeof(b),in,len);
|
||||||
|
|
||||||
// PoW passes if sum of first two 64-bit integers (treated as little-endian) mod 180 is 0.
|
// PoW passes if sum of first two 64-bit integers (treated as little-endian) mod 180 is 0.
|
||||||
|
@ -197,7 +158,7 @@ bool Identity::generate(const Type t)
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case P384: {
|
case P384: {
|
||||||
uint64_t *const b = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE * 8); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
uint64_t *const b = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||||
if (!b)
|
if (!b)
|
||||||
return false;
|
return false;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ bool NetworkConfig::toDictionary(Dictionary &d) const
|
||||||
d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,tmp,this->com.marshal(tmp));
|
d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,tmp,this->com.marshal(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES]);
|
Vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES]);
|
||||||
for (unsigned int i = 0; i < this->capabilityCount; ++i) {
|
for (unsigned int i = 0; i < this->capabilityCount; ++i) {
|
||||||
int l = this->capabilities[i].marshal(tmp);
|
int l = this->capabilities[i].marshal(tmp);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
|
@ -121,7 +121,7 @@ bool NetworkConfig::fromDictionary(const Dictionary &d)
|
||||||
this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,0);
|
this->credentialTimeMaxDelta = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA,0);
|
||||||
this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION,0);
|
this->revision = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_REVISION,0);
|
||||||
this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0);
|
this->issuedTo = d.getUI(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO,0);
|
||||||
const std::vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH]);
|
const Vector<uint8_t> *blob = &(d[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO_IDENTITY_HASH]);
|
||||||
if (blob->size() == ZT_FINGERPRINT_HASH_SIZE) {
|
if (blob->size() == ZT_FINGERPRINT_HASH_SIZE) {
|
||||||
Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(this->issuedToFingerprintHash,blob->data());
|
Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(this->issuedToFingerprintHash,blob->data());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -99,9 +99,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_INLINE SharedPtr<Peer> &operator[](const unsigned int i) noexcept { return m_peers[i]; }
|
ZT_INLINE SharedPtr <Peer> &operator[](const unsigned int i) noexcept
|
||||||
ZT_INLINE const SharedPtr<Peer> &operator[](const unsigned int i) const noexcept { return m_peers[i]; }
|
{ return m_peers[i]; }
|
||||||
ZT_INLINE unsigned int size() const noexcept { return m_peerCount; }
|
|
||||||
|
ZT_INLINE const SharedPtr <Peer> &operator[](const unsigned int i) const noexcept
|
||||||
|
{ return m_peers[i]; }
|
||||||
|
|
||||||
|
ZT_INLINE unsigned int size() const noexcept
|
||||||
|
{ return m_peerCount; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedPtr <Peer> m_onePeer;
|
SharedPtr <Peer> m_onePeer;
|
||||||
|
|
|
@ -33,15 +33,24 @@ int Revocation::marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],bool forSig
|
||||||
for (int k = 0;k < 8;++k)
|
for (int k = 0;k < 8;++k)
|
||||||
data[p++] = 0x7f;
|
data[p++] = 0x7f;
|
||||||
}
|
}
|
||||||
Utils::storeBigEndian<uint32_t>(data + p,0); p += 4;
|
Utils::storeBigEndian<uint32_t>(data + p, 0);
|
||||||
Utils::storeBigEndian<uint32_t>(data + p, m_id); p += 4;
|
p += 4;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p, m_networkId); p += 8;
|
Utils::storeBigEndian<uint32_t>(data + p, m_id);
|
||||||
Utils::storeBigEndian<uint32_t>(data + p,0); p += 4;
|
p += 4;
|
||||||
Utils::storeBigEndian<uint32_t>(data + p, m_credentialId); p += 4;
|
Utils::storeBigEndian<uint64_t>(data + p, m_networkId);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)m_threshold); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint64_t>(data + p, m_flags); p += 8;
|
Utils::storeBigEndian<uint32_t>(data + p, 0);
|
||||||
m_target.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
p += 4;
|
||||||
m_signedBy.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
Utils::storeBigEndian<uint32_t>(data + p, m_credentialId);
|
||||||
|
p += 4;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_threshold);
|
||||||
|
p += 8;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p, m_flags);
|
||||||
|
p += 8;
|
||||||
|
m_target.copyTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
|
m_signedBy.copyTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
data[p++] = (uint8_t) m_type;
|
data[p++] = (uint8_t) m_type;
|
||||||
if (!forSign) {
|
if (!forSign) {
|
||||||
data[p++] = 1;
|
data[p++] = 1;
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
#include "SHA512.hpp"
|
#include "SHA512.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
#ifndef ZT_HAVE_NATIVE_SHA512
|
#ifndef ZT_HAVE_NATIVE_SHA512
|
||||||
|
|
|
@ -14,18 +14,11 @@
|
||||||
#ifndef ZT_SALSA20_HPP
|
#ifndef ZT_SALSA20_HPP
|
||||||
#define ZT_SALSA20_HPP
|
#define ZT_SALSA20_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "TriviallyCopyable.hpp"
|
#include "TriviallyCopyable.hpp"
|
||||||
|
|
||||||
#ifdef ZT_ARCH_X64
|
#ifdef ZT_ARCH_X64
|
||||||
#include <xmmintrin.h>
|
|
||||||
#include <emmintrin.h>
|
|
||||||
#include <immintrin.h>
|
|
||||||
#define ZT_SALSA20_SSE 1
|
#define ZT_SALSA20_SSE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,195 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c)2013-2020 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* Use of this software is governed by the Business Source License included
|
|
||||||
* in the LICENSE.TXT file in the project's root directory.
|
|
||||||
*
|
|
||||||
* Change Date: 2024-01-01
|
|
||||||
*
|
|
||||||
* On the date above, in accordance with the Business Source License, use
|
|
||||||
* of this software will be governed by version 2.0 of the Apache License.
|
|
||||||
*/
|
|
||||||
/****/
|
|
||||||
|
|
||||||
#ifndef ZT_SPECK128_HPP
|
|
||||||
#define ZT_SPECK128_HPP
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
|
||||||
#include "Utils.hpp"
|
|
||||||
|
|
||||||
#define ZT_SPECK128_KEY_SIZE 16
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tiny and simple 128-bit ARX block cipher
|
|
||||||
*
|
|
||||||
* Speck does not specify a mandatory endian-ness. This implementation is
|
|
||||||
* little-endian for higher performance on the majority of platforms.
|
|
||||||
*
|
|
||||||
* Right now this is only used as part of the PoW function for V1 identity
|
|
||||||
* generation. It's used because it's faster than SHA for filling a buffer
|
|
||||||
* with randomness and unlike AES its relative performance advantage
|
|
||||||
* across CPU architectures is pretty much identical.
|
|
||||||
*
|
|
||||||
* @tparam R Number of rounds (default: 32)
|
|
||||||
*/
|
|
||||||
template<int R = 32>
|
|
||||||
class Speck128
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Create an uninitialized instance, init() must be called to set up.
|
|
||||||
*/
|
|
||||||
ZT_INLINE Speck128() noexcept {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize Speck from a 128-bit key
|
|
||||||
*
|
|
||||||
* @param k 128-bit / 16 byte key
|
|
||||||
*/
|
|
||||||
ZT_INLINE Speck128(const void *k) noexcept { this->init(k); }
|
|
||||||
|
|
||||||
ZT_INLINE ~Speck128() { Utils::burn(m_expandedKey, sizeof(m_expandedKey)); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize Speck from a 128-bit key
|
|
||||||
*
|
|
||||||
* @param k 128-bit / 16 byte key
|
|
||||||
*/
|
|
||||||
ZT_INLINE void init(const void *k) noexcept
|
|
||||||
{
|
|
||||||
initXY(Utils::loadLittleEndian<uint64_t>(k),Utils::loadLittleEndian<uint64_t>(reinterpret_cast<const uint8_t *>(k) + 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize Speck from a 128-bit key in two 64-bit words
|
|
||||||
*
|
|
||||||
* @param x Least significant 64 bits
|
|
||||||
* @param y Most significant 64 bits
|
|
||||||
*/
|
|
||||||
ZT_INLINE void initXY(uint64_t x,uint64_t y) noexcept
|
|
||||||
{
|
|
||||||
m_expandedKey[0] = x;
|
|
||||||
for(uint64_t i=0;i<(R-1);++i) {
|
|
||||||
x = x >> 8U | x << 56U;
|
|
||||||
x += y;
|
|
||||||
x ^= i;
|
|
||||||
y = y << 3U | y >> 61U;
|
|
||||||
y ^= x;
|
|
||||||
m_expandedKey[i + 1] = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt a 128-bit block as two 64-bit words
|
|
||||||
*
|
|
||||||
* These should be in host byte order. If read or written to/from data
|
|
||||||
* they should be stored in little-endian byte order.
|
|
||||||
*
|
|
||||||
* @param x Least significant 64 bits
|
|
||||||
* @param y Most significant 64 bits
|
|
||||||
*/
|
|
||||||
ZT_INLINE void encryptXY(uint64_t &x,uint64_t &y) const noexcept
|
|
||||||
{
|
|
||||||
for (int i=0;i<R;++i) {
|
|
||||||
const uint64_t kk = m_expandedKey[i];
|
|
||||||
x = x >> 8U | x << 56U;
|
|
||||||
x += y;
|
|
||||||
x ^= kk;
|
|
||||||
y = y << 3U | y >> 61U;
|
|
||||||
y ^= x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt 512 bits in parallel with the same key.
|
|
||||||
*
|
|
||||||
* Parallel in this case assumes instruction level parallelism, but even without that
|
|
||||||
* it may be faster due to cache/memory effects.
|
|
||||||
*/
|
|
||||||
ZT_INLINE void encryptXYXYXYXY(uint64_t &x0,uint64_t &y0,uint64_t &x1,uint64_t &y1,uint64_t &x2,uint64_t &y2,uint64_t &x3,uint64_t &y3) const noexcept
|
|
||||||
{
|
|
||||||
for (int i=0;i<R;++i) {
|
|
||||||
const uint64_t kk = m_expandedKey[i];
|
|
||||||
x0 = x0 >> 8U | x0 << 56U;
|
|
||||||
x1 = x1 >> 8U | x1 << 56U;
|
|
||||||
x2 = x2 >> 8U | x2 << 56U;
|
|
||||||
x3 = x3 >> 8U | x3 << 56U;
|
|
||||||
x0 += y0;
|
|
||||||
x1 += y1;
|
|
||||||
x2 += y2;
|
|
||||||
x3 += y3;
|
|
||||||
x0 ^= kk;
|
|
||||||
x1 ^= kk;
|
|
||||||
x2 ^= kk;
|
|
||||||
x3 ^= kk;
|
|
||||||
y0 = y0 << 3U | y0 >> 61U;
|
|
||||||
y1 = y1 << 3U | y1 >> 61U;
|
|
||||||
y2 = y2 << 3U | y2 >> 61U;
|
|
||||||
y3 = y3 << 3U | y3 >> 61U;
|
|
||||||
y0 ^= x0;
|
|
||||||
y1 ^= x1;
|
|
||||||
y2 ^= x2;
|
|
||||||
y3 ^= x3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt a 128-bit block as two 64-bit words
|
|
||||||
*
|
|
||||||
* These should be in host byte order. If read or written to/from data
|
|
||||||
* they should be stored in little-endian byte order.
|
|
||||||
*
|
|
||||||
* @param x Least significant 64 bits
|
|
||||||
* @param y Most significant 64 bits
|
|
||||||
*/
|
|
||||||
ZT_INLINE void decryptXY(uint64_t &x,uint64_t &y) const noexcept
|
|
||||||
{
|
|
||||||
for (int i=(R-1);i>=0;--i) {
|
|
||||||
const uint64_t kk = m_expandedKey[i];
|
|
||||||
y ^= x;
|
|
||||||
y = y >> 3U | y << 61U;
|
|
||||||
x ^= kk;
|
|
||||||
x -= y;
|
|
||||||
x = x << 8U | x >> 56U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt a block
|
|
||||||
*
|
|
||||||
* @param in 128-bit / 16 byte input
|
|
||||||
* @param out 128-bit / 16 byte output
|
|
||||||
*/
|
|
||||||
ZT_INLINE void encrypt(const void *const in,void *const out) const noexcept
|
|
||||||
{
|
|
||||||
uint64_t x = Utils::loadLittleEndian<uint64_t>(in);
|
|
||||||
uint64_t y = Utils::loadLittleEndian<uint64_t>(reinterpret_cast<const uint8_t *>(in) + 8);
|
|
||||||
encryptXY(x,y);
|
|
||||||
Utils::storeLittleEndian<uint64_t>(out,x);
|
|
||||||
Utils::storeLittleEndian<uint64_t>(reinterpret_cast<uint8_t *>(out) + 8,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt a block
|
|
||||||
*
|
|
||||||
* @param in 128-bit / 16 byte input
|
|
||||||
* @param out 128-bit / 16 byte output
|
|
||||||
*/
|
|
||||||
ZT_INLINE void decrypt(const void *const in,void *const out) const noexcept
|
|
||||||
{
|
|
||||||
uint64_t x = Utils::loadLittleEndian<uint64_t>(in);
|
|
||||||
uint64_t y = Utils::loadLittleEndian<uint64_t>(reinterpret_cast<const uint8_t *>(in) + 8);
|
|
||||||
decryptXY(x,y);
|
|
||||||
Utils::storeLittleEndian<uint64_t>(out,x);
|
|
||||||
Utils::storeLittleEndian<uint64_t>(reinterpret_cast<uint8_t *>(out) + 8,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t m_expandedKey[R];
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
|
||||||
|
|
||||||
#endif
|
|
21
node/Tag.cpp
21
node/Tag.cpp
|
@ -33,15 +33,22 @@ int Tag::marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign) const noexc
|
||||||
for (int k = 0;k < 8;++k)
|
for (int k = 0;k < 8;++k)
|
||||||
data[p++] = 0x7f;
|
data[p++] = 0x7f;
|
||||||
}
|
}
|
||||||
Utils::storeBigEndian<uint64_t>(data + p, m_networkId); p += 8;
|
Utils::storeBigEndian<uint64_t>(data + p, m_networkId);
|
||||||
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)m_ts); p += 8;
|
p += 8;
|
||||||
Utils::storeBigEndian<uint32_t>(data + p, m_id); p += 4;
|
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_ts);
|
||||||
Utils::storeBigEndian<uint32_t>(data + p, m_value); p += 4;
|
p += 8;
|
||||||
m_issuedTo.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
Utils::storeBigEndian<uint32_t>(data + p, m_id);
|
||||||
m_signedBy.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
p += 4;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p, m_value);
|
||||||
|
p += 4;
|
||||||
|
m_issuedTo.copyTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
|
m_signedBy.copyTo(data + p);
|
||||||
|
p += ZT_ADDRESS_LENGTH;
|
||||||
if (!forSign) {
|
if (!forSign) {
|
||||||
data[p++] = 1;
|
data[p++] = 1;
|
||||||
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)m_signatureLength); p += 2;
|
Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_signatureLength);
|
||||||
|
p += 2;
|
||||||
Utils::copy(data + p, m_signature, m_signatureLength);
|
Utils::copy(data + p, m_signature, m_signatureLength);
|
||||||
p += (int) m_signatureLength;
|
p += (int) m_signatureLength;
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,29 +403,29 @@ extern "C" const char *ZTT_general()
|
||||||
FCV<LifeCycleTracker,1024> test,test2;
|
FCV<LifeCycleTracker,1024> test,test2;
|
||||||
for(unsigned int i=0;i<512;++i)
|
for(unsigned int i=0;i<512;++i)
|
||||||
test.push_back(LifeCycleTracker(cnt));
|
test.push_back(LifeCycleTracker(cnt));
|
||||||
if (cnt != 512) {
|
if (cnt != (long)test.size()) {
|
||||||
ZT_T_PRINTF("FAILED (expected 512 objects, got %lu (1))" ZT_EOL_S,cnt);
|
ZT_T_PRINTF("FAILED (expected 512 objects, got %lu (1))" ZT_EOL_S,cnt);
|
||||||
return "FCV object life cycle test failed (1)";
|
return "FCV object life cycle test failed (1)";
|
||||||
}
|
}
|
||||||
test2 = test;
|
test2 = test;
|
||||||
if (cnt != 1024) {
|
if (cnt != (long)(test.size() + test2.size())) {
|
||||||
ZT_T_PRINTF("FAILED (expected 1024 objects, got %lu (2))" ZT_EOL_S,cnt);
|
ZT_T_PRINTF("FAILED (expected 1024 objects, got %lu (2))" ZT_EOL_S,cnt);
|
||||||
return "FCV object life cycle test failed (2)";
|
return "FCV object life cycle test failed (2)";
|
||||||
}
|
}
|
||||||
test.clear();
|
test.clear();
|
||||||
if (cnt != 512) {
|
if (cnt != (long)test.size()) {
|
||||||
ZT_T_PRINTF("FAILED (expected 512 objects, got %lu (3))" ZT_EOL_S,cnt);
|
ZT_T_PRINTF("FAILED (expected 512 objects, got %lu (3))" ZT_EOL_S,cnt);
|
||||||
return "FCV object life cycle test failed (3)";
|
return "FCV object life cycle test failed (3)";
|
||||||
}
|
}
|
||||||
for(unsigned int i=0;i<512;++i)
|
for(unsigned int i=0;i<512;++i)
|
||||||
test.push_back(LifeCycleTracker(cnt));
|
test.push_back(LifeCycleTracker(cnt));
|
||||||
if (cnt != 1024) {
|
if (cnt != (long)(test.size() + test2.size())) {
|
||||||
ZT_T_PRINTF("FAILED (expected 1024 objects, got %lu (4))" ZT_EOL_S,cnt);
|
ZT_T_PRINTF("FAILED (expected 1024 objects, got %lu (4))" ZT_EOL_S,cnt);
|
||||||
return "FCV object life cycle test failed (4)";
|
return "FCV object life cycle test failed (4)";
|
||||||
}
|
}
|
||||||
test.clear();
|
test.clear();
|
||||||
test2.clear();
|
test2.clear();
|
||||||
if (cnt != 0) {
|
if (cnt != (long)test.size()) {
|
||||||
ZT_T_PRINTF("FAILED (expected 0 objects, got %lu (5))" ZT_EOL_S,cnt);
|
ZT_T_PRINTF("FAILED (expected 0 objects, got %lu (5))" ZT_EOL_S,cnt);
|
||||||
return "FCV object life cycle test failed (5)";
|
return "FCV object life cycle test failed (5)";
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
|
||||||
RR(renv),
|
RR(renv),
|
||||||
m_numConfiguredPhysicalPaths(0)
|
m_numConfiguredPhysicalPaths(0)
|
||||||
{
|
{
|
||||||
uint64_t idtmp[2]; idtmp[0] = 0; idtmp[1] = 0;
|
uint64_t idtmp[2];
|
||||||
|
idtmp[0] = 0;
|
||||||
|
idtmp[1] = 0;
|
||||||
Vector<uint8_t> data(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_ROOTS, idtmp));
|
Vector<uint8_t> data(RR->node->stateObjectGet(tPtr, ZT_STATE_OBJECT_ROOTS, idtmp));
|
||||||
if (!data.empty()) {
|
if (!data.empty()) {
|
||||||
uint8_t *dptr = data.data();
|
uint8_t *dptr = data.data();
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
{
|
{
|
||||||
RWMutex::RLock l(m_peers_l);
|
RWMutex::RLock l(m_peers_l);
|
||||||
const SharedPtr<Peer> *const ap = m_peers.get(zta);
|
const SharedPtr<Peer> *const ap = m_peers.get(zta);
|
||||||
if (ap)
|
if (likely(ap != nullptr))
|
||||||
return *ap;
|
return *ap;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ public:
|
||||||
{
|
{
|
||||||
RWMutex::RLock lck(m_paths_l);
|
RWMutex::RLock lck(m_paths_l);
|
||||||
SharedPtr<Path> *const p = m_paths.get(k);
|
SharedPtr<Path> *const p = m_paths.get(k);
|
||||||
if (p)
|
if (likely(p != nullptr))
|
||||||
return *p;
|
return *p;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,7 @@ public:
|
||||||
ZT_INLINE SharedPtr<Peer> root() const
|
ZT_INLINE SharedPtr<Peer> root() const
|
||||||
{
|
{
|
||||||
RWMutex::RLock l(m_peers_l);
|
RWMutex::RLock l(m_peers_l);
|
||||||
if (m_rootPeers.empty())
|
if (unlikely(m_rootPeers.empty()))
|
||||||
return SharedPtr<Peer>();
|
return SharedPtr<Peer>();
|
||||||
return m_rootPeers.front();
|
return m_rootPeers.front();
|
||||||
}
|
}
|
||||||
|
@ -167,10 +167,8 @@ public:
|
||||||
rootPeerPtrs.push_back((uintptr_t)rp->ptr());
|
rootPeerPtrs.push_back((uintptr_t)rp->ptr());
|
||||||
std::sort(rootPeerPtrs.begin(),rootPeerPtrs.end());
|
std::sort(rootPeerPtrs.begin(),rootPeerPtrs.end());
|
||||||
|
|
||||||
try {
|
|
||||||
for(Map< Address,SharedPtr<Peer> >::const_iterator i(m_peers.begin());i != m_peers.end();++i)
|
for(Map< Address,SharedPtr<Peer> >::const_iterator i(m_peers.begin());i != m_peers.end();++i)
|
||||||
f(i->second,std::binary_search(rootPeerPtrs.begin(),rootPeerPtrs.end(),(uintptr_t)i->second.ptr()));
|
f(i->second,std::binary_search(rootPeerPtrs.begin(),rootPeerPtrs.end(),(uintptr_t)i->second.ptr()));
|
||||||
} catch ( ... ) {} // should not throw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,56 +183,6 @@ public:
|
||||||
allPeers.push_back(i->second);
|
allPeers.push_back(i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get info about a path
|
|
||||||
*
|
|
||||||
* The supplied result variables are not modified if no special config info is found.
|
|
||||||
*
|
|
||||||
* @param physicalAddress Physical endpoint address
|
|
||||||
* @param mtu Variable set to MTU
|
|
||||||
* @param trustedPathId Variable set to trusted path ID
|
|
||||||
*/
|
|
||||||
ZT_INLINE void getOutboundPathInfo(const InetAddress &physicalAddress,unsigned int &mtu,uint64_t &trustedPathId)
|
|
||||||
{
|
|
||||||
for(unsigned int i=0,j=m_numConfiguredPhysicalPaths;i < j;++i) {
|
|
||||||
if (m_physicalPathConfig[i].first.containsAddress(physicalAddress)) {
|
|
||||||
trustedPathId = m_physicalPathConfig[i].second.trustedPathId;
|
|
||||||
mtu = m_physicalPathConfig[i].second.mtu;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the outbound trusted path ID for a physical address, or 0 if none
|
|
||||||
*
|
|
||||||
* @param physicalAddress Physical address to which we are sending the packet
|
|
||||||
* @return Trusted path ID or 0 if none (0 is not a valid trusted path ID)
|
|
||||||
*/
|
|
||||||
ZT_INLINE uint64_t getOutboundPathTrust(const InetAddress &physicalAddress)
|
|
||||||
{
|
|
||||||
for(unsigned int i=0,j=m_numConfiguredPhysicalPaths;i < j;++i) {
|
|
||||||
if (m_physicalPathConfig[i].first.containsAddress(physicalAddress))
|
|
||||||
return m_physicalPathConfig[i].second.trustedPathId;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether in incoming trusted path marked packet is valid
|
|
||||||
*
|
|
||||||
* @param physicalAddress Originating physical address
|
|
||||||
* @param trustedPathId Trusted path ID from packet (from MAC field)
|
|
||||||
*/
|
|
||||||
ZT_INLINE bool shouldInboundPathBeTrusted(const InetAddress &physicalAddress,const uint64_t trustedPathId)
|
|
||||||
{
|
|
||||||
for(unsigned int i=0,j=m_numConfiguredPhysicalPaths;i < j;++i) {
|
|
||||||
if ((m_physicalPathConfig[i].second.trustedPathId == trustedPathId) && (m_physicalPathConfig[i].first.containsAddress(physicalAddress)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
|
* Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration)
|
||||||
*/
|
*/
|
||||||
|
@ -259,7 +207,7 @@ public:
|
||||||
bool removeRoot(void *tPtr,const Identity &id);
|
bool removeRoot(void *tPtr,const Identity &id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort roots in asecnding order of apparent latency
|
* Sort roots in ascending order of apparent latency
|
||||||
*
|
*
|
||||||
* @param now Current time
|
* @param now Current time
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "RuntimeEnvironment.hpp"
|
#include "RuntimeEnvironment.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "Peer.hpp"
|
#include "Peer.hpp"
|
||||||
#include "Path.hpp"
|
|
||||||
#include "InetAddress.hpp"
|
#include "InetAddress.hpp"
|
||||||
#include "FCV.hpp"
|
#include "FCV.hpp"
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,10 @@
|
||||||
*/
|
*/
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Mutex.hpp"
|
#include "Mutex.hpp"
|
||||||
#include "AES.hpp"
|
#include "AES.hpp"
|
||||||
#include "SHA512.hpp"
|
#include "SHA512.hpp"
|
||||||
#include "Speck128.hpp"
|
|
||||||
|
|
||||||
#ifdef __UNIX_LIKE__
|
#ifdef __UNIX_LIKE__
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -27,6 +22,8 @@
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -189,38 +186,28 @@ unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ZT_GETSECURERANDOM_STATE_SIZE 64
|
#define ZT_GETSECURERANDOM_STATE_SIZE 64
|
||||||
#define ZT_GETSECURERANDOM_BUF_SIZE 4096
|
#define ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR 1048576
|
||||||
|
|
||||||
void getSecureRandom(void *const buf,const unsigned int bytes) noexcept
|
void getSecureRandom(void *const buf,unsigned int bytes) noexcept
|
||||||
{
|
{
|
||||||
static Mutex globalLock;
|
static Mutex globalLock;
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
static uint64_t randomState[ZT_GETSECURERANDOM_STATE_SIZE]; // secret state
|
static uint64_t randomState[ZT_GETSECURERANDOM_STATE_SIZE];
|
||||||
static uint64_t randomBuf[ZT_GETSECURERANDOM_BUF_SIZE]; // next batch of random bytes
|
static unsigned int randomByteCounter = ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR; // init on first run
|
||||||
static unsigned long randomPtr = sizeof(randomBuf); // refresh on first iteration
|
static AES randomGen;
|
||||||
|
|
||||||
Mutex::Lock gl(globalLock);
|
Mutex::Lock gl(globalLock);
|
||||||
|
|
||||||
// This could be a lot faster if we're not going to need a new block.
|
// Re-initialize the generator every ITERATIONS_PER_GENERATOR bytes.
|
||||||
if ((randomPtr + (unsigned long)bytes) <= sizeof(randomBuf)) {
|
if (unlikely((randomByteCounter += bytes) >= ZT_GETSECURERANDOM_ITERATIONS_PER_GENERATOR)) {
|
||||||
Utils::copy(buf,reinterpret_cast<uint8_t *>(randomBuf) + randomPtr,bytes);
|
// On first run fill randomState with random bits from the system.
|
||||||
randomPtr += bytes;
|
if (unlikely(!initialized)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i=0;i<bytes;++i) {
|
|
||||||
// Generate a new block of random data if we're at the end of the current block.
|
|
||||||
// Note that randomPtr is a byte pointer not a word pointer so we compare with sizeof.
|
|
||||||
if (randomPtr >= (unsigned long)sizeof(randomBuf)) {
|
|
||||||
randomPtr = 0;
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
|
// Don't let randomState be swapped to disk (if supported by OS).
|
||||||
Utils::memoryLock(randomState,sizeof(randomState));
|
Utils::memoryLock(randomState,sizeof(randomState));
|
||||||
Utils::memoryLock(randomBuf,sizeof(randomBuf));
|
|
||||||
|
|
||||||
// Fill randomState with entropy from the system. If this doesn't work this is a hard fail.
|
// Fill randomState with entropy from the system. Failure equals hard exit.
|
||||||
Utils::zero<sizeof(randomState)>(randomState);
|
Utils::zero<sizeof(randomState)>(randomState);
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
HCRYPTPROV cryptProvider = NULL;
|
HCRYPTPROV cryptProvider = NULL;
|
||||||
|
@ -265,35 +252,32 @@ void getSecureRandom(void *const buf,const unsigned int bytes) noexcept
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perturb state, hash, and overwrite the first 64 bytes with this hash.
|
// Initialize or re-initialize generator by hashing the full state,
|
||||||
++randomState[ZT_GETSECURERANDOM_STATE_SIZE-1];
|
// replacing the first 64 bytes with this hash, and then re-initializing
|
||||||
|
// AES with the first 32 bytes.
|
||||||
|
randomByteCounter = 0;
|
||||||
SHA512(randomState,randomState,sizeof(randomState));
|
SHA512(randomState,randomState,sizeof(randomState));
|
||||||
|
randomGen.init(randomState);
|
||||||
// Use the part of the state that was overwritten with new state to key a
|
|
||||||
// stream cipher and re-fill the buffer. Use AES if we're HW accel or use
|
|
||||||
// Speck if not since it's way faster on tiny chips without AES units.
|
|
||||||
if (AES::accelerated()) {
|
|
||||||
AES aes(randomState);
|
|
||||||
uint64_t ctr[2];
|
|
||||||
ctr[0] = randomState[4];
|
|
||||||
ctr[1] = randomState[5];
|
|
||||||
for (int k = 0;k < ZT_GETSECURERANDOM_BUF_SIZE;k += 2) {
|
|
||||||
++ctr[0];
|
|
||||||
aes.encrypt(ctr,randomBuf + k);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Speck128<> speck(randomState);
|
|
||||||
uint64_t ctr[2];
|
|
||||||
ctr[0] = randomState[4];
|
|
||||||
ctr[1] = randomState[5];
|
|
||||||
for (int k = 0;k < ZT_GETSECURERANDOM_BUF_SIZE;k += 2) {
|
|
||||||
++ctr[0];
|
|
||||||
speck.encrypt(ctr,randomBuf + k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reinterpret_cast<uint8_t *>(buf)[i] = reinterpret_cast<uint8_t *>(randomBuf)[randomPtr++];
|
// Generate random bytes using AES and bytes 32-48 of randomState as an in-place
|
||||||
|
// AES-CTR counter. Counter can be machine endian; we don't care about portability
|
||||||
|
// for a random generator.
|
||||||
|
uint64_t *const ctr = randomState + 4;
|
||||||
|
uint8_t *out = reinterpret_cast<uint8_t *>(buf);
|
||||||
|
while (bytes >= 16) {
|
||||||
|
++*ctr;
|
||||||
|
randomGen.encrypt(ctr,out);
|
||||||
|
out += 16;
|
||||||
|
bytes -= 16;
|
||||||
|
}
|
||||||
|
if (bytes > 0) {
|
||||||
|
uint8_t tmp[16];
|
||||||
|
++*ctr;
|
||||||
|
randomGen.encrypt(ctr,tmp);
|
||||||
|
for(unsigned int i=0;i<bytes;++i)
|
||||||
|
out[i] = tmp[i];
|
||||||
|
Utils::burn(tmp,sizeof(tmp)); // don't leave used cryptographic randomness lying around!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
91
node/VL1.cpp
91
node/VL1.cpp
|
@ -49,6 +49,7 @@ struct p_SalsaPolyCopyFunction
|
||||||
s20.crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
|
s20.crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
|
||||||
poly1305.init(macKey);
|
poly1305.init(macKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_INLINE void operator()(void *dest, const void *src, unsigned int len) noexcept
|
ZT_INLINE void operator()(void *dest, const void *src, unsigned int len) noexcept
|
||||||
{
|
{
|
||||||
if (hdrRemaining != 0) {
|
if (hdrRemaining != 0) {
|
||||||
|
@ -76,6 +77,7 @@ struct p_PolyCopyFunction
|
||||||
Salsa20(salsaKey, salsaIv).crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
|
Salsa20(salsaKey, salsaIv).crypt12(Utils::ZERO256, macKey, ZT_POLY1305_KEY_SIZE);
|
||||||
poly1305.init(macKey);
|
poly1305.init(macKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_INLINE void operator()(void *dest, const void *src, unsigned int len) noexcept
|
ZT_INLINE void operator()(void *dest, const void *src, unsigned int len) noexcept
|
||||||
{
|
{
|
||||||
if (hdrRemaining != 0) {
|
if (hdrRemaining != 0) {
|
||||||
|
@ -226,7 +228,7 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const SharedPtr<Peer> peer(m_HELLO(tPtr, path, *pkt, pktSize));
|
const SharedPtr<Peer> peer(m_HELLO(tPtr, path, *pkt, pktSize));
|
||||||
if (peer)
|
if (likely(peer))
|
||||||
peer->received(tPtr, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
|
peer->received(tPtr, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +239,7 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd
|
||||||
unsigned int auth = 0;
|
unsigned int auth = 0;
|
||||||
|
|
||||||
SharedPtr<Peer> peer(RR->topology->peer(tPtr, source));
|
SharedPtr<Peer> peer(RR->topology->peer(tPtr, source));
|
||||||
if (peer) {
|
if (likely(peer)) {
|
||||||
switch (cipher) {
|
switch (cipher) {
|
||||||
|
|
||||||
case ZT_PROTO_CIPHER_SUITE__POLY1305_NONE: {
|
case ZT_PROTO_CIPHER_SUITE__POLY1305_NONE: {
|
||||||
|
@ -346,28 +348,65 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd
|
||||||
// own internal authentication logic as usual. It would be abnormal to make it here with HELLO
|
// own internal authentication logic as usual. It would be abnormal to make it here with HELLO
|
||||||
// but not invalid.
|
// but not invalid.
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
Protocol::Verb inReVerb = Protocol::VERB_NOP;
|
Protocol::Verb inReVerb = Protocol::VERB_NOP;
|
||||||
|
bool ok = true;
|
||||||
switch (verb) {
|
switch (verb) {
|
||||||
case Protocol::VERB_NOP: break;
|
case Protocol::VERB_NOP:
|
||||||
case Protocol::VERB_HELLO: ok = (bool)(m_HELLO(tPtr, path, *pkt, pktSize)); break;
|
break;
|
||||||
case Protocol::VERB_ERROR: ok = m_ERROR(tPtr, packetId, auth, path, peer, *pkt, pktSize, inReVerb); break;
|
case Protocol::VERB_HELLO:
|
||||||
case Protocol::VERB_OK: ok = m_OK(tPtr, packetId, auth, path, peer, *pkt, pktSize, inReVerb); break;
|
ok = (bool) (m_HELLO(tPtr, path, *pkt, pktSize));
|
||||||
case Protocol::VERB_WHOIS: ok = m_WHOIS(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
break;
|
||||||
case Protocol::VERB_RENDEZVOUS: ok = m_RENDEZVOUS(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
case Protocol::VERB_ERROR:
|
||||||
case Protocol::VERB_FRAME: ok = RR->vl2->m_FRAME(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
ok = m_ERROR(tPtr, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
|
||||||
case Protocol::VERB_EXT_FRAME: ok = RR->vl2->m_EXT_FRAME(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
break;
|
||||||
case Protocol::VERB_ECHO: ok = m_ECHO(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
case Protocol::VERB_OK:
|
||||||
case Protocol::VERB_MULTICAST_LIKE: ok = RR->vl2->m_MULTICAST_LIKE(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
ok = m_OK(tPtr, packetId, auth, path, peer, *pkt, pktSize, inReVerb);
|
||||||
case Protocol::VERB_NETWORK_CREDENTIALS: ok = RR->vl2->m_NETWORK_CREDENTIALS(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
break;
|
||||||
case Protocol::VERB_NETWORK_CONFIG_REQUEST: ok = RR->vl2->m_NETWORK_CONFIG_REQUEST(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
case Protocol::VERB_WHOIS:
|
||||||
case Protocol::VERB_NETWORK_CONFIG: ok = RR->vl2->m_NETWORK_CONFIG(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
ok = m_WHOIS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
case Protocol::VERB_MULTICAST_GATHER: ok = RR->vl2->m_MULTICAST_GATHER(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
break;
|
||||||
case Protocol::VERB_MULTICAST_FRAME_deprecated: ok = RR->vl2->m_MULTICAST_FRAME_deprecated(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
case Protocol::VERB_RENDEZVOUS:
|
||||||
case Protocol::VERB_PUSH_DIRECT_PATHS: ok = m_PUSH_DIRECT_PATHS(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
ok = m_RENDEZVOUS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
case Protocol::VERB_USER_MESSAGE: ok = m_USER_MESSAGE(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
break;
|
||||||
case Protocol::VERB_MULTICAST: ok = RR->vl2->m_MULTICAST(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
case Protocol::VERB_FRAME:
|
||||||
case Protocol::VERB_ENCAP: ok = m_ENCAP(tPtr, packetId, auth, path, peer, *pkt, pktSize); break;
|
ok = RR->vl2->m_FRAME(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_EXT_FRAME:
|
||||||
|
ok = RR->vl2->m_EXT_FRAME(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_ECHO:
|
||||||
|
ok = m_ECHO(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_MULTICAST_LIKE:
|
||||||
|
ok = RR->vl2->m_MULTICAST_LIKE(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_NETWORK_CREDENTIALS:
|
||||||
|
ok = RR->vl2->m_NETWORK_CREDENTIALS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_NETWORK_CONFIG_REQUEST:
|
||||||
|
ok = RR->vl2->m_NETWORK_CONFIG_REQUEST(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_NETWORK_CONFIG:
|
||||||
|
ok = RR->vl2->m_NETWORK_CONFIG(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_MULTICAST_GATHER:
|
||||||
|
ok = RR->vl2->m_MULTICAST_GATHER(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_MULTICAST_FRAME_deprecated:
|
||||||
|
ok = RR->vl2->m_MULTICAST_FRAME_deprecated(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_PUSH_DIRECT_PATHS:
|
||||||
|
ok = m_PUSH_DIRECT_PATHS(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_USER_MESSAGE:
|
||||||
|
ok = m_USER_MESSAGE(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_MULTICAST:
|
||||||
|
ok = RR->vl2->m_MULTICAST(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
case Protocol::VERB_ENCAP:
|
||||||
|
ok = m_ENCAP(tPtr, packetId, auth, path, peer, *pkt, pktSize);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RR->t->incomingPacketDropped(tPtr, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
|
RR->t->incomingPacketDropped(tPtr, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
|
||||||
|
@ -413,7 +452,7 @@ void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
|
||||||
if (unlikely(!rootPath))
|
if (unlikely(!rootPath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<Address> toSend;
|
Vector<Address> toSend;
|
||||||
{
|
{
|
||||||
Mutex::Lock wl(m_whoisQueue_l);
|
Mutex::Lock wl(m_whoisQueue_l);
|
||||||
for (Map<Address, p_WhoisQueueItem>::iterator wi(m_whoisQueue.begin());wi != m_whoisQueue.end();++wi) {
|
for (Map<Address, p_WhoisQueueItem>::iterator wi(m_whoisQueue.begin());wi != m_whoisQueue.end();++wi) {
|
||||||
|
@ -430,7 +469,7 @@ void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
|
||||||
|
|
||||||
const SharedPtr<SymmetricKey> key(root->key());
|
const SharedPtr<SymmetricKey> key(root->key());
|
||||||
uint8_t outp[ZT_DEFAULT_UDP_MTU - ZT_PROTO_MIN_PACKET_LENGTH];
|
uint8_t outp[ZT_DEFAULT_UDP_MTU - ZT_PROTO_MIN_PACKET_LENGTH];
|
||||||
std::vector<Address>::iterator a(toSend.begin());
|
Vector<Address>::iterator a(toSend.begin());
|
||||||
while (a != toSend.end()) {
|
while (a != toSend.end()) {
|
||||||
const uint64_t packetId = key->nextMessage(RR->identity.address(), root->address());
|
const uint64_t packetId = key->nextMessage(RR->identity.address(), root->address());
|
||||||
int p = Protocol::newPacket(outp, packetId, root->address(), RR->identity.address(), Protocol::VERB_WHOIS);
|
int p = Protocol::newPacket(outp, packetId, root->address(), RR->identity.address(), Protocol::VERB_WHOIS);
|
||||||
|
@ -477,11 +516,11 @@ SharedPtr<Peer> VL1::m_HELLO(void *tPtr, const SharedPtr<Path> &path, Buf &pkt,
|
||||||
// Get the peer that matches this identity, or learn a new one if we don't know it.
|
// Get the peer that matches this identity, or learn a new one if we don't know it.
|
||||||
SharedPtr<Peer> peer(RR->topology->peer(tPtr, id.address(), true));
|
SharedPtr<Peer> peer(RR->topology->peer(tPtr, id.address(), true));
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if (peer->identity() != id) {
|
if (unlikely(peer->identity() != id)) {
|
||||||
RR->t->incomingPacketDropped(tPtr, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
RR->t->incomingPacketDropped(tPtr, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||||
return SharedPtr<Peer>();
|
return SharedPtr<Peer>();
|
||||||
}
|
}
|
||||||
if (peer->deduplicateIncomingPacket(packetId)) {
|
if (unlikely(peer->deduplicateIncomingPacket(packetId))) {
|
||||||
ZT_SPEW("discarding packet %.16llx from %s(%s): duplicate!", packetId, id.address().toString().c_str(), path->address().toString().c_str());
|
ZT_SPEW("discarding packet %.16llx from %s(%s): duplicate!", packetId, id.address().toString().c_str(), path->address().toString().c_str());
|
||||||
return SharedPtr<Peer>();
|
return SharedPtr<Peer>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ VL2::VL2(const RuntimeEnvironment *renv)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void VL2::onLocalEthernet(void *const tPtr,const uint64_t packetId,const unsigned int auth,const SharedPtr<Network> &network,const MAC &from,const MAC &to,const unsigned int etherType,unsigned int vlanId,SharedPtr<Buf> &data,unsigned int len)
|
void VL2::onLocalEthernet(void *const tPtr,const SharedPtr<Network> &network,const MAC &from,const MAC &to,const unsigned int etherType,unsigned int vlanId,SharedPtr<Buf> &data,unsigned int len)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue