mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-19 13:36:54 +02:00
Some symbol renaming, performance improvements, a bug fix for compiling on some platforms, and some Topology work.
This commit is contained in:
parent
f33574dfbc
commit
92d2bbc63c
18 changed files with 232 additions and 178 deletions
16
core/AES.cpp
16
core/AES.cpp
|
@ -349,8 +349,8 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept
|
|||
--len;
|
||||
_r[_rp++] = *(in++);
|
||||
if (_rp == 16) {
|
||||
y0 ^= Utils::loadAsIsEndian< uint64_t >(_r);
|
||||
y1 ^= Utils::loadAsIsEndian< uint64_t >(_r + 8);
|
||||
y0 ^= Utils::loadMachineEndian< uint64_t >(_r);
|
||||
y1 ^= Utils::loadMachineEndian< uint64_t >(_r + 8);
|
||||
s_gfmul(h0, h1, y0, y1);
|
||||
break;
|
||||
}
|
||||
|
@ -358,8 +358,8 @@ void AES::GMAC::update(const void *const data, unsigned int len) noexcept
|
|||
}
|
||||
|
||||
while (len >= 16) {
|
||||
y0 ^= Utils::loadAsIsEndian< uint64_t >(in);
|
||||
y1 ^= Utils::loadAsIsEndian< uint64_t >(in + 8);
|
||||
y0 ^= Utils::loadMachineEndian< uint64_t >(in);
|
||||
y1 ^= Utils::loadMachineEndian< uint64_t >(in + 8);
|
||||
s_gfmul(h0, h1, y0, y1);
|
||||
in += 16;
|
||||
len -= 16;
|
||||
|
@ -488,8 +488,8 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept
|
|||
if (_rp) {
|
||||
while (_rp < 16)
|
||||
_r[_rp++] = 0;
|
||||
y0 ^= Utils::loadAsIsEndian< uint64_t >(_r);
|
||||
y1 ^= Utils::loadAsIsEndian< uint64_t >(_r + 8);
|
||||
y0 ^= Utils::loadMachineEndian< uint64_t >(_r);
|
||||
y1 ^= Utils::loadMachineEndian< uint64_t >(_r + 8);
|
||||
s_gfmul(h0, h1, y0, y1);
|
||||
}
|
||||
|
||||
|
@ -504,8 +504,8 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept
|
|||
((uint8_t *)iv2)[15] = 1;
|
||||
_aes._encryptSW((const uint8_t *)iv2, (uint8_t *)iv2);
|
||||
|
||||
Utils::storeAsIsEndian< uint64_t >(tag, iv2[0] ^ y0);
|
||||
Utils::storeAsIsEndian< uint64_t >(tag + 8, iv2[1] ^ y1);
|
||||
Utils::storeMachineEndian< uint64_t >(tag, iv2[0] ^ y0);
|
||||
Utils::storeMachineEndian< uint64_t >(tag + 8, iv2[1] ^ y1);
|
||||
}
|
||||
|
||||
// AES-CTR ------------------------------------------------------------------------------------------------------------
|
||||
|
|
100
core/Blob.hpp
100
core/Blob.hpp
|
@ -16,37 +16,101 @@
|
|||
|
||||
#include "Constants.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "TriviallyCopyable.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// This header contains simple statically sized binary object types.
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Container for arbitrary bytes for use in collections
|
||||
*
|
||||
* @tparam S Size of container in bytes
|
||||
* Blob type for SHA384 hashes
|
||||
*/
|
||||
template<unsigned int S>
|
||||
struct Blob
|
||||
struct SHA384Hash
|
||||
{
|
||||
uint8_t data[S];
|
||||
uint64_t data[6];
|
||||
|
||||
ZT_INLINE Blob() noexcept { Utils::zero<S>(data); }
|
||||
explicit ZT_INLINE Blob(const void *const d) noexcept { Utils::copy<S>(data,d); }
|
||||
ZT_INLINE SHA384Hash() noexcept
|
||||
{ Utils::zero< 48 >(data); }
|
||||
|
||||
explicit ZT_INLINE SHA384Hash(const void *const d) noexcept
|
||||
{ Utils::copy< 48 >(data, d); }
|
||||
|
||||
ZT_INLINE const uint8_t *bytes() const noexcept
|
||||
{ return reinterpret_cast<const uint8_t *>(data); }
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{ return (unsigned long)Utils::fnv1a32(data, S); }
|
||||
{ return (unsigned long)data[0]; }
|
||||
|
||||
ZT_INLINE operator bool() const noexcept { return !Utils::allZero(data); }
|
||||
ZT_INLINE operator bool() const noexcept
|
||||
{ return ((data[0] != 0) && (data[1] != 0) && (data[2] != 0) && (data[3] != 0) && (data[4] != 0) && (data[5] != 0)); }
|
||||
|
||||
ZT_INLINE bool operator==(const Blob &b) const noexcept { return (memcmp(data,b.data,S) == 0); }
|
||||
ZT_INLINE bool operator!=(const Blob &b) const noexcept { return (memcmp(data,b.data,S) != 0); }
|
||||
ZT_INLINE bool operator<(const Blob &b) const noexcept { return (memcmp(data,b.data,S) < 0); }
|
||||
ZT_INLINE bool operator>(const Blob &b) const noexcept { return (memcmp(data,b.data,S) > 0); }
|
||||
ZT_INLINE bool operator<=(const Blob &b) const noexcept { return (memcmp(data,b.data,S) <= 0); }
|
||||
ZT_INLINE bool operator>=(const Blob &b) const noexcept { return (memcmp(data,b.data,S) >= 0); }
|
||||
ZT_INLINE bool operator==(const SHA384Hash &b) const noexcept
|
||||
{ return ((data[0] == b.data[0]) && (data[1] == b.data[1]) && (data[2] == b.data[2]) && (data[3] == b.data[3]) && (data[4] == b.data[4]) && (data[5] == b.data[5])); }
|
||||
|
||||
ZT_INLINE bool operator!=(const SHA384Hash &b) const noexcept
|
||||
{ return !(*this == b); }
|
||||
|
||||
ZT_INLINE bool operator<(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 48) < 0); }
|
||||
|
||||
ZT_INLINE bool operator>(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 48) > 0); }
|
||||
|
||||
ZT_INLINE bool operator<=(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 48) <= 0); }
|
||||
|
||||
ZT_INLINE bool operator>=(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 48) >= 0); }
|
||||
};
|
||||
|
||||
typedef Blob<48> SHA384Hash;
|
||||
typedef Blob<16> GUID;
|
||||
/**
|
||||
* Blob type for 128-bit GUIDs, UUIDs, etc.
|
||||
*/
|
||||
struct UniqueID
|
||||
{
|
||||
uint64_t data[2];
|
||||
|
||||
ZT_INLINE UniqueID() noexcept
|
||||
{}
|
||||
|
||||
ZT_INLINE UniqueID(const uint64_t a, const uint64_t b) noexcept
|
||||
{
|
||||
data[0] = a;
|
||||
data[1] = b;
|
||||
}
|
||||
|
||||
explicit ZT_INLINE UniqueID(const void *const d) noexcept
|
||||
{ Utils::copy< 16 >(data, d); }
|
||||
|
||||
ZT_INLINE const uint8_t *bytes() const noexcept
|
||||
{ return reinterpret_cast<const uint8_t *>(data); }
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{ return (unsigned long)data[1]; }
|
||||
|
||||
ZT_INLINE operator bool() const noexcept
|
||||
{ return ((data[0] != 0) && (data[1] != 0)); }
|
||||
|
||||
ZT_INLINE bool operator==(const SHA384Hash &b) const noexcept
|
||||
{ return ((data[0] == b.data[0]) && (data[1] == b.data[1])); }
|
||||
|
||||
ZT_INLINE bool operator!=(const SHA384Hash &b) const noexcept
|
||||
{ return !(*this == b); }
|
||||
|
||||
ZT_INLINE bool operator<(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 16) < 0); }
|
||||
|
||||
ZT_INLINE bool operator>(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 16) > 0); }
|
||||
|
||||
ZT_INLINE bool operator<=(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 16) <= 0); }
|
||||
|
||||
ZT_INLINE bool operator>=(const SHA384Hash &b) const noexcept
|
||||
{ return (memcmp(data, b.data, 16) >= 0); }
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ void Certificate::addSubjectCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_
|
|||
// Enlarge array of uint8_t pointers, set new pointer to local copy of serial, and set
|
||||
// certificates to point to potentially reallocated array.
|
||||
m_subjectCertificates.resize(++this->subject.certificateCount);
|
||||
m_subjectCertificates.back() = m_serials.back().data;
|
||||
m_subjectCertificates.back() = m_serials.back().bytes();
|
||||
this->subject.certificates = m_subjectCertificates.data();
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ public:
|
|||
}
|
||||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{ return (unsigned long)Utils::loadAsIsEndian< uint32_t >(this->serialNo); }
|
||||
{ return (unsigned long)Utils::loadMachineEndian< uint32_t >(this->serialNo); }
|
||||
|
||||
ZT_INLINE bool operator==(const ZT_Certificate &c) const noexcept
|
||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) == 0; }
|
||||
|
|
|
@ -106,7 +106,7 @@ void InetAddress::set(const void *ipBytes, unsigned int ipLen, unsigned int port
|
|||
if (ipLen == 4) {
|
||||
as.sa_in.sin_family = AF_INET;
|
||||
as.sa_in.sin_port = Utils::hton((uint16_t) port);
|
||||
as.sa_in.sin_addr.s_addr = Utils::loadAsIsEndian<uint32_t>(ipBytes);
|
||||
as.sa_in.sin_addr.s_addr = Utils::loadMachineEndian< uint32_t >(ipBytes);
|
||||
} else if (ipLen == 16) {
|
||||
as.sa_in6.sin6_family = AF_INET6;
|
||||
as.sa_in6.sin6_port = Utils::hton((uint16_t) port);
|
||||
|
@ -369,14 +369,14 @@ int InetAddress::unmarshal(const uint8_t *restrict data, const int len) noexcept
|
|||
if (unlikely(len < 7))
|
||||
return -1;
|
||||
as.sa_in.sin_family = AF_INET;
|
||||
as.sa_in.sin_port = Utils::loadAsIsEndian<uint16_t>(data + 5);
|
||||
as.sa_in.sin_addr.s_addr = Utils::loadAsIsEndian<uint32_t>(data + 1);
|
||||
as.sa_in.sin_port = Utils::loadMachineEndian< uint16_t >(data + 5);
|
||||
as.sa_in.sin_addr.s_addr = Utils::loadMachineEndian< uint32_t >(data + 1);
|
||||
return 7;
|
||||
case 6:
|
||||
if (unlikely(len < 19))
|
||||
return -1;
|
||||
as.sa_in6.sin6_family = AF_INET6;
|
||||
as.sa_in6.sin6_port = Utils::loadAsIsEndian<uint16_t>(data + 17);
|
||||
as.sa_in6.sin6_port = Utils::loadMachineEndian< uint16_t >(data + 17);
|
||||
Utils::copy<16>(as.sa_in6.sin6_addr.s6_addr, data + 1);
|
||||
return 19;
|
||||
default:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "MAC.hpp"
|
||||
#include "Containers.hpp"
|
||||
#include "TriviallyCopyable.hpp"
|
||||
#include "Blob.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -74,7 +75,7 @@ public:
|
|||
struct Hasher
|
||||
{
|
||||
ZT_INLINE std::size_t operator()(const InetAddress &a) const noexcept
|
||||
{ return (std::size_t) a.hashCode(); }
|
||||
{ return (std::size_t)a.hashCode(); }
|
||||
};
|
||||
|
||||
ZT_INLINE InetAddress() noexcept
|
||||
|
@ -211,10 +212,10 @@ public:
|
|||
{
|
||||
switch (as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
as.sa_in.sin_port = Utils::hton((uint16_t) port);
|
||||
as.sa_in.sin_port = Utils::hton((uint16_t)port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
as.sa_in6.sin6_port = Utils::hton((uint16_t) port);
|
||||
as.sa_in6.sin6_port = Utils::hton((uint16_t)port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +388,7 @@ public:
|
|||
break;
|
||||
case AF_INET6:
|
||||
r.as.sa_in6.sin6_family = AF_INET6;
|
||||
Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr, as.sa_in6.sin6_addr.s6_addr);
|
||||
Utils::copy< 16 >(r.as.sa_in6.sin6_addr.s6_addr, as.sa_in6.sin6_addr.s6_addr);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
|
@ -436,12 +437,12 @@ public:
|
|||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{
|
||||
if (as.ss.ss_family == AF_INET) {
|
||||
return (unsigned long) Utils::hash32(((uint32_t) as.sa_in.sin_addr.s_addr + (uint32_t) as.sa_in.sin_port) ^ (uint32_t) Utils::s_mapNonce);
|
||||
return (unsigned long)Utils::hash32(((uint32_t)as.sa_in.sin_addr.s_addr + (uint32_t)as.sa_in.sin_port) ^ (uint32_t)Utils::s_mapNonce);
|
||||
} else if (as.ss.ss_family == AF_INET6) {
|
||||
return (unsigned long) Utils::hash64(
|
||||
(Utils::loadAsIsEndian<uint64_t>(as.sa_in6.sin6_addr.s6_addr) +
|
||||
Utils::loadAsIsEndian<uint64_t>(as.sa_in6.sin6_addr.s6_addr + 8) +
|
||||
(uint64_t) as.sa_in6.sin6_port) ^
|
||||
return (unsigned long)Utils::hash64(
|
||||
(Utils::loadMachineEndian< uint64_t >(as.sa_in6.sin6_addr.s6_addr) +
|
||||
Utils::loadMachineEndian< uint64_t >(as.sa_in6.sin6_addr.s6_addr + 8) +
|
||||
(uint64_t)as.sa_in6.sin6_port) ^
|
||||
Utils::s_mapNonce);
|
||||
}
|
||||
return Utils::fnv1a32(this, sizeof(InetAddress));
|
||||
|
@ -486,15 +487,15 @@ public:
|
|||
{
|
||||
if (as.ss.ss_family == a.as.ss.ss_family) {
|
||||
if (as.ss.ss_family == AF_INET) {
|
||||
const uint16_t p0 = Utils::ntoh((uint16_t) as.sa_in.sin_port);
|
||||
const uint16_t p1 = Utils::ntoh((uint16_t) a.as.sa_in.sin_port);
|
||||
const uint16_t p0 = Utils::ntoh((uint16_t)as.sa_in.sin_port);
|
||||
const uint16_t p1 = Utils::ntoh((uint16_t)a.as.sa_in.sin_port);
|
||||
if (p0 == p1)
|
||||
return Utils::ntoh((uint32_t) as.sa_in.sin_addr.s_addr) < Utils::ntoh((uint32_t) a.as.sa_in.sin_addr.s_addr);
|
||||
return Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr) < Utils::ntoh((uint32_t)a.as.sa_in.sin_addr.s_addr);
|
||||
return p0 < p1;
|
||||
}
|
||||
if (as.ss.ss_family == AF_INET6) {
|
||||
const uint16_t p0 = Utils::ntoh((uint16_t) as.sa_in6.sin6_port);
|
||||
const uint16_t p1 = Utils::ntoh((uint16_t) a.as.sa_in6.sin6_port);
|
||||
const uint16_t p0 = Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
|
||||
const uint16_t p1 = Utils::ntoh((uint16_t)a.as.sa_in6.sin6_port);
|
||||
if (p0 == p1)
|
||||
return memcmp(as.sa_in6.sin6_addr.s6_addr, a.as.sa_in6.sin6_addr.s6_addr, 16) < 0;
|
||||
return p0 < p1;
|
||||
|
@ -516,6 +517,34 @@ public:
|
|||
ZT_INLINE bool operator>=(const InetAddress &a) const noexcept
|
||||
{ return !(*this < a); }
|
||||
|
||||
/**
|
||||
* Generate a local unique key for this address
|
||||
*
|
||||
* This key is not comparable across instances or architectures.
|
||||
*
|
||||
* @return Local unique key
|
||||
*/
|
||||
ZT_INLINE UniqueID key() const noexcept
|
||||
{
|
||||
if (as.ss.ss_family == AF_INET) {
|
||||
// For IPv4 we can just pack the IP and port into the first element.
|
||||
return UniqueID(((uint64_t)as.sa_in.sin_addr.s_addr << 16U) ^ (uint64_t)as.sa_in.sin_port, 0);
|
||||
} else if (likely(as.ss.ss_family == AF_INET6)) {
|
||||
// The OR with (a2 == 0) is to make sure the second part of the UniqueID
|
||||
// can never be zero, otherwise it could be made to collide with an IPv4
|
||||
// IP address. We also construct this to make it so someone in a /64
|
||||
// can't collide another address in the same /64.
|
||||
const uint64_t a1 = Utils::loadMachineEndian< uint64_t >(as.sa_in6.sin6_addr.s6_addr);
|
||||
const uint64_t a2 = Utils::hash64(Utils::s_mapNonce ^ Utils::loadMachineEndian< uint64_t >(as.sa_in6.sin6_addr.s6_addr + 8)) + (uint64_t)as.sa_in6.sin6_port;
|
||||
return UniqueID(a1, a2 | (uint64_t)(a2 == 0));
|
||||
} else if (likely(as.ss.ss_family == 0)) {
|
||||
return UniqueID(0, 0);
|
||||
} else {
|
||||
// This should never be reached, but handle it somehow.
|
||||
return UniqueID(Utils::fnv1a32(&as, sizeof(as)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute an IPv6 link-local address
|
||||
*
|
||||
|
|
|
@ -109,7 +109,7 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool exclu
|
|||
p += l;
|
||||
}
|
||||
|
||||
Utils::storeAsIsEndian<uint16_t>(data + p, 0); // length of meta-data, currently always 0
|
||||
Utils::storeMachineEndian< uint16_t >(data + p, 0); // length of meta-data, currently always 0
|
||||
p += 2;
|
||||
|
||||
if (!excludeSignature) {
|
||||
|
|
|
@ -28,7 +28,7 @@ Member::Member() :
|
|||
{
|
||||
}
|
||||
|
||||
void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int64_t now, const SharedPtr<Peer> &to, const NetworkConfig &nconf)
|
||||
void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int64_t now, const SharedPtr< Peer > &to, const NetworkConfig &nconf)
|
||||
{
|
||||
if (!nconf.com) // sanity check
|
||||
return;
|
||||
|
@ -117,36 +117,36 @@ void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int
|
|||
|
||||
void Member::clean(const int64_t now, const NetworkConfig &nconf)
|
||||
{
|
||||
m_cleanCredImpl<TagCredential>(nconf, m_remoteTags);
|
||||
m_cleanCredImpl<CapabilityCredential>(nconf, m_remoteCaps);
|
||||
m_cleanCredImpl<OwnershipCredential>(nconf, m_remoteCoos);
|
||||
m_cleanCredImpl< TagCredential >(nconf, m_remoteTags);
|
||||
m_cleanCredImpl< CapabilityCredential >(nconf, m_remoteCaps);
|
||||
m_cleanCredImpl< OwnershipCredential >(nconf, m_remoteCoos);
|
||||
}
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com)
|
||||
{
|
||||
const int64_t newts = com.timestamp();
|
||||
if (newts <= m_comRevocationThreshold) {
|
||||
RR->t->credentialRejected(tPtr,0xd9992121,com.networkId(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
RR->t->credentialRejected(tPtr, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
|
||||
const int64_t oldts = m_com.timestamp();
|
||||
if (newts < oldts) {
|
||||
RR->t->credentialRejected(tPtr,0xd9928192,com.networkId(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
RR->t->credentialRejected(tPtr, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
if ((newts == oldts)&&(m_com == com))
|
||||
if ((newts == oldts) && (m_com == com))
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
|
||||
switch(com.verify(RR,tPtr)) {
|
||||
switch (com.verify(RR, tPtr)) {
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr,0x0f198241,com.networkId(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(tPtr, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return Member::ADD_REJECTED;
|
||||
case Credential::VERIFY_OK:
|
||||
m_com = com;
|
||||
return ADD_ACCEPTED_NEW;
|
||||
case Credential::VERIFY_BAD_SIGNATURE:
|
||||
RR->t->credentialRejected(tPtr,0xbaf0aaaa,com.networkId(),sourcePeerIdentity,com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
|
||||
RR->t->credentialRejected(tPtr, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
|
||||
return ADD_REJECTED;
|
||||
case Credential::VERIFY_NEED_IDENTITY:
|
||||
return ADD_DEFERRED_FOR_WHOIS;
|
||||
|
@ -154,10 +154,10 @@ Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR,
|
|||
}
|
||||
|
||||
// 3/5 of the credential types have identical addCredential() code
|
||||
template<typename C>
|
||||
template< typename C >
|
||||
static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
||||
Map<uint32_t,C> &remoteCreds,
|
||||
const Map<uint64_t,int64_t> &revocations,
|
||||
Map< uint32_t, C > &remoteCreds,
|
||||
const Map< uint64_t, int64_t > &revocations,
|
||||
const RuntimeEnvironment *const RR,
|
||||
void *const tPtr,
|
||||
const Identity &sourcePeerIdentity,
|
||||
|
@ -167,7 +167,7 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
|||
C *rc = remoteCreds.get(cred.id());
|
||||
if (rc) {
|
||||
if (rc->timestamp() > cred.timestamp()) {
|
||||
RR->t->credentialRejected(tPtr,0x40000001,nconf.networkId,sourcePeerIdentity,cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
RR->t->credentialRejected(tPtr, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
|
||||
return Member::ADD_REJECTED;
|
||||
}
|
||||
if (*rc == cred)
|
||||
|
@ -175,14 +175,14 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
|||
}
|
||||
|
||||
const int64_t *const rt = revocations.get(Member::credentialKey(C::credentialType(), cred.id()));
|
||||
if ((rt)&&(*rt >= cred.timestamp())) {
|
||||
RR->t->credentialRejected(tPtr,0x24248124,nconf.networkId,sourcePeerIdentity,cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
if ((rt) && (*rt >= cred.timestamp())) {
|
||||
RR->t->credentialRejected(tPtr, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
|
||||
return Member::ADD_REJECTED;
|
||||
}
|
||||
|
||||
switch(cred.verify(RR,tPtr)) {
|
||||
switch (cred.verify(RR, tPtr)) {
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr,0x01feba012,nconf.networkId,sourcePeerIdentity,cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(tPtr, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.timestamp(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return Member::ADD_REJECTED;
|
||||
case 0:
|
||||
if (!rc)
|
||||
|
@ -193,20 +193,26 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
|
|||
return Member::ADD_DEFERRED_FOR_WHOIS;
|
||||
}
|
||||
}
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag) { return _addCredImpl<TagCredential>(m_remoteTags, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, tag); }
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap) { return _addCredImpl<CapabilityCredential>(m_remoteCaps, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, cap); }
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo) { return _addCredImpl<OwnershipCredential>(m_remoteCoos, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, coo); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag)
|
||||
{ return _addCredImpl< TagCredential >(m_remoteTags, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, tag); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap)
|
||||
{ return _addCredImpl< CapabilityCredential >(m_remoteCaps, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, cap); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo)
|
||||
{ return _addCredImpl< OwnershipCredential >(m_remoteCoos, m_revocations, RR, tPtr, sourcePeerIdentity, nconf, coo); }
|
||||
|
||||
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, void *tPtr, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev)
|
||||
{
|
||||
int64_t *rt;
|
||||
switch(rev.verify(RR,tPtr)) {
|
||||
switch (rev.verify(RR, tPtr)) {
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr,0x938fffff,nconf.networkId,sourcePeerIdentity,rev.id(),0,ZT_CREDENTIAL_TYPE_REVOCATION,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(tPtr, 0x938fffff, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return ADD_REJECTED;
|
||||
case 0: {
|
||||
const ZT_CredentialType ct = rev.typeBeingRevoked();
|
||||
switch(ct) {
|
||||
switch (ct) {
|
||||
case ZT_CREDENTIAL_TYPE_COM:
|
||||
if (rev.threshold() > m_comRevocationThreshold) {
|
||||
m_comRevocationThreshold = rev.threshold();
|
||||
|
@ -224,7 +230,7 @@ Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR,
|
|||
}
|
||||
return ADD_ACCEPTED_REDUNDANT;
|
||||
default:
|
||||
RR->t->credentialRejected(tPtr,0x0bbbb1a4,nconf.networkId,sourcePeerIdentity,rev.id(),0,ZT_CREDENTIAL_TYPE_REVOCATION,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
RR->t->credentialRejected(tPtr, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
|
||||
return ADD_REJECTED;
|
||||
}
|
||||
}
|
||||
|
@ -235,40 +241,14 @@ Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR,
|
|||
|
||||
bool Member::m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept
|
||||
{
|
||||
if ((ip.isV6())&&(nconf.ndpEmulation())) {
|
||||
const InetAddress sixpl(InetAddress::makeIpv66plane(nconf.networkId,nconf.issuedTo.toInt()));
|
||||
for(unsigned int i=0;i<nconf.staticIpCount;++i) {
|
||||
if (nconf.staticIps[i].ipsEqual(sixpl)) {
|
||||
bool prefixMatches = true;
|
||||
for(unsigned int j=0;j<5;++j) { // check for match on /40
|
||||
if ((((const struct sockaddr_in6 *)&ip)->sin6_addr.s6_addr)[j] != (((const struct sockaddr_in6 *)&sixpl)->sin6_addr.s6_addr)[j]) {
|
||||
prefixMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prefixMatches)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const InetAddress rfc4193(InetAddress::makeIpv6rfc4193(nconf.networkId,nconf.issuedTo.toInt()));
|
||||
for(unsigned int i=0;i<nconf.staticIpCount;++i) {
|
||||
if (nconf.staticIps[i].ipsEqual(rfc4193)) {
|
||||
bool prefixMatches = true;
|
||||
for(unsigned int j=0;j<11;++j) { // check for match on /88
|
||||
if ((((const struct sockaddr_in6 *)&ip)->sin6_addr.s6_addr)[j] != (((const struct sockaddr_in6 *)&rfc4193)->sin6_addr.s6_addr)[j]) {
|
||||
prefixMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prefixMatches)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return (
|
||||
ip.isV6() &&
|
||||
nconf.ndpEmulation() &&
|
||||
(
|
||||
(ip == InetAddress::makeIpv66plane(nconf.networkId, m_com.issuedTo().address)) ||
|
||||
(ip == InetAddress::makeIpv6rfc4193(nconf.networkId, m_com.issuedTo().address))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
* @return True if this peer has a certificate of ownership for the given resource
|
||||
*/
|
||||
template<typename T>
|
||||
ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf,const T &r) const noexcept
|
||||
ZT_INLINE bool peerOwnsAddress(const NetworkConfig &nconf, const T &r) const noexcept
|
||||
{
|
||||
if (m_isUnspoofableAddress(nconf, r))
|
||||
return true;
|
||||
|
@ -156,7 +156,7 @@ private:
|
|||
// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT
|
||||
// address of the peer and therefore cannot be spoofed, causing peerOwnsAddress() to
|
||||
// always return true for them. A certificate is not required for these.
|
||||
constexpr bool m_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) const noexcept { return false; }
|
||||
ZT_INLINE bool m_isUnspoofableAddress(const NetworkConfig &nconf, const MAC &m) const noexcept { return false; }
|
||||
bool m_isUnspoofableAddress(const NetworkConfig &nconf, const InetAddress &ip) const noexcept;
|
||||
|
||||
// This compares the remote credential's timestamp to the timestamp in our network config
|
||||
|
|
|
@ -117,7 +117,7 @@ int MembershipCredential::marshal(uint8_t data[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_
|
|||
p += 8;
|
||||
Utils::storeBigEndian<uint64_t>(data + p, m_issuedTo.address);
|
||||
p += 8;
|
||||
Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
|
||||
Utils::storeMachineEndian< uint64_t >(data + p, 0xffffffffffffffffULL);
|
||||
p += 8;
|
||||
|
||||
if (v2) {
|
||||
|
@ -131,9 +131,9 @@ int MembershipCredential::marshal(uint8_t data[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_
|
|||
for (int k = 0;k < 6;++k) {
|
||||
Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) k + 3);
|
||||
p += 8;
|
||||
Utils::storeAsIsEndian<uint64_t>(data + p, Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + (k * 8)));
|
||||
Utils::storeMachineEndian< uint64_t >(data + p, Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + (k * 8)));
|
||||
p += 8;
|
||||
Utils::storeAsIsEndian<uint64_t>(data + p, 0xffffffffffffffffULL);
|
||||
Utils::storeMachineEndian< uint64_t >(data + p, 0xffffffffffffffffULL);
|
||||
p += 8;
|
||||
}
|
||||
}
|
||||
|
@ -268,22 +268,22 @@ unsigned int MembershipCredential::m_fillSigningBuf(uint64_t *buf) const noexcep
|
|||
// embeded as a series of informational tuples.
|
||||
if (m_issuedTo.haveHash()) {
|
||||
buf[p++] = ZT_CONST_TO_BE_UINT64(3);
|
||||
buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash);
|
||||
buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash);
|
||||
buf[p++] = informational;
|
||||
buf[p++] = ZT_CONST_TO_BE_UINT64(4);
|
||||
buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 8);
|
||||
buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + 8);
|
||||
buf[p++] = informational;
|
||||
buf[p++] = ZT_CONST_TO_BE_UINT64(5);
|
||||
buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 16);
|
||||
buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + 16);
|
||||
buf[p++] = informational;
|
||||
buf[p++] = ZT_CONST_TO_BE_UINT64(6);
|
||||
buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 24);
|
||||
buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + 24);
|
||||
buf[p++] = informational;
|
||||
buf[p++] = ZT_CONST_TO_BE_UINT64(7);
|
||||
buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 32);
|
||||
buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + 32);
|
||||
buf[p++] = informational;
|
||||
buf[p++] = ZT_CONST_TO_BE_UINT64(8);
|
||||
buf[p++] = Utils::loadAsIsEndian<uint64_t>(m_issuedTo.hash + 40);
|
||||
buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + 40);
|
||||
buf[p++] = informational;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ unsigned int Peer::hello(void *tPtr, int64_t localSocket, const InetAddress &atA
|
|||
p1305.update(outp.unsafeData + ZT_PROTO_PACKET_ENCRYPTED_SECTION_START, ii - ZT_PROTO_PACKET_ENCRYPTED_SECTION_START);
|
||||
uint64_t polyMac[2];
|
||||
p1305.finish(polyMac);
|
||||
Utils::storeAsIsEndian< uint64_t >(outp.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, polyMac[0]);
|
||||
Utils::storeMachineEndian< uint64_t >(outp.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, polyMac[0]);
|
||||
|
||||
return (likely(RR->node->putPacket(tPtr, localSocket, atAddress, outp.unsafeData, ii))) ? ii : 0;
|
||||
}
|
||||
|
@ -704,7 +704,7 @@ unsigned int Peer::m_sendProbe(void *tPtr, int64_t localSocket, const InetAddres
|
|||
const uint64_t packetId = k->nextMessage(RR->identity.address(), m_id.address());
|
||||
|
||||
uint8_t p[ZT_PROTO_MIN_PACKET_LENGTH];
|
||||
Utils::storeAsIsEndian< uint64_t >(p + ZT_PROTO_PACKET_ID_INDEX, packetId);
|
||||
Utils::storeMachineEndian< uint64_t >(p + ZT_PROTO_PACKET_ID_INDEX, packetId);
|
||||
m_id.address().copyTo(p + ZT_PROTO_PACKET_DESTINATION_INDEX);
|
||||
RR->identity.address().copyTo(p + ZT_PROTO_PACKET_SOURCE_INDEX);
|
||||
p[ZT_PROTO_PACKET_FLAGS_INDEX] = 0;
|
||||
|
|
|
@ -834,11 +834,11 @@ static ZT_INLINE void salsa2012DeriveKey(const uint8_t *const in,uint8_t *const
|
|||
*/
|
||||
static ZT_INLINE int newPacket(uint8_t pkt[28],const uint64_t packetId,const Address destination,const Address source,const Verb verb) noexcept
|
||||
{
|
||||
Utils::storeAsIsEndian<uint64_t>(pkt + ZT_PROTO_PACKET_ID_INDEX,packetId);
|
||||
Utils::storeMachineEndian< uint64_t >(pkt + ZT_PROTO_PACKET_ID_INDEX, packetId);
|
||||
destination.copyTo(pkt + ZT_PROTO_PACKET_DESTINATION_INDEX);
|
||||
source.copyTo(pkt + ZT_PROTO_PACKET_SOURCE_INDEX);
|
||||
pkt[ZT_PROTO_PACKET_FLAGS_INDEX] = 0;
|
||||
Utils::storeAsIsEndian<uint64_t>(pkt + ZT_PROTO_PACKET_MAC_INDEX,0);
|
||||
Utils::storeMachineEndian< uint64_t >(pkt + ZT_PROTO_PACKET_MAC_INDEX, 0);
|
||||
pkt[ZT_PROTO_PACKET_VERB_INDEX] = (uint8_t)verb;
|
||||
return ZT_PROTO_PACKET_VERB_INDEX + 1;
|
||||
}
|
||||
|
|
|
@ -200,12 +200,12 @@ void HMACSHA384(const uint8_t key[ZT_SYMMETRIC_KEY_SIZE],const void *msg,const u
|
|||
uint64_t kInPadded[16]; // input padded key
|
||||
uint64_t outer[22]; // output padded key | H(input padded key | msg)
|
||||
|
||||
const uint64_t k0 = Utils::loadAsIsEndian<uint64_t>(key);
|
||||
const uint64_t k1 = Utils::loadAsIsEndian<uint64_t>(key + 8);
|
||||
const uint64_t k2 = Utils::loadAsIsEndian<uint64_t>(key + 16);
|
||||
const uint64_t k3 = Utils::loadAsIsEndian<uint64_t>(key + 24);
|
||||
const uint64_t k4 = Utils::loadAsIsEndian<uint64_t>(key + 32);
|
||||
const uint64_t k5 = Utils::loadAsIsEndian<uint64_t>(key + 40);
|
||||
const uint64_t k0 = Utils::loadMachineEndian< uint64_t >(key);
|
||||
const uint64_t k1 = Utils::loadMachineEndian< uint64_t >(key + 8);
|
||||
const uint64_t k2 = Utils::loadMachineEndian< uint64_t >(key + 16);
|
||||
const uint64_t k3 = Utils::loadMachineEndian< uint64_t >(key + 24);
|
||||
const uint64_t k4 = Utils::loadMachineEndian< uint64_t >(key + 32);
|
||||
const uint64_t k5 = Utils::loadMachineEndian< uint64_t >(key + 40);
|
||||
|
||||
const uint64_t ipad = 0x3636363636363636ULL;
|
||||
kInPadded[0] = k0 ^ ipad;
|
||||
|
|
|
@ -427,35 +427,35 @@ extern "C" const char *ZTT_general()
|
|||
return "ZT_CONST_TO_BE_UINT16 macro is not working";
|
||||
}
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
if (Utils::loadAsIsEndian< uint64_t >(&a) != 0x0102030405060708ULL) {
|
||||
ZT_T_PRINTF("FAILED (loadAsIsEndian)" ZT_EOL_S);
|
||||
return "Utils::loadAsIsEndian() broken";
|
||||
if (Utils::loadMachineEndian< uint64_t >(&a) != 0x0102030405060708ULL) {
|
||||
ZT_T_PRINTF("FAILED (loadMachineEndian)" ZT_EOL_S);
|
||||
return "Utils::loadMachineEndian() broken";
|
||||
}
|
||||
if (Utils::loadAsIsEndian< uint32_t >(&b) != 0x01020304) {
|
||||
ZT_T_PRINTF("FAILED (loadAsIsEndian)" ZT_EOL_S);
|
||||
return "Utils::loadAsIsEndian() broken";
|
||||
if (Utils::loadMachineEndian< uint32_t >(&b) != 0x01020304) {
|
||||
ZT_T_PRINTF("FAILED (loadMachineEndian)" ZT_EOL_S);
|
||||
return "Utils::loadMachineEndian() broken";
|
||||
}
|
||||
if (Utils::loadAsIsEndian< uint16_t >(&c) != 0x0102) {
|
||||
ZT_T_PRINTF("FAILED (loadAsIsEndian)" ZT_EOL_S);
|
||||
return "Utils::loadAsIsEndian() broken";
|
||||
if (Utils::loadMachineEndian< uint16_t >(&c) != 0x0102) {
|
||||
ZT_T_PRINTF("FAILED (loadMachineEndian)" ZT_EOL_S);
|
||||
return "Utils::loadMachineEndian() broken";
|
||||
}
|
||||
Utils::zero< sizeof(t) >(t);
|
||||
Utils::storeAsIsEndian< uint64_t >(t, 0x0807060504030201ULL);
|
||||
Utils::storeMachineEndian< uint64_t >(t, 0x0807060504030201ULL);
|
||||
if (t[0] != 1) {
|
||||
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
|
||||
return "Utils::storeAsIsEndian() broken";
|
||||
ZT_T_PRINTF("FAILED (storeMachineEndian)" ZT_EOL_S);
|
||||
return "Utils::storeMachineEndian() broken";
|
||||
}
|
||||
Utils::zero< sizeof(t) >(t);
|
||||
Utils::storeAsIsEndian< uint32_t >(t, 0x04030201);
|
||||
Utils::storeMachineEndian< uint32_t >(t, 0x04030201);
|
||||
if (t[0] != 1) {
|
||||
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
|
||||
return "Utils::storeAsIsEndian() broken";
|
||||
ZT_T_PRINTF("FAILED (storeMachineEndian)" ZT_EOL_S);
|
||||
return "Utils::storeMachineEndian() broken";
|
||||
}
|
||||
Utils::zero< sizeof(t) >(t);
|
||||
Utils::storeAsIsEndian< uint16_t >(t, 0x0201);
|
||||
Utils::storeMachineEndian< uint16_t >(t, 0x0201);
|
||||
if (t[0] != 1) {
|
||||
ZT_T_PRINTF("FAILED (storeAsIsEndian)" ZT_EOL_S);
|
||||
return "Utils::storeAsIsEndian() broken";
|
||||
ZT_T_PRINTF("FAILED (storeMachineEndian)" ZT_EOL_S);
|
||||
return "Utils::storeMachineEndian() broken";
|
||||
}
|
||||
#else
|
||||
if (Utils::loadAsIsEndian<uint64_t>(&a) != 0x0807060504030201ULL) {
|
||||
|
|
|
@ -182,18 +182,18 @@ void Topology::doPeriodicTasks(void *tPtr, const int64_t now)
|
|||
|
||||
// Delete paths that are no longer held by anyone else ("weak reference" type behavior).
|
||||
{
|
||||
Vector< uint64_t > toDelete;
|
||||
Vector< UniqueID > toDelete;
|
||||
{
|
||||
RWMutex::RLock l1(m_paths_l);
|
||||
for (Map< uint64_t, SharedPtr< Path > >::iterator i(m_paths.begin()); i != m_paths.end();
|
||||
for (Map< UniqueID, SharedPtr< Path > >::iterator i(m_paths.begin()); i != m_paths.end();
|
||||
++i) {
|
||||
if (i->second.weakGC())
|
||||
toDelete.push_back(i->first);
|
||||
}
|
||||
}
|
||||
for (Vector< uint64_t >::iterator i(toDelete.begin()); i != toDelete.end(); ++i) {
|
||||
for (Vector< UniqueID >::iterator i(toDelete.begin()); i != toDelete.end(); ++i) {
|
||||
RWMutex::Lock l1(m_paths_l);
|
||||
const Map< uint64_t, SharedPtr< Path > >::iterator p(m_paths.find(*i));
|
||||
const Map< UniqueID, SharedPtr< Path > >::iterator p(m_paths.find(*i));
|
||||
if (likely(p != m_paths.end()))
|
||||
m_paths.erase(p);
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
*/
|
||||
ZT_INLINE SharedPtr< Path > path(const int64_t l, const InetAddress &r)
|
||||
{
|
||||
const uint64_t k = s_getPathKey(l, r);
|
||||
const UniqueID k(r.key());
|
||||
{
|
||||
RWMutex::RLock lck(m_paths_l);
|
||||
SharedPtr< Path > *const p = m_paths.get(k);
|
||||
|
@ -238,25 +238,6 @@ private:
|
|||
void m_updateRootPeers_l_roots_certs(void *tPtr);
|
||||
void m_writeTrustStore_l_roots_certs(void *tPtr) const;
|
||||
|
||||
// This gets an integer key from an InetAddress for looking up paths.
|
||||
static ZT_INLINE uint64_t s_getPathKey(const int64_t l, const InetAddress &r) noexcept
|
||||
{
|
||||
// SECURITY: these will be used as keys in a Map<> which uses its own hasher that
|
||||
// mixes in a per-invocation secret to work against hash collision attacks. See the
|
||||
// map hasher in Containers.hpp. Otherwise the point here is really really fast
|
||||
// path lookup by address. The number of paths is never likely to be high enough
|
||||
// for a collision to be something we worry about. That would require a minimum of
|
||||
// millions and millions of paths on a single node.
|
||||
if (r.family() == AF_INET) {
|
||||
return ((uint64_t)(r.as.sa_in.sin_addr.s_addr) << 32U) ^ ((uint64_t)r.as.sa_in.sin_port << 16U) ^ (uint64_t)l;
|
||||
} else if (r.family() == AF_INET6) {
|
||||
return Utils::loadAsIsEndian< uint64_t >(r.as.sa_in6.sin6_addr.s6_addr) + Utils::loadAsIsEndian< uint64_t >(r.as.sa_in6.sin6_addr.s6_addr + 8) + (uint64_t)r.as.sa_in6.sin6_port + (uint64_t)l;
|
||||
} else {
|
||||
// This should never really be used but it's here just in case.
|
||||
return (uint64_t)Utils::fnv1a32(reinterpret_cast<const void *>(&r), sizeof(InetAddress)) + (uint64_t)l;
|
||||
}
|
||||
}
|
||||
|
||||
const RuntimeEnvironment *const RR;
|
||||
|
||||
RWMutex m_paths_l; // m_paths
|
||||
|
@ -264,7 +245,7 @@ private:
|
|||
RWMutex m_roots_l; // m_roots, m_rootPeers
|
||||
Mutex m_certs_l; // m_certs, m_certsBySubjectIdentity
|
||||
|
||||
Map< uint64_t, SharedPtr< Path > > m_paths;
|
||||
Map< UniqueID, SharedPtr< Path > > m_paths;
|
||||
|
||||
Map< Address, SharedPtr< Peer > > m_peers;
|
||||
|
||||
|
|
|
@ -593,7 +593,7 @@ static ZT_INLINE I ntoh(const I n) noexcept
|
|||
* @return Loaded raw integer
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE I loadAsIsEndian(const void *const p) noexcept
|
||||
static ZT_INLINE I loadMachineEndian(const void *const p) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
I tmp;
|
||||
|
@ -613,7 +613,7 @@ static ZT_INLINE I loadAsIsEndian(const void *const p) noexcept
|
|||
* @param i Integer to store
|
||||
*/
|
||||
template< typename I >
|
||||
static ZT_INLINE void storeAsIsEndian(void *const p, const I i) noexcept
|
||||
static ZT_INLINE void storeMachineEndian(void *const p, const I i) noexcept
|
||||
{
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
for(unsigned int k=0;k<sizeof(I);++k)
|
||||
|
|
12
core/VL1.cpp
12
core/VL1.cpp
|
@ -117,7 +117,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
return;
|
||||
|
||||
static_assert((ZT_PROTO_PACKET_ID_INDEX + sizeof(uint64_t)) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
|
||||
const uint64_t packetId = Utils::loadAsIsEndian< uint64_t >(data->unsafeData + ZT_PROTO_PACKET_ID_INDEX);
|
||||
const uint64_t packetId = Utils::loadMachineEndian< uint64_t >(data->unsafeData + ZT_PROTO_PACKET_ID_INDEX);
|
||||
|
||||
static_assert((ZT_PROTO_PACKET_DESTINATION_INDEX + ZT_ADDRESS_LENGTH) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
|
||||
const Address destination(data->unsafeData + ZT_PROTO_PACKET_DESTINATION_INDEX);
|
||||
|
@ -244,7 +244,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
uint64_t mac[2];
|
||||
s20cf.poly1305.finish(mac);
|
||||
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
|
||||
if (unlikely(Utils::loadAsIsEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
|
||||
if (unlikely(Utils::loadMachineEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
|
||||
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (none/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
|
||||
RR->t->incomingPacketDropped(tPtr, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return;
|
||||
|
@ -268,7 +268,7 @@ void VL1::onRemotePacket(void *const tPtr, const int64_t localSocket, const Inet
|
|||
uint64_t mac[2];
|
||||
s20cf.poly1305.finish(mac);
|
||||
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
|
||||
if (unlikely(Utils::loadAsIsEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
|
||||
if (unlikely(Utils::loadMachineEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
|
||||
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (salsa/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
|
||||
RR->t->incomingPacketDropped(tPtr, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
return;
|
||||
|
@ -477,8 +477,8 @@ void VL1::m_sendPendingWhois(void *tPtr, int64_t now)
|
|||
|
||||
SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &pkt, int packetSize)
|
||||
{
|
||||
const uint64_t packetId = Utils::loadAsIsEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_ID_INDEX);
|
||||
const uint64_t mac = Utils::loadAsIsEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX);
|
||||
const uint64_t packetId = Utils::loadMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_ID_INDEX);
|
||||
const uint64_t mac = Utils::loadMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX);
|
||||
const uint8_t hops = pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] & ZT_PROTO_FLAG_FIELD_HOPS_MASK;
|
||||
|
||||
const uint8_t protoVersion = pkt.lI8< ZT_PROTO_PACKET_PAYLOAD_START >();
|
||||
|
@ -543,7 +543,7 @@ SharedPtr< Peer > VL1::m_HELLO(void *tPtr, const SharedPtr< Path > &path, Buf &p
|
|||
}
|
||||
packetSize -= ZT_HMACSHA384_LEN;
|
||||
pkt.unsafeData[ZT_PROTO_PACKET_FLAGS_INDEX] &= ~ZT_PROTO_FLAG_FIELD_HOPS_MASK; // mask hops to 0
|
||||
Utils::storeAsIsEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, 0); // set MAC field to 0
|
||||
Utils::storeMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, 0); // set MAC field to 0
|
||||
HMACSHA384(peer->identityHelloHmacKey(), pkt.unsafeData, packetSize, hmac);
|
||||
if (unlikely(!Utils::secureEq(hmac, pkt.unsafeData + packetSize, ZT_HMACSHA384_LEN))) {
|
||||
RR->t->incomingPacketDropped(tPtr, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
|
||||
|
|
Loading…
Add table
Reference in a new issue