| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /*
- * 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 "MAC.hpp"
- #define ZT_ENDPOINT_MARSHAL_SIZE_MAX 128
- static_assert(ZT_ENDPOINT_MARSHAL_SIZE_MAX > (ZT_INETADDRESS_MARSHAL_SIZE_MAX + 1),"ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
- static_assert(ZT_ENDPOINT_MARSHAL_SIZE_MAX > (sizeof(ZT_Fingerprint) + 1),"ZT_ENDPOINT_MARSHAL_SIZE_MAX not large enough");
- namespace ZeroTier {
- /**
- * Endpoint variant specifying some form of network endpoint.
- *
- * This is sort of a superset of InetAddress and for the standard UDP
- * protocol marshals and unmarshals to a compatible format. This makes
- * it backward compatible with older node versions' protocol fields
- * where InetAddress was used as long as only the UDP type is exchanged
- * with those nodes.
- */
- class Endpoint : public TriviallyCopyable
- {
- public:
- /**
- * Endpoint type (defined in the API)
- */
- typedef ZT_EndpointType Type;
- /**
- * Create a NIL/empty endpoint
- */
- ZT_INLINE Endpoint() noexcept { memoryZero(this); }
- /**
- * Create an endpoint for a type that uses an IP
- *
- * @param a IP/port
- * @param et Endpoint type (default: IP_UDP)
- */
- ZT_INLINE Endpoint(const InetAddress &a,const Type et = ZT_ENDPOINT_TYPE_IP_UDP) noexcept
- {
- if (a) {
- Utils::copy<sizeof(InetAddress)>(m_value,&a);
- m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] = (uint8_t)et;
- } else {
- memoryZero(this);
- }
- }
- /**
- * Create an endpoint for ZeroTier relaying (ZEROTIER type)
- *
- * @param zt_ ZeroTier identity fingerprint
- */
- ZT_INLINE Endpoint(const Fingerprint &zt_) noexcept
- {
- if (zt_) {
- Utils::copy<sizeof(Fingerprint)>(m_value,&zt_);
- m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] = (uint8_t)ZT_ENDPOINT_TYPE_ZEROTIER;
- } else {
- memoryZero(this);
- }
- }
- /**
- * Create an endpoint for a type that uses a MAC address
- *
- * @param eth_ Ethernet address
- * @param et Endpoint type (default: ETHERNET)
- */
- ZT_INLINE Endpoint(const MAC ð_,const Type et = ZT_ENDPOINT_TYPE_ETHERNET) noexcept
- {
- if (eth_) {
- Utils::copy<sizeof(MAC)>(m_value,ð_);
- m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] = (uint8_t)et;
- } else {
- memoryZero(this);
- }
- }
- /**
- * @return Endpoint type
- */
- ZT_INLINE Type type() const noexcept { return (Type)m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1]; }
- /**
- * @return True if endpoint type isn't NIL
- */
- ZT_INLINE operator bool() const noexcept { return (m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] != (uint8_t)ZT_ENDPOINT_TYPE_NIL); }
- /**
- * @return True if this endpoint type has an InetAddress address type and thus ip() is valid
- */
- ZT_INLINE bool isInetAddr() const noexcept
- {
- switch(this->type()) {
- case ZT_ENDPOINT_TYPE_IP:
- case ZT_ENDPOINT_TYPE_IP_UDP:
- case ZT_ENDPOINT_TYPE_IP_TCP:
- case ZT_ENDPOINT_TYPE_IP_HTTP2:
- return true;
- default:
- return false;
- }
- }
- /**
- * Get InetAddress if this type uses IPv4 or IPv6 addresses (undefined otherwise)
- *
- * @return InetAddress instance
- */
- ZT_INLINE const InetAddress &ip() const noexcept { return *reinterpret_cast<const InetAddress *>(m_value); }
- /**
- * Get MAC if this is an Ethernet, WiFi direct, or Bluetooth type (undefined otherwise)
- *
- * @return Ethernet MAC
- */
- ZT_INLINE const MAC ð() const noexcept { return *reinterpret_cast<const MAC *>(m_value); }
- /**
- * Get fingerprint if this is a ZeroTier endpoint type (undefined otherwise)
- *
- * @return ZeroTier fingerprint
- */
- ZT_INLINE const Fingerprint &zt() const noexcept { return *reinterpret_cast<const Fingerprint *>(m_value); }
- 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:
- uint8_t m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX]; // the last byte in this buffer is the type
- };
- } // namespace ZeroTier
- #endif
|