SelfAwareness.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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: 2025-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_SELFAWARENESS_HPP
  14. #define ZT_SELFAWARENESS_HPP
  15. #include "Constants.hpp"
  16. #include "InetAddress.hpp"
  17. #include "Containers.hpp"
  18. #include "Address.hpp"
  19. #include "Mutex.hpp"
  20. namespace ZeroTier {
  21. class Identity;
  22. class RuntimeEnvironment;
  23. /**
  24. * SelfAwareness manages awareness of this peer's external address(es) and NAT situation.
  25. *
  26. * Name aside, it shouldn't be capable of achieving sentience.
  27. */
  28. class SelfAwareness
  29. {
  30. public:
  31. explicit SelfAwareness(const RuntimeEnvironment *renv);
  32. /**
  33. * Called when a remote peer informs us of our external network address
  34. *
  35. * @param reporter Identity of reporting peer
  36. * @param receivedOnLocalAddress Local address on which report was received
  37. * @param reporterPhysicalAddress Physical address that reporting peer seems to have
  38. * @param myPhysicalAddress Physical address that peer says we have
  39. * @param trusted True if this peer is trusted as an authority to inform us of external address changes
  40. * @param now Current time
  41. */
  42. void iam(void *tPtr, const Identity &reporter, int64_t receivedOnLocalSocket, const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted, int64_t now);
  43. /**
  44. * Clean up database periodically
  45. *
  46. * @param now Current time
  47. */
  48. void clean(int64_t now);
  49. /**
  50. * Get external address consensus, which is the statistical "mode" of external addresses.
  51. *
  52. * @param now Current time
  53. * @return Map of count to IP/port representing how many endpoints reported each address
  54. */
  55. MultiMap< unsigned int, InetAddress > externalAddresses(int64_t now) const;
  56. private:
  57. struct p_PhySurfaceKey
  58. {
  59. Address reporter;
  60. int64_t receivedOnLocalSocket;
  61. InetAddress reporterPhysicalAddress;
  62. InetAddress::IpScope scope;
  63. ZT_INLINE p_PhySurfaceKey() noexcept
  64. {}
  65. ZT_INLINE p_PhySurfaceKey(const Address &r, const int64_t rol, const InetAddress &ra, InetAddress::IpScope s) noexcept: reporter(r), receivedOnLocalSocket(rol), reporterPhysicalAddress(ra), scope(s)
  66. {}
  67. ZT_INLINE unsigned long hashCode() const noexcept
  68. { return ((unsigned long)reporter.toInt() + (unsigned long)receivedOnLocalSocket + (unsigned long)scope); }
  69. ZT_INLINE bool operator==(const p_PhySurfaceKey &k) const noexcept
  70. { return ((reporter == k.reporter) && (receivedOnLocalSocket == k.receivedOnLocalSocket) && (reporterPhysicalAddress == k.reporterPhysicalAddress) && (scope == k.scope)); }
  71. ZT_INLINE bool operator!=(const p_PhySurfaceKey &k) const noexcept
  72. { return (!(*this == k)); }
  73. ZT_INLINE bool operator<(const p_PhySurfaceKey &k) const noexcept
  74. {
  75. if (reporter < k.reporter) {
  76. return true;
  77. } else if (reporter == k.reporter) {
  78. if (receivedOnLocalSocket < k.receivedOnLocalSocket) {
  79. return true;
  80. } else if (receivedOnLocalSocket == k.receivedOnLocalSocket) {
  81. if (reporterPhysicalAddress < k.reporterPhysicalAddress) {
  82. return true;
  83. } else if (reporterPhysicalAddress == k.reporterPhysicalAddress) {
  84. return scope < k.scope;
  85. }
  86. }
  87. }
  88. return false;
  89. }
  90. };
  91. struct p_PhySurfaceEntry
  92. {
  93. InetAddress mySurface;
  94. int64_t ts;
  95. bool trusted;
  96. ZT_INLINE p_PhySurfaceEntry() noexcept: mySurface(), ts(0), trusted(false)
  97. {}
  98. ZT_INLINE p_PhySurfaceEntry(const InetAddress &a, const int64_t t) noexcept: mySurface(a), ts(t), trusted(false)
  99. {}
  100. };
  101. const RuntimeEnvironment *RR;
  102. Map< p_PhySurfaceKey, p_PhySurfaceEntry > m_phy;
  103. Mutex m_phy_l;
  104. };
  105. } // namespace ZeroTier
  106. #endif