From 92d2bbc63cb444203b0ef9ac7cac7b760e70c4fb Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 30 Jun 2020 11:20:44 -0700 Subject: [PATCH] Some symbol renaming, performance improvements, a bug fix for compiling on some platforms, and some Topology work. --- core/AES.cpp | 16 +++--- core/Blob.hpp | 100 ++++++++++++++++++++++++++++------ core/Certificate.cpp | 2 +- core/Certificate.hpp | 2 +- core/InetAddress.cpp | 8 +-- core/InetAddress.hpp | 57 ++++++++++++++----- core/Locator.cpp | 2 +- core/Member.cpp | 98 +++++++++++++-------------------- core/Member.hpp | 4 +- core/MembershipCredential.cpp | 18 +++--- core/Peer.cpp | 4 +- core/Protocol.hpp | 4 +- core/SHA512.cpp | 12 ++-- core/Tests.cpp | 36 ++++++------ core/Topology.cpp | 8 +-- core/Topology.hpp | 23 +------- core/Utils.hpp | 4 +- core/VL1.cpp | 12 ++-- 18 files changed, 232 insertions(+), 178 deletions(-) diff --git a/core/AES.cpp b/core/AES.cpp index 4aee9e5df..7f93c57ce 100644 --- a/core/AES.cpp +++ b/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 ------------------------------------------------------------------------------------------------------------ diff --git a/core/Blob.hpp b/core/Blob.hpp index 72d41d9aa..004093ea9 100644 --- a/core/Blob.hpp +++ b/core/Blob.hpp @@ -16,37 +16,101 @@ #include "Constants.hpp" #include "Utils.hpp" +#include "TriviallyCopyable.hpp" + +#include + +// 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 -struct Blob +struct SHA384Hash { - uint8_t data[S]; + uint64_t data[6]; - ZT_INLINE Blob() noexcept { Utils::zero(data); } - explicit ZT_INLINE Blob(const void *const d) noexcept { Utils::copy(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(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(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 diff --git a/core/Certificate.cpp b/core/Certificate.cpp index 16fdd044b..cb12d3d1e 100644 --- a/core/Certificate.cpp +++ b/core/Certificate.cpp @@ -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(); } diff --git a/core/Certificate.hpp b/core/Certificate.hpp index 277d90c44..f3d538149 100644 --- a/core/Certificate.hpp +++ b/core/Certificate.hpp @@ -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; } diff --git a/core/InetAddress.cpp b/core/InetAddress.cpp index a87b15d36..827bb31c1 100644 --- a/core/InetAddress.cpp +++ b/core/InetAddress.cpp @@ -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(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(data + 5); - as.sa_in.sin_addr.s_addr = Utils::loadAsIsEndian(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(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: diff --git a/core/InetAddress.hpp b/core/InetAddress.hpp index e091c69fd..4af4f867b 100644 --- a/core/InetAddress.hpp +++ b/core/InetAddress.hpp @@ -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(as.sa_in6.sin6_addr.s6_addr) + - Utils::loadAsIsEndian(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 * diff --git a/core/Locator.cpp b/core/Locator.cpp index 76067245c..50c951473 100644 --- a/core/Locator.cpp +++ b/core/Locator.cpp @@ -109,7 +109,7 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool exclu p += l; } - Utils::storeAsIsEndian(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) { diff --git a/core/Member.cpp b/core/Member.cpp index e7ad98864..cd18f326e 100644 --- a/core/Member.cpp +++ b/core/Member.cpp @@ -28,7 +28,7 @@ Member::Member() : { } -void Member::pushCredentials(const RuntimeEnvironment *RR, void *tPtr, const int64_t now, const SharedPtr &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(nconf, m_remoteTags); - m_cleanCredImpl(nconf, m_remoteCaps); - m_cleanCredImpl(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 +template< typename C > static ZT_INLINE Member::AddCredentialResult _addCredImpl( - Map &remoteCreds, - const Map &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(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(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(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;isin6_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;isin6_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 diff --git a/core/Member.hpp b/core/Member.hpp index bb617f920..57055dac6 100644 --- a/core/Member.hpp +++ b/core/Member.hpp @@ -99,7 +99,7 @@ public: * @return True if this peer has a certificate of ownership for the given resource */ template - 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 diff --git a/core/MembershipCredential.cpp b/core/MembershipCredential.cpp index 0f0093735..ae3f2ae88 100644 --- a/core/MembershipCredential.cpp +++ b/core/MembershipCredential.cpp @@ -117,7 +117,7 @@ int MembershipCredential::marshal(uint8_t data[ZT_MEMBERSHIP_CREDENTIAL_MARSHAL_ p += 8; Utils::storeBigEndian(data + p, m_issuedTo.address); p += 8; - Utils::storeAsIsEndian(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(data + p, (uint64_t) k + 3); p += 8; - Utils::storeAsIsEndian(data + p, Utils::loadAsIsEndian(m_issuedTo.hash + (k * 8))); + Utils::storeMachineEndian< uint64_t >(data + p, Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + (k * 8))); p += 8; - Utils::storeAsIsEndian(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(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(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(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(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(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(m_issuedTo.hash + 40); + buf[p++] = Utils::loadMachineEndian< uint64_t >(m_issuedTo.hash + 40); buf[p++] = informational; } diff --git a/core/Peer.cpp b/core/Peer.cpp index 686ed222c..b4af96006 100644 --- a/core/Peer.cpp +++ b/core/Peer.cpp @@ -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; diff --git a/core/Protocol.hpp b/core/Protocol.hpp index 206af42d4..b8c9c826b 100644 --- a/core/Protocol.hpp +++ b/core/Protocol.hpp @@ -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(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(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; } diff --git a/core/SHA512.cpp b/core/SHA512.cpp index ead124354..f6b8ba8c9 100644 --- a/core/SHA512.cpp +++ b/core/SHA512.cpp @@ -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(key); - const uint64_t k1 = Utils::loadAsIsEndian(key + 8); - const uint64_t k2 = Utils::loadAsIsEndian(key + 16); - const uint64_t k3 = Utils::loadAsIsEndian(key + 24); - const uint64_t k4 = Utils::loadAsIsEndian(key + 32); - const uint64_t k5 = Utils::loadAsIsEndian(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; diff --git a/core/Tests.cpp b/core/Tests.cpp index 429c0a556..5f512aa56 100644 --- a/core/Tests.cpp +++ b/core/Tests.cpp @@ -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(&a) != 0x0807060504030201ULL) { diff --git a/core/Topology.cpp b/core/Topology.cpp index 4badc50d9..3c7f54a56 100644 --- a/core/Topology.cpp +++ b/core/Topology.cpp @@ -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); } diff --git a/core/Topology.hpp b/core/Topology.hpp index 462475926..29793668c 100644 --- a/core/Topology.hpp +++ b/core/Topology.hpp @@ -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(&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; diff --git a/core/Utils.hpp b/core/Utils.hpp index e7b54ab80..25c4ff7f4 100644 --- a/core/Utils.hpp +++ b/core/Utils.hpp @@ -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(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);