Endpoint.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #ifndef ZT_ENDPOINT_HPP
  14. #define ZT_ENDPOINT_HPP
  15. #include "Constants.hpp"
  16. #include "InetAddress.hpp"
  17. #include "Address.hpp"
  18. #include "Utils.hpp"
  19. #include "TriviallyCopyable.hpp"
  20. #include <cstdio>
  21. #include <cstdlib>
  22. #include <cstdint>
  23. #include <cstring>
  24. // max name size + type byte + port (for DNS name/port) + 3x 16-bit coordinate for location
  25. #define ZT_ENDPOINT_MARSHAL_SIZE_MAX (ZT_ENDPOINT_MAX_NAME_SIZE+1+2+2+2+2)
  26. namespace ZeroTier {
  27. /**
  28. * Endpoint variant specifying some form of network endpoint
  29. *
  30. * This data structure supports a number of types that are not yet actually used:
  31. * DNSNAME, URL, and ETHERNET. These are present to reserve them for future use.
  32. */
  33. class Endpoint : public TriviallyCopyable
  34. {
  35. public:
  36. /**
  37. * Endpoint type
  38. *
  39. * These are set to be the same as the IDs used for trace events in ZeroTierCore.h.
  40. */
  41. enum Type
  42. {
  43. TYPE_NIL = ZT_TRACE_EVENT_PATH_TYPE_NIL,
  44. TYPE_ZEROTIER = ZT_TRACE_EVENT_PATH_TYPE_ZEROTIER,
  45. TYPE_DNSNAME = ZT_TRACE_EVENT_PATH_TYPE_DNSNAME,
  46. TYPE_URL = ZT_TRACE_EVENT_PATH_TYPE_URL,
  47. TYPE_INETADDR_V4 = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V4,
  48. TYPE_ETHERNET = ZT_TRACE_EVENT_PATH_TYPE_ETHERNET,
  49. TYPE_INETADDR_V6 = ZT_TRACE_EVENT_PATH_TYPE_INETADDR_V6
  50. };
  51. /**
  52. * Protocol identifiers for INETADDR endpoint types
  53. *
  54. * Most of these are reserved for future use.
  55. */
  56. enum Protocol
  57. {
  58. PROTO_UDP_ZT = 0,
  59. PROTO_TCP_ZT = 1,
  60. PROTO_IP_ZT = 2
  61. };
  62. ZT_ALWAYS_INLINE Endpoint() noexcept { memoryZero(this); }
  63. explicit ZT_ALWAYS_INLINE Endpoint(const InetAddress &sa,const Protocol proto = PROTO_UDP_ZT)
  64. {
  65. switch (sa.family()) {
  66. case AF_INET:
  67. _t = TYPE_INETADDR_V4;
  68. break;
  69. case AF_INET6:
  70. _t = TYPE_INETADDR_V6;
  71. default:
  72. _t = TYPE_NIL;
  73. return;
  74. }
  75. asInetAddress(_v.in.sa) = sa;
  76. _v.in.proto = (uint8_t)proto;
  77. }
  78. ZT_ALWAYS_INLINE Endpoint(const Address &zt,const uint8_t identityHash[ZT_IDENTITY_HASH_SIZE]) :
  79. _t(TYPE_ZEROTIER)
  80. {
  81. _v.zt.a = zt.toInt();
  82. memcpy(_v.zt.idh,identityHash,ZT_IDENTITY_HASH_SIZE);
  83. }
  84. ZT_ALWAYS_INLINE Endpoint(const char *name,const int port) :
  85. _t(TYPE_DNSNAME)
  86. {
  87. _v.dns.port = port;
  88. Utils::scopy(_v.dns.name,sizeof(_v.dns.name),name);
  89. }
  90. explicit ZT_ALWAYS_INLINE Endpoint(const char *url) :
  91. _t(TYPE_URL)
  92. {
  93. Utils::scopy(_v.url,sizeof(_v.url),url);
  94. }
  95. /**
  96. * @return InetAddress or NIL if not of this type
  97. */
  98. ZT_ALWAYS_INLINE const InetAddress &inetAddr() const noexcept { return ((_t == TYPE_INETADDR_V4)||(_t == TYPE_INETADDR_V6)) ? asInetAddress(_v.in.sa) : InetAddress::NIL; }
  99. /**
  100. * @return Protocol for INETADDR types, undefined for other endpoint types
  101. */
  102. ZT_ALWAYS_INLINE Protocol inetAddrProto() const noexcept { return (Protocol)_v.in.proto; }
  103. /**
  104. * @return DNS name or empty string if not of this type
  105. */
  106. ZT_ALWAYS_INLINE const char *dnsName() const noexcept { return (_t == TYPE_DNSNAME) ? _v.dns.name : ""; }
  107. /**
  108. * @return Port associated with DNS name or -1 if not of this type
  109. */
  110. ZT_ALWAYS_INLINE int dnsPort() const noexcept { return (_t == TYPE_DNSNAME) ? _v.dns.port : -1; }
  111. /**
  112. * @return ZeroTier address or NIL if not of this type
  113. */
  114. ZT_ALWAYS_INLINE Address ztAddress() const noexcept { return Address((_t == TYPE_ZEROTIER) ? _v.zt.a : (uint64_t)0); }
  115. /**
  116. * @return 384-bit hash of identity keys or NULL if not of this type
  117. */
  118. ZT_ALWAYS_INLINE const uint8_t *ztIdentityHash() const noexcept { return (_t == TYPE_ZEROTIER) ? _v.zt.idh : nullptr; }
  119. /**
  120. * @return URL or empty string if not of this type
  121. */
  122. ZT_ALWAYS_INLINE const char *url() const noexcept { return (_t == TYPE_URL) ? _v.url : ""; }
  123. /**
  124. * @return Ethernet address or NIL if not of this type
  125. */
  126. ZT_ALWAYS_INLINE MAC ethernet() const noexcept { return (_t == TYPE_ETHERNET) ? MAC(_v.eth) : MAC(); }
  127. /**
  128. * @return Endpoint type or NIL if unset/empty
  129. */
  130. ZT_ALWAYS_INLINE Type type() const noexcept { return _t; }
  131. explicit ZT_ALWAYS_INLINE operator bool() const noexcept { return _t != TYPE_NIL; }
  132. bool operator==(const Endpoint &ep) const;
  133. ZT_ALWAYS_INLINE bool operator!=(const Endpoint &ep) const { return (!(*this == ep)); }
  134. bool operator<(const Endpoint &ep) const;
  135. ZT_ALWAYS_INLINE bool operator>(const Endpoint &ep) const { return (ep < *this); }
  136. ZT_ALWAYS_INLINE bool operator<=(const Endpoint &ep) const { return !(ep < *this); }
  137. ZT_ALWAYS_INLINE bool operator>=(const Endpoint &ep) const { return !(*this < ep); }
  138. static constexpr int marshalSizeMax() noexcept { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
  139. int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept;
  140. int unmarshal(const uint8_t *restrict data,int len) noexcept;
  141. private:
  142. Type _t;
  143. int _l[3]; // X,Y,Z location in kilometers from the nearest gravitational center of mass
  144. union {
  145. struct {
  146. sockaddr_storage sa;
  147. uint8_t proto;
  148. } in;
  149. struct {
  150. uint16_t port;
  151. char name[ZT_ENDPOINT_MAX_NAME_SIZE];
  152. } dns;
  153. struct {
  154. uint64_t a;
  155. uint8_t idh[ZT_IDENTITY_HASH_SIZE];
  156. } zt;
  157. char url[ZT_ENDPOINT_MAX_NAME_SIZE];
  158. uint64_t eth;
  159. } _v;
  160. };
  161. } // namespace ZeroTier
  162. #endif