Endpoint.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. enum Type
  37. {
  38. NIL = 0, // NIL value
  39. INETADDR_V4 = 1, // IPv4
  40. INETADDR_V6 = 2, // IPv6
  41. DNSNAME = 3, // DNS name and port that resolves to InetAddress
  42. ZEROTIER = 4, // ZeroTier Address (for relaying and meshy behavior)
  43. URL = 5, // URL for http/https/ws/etc. (not implemented yet)
  44. ETHERNET = 6, // 48-bit LAN-local Ethernet address
  45. WEBRTC = 7, // WebRTC data channels
  46. UNRECOGNIZED = 255 // Unrecognized endpoint type encountered in stream
  47. };
  48. ZT_ALWAYS_INLINE Endpoint() noexcept { memoryZero(this); }
  49. explicit ZT_ALWAYS_INLINE Endpoint(const InetAddress &sa) { *this = sa; }
  50. ZT_ALWAYS_INLINE Endpoint(const Address &zt,const uint8_t identityHash[ZT_IDENTITY_HASH_SIZE]) :
  51. _t(ZEROTIER)
  52. {
  53. _v.zt.a = zt.toInt();
  54. memcpy(_v.zt.idh,identityHash,ZT_IDENTITY_HASH_SIZE);
  55. }
  56. ZT_ALWAYS_INLINE Endpoint(const char *name,const int port) :
  57. _t(DNSNAME)
  58. {
  59. _v.dns.port = port;
  60. Utils::scopy(_v.dns.name,sizeof(_v.dns.name),name);
  61. }
  62. explicit ZT_ALWAYS_INLINE Endpoint(const char *url) :
  63. _t(URL)
  64. { Utils::scopy(_v.url,sizeof(_v.url),url); }
  65. ZT_ALWAYS_INLINE Endpoint &operator=(const InetAddress &sa)
  66. {
  67. switch(sa.ss_family) {
  68. case AF_INET:
  69. _t = INETADDR_V4;
  70. break;
  71. case AF_INET6:
  72. _t = INETADDR_V6;
  73. break;
  74. default:
  75. _t = NIL;
  76. return *this;
  77. }
  78. _v.sa = sa;
  79. return *this;
  80. }
  81. /**
  82. * @return InetAddress or NIL if not of this type
  83. */
  84. ZT_ALWAYS_INLINE const InetAddress &inetAddr() const noexcept { return ((_t == INETADDR_V4)||(_t == INETADDR_V6)) ? *reinterpret_cast<const InetAddress *>(&_v.sa) : InetAddress::NIL; }
  85. /**
  86. * @return DNS name or empty string if not of this type
  87. */
  88. ZT_ALWAYS_INLINE const char *dnsName() const noexcept { return (_t == DNSNAME) ? _v.dns.name : ""; }
  89. /**
  90. * @return Port associated with DNS name or -1 if not of this type
  91. */
  92. ZT_ALWAYS_INLINE int dnsPort() const noexcept { return (_t == DNSNAME) ? _v.dns.port : -1; }
  93. /**
  94. * @return ZeroTier address or NIL if not of this type
  95. */
  96. ZT_ALWAYS_INLINE Address ztAddress() const noexcept { return Address((_t == ZEROTIER) ? _v.zt.a : (uint64_t)0); }
  97. /**
  98. * @return 384-bit hash of identity keys or NULL if not of this type
  99. */
  100. ZT_ALWAYS_INLINE const uint8_t *ztIdentityHash() const noexcept { return (_t == ZEROTIER) ? _v.zt.idh : nullptr; }
  101. /**
  102. * @return URL or empty string if not of this type
  103. */
  104. ZT_ALWAYS_INLINE const char *url() const noexcept { return (_t == URL) ? _v.url : ""; }
  105. /**
  106. * @return Ethernet address or NIL if not of this type
  107. */
  108. ZT_ALWAYS_INLINE MAC ethernet() const noexcept { return (_t == ETHERNET) ? MAC(_v.eth) : MAC(); }
  109. /**
  110. * @return Endpoint type or NIL if unset/empty
  111. */
  112. ZT_ALWAYS_INLINE Type type() const noexcept { return _t; }
  113. explicit ZT_ALWAYS_INLINE operator bool() const noexcept { return _t != NIL; }
  114. bool operator==(const Endpoint &ep) const;
  115. ZT_ALWAYS_INLINE bool operator!=(const Endpoint &ep) const { return (!(*this == ep)); }
  116. bool operator<(const Endpoint &ep) const;
  117. ZT_ALWAYS_INLINE bool operator>(const Endpoint &ep) const { return (ep < *this); }
  118. ZT_ALWAYS_INLINE bool operator<=(const Endpoint &ep) const { return !(ep < *this); }
  119. ZT_ALWAYS_INLINE bool operator>=(const Endpoint &ep) const { return !(*this < ep); }
  120. static constexpr int marshalSizeMax() noexcept { return ZT_ENDPOINT_MARSHAL_SIZE_MAX; }
  121. int marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept;
  122. int unmarshal(const uint8_t *restrict data,int len) noexcept;
  123. private:
  124. Type _t;
  125. int _l[3]; // X,Y,Z location in kilometers from the nearest gravitational center of mass
  126. union {
  127. struct sockaddr_storage sa;
  128. struct {
  129. uint16_t port;
  130. char name[ZT_ENDPOINT_MAX_NAME_SIZE];
  131. } dns;
  132. struct {
  133. uint16_t offerLen;
  134. uint8_t offer[ZT_ENDPOINT_MAX_NAME_SIZE];
  135. } webrtc;
  136. struct {
  137. uint64_t a;
  138. uint8_t idh[ZT_IDENTITY_HASH_SIZE];
  139. } zt;
  140. char url[ZT_ENDPOINT_MAX_NAME_SIZE];
  141. uint64_t eth;
  142. } _v;
  143. };
  144. } // namespace ZeroTier
  145. #endif