/* * Copyright (c)2013-2020 ZeroTier, Inc. * * Use of this software is governed by the Business Source License included * in the LICENSE.TXT file in the project's root directory. * * Change Date: 2024-01-01 * * On the date above, in accordance with the Business Source License, use * of this software will be governed by version 2.0 of the Apache License. */ /****/ #ifndef ZT_ENDPOINT_HPP #define ZT_ENDPOINT_HPP #include "Constants.hpp" #include "InetAddress.hpp" #include "Address.hpp" #include "Utils.hpp" #include "TriviallyCopyable.hpp" #include "Fingerprint.hpp" #include #include #include #include #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. */ class Endpoint : public TriviallyCopyable { public: /** * Endpoint type * * These are set to be the same as the IDs used for trace events in ZeroTierCore.h. */ 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 }; /** * 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 }; ZT_INLINE Endpoint() noexcept { memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init) explicit Endpoint(const InetAddress &sa,Protocol proto = PROTO_DGRAM) noexcept; /** * @return True if this is an IPv4 or IPv6 IP address */ ZT_INLINE bool isInetAddr() const noexcept { return ((_t == TYPE_INETADDR_V4)||(_t == TYPE_INETADDR_V6)); } /** * @return InetAddress or NIL if not of this type */ ZT_INLINE const InetAddress &inetAddr() const noexcept { return ((_t == TYPE_INETADDR_V4) || (_t == TYPE_INETADDR_V6)) ? asInetAddress(_v.sa) : InetAddress::NIL; } /** * @return Protocol bit mask */ ZT_INLINE Protocol protocol() const noexcept { return _proto; } /** * @return 384-bit hash of identity keys or NULL if not of this type */ ZT_INLINE const Fingerprint &fingerprint() const noexcept { return *reinterpret_cast(&_v.zt); } /** * @return Ethernet address or NIL if not of this type */ ZT_INLINE MAC ethernet() const noexcept { return (_t == TYPE_ETHERNET) ? MAC(_v.eth) : MAC(); } /** * @return Endpoint type or NIL if unset/empty */ ZT_INLINE Type type() const noexcept { return _t; } ZT_INLINE operator bool() const noexcept { return _t != TYPE_NIL; } // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) bool operator==(const Endpoint &ep) const noexcept; ZT_INLINE bool operator!=(const Endpoint &ep) const noexcept { return (!(*this == ep)); } bool operator<(const Endpoint &ep) const noexcept; ZT_INLINE bool operator>(const Endpoint &ep) const noexcept { return (ep < *this); } ZT_INLINE bool operator<=(const Endpoint &ep) const noexcept { return !(ep < *this); } ZT_INLINE bool operator>=(const Endpoint &ep) const noexcept { return !(*this < ep); } static constexpr int marshalSizeMax() noexcept { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; } int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept; int unmarshal(const uint8_t *restrict data,int len) noexcept; private: Type _t; Protocol _proto; int _l[3]; // X,Y,Z location in kilometers from the nearest gravitational center of mass (e.g. Earth) union { sockaddr_storage sa; ZT_Fingerprint zt; uint8_t eth[6]; } _v; }; } // namespace ZeroTier #endif