mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
A bunch more cleanup, remove a ton of reinterpret_cast cruft in favor of a simple union in InetAddress.
This commit is contained in:
parent
2b0127c26d
commit
78d223d709
12 changed files with 278 additions and 444 deletions
|
@ -58,12 +58,12 @@ extern "C" {
|
|||
#define ZT_BUF_SIZE 16384
|
||||
|
||||
/**
|
||||
* Minimum MTU allowed on virtual networks
|
||||
* Minimum Ethernet MTU allowed on virtual (not physical) networks
|
||||
*/
|
||||
#define ZT_MIN_MTU 1280
|
||||
|
||||
/**
|
||||
* Maximum MTU allowed on virtual networks
|
||||
* Maximum Ethernet MTU allowed on virtual (not physical) networks
|
||||
*/
|
||||
#define ZT_MAX_MTU 10000
|
||||
|
||||
|
@ -73,16 +73,16 @@ extern "C" {
|
|||
#define ZT_MIN_UDP_MTU 1400
|
||||
|
||||
/**
|
||||
* Default UDP payload size (physical path MTU) not including UDP and IP overhead
|
||||
* Default UDP payload size NOT including UDP and IP overhead
|
||||
*
|
||||
* This is small enough for PPPoE and for Google Cloud's bizarrely tiny MTUs.
|
||||
* A 2800 byte payload still fits into two packets, so this should not impact
|
||||
* real world throughput at all vs the previous default of 1444.
|
||||
* A payload size corresponding to the default 2800 byte virtual MTU fits
|
||||
* into two packets of less than or equal to this size.
|
||||
*/
|
||||
#define ZT_DEFAULT_UDP_MTU 1432
|
||||
|
||||
/**
|
||||
* Maximum physical UDP payload
|
||||
* Maximum physical payload size that can ever be used
|
||||
*/
|
||||
#define ZT_MAX_UDP_PHYSPAYLOAD 10100
|
||||
|
||||
|
@ -265,8 +265,8 @@ extern "C" {
|
|||
enum ZT_Identity_Type
|
||||
{
|
||||
/* These values must be the same as in Identity.hpp in the core. */
|
||||
ZT_IDENTITY_TYPE_C25519 = 0,
|
||||
ZT_IDENTITY_TYPE_P384 = 1
|
||||
ZT_IDENTITY_TYPE_C25519 = 0, /* C25519/Ed25519 */
|
||||
ZT_IDENTITY_TYPE_P384 = 1 /* Combined C25519/NIST-P-384 key */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -303,12 +303,6 @@ enum ZT_CredentialType
|
|||
ZT_CREDENTIAL_TYPE_REVOCATION = 6
|
||||
};
|
||||
|
||||
/* Trace events are sent and received as packed structures of a fixed size.
|
||||
* Normally we don't use this form of brittle encoding but in this case the
|
||||
* performance benefit is non-trivial.
|
||||
*
|
||||
* All integer fields larger than one byte are stored in big-endian order. */
|
||||
|
||||
/**
|
||||
* Flag indicating that VL1 tracing should be generated
|
||||
*/
|
||||
|
@ -391,30 +385,27 @@ enum ZT_TraceFrameDropReason
|
|||
* if possible for consistency. Not all of these are used (yet?) but they are defined
|
||||
* for possible future use and the structure is sized to support them.
|
||||
*/
|
||||
enum ZT_TraceEventPathAddressType
|
||||
enum ZT_EndpointType
|
||||
{
|
||||
ZT_TRACE_EVENT_PATH_TYPE_NIL = 0, /* none/empty */
|
||||
ZT_TRACE_EVENT_PATH_TYPE_ZEROTIER = 1, /* 5-byte ZeroTier + 48-byte identity hash */
|
||||
ZT_TRACE_EVENT_PATH_TYPE_ETHERNET = 2, /* 6-byte Ethernet */
|
||||
ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V4 = 4, /* 4-byte IPv4 */
|
||||
ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V6 = 6 /* 16-byte IPv6 */
|
||||
ZT_ENDPOINT_TYPE_NIL = 0, /* none/empty */
|
||||
ZT_ENDPOINT_TYPE_ZEROTIER = 1, /* 5-byte ZeroTier + 48-byte identity hash */
|
||||
ZT_ENDPOINT_TYPE_ETHERNET = 2, /* 6-byte Ethernet */
|
||||
ZT_ENDPOINT_TYPE_INETADDR_V4 = 4, /* 4-byte IPv4 */
|
||||
ZT_ENDPOINT_TYPE_INETADDR_V6 = 6 /* 16-byte IPv6 */
|
||||
};
|
||||
|
||||
/**
|
||||
* Maximum integer value of enum ZT_TraceEventPathAddressType
|
||||
* Protocol bits allowed for endpoint addresses.
|
||||
*/
|
||||
#define ZT_TRACE_EVENT_PATH_TYPE__MAX 6
|
||||
|
||||
/**
|
||||
* Reasons for trying new paths
|
||||
*/
|
||||
enum ZT_TraceTryingNewPathReason
|
||||
enum ZT_EndpointProtocol
|
||||
{
|
||||
ZT_TRACE_TRYING_NEW_PATH_REASON_PACKET_RECEIVED_FROM_UNKNOWN_PATH = 1,
|
||||
ZT_TRACE_TRYING_NEW_PATH_REASON_RECEIVED_PUSH_DIRECT_PATHS = 2,
|
||||
ZT_TRACE_TRYING_NEW_PATH_REASON_RENDEZVOUS = 3,
|
||||
ZT_TRACE_TRYING_NEW_PATH_REASON_BOOTSTRAP_ADDRESS = 4,
|
||||
ZT_TRACE_TRYING_NEW_PATH_REASON_EXPLICITLY_SUGGESTED_ADDRESS = 5
|
||||
ZT_ENDPOINT_PROTO_DGRAM = 0x0001,
|
||||
ZT_ENDPOINT_PROTO_STREAM = 0x0002,
|
||||
ZT_ENDPOINT_PROTO_HTTP2 = 0x0004,
|
||||
ZT_ENDPOINT_PROTO_HTTPS2 = 0x0008,
|
||||
ZT_ENDPOINT_PROTO_WS = 0x0010,
|
||||
ZT_ENDPOINT_PROTO_WEBRTC = 0x0020,
|
||||
ZT_ENDPOINT_PROTO_WIREGUARD = 0x0040
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
#include "TriviallyCopyable.hpp"
|
||||
#include "FCV.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
|
|
@ -217,10 +217,10 @@ public:
|
|||
if ((via)&&(!e->via)) {
|
||||
e->via = via;
|
||||
bool tooManyPerPath = false;
|
||||
via->_inboundFragmentedMessages_l.lock();
|
||||
via->m_inboundFragmentedMessages_l.lock();
|
||||
try {
|
||||
if (via->_inboundFragmentedMessages.size() < MFP) {
|
||||
via->_inboundFragmentedMessages.insert(messageId);
|
||||
if (via->m_inboundFragmentedMessages.size() < MFP) {
|
||||
via->m_inboundFragmentedMessages.insert(messageId);
|
||||
} else {
|
||||
tooManyPerPath = true;
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ public:
|
|||
// it as limit exceeded.
|
||||
tooManyPerPath = true;
|
||||
}
|
||||
via->_inboundFragmentedMessages_l.unlock();
|
||||
via->m_inboundFragmentedMessages_l.unlock();
|
||||
if (tooManyPerPath)
|
||||
return ERR_TOO_MANY_FRAGMENTS_FOR_PATH;
|
||||
}
|
||||
|
@ -255,9 +255,9 @@ public:
|
|||
if ((e->fragmentsReceived >= e->totalFragmentsExpected)&&(e->totalFragmentsExpected > 0)) {
|
||||
// This message is done so de-register it with its path if one is associated.
|
||||
if (e->via) {
|
||||
e->via->_inboundFragmentedMessages_l.lock();
|
||||
e->via->_inboundFragmentedMessages.erase(messageId);
|
||||
e->via->_inboundFragmentedMessages_l.unlock();
|
||||
e->via->m_inboundFragmentedMessages_l.lock();
|
||||
e->via->m_inboundFragmentedMessages.erase(messageId);
|
||||
e->via->m_inboundFragmentedMessages_l.unlock();
|
||||
e->via.zero();
|
||||
}
|
||||
|
||||
|
@ -312,9 +312,9 @@ private:
|
|||
ZT_INLINE ~p_E()
|
||||
{
|
||||
if (via) {
|
||||
via->_inboundFragmentedMessages_l.lock();
|
||||
via->_inboundFragmentedMessages.erase(id);
|
||||
via->_inboundFragmentedMessages_l.unlock();
|
||||
via->m_inboundFragmentedMessages_l.lock();
|
||||
via->m_inboundFragmentedMessages.erase(id);
|
||||
via->m_inboundFragmentedMessages_l.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ void Dictionary::clear()
|
|||
m_entries.clear();
|
||||
}
|
||||
|
||||
void Dictionary::encode(std::vector<uint8_t> &out) const
|
||||
void Dictionary::encode(Vector<uint8_t> &out) const
|
||||
{
|
||||
uint64_t str[2] = { 0,0 }; // second entry causes all strings to be null-terminated even if 8 chars in length
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ public:
|
|||
*
|
||||
* @param out String encoded dictionary
|
||||
*/
|
||||
void encode(std::vector<uint8_t> &out) const;
|
||||
void encode(Vector<uint8_t> &out) const;
|
||||
|
||||
/**
|
||||
* Decode a string encoded dictionary
|
||||
|
|
|
@ -21,20 +21,12 @@
|
|||
#include "TriviallyCopyable.hpp"
|
||||
#include "Fingerprint.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#define ZT_ENDPOINT_MARSHAL_SIZE_MAX 64
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* Endpoint variant specifying some form of network endpoint
|
||||
*
|
||||
* This data structure supports a number of types that are not yet actually used:
|
||||
* DNSNAME, URL, and ETHERNET. These are present to reserve them for future use.
|
||||
* Endpoint variant specifying some form of network endpoint.
|
||||
*/
|
||||
class Endpoint : public TriviallyCopyable
|
||||
{
|
||||
|
@ -46,29 +38,25 @@ public:
|
|||
*/
|
||||
enum Type
|
||||
{
|
||||
TYPE_NIL = ZT_TRACE_EVENT_PATH_TYPE_NIL,
|
||||
TYPE_ZEROTIER = ZT_TRACE_EVENT_PATH_TYPE_ZEROTIER,
|
||||
TYPE_ETHERNET = ZT_TRACE_EVENT_PATH_TYPE_ETHERNET,
|
||||
TYPE_INETADDR_V4 = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V4,
|
||||
TYPE_INETADDR_V6 = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V6
|
||||
TYPE_NIL = ZT_ENDPOINT_TYPE_NIL,
|
||||
TYPE_ZEROTIER = ZT_ENDPOINT_TYPE_ZEROTIER,
|
||||
TYPE_ETHERNET = ZT_ENDPOINT_TYPE_ETHERNET,
|
||||
TYPE_INETADDR_V4 = ZT_ENDPOINT_TYPE_INETADDR_V4,
|
||||
TYPE_INETADDR_V6 = ZT_ENDPOINT_TYPE_INETADDR_V6
|
||||
};
|
||||
|
||||
/**
|
||||
* Protocol identifier bits.
|
||||
*
|
||||
* Endpoint types can support more than one of these, though it depends on the type.
|
||||
*
|
||||
* Most of these are reserved for possible future use.
|
||||
*/
|
||||
enum Protocol
|
||||
{
|
||||
PROTO_DGRAM = 0x0001, // UDP for IP or naked Ethernet frames
|
||||
PROTO_STREAM = 0x0002, // TCP
|
||||
PROTO_HTTP2 = 0x0004, // HTTP2 bidirectional protocol
|
||||
PROTO_HTTPS2 = 0x0008, // HTTP2 over SSL/TLS
|
||||
PROTO_WS = 0x0010, // Web sockets
|
||||
PROTO_WEBRTC = 0x0020, // WebRTC data channels
|
||||
PROTO_WIREGUARD = 0x0040 // Wireguard as low-level transport
|
||||
PROTO_DGRAM = ZT_ENDPOINT_PROTO_DGRAM,
|
||||
PROTO_STREAM = ZT_ENDPOINT_PROTO_STREAM,
|
||||
PROTO_HTTP2 = ZT_ENDPOINT_PROTO_HTTP2,
|
||||
PROTO_HTTPS2 = ZT_ENDPOINT_PROTO_HTTPS2,
|
||||
PROTO_WS = ZT_ENDPOINT_PROTO_WS,
|
||||
PROTO_WEBRTC = ZT_ENDPOINT_PROTO_WEBRTC,
|
||||
PROTO_WIREGUARD = ZT_ENDPOINT_PROTO_WIREGUARD
|
||||
};
|
||||
|
||||
ZT_INLINE Endpoint() noexcept { memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
|
|
|
@ -99,8 +99,6 @@ private:
|
|||
ZT_Fingerprint m_cfp;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Fingerprint) == sizeof(ZT_Fingerprint),"Fingerprint should be the same size as the underlying C ZT_Fingerprint");
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,10 +26,10 @@ const InetAddress InetAddress::NIL;
|
|||
|
||||
InetAddress::IpScope InetAddress::ipScope() const noexcept
|
||||
{
|
||||
switch(m_sockaddr.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
|
||||
case AF_INET: {
|
||||
const uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
const uint32_t ip = Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr);
|
||||
switch(ip >> 24U) {
|
||||
case 0x00: return IP_SCOPE_NONE; // 0.0.0.0/8 (reserved, never used)
|
||||
case 0x06: return IP_SCOPE_PSEUDOPRIVATE; // 6.0.0.0/8 (US Army)
|
||||
|
@ -68,7 +68,7 @@ InetAddress::IpScope InetAddress::ipScope() const noexcept
|
|||
}
|
||||
|
||||
case AF_INET6: {
|
||||
const unsigned char *ip = reinterpret_cast<const unsigned char *>(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *const ip = as.sa_in6.sin6_addr.s6_addr;
|
||||
if ((ip[0] & 0xf0U) == 0xf0) {
|
||||
if (ip[0] == 0xff) return IP_SCOPE_MULTICAST; // ff00::/8
|
||||
if ((ip[0] == 0xfe)&&((ip[1] & 0xc0U) == 0x80)) {
|
||||
|
@ -97,32 +97,33 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
|
|||
{
|
||||
memoryZero(this);
|
||||
if (ipLen == 4) {
|
||||
uint32_t ipb[1];
|
||||
Utils::copy<4>(ipb,ipBytes);
|
||||
m_sockaddr.ss_family = AF_INET;
|
||||
reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr = ipb[0];
|
||||
reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
|
||||
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);
|
||||
} else if (ipLen == 16) {
|
||||
m_sockaddr.ss_family = AF_INET6;
|
||||
Utils::copy<16>(reinterpret_cast<sockaddr_in6 *>(this)->sin6_addr.s6_addr,ipBytes);
|
||||
reinterpret_cast<sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port);
|
||||
as.sa_in6.sin6_family = AF_INET6;
|
||||
as.sa_in6.sin6_port = Utils::hton((uint16_t)port);
|
||||
Utils::copy<16>(as.sa_in6.sin6_addr.s6_addr,ipBytes);
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddress::isDefaultRoute() const noexcept
|
||||
{
|
||||
switch(m_sockaddr.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
return ( (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == 0) && (reinterpret_cast<const sockaddr_in *>(this)->sin_port == 0) );
|
||||
return ((as.sa_in.sin_port == 0)&&(as.sa_in.sin_addr.s_addr == 0));
|
||||
case AF_INET6:
|
||||
const uint8_t *ipb = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
for(int i=0;i<16;++i) {
|
||||
if (ipb[i])
|
||||
return false;
|
||||
if (as.sa_in6.sin6_port == 0) {
|
||||
for (unsigned int i=0;i<16;++i) {
|
||||
if (as.sa_in6.sin6_addr.s6_addr[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return (reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port == 0);
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
char *InetAddress::toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
|
||||
|
@ -139,22 +140,9 @@ char *InetAddress::toString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noex
|
|||
char *InetAddress::toIpString(char buf[ZT_INETADDRESS_STRING_SIZE_MAX]) const noexcept
|
||||
{
|
||||
buf[0] = (char)0;
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET: {
|
||||
#ifdef _WIN32
|
||||
inet_ntop(AF_INET, (void*)&reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN);
|
||||
#else
|
||||
inet_ntop(AF_INET, &reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr, buf, INET_ADDRSTRLEN);
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case AF_INET6: {
|
||||
#ifdef _WIN32
|
||||
inet_ntop(AF_INET6, (void*)reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN);
|
||||
#else
|
||||
inet_ntop(AF_INET6, reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr, buf, INET6_ADDRSTRLEN);
|
||||
#endif
|
||||
} break;
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: inet_ntop(AF_INET,&as.sa_in.sin_addr.s_addr,buf,INET_ADDRSTRLEN); break;
|
||||
case AF_INET6: inet_ntop(AF_INET6,as.sa_in6.sin6_addr.s6_addr,buf,INET6_ADDRSTRLEN); break;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
@ -180,16 +168,14 @@ bool InetAddress::fromString(const char *ipSlashPort) noexcept
|
|||
}
|
||||
|
||||
if (strchr(buf,':')) {
|
||||
sockaddr_in6 *const in6 = reinterpret_cast<sockaddr_in6 *>(this); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
inet_pton(AF_INET6, buf, &in6->sin6_addr.s6_addr);
|
||||
in6->sin6_family = AF_INET6;
|
||||
in6->sin6_port = Utils::hton((uint16_t)port);
|
||||
as.sa_in6.sin6_family = AF_INET6;
|
||||
as.sa_in6.sin6_port = Utils::hton((uint16_t)port);
|
||||
inet_pton(AF_INET6,buf,as.sa_in6.sin6_addr.s6_addr);
|
||||
return true;
|
||||
} else if (strchr(buf,'.')) {
|
||||
sockaddr_in *const in = reinterpret_cast<sockaddr_in *>(this); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
inet_pton(AF_INET, buf, &in->sin_addr.s_addr);
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_port = Utils::hton((uint16_t)port);
|
||||
as.sa_in.sin_family = AF_INET;
|
||||
as.sa_in.sin_port = Utils::hton((uint16_t)port);
|
||||
inet_pton(AF_INET,buf,&as.sa_in.sin_addr.s_addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -199,9 +185,9 @@ bool InetAddress::fromString(const char *ipSlashPort) noexcept
|
|||
InetAddress InetAddress::netmask() const noexcept
|
||||
{
|
||||
InetAddress r(*this);
|
||||
switch(r.m_sockaddr.ss_family) {
|
||||
switch(r.as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
|
||||
r.as.sa_in.sin_addr.s_addr = Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
|
||||
break;
|
||||
case AF_INET6: {
|
||||
uint64_t nm[2];
|
||||
|
@ -213,7 +199,7 @@ InetAddress InetAddress::netmask() const noexcept
|
|||
nm[0] = 0;
|
||||
nm[1] = 0;
|
||||
}
|
||||
Utils::copy<16>(reinterpret_cast<sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm);
|
||||
Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr,nm);
|
||||
} break;
|
||||
}
|
||||
return r;
|
||||
|
@ -221,7 +207,7 @@ InetAddress InetAddress::netmask() const noexcept
|
|||
|
||||
InetAddress InetAddress::broadcast() const noexcept
|
||||
{
|
||||
if (m_sockaddr.ss_family == AF_INET) {
|
||||
if (as.ss.ss_family == AF_INET) {
|
||||
InetAddress r(*this);
|
||||
reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr |= Utils::hton((uint32_t)(0xffffffffU >> netmaskBits()));
|
||||
return r;
|
||||
|
@ -232,9 +218,9 @@ InetAddress InetAddress::broadcast() const noexcept
|
|||
InetAddress InetAddress::network() const noexcept
|
||||
{
|
||||
InetAddress r(*this);
|
||||
switch(r.m_sockaddr.ss_family) {
|
||||
switch(r.as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
|
||||
r.as.sa_in.sin_addr.s_addr &= Utils::hton((uint32_t)(0xffffffffU << (32 - netmaskBits())));
|
||||
break;
|
||||
case AF_INET6: {
|
||||
uint64_t nm[2];
|
||||
|
@ -242,7 +228,7 @@ InetAddress InetAddress::network() const noexcept
|
|||
Utils::copy<16>(nm,reinterpret_cast<sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
|
||||
nm[0] &= Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
|
||||
nm[1] &= Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
|
||||
Utils::copy<16>(reinterpret_cast<sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm);
|
||||
Utils::copy<16>(r.as.sa_in6.sin6_addr.s6_addr,nm);
|
||||
} break;
|
||||
}
|
||||
return r;
|
||||
|
@ -250,15 +236,15 @@ InetAddress InetAddress::network() const noexcept
|
|||
|
||||
bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
|
||||
{
|
||||
if (addr.m_sockaddr.ss_family == m_sockaddr.ss_family) {
|
||||
switch(m_sockaddr.ss_family) {
|
||||
if (addr.as.ss.ss_family == as.ss.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET6: {
|
||||
const InetAddress mask(netmask());
|
||||
InetAddress addr_mask(addr.netmask());
|
||||
const uint8_t *n = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(&addr_mask)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *m = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(&mask)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *a = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(&addr)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *b = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *const n = addr_mask.as.sa_in6.sin6_addr.s6_addr;
|
||||
const uint8_t *const m = mask.as.sa_in6.sin6_addr.s6_addr;
|
||||
const uint8_t *const a = addr.as.sa_in6.sin6_addr.s6_addr;
|
||||
const uint8_t *const b = as.sa_in6.sin6_addr.s6_addr;
|
||||
for(unsigned int i=0;i<16;++i) {
|
||||
if ((a[i] & m[i]) != (b[i] & n[i]))
|
||||
return false;
|
||||
|
@ -272,22 +258,22 @@ bool InetAddress::isEqualPrefix(const InetAddress &addr) const noexcept
|
|||
|
||||
bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
|
||||
{
|
||||
if (addr.m_sockaddr.ss_family == m_sockaddr.ss_family) {
|
||||
switch(m_sockaddr.ss_family) {
|
||||
if (addr.as.ss.ss_family == as.ss.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: {
|
||||
const unsigned int bits = netmaskBits();
|
||||
if (bits == 0)
|
||||
return true;
|
||||
return (
|
||||
(Utils::ntoh((uint32_t)reinterpret_cast<const sockaddr_in *>(&addr)->sin_addr.s_addr) >> (32 - bits)) ==
|
||||
(Utils::ntoh((uint32_t)reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr) >> (32 - bits))
|
||||
(Utils::ntoh((uint32_t)addr.as.sa_in.sin_addr.s_addr) >> (32 - bits)) ==
|
||||
(Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr) >> (32 - bits))
|
||||
);
|
||||
}
|
||||
case AF_INET6: {
|
||||
const InetAddress mask(netmask());
|
||||
const uint8_t *m = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(&mask)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *a = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(&addr)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *b = reinterpret_cast<const uint8_t *>(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *const m = mask.as.sa_in6.sin6_addr.s6_addr;
|
||||
const uint8_t *const a = addr.as.sa_in6.sin6_addr.s6_addr;
|
||||
const uint8_t *const b = as.sa_in6.sin6_addr.s6_addr;
|
||||
for(unsigned int i=0;i<16;++i) {
|
||||
if ((a[i] & m[i]) != b[i])
|
||||
return false;
|
||||
|
@ -299,42 +285,16 @@ bool InetAddress::containsAddress(const InetAddress &addr) const noexcept
|
|||
return false;
|
||||
}
|
||||
|
||||
void InetAddress::forTrace(ZT_TraceEventPathAddress &ta) const noexcept
|
||||
{
|
||||
uint32_t tmp;
|
||||
switch(m_sockaddr.ss_family) {
|
||||
default:
|
||||
Utils::zero<sizeof(ZT_TraceEventPathAddress)>(&ta);
|
||||
break;
|
||||
case AF_INET:
|
||||
ta.type = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V4;
|
||||
tmp = (uint32_t)(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
ta.address[0] = reinterpret_cast<const uint8_t *>(&tmp)[0];
|
||||
ta.address[1] = reinterpret_cast<const uint8_t *>(&tmp)[1];
|
||||
ta.address[2] = reinterpret_cast<const uint8_t *>(&tmp)[2];
|
||||
ta.address[3] = reinterpret_cast<const uint8_t *>(&tmp)[3];
|
||||
Utils::zero<sizeof(ta.address) - 4>(ta.address + 4);
|
||||
ta.port = reinterpret_cast<const sockaddr_in *>(this)->sin_port;
|
||||
break;
|
||||
case AF_INET6:
|
||||
ta.type = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V6;
|
||||
Utils::copy<16>(ta.address,reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr);
|
||||
Utils::zero<sizeof(ta.address) - 16>(ta.address + 16);
|
||||
ta.port = reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddress::isNetwork() const noexcept
|
||||
{
|
||||
switch(m_sockaddr.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: {
|
||||
unsigned int bits = netmaskBits();
|
||||
if (bits <= 0)
|
||||
return false;
|
||||
if (bits >= 32)
|
||||
return false;
|
||||
uint32_t ip = Utils::ntoh((uint32_t)reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
const uint32_t ip = Utils::ntoh((uint32_t)as.sa_in.sin_addr.s_addr);
|
||||
return ((ip & (0xffffffffU >> bits)) == 0);
|
||||
}
|
||||
case AF_INET6: {
|
||||
|
@ -343,7 +303,7 @@ bool InetAddress::isNetwork() const noexcept
|
|||
return false;
|
||||
if (bits >= 128)
|
||||
return false;
|
||||
const unsigned char *ip = reinterpret_cast<const unsigned char *>(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
const uint8_t *const ip = as.sa_in6.sin6_addr.s6_addr;
|
||||
unsigned int p = bits / 8;
|
||||
if ((ip[p++] & (0xffU >> (bits % 8))) != 0)
|
||||
return false;
|
||||
|
@ -360,22 +320,21 @@ bool InetAddress::isNetwork() const noexcept
|
|||
int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept
|
||||
{
|
||||
unsigned int port;
|
||||
switch(m_sockaddr.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
port = Utils::ntoh((uint16_t)reinterpret_cast<const sockaddr_in *>(this)->sin_port);
|
||||
data[0] = 4;
|
||||
data[1] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[0];
|
||||
data[2] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[1];
|
||||
data[3] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[2];
|
||||
data[4] = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr))[3];
|
||||
data[1] = reinterpret_cast<const uint8_t *>(&as.sa_in.sin_addr.s_addr)[0];
|
||||
data[2] = reinterpret_cast<const uint8_t *>(&as.sa_in.sin_addr.s_addr)[1];
|
||||
data[3] = reinterpret_cast<const uint8_t *>(&as.sa_in.sin_addr.s_addr)[2];
|
||||
data[4] = reinterpret_cast<const uint8_t *>(&as.sa_in.sin_addr.s_addr)[3];
|
||||
data[5] = (uint8_t)(port >> 8U);
|
||||
data[6] = (uint8_t)port;
|
||||
return 7;
|
||||
case AF_INET6:
|
||||
port = Utils::ntoh((uint16_t)reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port);
|
||||
port = Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
|
||||
data[0] = 6;
|
||||
for(int i=0;i<16;++i)
|
||||
data[i+1] = reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr[i];
|
||||
Utils::copy<16>(data + 1,as.sa_in6.sin6_addr.s6_addr);
|
||||
data[17] = (uint8_t)(port >> 8U);
|
||||
data[18] = (uint8_t)port;
|
||||
return 19;
|
||||
|
@ -389,141 +348,74 @@ int InetAddress::unmarshal(const uint8_t *restrict data,const int len) noexcept
|
|||
{
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
memoryZero(this);
|
||||
switch(data[0]) {
|
||||
case 0:
|
||||
return 1;
|
||||
case 4:
|
||||
if (len < 7)
|
||||
return -1;
|
||||
memoryZero(this);
|
||||
reinterpret_cast<sockaddr_in *>(this)->sin_family = AF_INET;
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[0] = data[1];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[1] = data[2];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[2] = data[3];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_addr.s_addr))[3] = data[4];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_port))[sizeof(reinterpret_cast<sockaddr_in *>(this)->sin_port)-2] = data[5];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in *>(this)->sin_port))[sizeof(reinterpret_cast<sockaddr_in *>(this)->sin_port)-1] = data[6];
|
||||
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);
|
||||
return 7;
|
||||
case 6:
|
||||
if (len < 19)
|
||||
return -1;
|
||||
memoryZero(this);
|
||||
reinterpret_cast<sockaddr_in6 *>(this)->sin6_family = AF_INET6;
|
||||
for(int i=0;i<16;i++)
|
||||
(reinterpret_cast<sockaddr_in6 *>(this)->sin6_addr.s6_addr)[i] = data[i+1];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in6 *>(this)->sin6_port))[sizeof(reinterpret_cast<sockaddr_in6 *>(this)->sin6_port)-2] = data[17];
|
||||
reinterpret_cast<uint8_t *>(&(reinterpret_cast<sockaddr_in6 *>(this)->sin6_port))[sizeof(reinterpret_cast<sockaddr_in6 *>(this)->sin6_port)-1] = data[18];
|
||||
as.sa_in6.sin6_family = AF_INET6;
|
||||
as.sa_in6.sin6_port = Utils::loadAsIsEndian<uint16_t>(data + 17);
|
||||
Utils::copy<16>(as.sa_in6.sin6_addr.s6_addr,data + 1);
|
||||
return 19;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool InetAddress::operator==(const InetAddress &a) const noexcept
|
||||
{
|
||||
if (m_sockaddr.ss_family == a.m_sockaddr.ss_family) {
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET:
|
||||
return (
|
||||
(reinterpret_cast<const sockaddr_in *>(this)->sin_port == reinterpret_cast<const sockaddr_in *>(&a)->sin_port)&&
|
||||
(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr));
|
||||
case AF_INET6:
|
||||
return (
|
||||
(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port == reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_port)&&
|
||||
(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_flowinfo == reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_flowinfo)&&
|
||||
(memcmp(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0)&&
|
||||
(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_scope_id == reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_scope_id));
|
||||
default:
|
||||
return (memcmp(this,&a,sizeof(InetAddress)) == 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InetAddress::operator<(const InetAddress &a) const noexcept
|
||||
{
|
||||
if (m_sockaddr.ss_family < a.m_sockaddr.ss_family)
|
||||
return true;
|
||||
else if (m_sockaddr.ss_family == a.m_sockaddr.ss_family) {
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET:
|
||||
if (reinterpret_cast<const sockaddr_in *>(this)->sin_port < reinterpret_cast<const sockaddr_in *>(&a)->sin_port)
|
||||
return true;
|
||||
else if (reinterpret_cast<const sockaddr_in *>(this)->sin_port == reinterpret_cast<const sockaddr_in *>(&a)->sin_port) {
|
||||
if (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr < reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port < reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_port)
|
||||
return true;
|
||||
else if (reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port == reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_port) {
|
||||
if (reinterpret_cast<const sockaddr_in6 *>(this)->sin6_flowinfo < reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_flowinfo)
|
||||
return true;
|
||||
else if (reinterpret_cast<const sockaddr_in6 *>(this)->sin6_flowinfo == reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_flowinfo) {
|
||||
if (memcmp(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) < 0)
|
||||
return true;
|
||||
else if (memcmp(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0) {
|
||||
if (reinterpret_cast<const sockaddr_in6 *>(this)->sin6_scope_id < reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_scope_id)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (memcmp(this,&a,sizeof(InetAddress)) < 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) noexcept
|
||||
{
|
||||
InetAddress r;
|
||||
sockaddr_in6 *const sin6 = reinterpret_cast<sockaddr_in6 *>(&r); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_addr.s6_addr[0] = 0xfe;
|
||||
sin6->sin6_addr.s6_addr[1] = 0x80;
|
||||
sin6->sin6_addr.s6_addr[2] = 0x00;
|
||||
sin6->sin6_addr.s6_addr[3] = 0x00;
|
||||
sin6->sin6_addr.s6_addr[4] = 0x00;
|
||||
sin6->sin6_addr.s6_addr[5] = 0x00;
|
||||
sin6->sin6_addr.s6_addr[6] = 0x00;
|
||||
sin6->sin6_addr.s6_addr[7] = 0x00;
|
||||
sin6->sin6_addr.s6_addr[8] = mac[0] & 0xfdU;
|
||||
sin6->sin6_addr.s6_addr[9] = mac[1];
|
||||
sin6->sin6_addr.s6_addr[10] = mac[2];
|
||||
sin6->sin6_addr.s6_addr[11] = 0xff;
|
||||
sin6->sin6_addr.s6_addr[12] = 0xfe;
|
||||
sin6->sin6_addr.s6_addr[13] = mac[3];
|
||||
sin6->sin6_addr.s6_addr[14] = mac[4];
|
||||
sin6->sin6_addr.s6_addr[15] = mac[5];
|
||||
sin6->sin6_port = Utils::hton((uint16_t)64);
|
||||
r.as.sa_in6.sin6_family = AF_INET6;
|
||||
r.as.sa_in6.sin6_port = ZT_CONST_TO_BE_UINT16(64);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[0] = 0xfe;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[1] = 0x80;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[2] = 0x00;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[3] = 0x00;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[4] = 0x00;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[5] = 0x00;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[6] = 0x00;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[7] = 0x00;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[8] = mac[0] & 0xfdU;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[9] = mac[1];
|
||||
r.as.sa_in6.sin6_addr.s6_addr[10] = mac[2];
|
||||
r.as.sa_in6.sin6_addr.s6_addr[11] = 0xff;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[12] = 0xfe;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[13] = mac[3];
|
||||
r.as.sa_in6.sin6_addr.s6_addr[14] = mac[4];
|
||||
r.as.sa_in6.sin6_addr.s6_addr[15] = mac[5];
|
||||
return r;
|
||||
}
|
||||
|
||||
InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) noexcept
|
||||
{
|
||||
InetAddress r;
|
||||
sockaddr_in6 *const sin6 = reinterpret_cast<sockaddr_in6 *>(&r); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_addr.s6_addr[0] = 0xfd;
|
||||
sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 56U);
|
||||
sin6->sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 48U);
|
||||
sin6->sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 40U);
|
||||
sin6->sin6_addr.s6_addr[4] = (uint8_t)(nwid >> 32U);
|
||||
sin6->sin6_addr.s6_addr[5] = (uint8_t)(nwid >> 24U);
|
||||
sin6->sin6_addr.s6_addr[6] = (uint8_t)(nwid >> 16U);
|
||||
sin6->sin6_addr.s6_addr[7] = (uint8_t)(nwid >> 8U);
|
||||
sin6->sin6_addr.s6_addr[8] = (uint8_t)nwid;
|
||||
sin6->sin6_addr.s6_addr[9] = 0x99;
|
||||
sin6->sin6_addr.s6_addr[10] = 0x93;
|
||||
sin6->sin6_addr.s6_addr[11] = (uint8_t)(zeroTierAddress >> 32U);
|
||||
sin6->sin6_addr.s6_addr[12] = (uint8_t)(zeroTierAddress >> 24U);
|
||||
sin6->sin6_addr.s6_addr[13] = (uint8_t)(zeroTierAddress >> 16U);
|
||||
sin6->sin6_addr.s6_addr[14] = (uint8_t)(zeroTierAddress >> 8U);
|
||||
sin6->sin6_addr.s6_addr[15] = (uint8_t)zeroTierAddress;
|
||||
sin6->sin6_port = Utils::hton((uint16_t)88); // /88 includes 0xfd + network ID, discriminating by device ID below that
|
||||
r.as.sa_in6.sin6_family = AF_INET6;
|
||||
r.as.sa_in6.sin6_port = ZT_CONST_TO_BE_UINT16(88); // /88 includes 0xfd + network ID, discriminating by device ID below that
|
||||
r.as.sa_in6.sin6_addr.s6_addr[0] = 0xfd;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 56U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 48U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 40U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[4] = (uint8_t)(nwid >> 32U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[5] = (uint8_t)(nwid >> 24U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[6] = (uint8_t)(nwid >> 16U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[7] = (uint8_t)(nwid >> 8U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[8] = (uint8_t)nwid;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[9] = 0x99;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[10] = 0x93;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[11] = (uint8_t)(zeroTierAddress >> 32U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[12] = (uint8_t)(zeroTierAddress >> 24U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[13] = (uint8_t)(zeroTierAddress >> 16U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[14] = (uint8_t)(zeroTierAddress >> 8U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[15] = (uint8_t)zeroTierAddress;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -531,20 +423,19 @@ InetAddress InetAddress::makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress)
|
|||
{
|
||||
nwid ^= (nwid >> 32U);
|
||||
InetAddress r;
|
||||
sockaddr_in6 *const sin6 = reinterpret_cast<sockaddr_in6 *>(&r); // NOLINT(hicpp-use-auto,modernize-use-auto)
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_addr.s6_addr[0] = 0xfc;
|
||||
sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 24U);
|
||||
sin6->sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 16U);
|
||||
sin6->sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 8U);
|
||||
sin6->sin6_addr.s6_addr[4] = (uint8_t)nwid;
|
||||
sin6->sin6_addr.s6_addr[5] = (uint8_t)(zeroTierAddress >> 32U);
|
||||
sin6->sin6_addr.s6_addr[6] = (uint8_t)(zeroTierAddress >> 24U);
|
||||
sin6->sin6_addr.s6_addr[7] = (uint8_t)(zeroTierAddress >> 16U);
|
||||
sin6->sin6_addr.s6_addr[8] = (uint8_t)(zeroTierAddress >> 8U);
|
||||
sin6->sin6_addr.s6_addr[9] = (uint8_t)zeroTierAddress;
|
||||
sin6->sin6_addr.s6_addr[15] = 0x01;
|
||||
sin6->sin6_port = Utils::hton((uint16_t)40);
|
||||
r.as.sa_in6.sin6_family = AF_INET6;
|
||||
r.as.sa_in6.sin6_port = ZT_CONST_TO_BE_UINT16(40);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[0] = 0xfc;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 24U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 16U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 8U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[4] = (uint8_t)nwid;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[5] = (uint8_t)(zeroTierAddress >> 32U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[6] = (uint8_t)(zeroTierAddress >> 24U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[7] = (uint8_t)(zeroTierAddress >> 16U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[8] = (uint8_t)(zeroTierAddress >> 8U);
|
||||
r.as.sa_in6.sin6_addr.s6_addr[9] = (uint8_t)zeroTierAddress;
|
||||
r.as.sa_in6.sin6_addr.s6_addr[15] = 0x01;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,16 +35,6 @@ namespace ZeroTier {
|
|||
*/
|
||||
struct InetAddress : public TriviallyCopyable
|
||||
{
|
||||
private:
|
||||
// Internal function to copy any sockaddr_X structure to this one even if it's smaller and unpadded.
|
||||
template<typename SA>
|
||||
ZT_INLINE void copySockaddrToThis(const SA *sa) noexcept
|
||||
{
|
||||
Utils::copy<sizeof(SA)>(reinterpret_cast<void *>(this),sa);
|
||||
if (sizeof(SA) < sizeof(InetAddress))
|
||||
Utils::zero<sizeof(InetAddress) - sizeof(SA)>(reinterpret_cast<uint8_t *>(this) + sizeof(SA));
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Loopback IPv4 address (no port)
|
||||
|
@ -83,67 +73,62 @@ public:
|
|||
// Hasher for unordered sets and maps in C++11
|
||||
struct Hasher { ZT_INLINE std::size_t operator()(const InetAddress &a) const noexcept { return (std::size_t)a.hashCode(); } };
|
||||
|
||||
ZT_INLINE InetAddress() noexcept { memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
ZT_INLINE InetAddress(const InetAddress &a) noexcept { memoryCopy(this,&a); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_storage &ss) noexcept { *this = ss; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_storage *ss) noexcept { *this = ss; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr &sa) noexcept { *this = sa; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr *sa) noexcept { *this = sa; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in &sa) noexcept { *this = sa; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in *sa) noexcept { *this = sa; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in6 &sa) noexcept { *this = sa; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in6 *sa) noexcept { *this = sa; } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
ZT_INLINE InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) noexcept { this->set(ipBytes,ipLen,port); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
ZT_INLINE InetAddress(const uint32_t ipv4,unsigned int port) noexcept { this->set(&ipv4,4,port); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
explicit ZT_INLINE InetAddress(const char *ipSlashPort) noexcept { this->fromString(ipSlashPort); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
ZT_INLINE InetAddress() noexcept { memoryZero(this); }
|
||||
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_storage &ss) noexcept { *this = ss; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_storage *const ss) noexcept { *this = ss; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr &sa) noexcept { *this = sa; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr *const sa) noexcept { *this = sa; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in &sa) noexcept { *this = sa; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in *const sa) noexcept { *this = sa; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in6 &sa) noexcept { *this = sa; }
|
||||
explicit ZT_INLINE InetAddress(const sockaddr_in6 *const sa) noexcept { *this = sa; }
|
||||
|
||||
ZT_INLINE InetAddress(const void *const ipBytes,const unsigned int ipLen,const unsigned int port) noexcept { this->set(ipBytes,ipLen,port); }
|
||||
ZT_INLINE InetAddress(const uint32_t ipv4,const unsigned int port) noexcept { this->set(&ipv4,4,port); }
|
||||
explicit ZT_INLINE InetAddress(const char *const ipSlashPort) noexcept { this->fromString(ipSlashPort); }
|
||||
|
||||
ZT_INLINE InetAddress &operator=(const InetAddress &a) noexcept
|
||||
{
|
||||
memoryCopy(this,a);
|
||||
return *this;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_storage &ss) noexcept
|
||||
{
|
||||
memoryCopyUnsafe(this,&ss);
|
||||
return *this;
|
||||
as.ss = ss;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_storage *ss) noexcept
|
||||
{
|
||||
if (ss)
|
||||
memoryCopyUnsafe(this,ss);
|
||||
as.ss = *ss;
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in &sa) noexcept
|
||||
{
|
||||
copySockaddrToThis(&sa);
|
||||
as.sa_in = sa;
|
||||
return *this;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in *sa) noexcept
|
||||
{
|
||||
if (sa)
|
||||
copySockaddrToThis(sa);
|
||||
as.sa_in = *sa;
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in6 &sa) noexcept
|
||||
{
|
||||
copySockaddrToThis(&sa);
|
||||
as.sa_in6 = sa;
|
||||
return *this;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr_in6 *sa) noexcept
|
||||
{
|
||||
if (sa)
|
||||
copySockaddrToThis(sa);
|
||||
as.sa_in6 = *sa;
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
ZT_INLINE InetAddress &operator=(const sockaddr &sa) noexcept
|
||||
{
|
||||
if (sa.sa_family == AF_INET)
|
||||
copySockaddrToThis(reinterpret_cast<const sockaddr_in *>(&sa));
|
||||
as.sa_in = *reinterpret_cast<const sockaddr_in *>(&sa);
|
||||
else if (sa.sa_family == AF_INET6)
|
||||
copySockaddrToThis(reinterpret_cast<const sockaddr_in6 *>(&sa));
|
||||
as.sa_in6 = *reinterpret_cast<const sockaddr_in6 *>(&sa);
|
||||
else memoryZero(this);
|
||||
return *this;
|
||||
}
|
||||
|
@ -151,9 +136,9 @@ public:
|
|||
{
|
||||
if (sa) {
|
||||
if (sa->sa_family == AF_INET)
|
||||
copySockaddrToThis(reinterpret_cast<const sockaddr_in *>(sa));
|
||||
as.sa_in = *reinterpret_cast<const sockaddr_in *>(sa);
|
||||
else if (sa->sa_family == AF_INET6)
|
||||
copySockaddrToThis(reinterpret_cast<const sockaddr_in6 *>(sa));
|
||||
as.sa_in6 = *reinterpret_cast<const sockaddr_in6 *>(sa);
|
||||
else memoryZero(this);
|
||||
} else {
|
||||
memoryZero(this);
|
||||
|
@ -166,7 +151,7 @@ public:
|
|||
/**
|
||||
* @return Address family (ss_family in sockaddr_storage)
|
||||
*/
|
||||
ZT_INLINE uint8_t family() const noexcept { return m_sockaddr.ss_family; }
|
||||
ZT_INLINE uint8_t family() const noexcept { return as.ss.ss_family; }
|
||||
|
||||
/**
|
||||
* @return IP scope classification (e.g. loopback, link-local, private, global)
|
||||
|
@ -189,13 +174,9 @@ public:
|
|||
*/
|
||||
ZT_INLINE void setPort(unsigned int port) noexcept
|
||||
{
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET:
|
||||
reinterpret_cast<sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
reinterpret_cast<sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port);
|
||||
break;
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: as.sa_in.sin_port = Utils::hton((uint16_t)port); break;
|
||||
case AF_INET6: as.sa_in6.sin6_port = Utils::hton((uint16_t)port); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,9 +208,9 @@ public:
|
|||
*/
|
||||
ZT_INLINE unsigned int port() const noexcept
|
||||
{
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET: return Utils::ntoh((uint16_t)(reinterpret_cast<const sockaddr_in *>(this)->sin_port));
|
||||
case AF_INET6: return Utils::ntoh((uint16_t)(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_port));
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: return Utils::ntoh((uint16_t)as.sa_in.sin_port);
|
||||
case AF_INET6: return Utils::ntoh((uint16_t)as.sa_in6.sin6_port);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
@ -251,8 +232,8 @@ public:
|
|||
ZT_INLINE bool netmaskBitsValid() const noexcept
|
||||
{
|
||||
const unsigned int n = port();
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET: return (n <= 32);
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: return (n <= 32);
|
||||
case AF_INET6: return (n <= 128);
|
||||
}
|
||||
return false;
|
||||
|
@ -311,21 +292,21 @@ public:
|
|||
/**
|
||||
* @return True if this is an IPv4 address
|
||||
*/
|
||||
ZT_INLINE bool isV4() const noexcept { return (family() == AF_INET); }
|
||||
ZT_INLINE bool isV4() const noexcept { return (as.ss.ss_family == AF_INET); }
|
||||
|
||||
/**
|
||||
* @return True if this is an IPv6 address
|
||||
*/
|
||||
ZT_INLINE bool isV6() const noexcept { return (family() == AF_INET6); }
|
||||
ZT_INLINE bool isV6() const noexcept { return (as.ss.ss_family == AF_INET6); }
|
||||
|
||||
/**
|
||||
* @return pointer to raw address bytes or NULL if not available
|
||||
*/
|
||||
ZT_INLINE const void *rawIpData() const noexcept
|
||||
{
|
||||
switch(m_sockaddr.ss_family) {
|
||||
case AF_INET: return (const void *)&(reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr);
|
||||
case AF_INET6: return (const void *)(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr);
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET: return reinterpret_cast<const void *>(&(as.sa_in.sin_addr.s_addr));
|
||||
case AF_INET6: return reinterpret_cast<const void *>(as.sa_in6.sin6_addr.s6_addr);
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -336,14 +317,14 @@ public:
|
|||
ZT_INLINE InetAddress ipOnly() const noexcept
|
||||
{
|
||||
InetAddress r;
|
||||
switch(m_sockaddr.ss_family) {
|
||||
switch(as.ss.ss_family) {
|
||||
case AF_INET:
|
||||
reinterpret_cast<sockaddr_in *>(&r)->sin_family = AF_INET;
|
||||
reinterpret_cast<sockaddr_in *>(&r)->sin_addr.s_addr = reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr;
|
||||
r.as.sa_in.sin_family = AF_INET;
|
||||
r.as.sa_in.sin_addr.s_addr = as.sa_in.sin_addr.s_addr;
|
||||
break;
|
||||
case AF_INET6:
|
||||
reinterpret_cast<sockaddr_in6 *>(&r)->sin6_family = AF_INET;
|
||||
Utils::copy<16>(reinterpret_cast<sockaddr_in6 *>(&r)->sin6_addr.s6_addr,reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
|
@ -357,13 +338,13 @@ public:
|
|||
*/
|
||||
ZT_INLINE bool ipsEqual(const InetAddress &a) const noexcept
|
||||
{
|
||||
const uint8_t f = m_sockaddr.ss_family;
|
||||
if (f == a.m_sockaddr.ss_family) {
|
||||
const uint8_t f = as.ss.ss_family;
|
||||
if (f == a.as.ss.ss_family) {
|
||||
if (f == AF_INET)
|
||||
return (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr);
|
||||
return as.sa_in.sin_addr.s_addr == a.as.sa_in.sin_addr.s_addr;
|
||||
if (f == AF_INET6)
|
||||
return (memcmp(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0);
|
||||
return (memcmp(this,&a,sizeof(InetAddress)) == 0);
|
||||
return memcmp(as.sa_in6.sin6_addr.s6_addr,a.as.sa_in6.sin6_addr.s6_addr,16) == 0;
|
||||
return memcmp(this,&a,sizeof(InetAddress)) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -378,12 +359,12 @@ public:
|
|||
*/
|
||||
ZT_INLINE bool ipsEqual2(const InetAddress &a) const noexcept
|
||||
{
|
||||
const uint8_t f = m_sockaddr.ss_family;
|
||||
if (f == a.m_sockaddr.ss_family) {
|
||||
const uint8_t f = as.ss.ss_family;
|
||||
if (f == a.as.ss.ss_family) {
|
||||
if (f == AF_INET)
|
||||
return (reinterpret_cast<const sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const sockaddr_in *>(&a)->sin_addr.s_addr);
|
||||
return as.sa_in.sin_addr.s_addr == a.as.sa_in.sin_addr.s_addr;
|
||||
if (f == AF_INET6)
|
||||
return (memcmp(reinterpret_cast<const sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const sockaddr_in6 *>(&a)->sin6_addr.s6_addr,8) == 0);
|
||||
return memcmp(as.sa_in6.sin6_addr.s6_addr,a.as.sa_in6.sin6_addr.s6_addr,8) == 0;
|
||||
return (memcmp(this,&a,sizeof(InetAddress)) == 0);
|
||||
}
|
||||
return false;
|
||||
|
@ -391,25 +372,18 @@ public:
|
|||
|
||||
ZT_INLINE unsigned long hashCode() const noexcept
|
||||
{
|
||||
if (m_sockaddr.ss_family == AF_INET) {
|
||||
return (unsigned long)Utils::hash32(((uint32_t)reinterpret_cast<const sockaddr_in *>(&m_sockaddr)->sin_addr.s_addr + (uint32_t)reinterpret_cast<const sockaddr_in *>(&m_sockaddr)->sin_port) ^ (uint32_t)Utils::s_mapNonce);
|
||||
} else if (m_sockaddr.ss_family == AF_INET6) {
|
||||
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);
|
||||
} else if (as.ss.ss_family == AF_INET6) {
|
||||
return (unsigned long)Utils::hash64(
|
||||
(Utils::loadAsIsEndian<uint64_t>(reinterpret_cast<const sockaddr_in6 *>(&m_sockaddr)->sin6_addr.s6_addr) +
|
||||
Utils::loadAsIsEndian<uint64_t>(reinterpret_cast<const sockaddr_in6 *>(&m_sockaddr)->sin6_addr.s6_addr + 8) +
|
||||
(uint64_t)reinterpret_cast<const sockaddr_in6 *>(&m_sockaddr)->sin6_port) ^ Utils::s_mapNonce
|
||||
);
|
||||
(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) ^
|
||||
Utils::s_mapNonce);
|
||||
}
|
||||
return Utils::fnv1a32(&m_sockaddr, sizeof(m_sockaddr));
|
||||
return Utils::fnv1a32(this,sizeof(InetAddress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill out a ZT_TraceEventPathAddress from this InetAddress
|
||||
*
|
||||
* @param ta ZT_TraceEventPathAddress to fill
|
||||
*/
|
||||
void forTrace(ZT_TraceEventPathAddress &ta) const noexcept;
|
||||
|
||||
/**
|
||||
* Check whether this is a network/route rather than an IP assignment
|
||||
*
|
||||
|
@ -423,14 +397,44 @@ public:
|
|||
/**
|
||||
* @return True if address family is non-zero
|
||||
*/
|
||||
explicit ZT_INLINE operator bool() const noexcept { return (family() != 0); }
|
||||
explicit ZT_INLINE operator bool() const noexcept { return (as.ss.ss_family != 0); }
|
||||
|
||||
static constexpr int marshalSizeMax() noexcept { return ZT_INETADDRESS_MARSHAL_SIZE_MAX; }
|
||||
int marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const noexcept;
|
||||
int unmarshal(const uint8_t *restrict data,int len) noexcept;
|
||||
|
||||
bool operator==(const InetAddress &a) const noexcept;
|
||||
bool operator<(const InetAddress &a) const noexcept;
|
||||
ZT_INLINE bool operator==(const InetAddress &a) const noexcept
|
||||
{
|
||||
if (as.ss.ss_family == a.as.ss.ss_family) {
|
||||
if (as.ss.ss_family == AF_INET)
|
||||
return ((as.sa_in.sin_port == a.as.sa_in.sin_port)&&(as.sa_in.sin_addr.s_addr == a.as.sa_in.sin_addr.s_addr));
|
||||
if (as.ss.ss_family == AF_INET6)
|
||||
return ((as.sa_in6.sin6_port == a.as.sa_in6.sin6_port)&&(memcmp(as.sa_in6.sin6_addr.s6_addr,a.as.sa_in6.sin6_addr.s6_addr,16) == 0));
|
||||
return memcmp(this,&a,sizeof(InetAddress)) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ZT_INLINE bool operator<(const InetAddress &a) const noexcept
|
||||
{
|
||||
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);
|
||||
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 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);
|
||||
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;
|
||||
}
|
||||
return memcmp(this,&a,sizeof(InetAddress)) < 0;
|
||||
}
|
||||
return as.ss.ss_family < a.as.ss.ss_family;
|
||||
}
|
||||
ZT_INLINE bool operator!=(const InetAddress &a) const noexcept { return !(*this == a); }
|
||||
ZT_INLINE bool operator>(const InetAddress &a) const noexcept { return (a < *this); }
|
||||
ZT_INLINE bool operator<=(const InetAddress &a) const noexcept { return !(a < *this); }
|
||||
|
@ -492,15 +496,17 @@ public:
|
|||
*/
|
||||
static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress) noexcept;
|
||||
|
||||
private:
|
||||
sockaddr_storage m_sockaddr;
|
||||
/**
|
||||
* Union allowing this to be accessed as a sockaddr of any supported type.
|
||||
*/
|
||||
union {
|
||||
sockaddr_storage ss;
|
||||
sockaddr sa;
|
||||
sockaddr_in sa_in;
|
||||
sockaddr_in6 sa_in6;
|
||||
} as;
|
||||
};
|
||||
|
||||
static_assert(sizeof(sockaddr_storage) == sizeof(InetAddress),"InetAddress sizing incorrect");
|
||||
static_assert(sizeof(sockaddr_in) <= sizeof(InetAddress),"InetAddress sizing incorrect");
|
||||
static_assert(sizeof(sockaddr_in6) <= sizeof(InetAddress),"InetAddress sizing incorrect");
|
||||
static_assert(sizeof(sockaddr) <= sizeof(InetAddress),"InetAddress sizing incorrect");
|
||||
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in *const p) noexcept { return reinterpret_cast<InetAddress *>(p); }
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr_in6 *const p) noexcept { return reinterpret_cast<InetAddress *>(p); }
|
||||
static ZT_INLINE InetAddress *asInetAddress(sockaddr *const p) noexcept { return reinterpret_cast<InetAddress *>(p); }
|
||||
|
|
|
@ -145,8 +145,8 @@ private:
|
|||
// These fields belong to Defragmenter but are kept in Path for performance
|
||||
// as it's much faster this way than having Defragmenter maintain another
|
||||
// mapping from paths to inbound message IDs.
|
||||
Set<uint64_t> _inboundFragmentedMessages;
|
||||
Mutex _inboundFragmentedMessages_l;
|
||||
Set<uint64_t> m_inboundFragmentedMessages;
|
||||
Mutex m_inboundFragmentedMessages_l;
|
||||
|
||||
std::atomic<int> __refCount;
|
||||
};
|
||||
|
|
|
@ -186,18 +186,6 @@ static const C25519TestVector C25519_TEST_VECTORS[ZT_NUM_C25519_TEST_VECTORS] =
|
|||
#define ZT_ENDIAN_S "big"
|
||||
#endif
|
||||
|
||||
// This is basically a unit test for compiler packed structure behavior.
|
||||
ZT_PACKED_STRUCT(struct StructPackingTestSample {
|
||||
uint8_t foo;
|
||||
uint16_t bar;
|
||||
uint32_t baz;
|
||||
uint8_t lala;
|
||||
uint64_t woop;
|
||||
uint8_t haha;
|
||||
uint64_t hoho[16];
|
||||
uint8_t lol;
|
||||
});
|
||||
|
||||
// Increments and decrements a counter based on object create/destroy
|
||||
class LifeCycleTracker
|
||||
{
|
||||
|
@ -264,12 +252,14 @@ extern "C" const char *ZTT_general()
|
|||
|
||||
{
|
||||
ZT_T_PRINTF("[general] Checking structure sizes, alignment, and packing... ");
|
||||
static_assert(sizeof(StructPackingTestSample) == 146,"StructPackingTestSample packed incorrectly");
|
||||
StructPackingTestSample packtest; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
if (((uintptr_t)&(packtest.woop) - (uintptr_t)&packtest) != 8)
|
||||
return "structure packing check failed: incorrect index of test field in example packed struct (compiler or environment problem)";
|
||||
if (((uintptr_t)&(packtest.hoho[5]) - (uintptr_t)&packtest) != 57)
|
||||
return "structure packing check failed: incorrect index of test array indexed field in example packed struct (compiler or environment problem)";
|
||||
if ((uintptr_t)&(InetAddress::LO4.as.sa_in) != (uintptr_t)&(InetAddress::LO4.as.sa_in6)) {
|
||||
ZT_T_PRINTF("FAILED (&sa_in != &sa_in6)" ZT_EOL_S);
|
||||
return "&sa_in != &sa_in6";
|
||||
}
|
||||
if ((uintptr_t)&(InetAddress::LO4.as.sa_in6.sin6_family) != (uintptr_t)&(InetAddress::LO4.as.ss.ss_family)) {
|
||||
ZT_T_PRINTF("FAILED (&sa_in6.sin6_family != &ss.ss_family)" ZT_EOL_S);
|
||||
return "&sa_in6.sin6_family != &ss.ss_family";
|
||||
}
|
||||
ZT_T_PRINTF("OK" ZT_EOL_S);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,9 @@ namespace ZeroTier {
|
|||
*
|
||||
* It also includes some static methods to do this conveniently.
|
||||
*/
|
||||
ZT_PACKED_STRUCT(struct TriviallyCopyable
|
||||
struct TriviallyCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Zero a TriviallyCopyable object
|
||||
*
|
||||
|
@ -52,34 +53,6 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
|
|||
Utils::zero<sizeof(T)>(&obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy any memory over a TriviallyCopyable object
|
||||
*
|
||||
* @tparam T Automatically inferred type of destination
|
||||
* @param dest Any TriviallyCopyable object
|
||||
* @param src Source memory of same size or less than sizeof(dest)
|
||||
*/
|
||||
template<typename T>
|
||||
static ZT_INLINE void memoryCopyUnsafe(T *dest,const void *src) noexcept
|
||||
{
|
||||
static_assert(isTriviallyCopyable(dest),"parameter is not TriviallyCopyable");
|
||||
Utils::copy<sizeof(T)>(dest,src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy any memory over a TriviallyCopyable object
|
||||
*
|
||||
* @tparam T Automatically inferred type of destination
|
||||
* @param dest Any TriviallyCopyable object
|
||||
* @param src Source memory of same size or less than sizeof(dest)
|
||||
*/
|
||||
template<typename T>
|
||||
static ZT_INLINE void memoryCopyUnsafe(T &dest,const void *src) noexcept
|
||||
{
|
||||
static_assert(isTriviallyCopyable(dest),"parameter is not TriviallyCopyable");
|
||||
Utils::copy<sizeof(T)>(&dest,src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a TriviallyCopyable object
|
||||
*
|
||||
|
@ -135,7 +108,7 @@ ZT_PACKED_STRUCT(struct TriviallyCopyable
|
|||
static_assert(isTriviallyCopyable(dest),"parameter is not TriviallyCopyable");
|
||||
Utils::copy<sizeof(T)>(&dest,&src);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
static constexpr bool isTriviallyCopyable(const TriviallyCopyable *) noexcept { return true; }
|
||||
static constexpr bool isTriviallyCopyable(const void *) noexcept { return false; }
|
||||
|
|
Loading…
Add table
Reference in a new issue