Endpoint.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #include "Endpoint.hpp"
  14. #include "Utils.hpp"
  15. namespace ZeroTier {
  16. int Endpoint::marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept
  17. {
  18. switch(m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1]) {
  19. default:
  20. //case ZT_ENDPOINT_TYPE_NIL:
  21. data[0] = 0;
  22. return 1;
  23. case ZT_ENDPOINT_TYPE_ZEROTIER:
  24. data[0] = 16 + ZT_ENDPOINT_TYPE_ZEROTIER;
  25. reinterpret_cast<const Fingerprint *>(m_value)->address().copyTo(data + 1);
  26. Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(data + 1 + ZT_ADDRESS_LENGTH,reinterpret_cast<const Fingerprint *>(m_value)->hash());
  27. return 1 + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE;
  28. case ZT_ENDPOINT_TYPE_ETHERNET:
  29. case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
  30. case ZT_ENDPOINT_TYPE_BLUETOOTH:
  31. data[0] = 16 + m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1];
  32. reinterpret_cast<const MAC *>(m_value)->copyTo(data + 1);
  33. return 7;
  34. case ZT_ENDPOINT_TYPE_IP_UDP:
  35. return reinterpret_cast<const InetAddress *>(m_value)->marshal(data);
  36. case ZT_ENDPOINT_TYPE_IP:
  37. case ZT_ENDPOINT_TYPE_IP_TCP:
  38. case ZT_ENDPOINT_TYPE_IP_HTTP2:
  39. data[0] = 16 + m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1];
  40. return 1 + reinterpret_cast<const InetAddress *>(m_value)->marshal(data + 1);
  41. }
  42. }
  43. int Endpoint::unmarshal(const uint8_t *restrict data,int len) noexcept
  44. {
  45. memoryZero(this);
  46. if (unlikely(len <= 0))
  47. return -1;
  48. // Serialized endpoints with type bytes less than 16 are passed through
  49. // to the unmarshal method of InetAddress and considered UDP endpoints.
  50. // This allows backward compatibility with old endpoint fields in the
  51. // protocol that were serialized InetAddress instances.
  52. if (data[0] < 16) {
  53. switch(data[0]) {
  54. case 0:
  55. return 1;
  56. case 4:
  57. case 6:
  58. m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] = (uint8_t)ZT_ENDPOINT_TYPE_IP_UDP;
  59. return reinterpret_cast<InetAddress *>(m_value)->unmarshal(data,len);
  60. }
  61. return -1;
  62. }
  63. switch((m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] = (data[0] - 16))) {
  64. case ZT_ENDPOINT_TYPE_NIL:
  65. return 1;
  66. case ZT_ENDPOINT_TYPE_ZEROTIER:
  67. if (len >= (1 + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE)) {
  68. reinterpret_cast<Fingerprint *>(m_value)->apiFingerprint()->address = Address(data + 1).toInt();
  69. Utils::copy<ZT_FINGERPRINT_HASH_SIZE>(reinterpret_cast<Fingerprint *>(m_value)->apiFingerprint()->hash,data + 1 + ZT_ADDRESS_LENGTH);
  70. return 1 + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE;
  71. }
  72. return -1;
  73. case ZT_ENDPOINT_TYPE_ETHERNET:
  74. case ZT_ENDPOINT_TYPE_WIFI_DIRECT:
  75. case ZT_ENDPOINT_TYPE_BLUETOOTH:
  76. if (len >= 7) {
  77. reinterpret_cast<MAC *>(m_value)->setTo(data + 1);
  78. return 7;
  79. }
  80. return -1;
  81. case ZT_ENDPOINT_TYPE_IP:
  82. case ZT_ENDPOINT_TYPE_IP_UDP:
  83. case ZT_ENDPOINT_TYPE_IP_TCP:
  84. case ZT_ENDPOINT_TYPE_IP_HTTP2:
  85. return reinterpret_cast<InetAddress *>(m_value)->unmarshal(data + 1,len - 1);
  86. default:
  87. break;
  88. }
  89. // Unrecognized types can still be passed over in a valid stream if they are
  90. // prefixed by a 16-bit size. This allows forward compatibility with future
  91. // endpoint types.
  92. m_value[ZT_ENDPOINT_MARSHAL_SIZE_MAX-1] = (uint8_t)ZT_ENDPOINT_TYPE_NIL;
  93. if (len < 3)
  94. return -1;
  95. const int unrecLen = 1 + (int)Utils::loadBigEndian<uint16_t>(data + 1);
  96. return (unrecLen > len) ? -1 : unrecLen;
  97. }
  98. } // namespace ZeroTier