SelfAwareness.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c)2019 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: 2026-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 "SelfAwareness.hpp"
  14. #include "Constants.hpp"
  15. #include "Node.hpp"
  16. #include "Packet.hpp"
  17. #include "Peer.hpp"
  18. #include "RuntimeEnvironment.hpp"
  19. #include "Switch.hpp"
  20. #include "Topology.hpp"
  21. #include "Trace.hpp"
  22. #include <set>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <vector>
  27. // Entry timeout -- make it fairly long since this is just to prevent stale buildup
  28. #define ZT_SELFAWARENESS_ENTRY_TIMEOUT 600000
  29. namespace ZeroTier {
  30. class _ResetWithinScope {
  31. public:
  32. _ResetWithinScope(void* tPtr, int64_t now, int inetAddressFamily, InetAddress::IpScope scope) : _now(now), _tPtr(tPtr), _family(inetAddressFamily), _scope(scope)
  33. {
  34. }
  35. inline void operator()(Topology& t, const SharedPtr<Peer>& p)
  36. {
  37. p->resetWithinScope(_tPtr, _scope, _family, _now);
  38. }
  39. private:
  40. uint64_t _now;
  41. void* _tPtr;
  42. int _family;
  43. InetAddress::IpScope _scope;
  44. };
  45. SelfAwareness::SelfAwareness(const RuntimeEnvironment* renv) : RR(renv), _phy(128)
  46. {
  47. }
  48. void SelfAwareness::iam(void* tPtr, const Address& reporter, const int64_t receivedOnLocalSocket, const InetAddress& reporterPhysicalAddress, const InetAddress& myPhysicalAddress, bool trusted, int64_t now)
  49. {
  50. const InetAddress::IpScope scope = myPhysicalAddress.ipScope();
  51. if ((scope != reporterPhysicalAddress.ipScope()) || (scope == InetAddress::IP_SCOPE_NONE) || (scope == InetAddress::IP_SCOPE_LOOPBACK) || (scope == InetAddress::IP_SCOPE_MULTICAST)) {
  52. return;
  53. }
  54. Mutex::Lock _l(_phy_m);
  55. PhySurfaceEntry& entry = _phy[PhySurfaceKey(reporter, receivedOnLocalSocket, reporterPhysicalAddress, scope)];
  56. if ((trusted) && ((now - entry.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (! entry.mySurface.ipsEqual(myPhysicalAddress))) {
  57. // Changes to external surface reported by trusted peers causes path reset in this scope
  58. RR->t->resettingPathsInScope(tPtr, reporter, reporterPhysicalAddress, myPhysicalAddress, scope);
  59. entry.mySurface = myPhysicalAddress;
  60. entry.ts = now;
  61. entry.trusted = trusted;
  62. // Erase all entries in this scope that were not reported from this remote address to prevent 'thrashing'
  63. // due to multiple reports of endpoint change.
  64. // Don't use 'entry' after this since hash table gets modified.
  65. {
  66. Hashtable<PhySurfaceKey, PhySurfaceEntry>::Iterator i(_phy);
  67. PhySurfaceKey* k = (PhySurfaceKey*)0;
  68. PhySurfaceEntry* e = (PhySurfaceEntry*)0;
  69. while (i.next(k, e)) {
  70. if ((k->reporterPhysicalAddress != reporterPhysicalAddress) && (k->scope == scope)) {
  71. _phy.erase(*k);
  72. }
  73. }
  74. }
  75. // Reset all paths within this scope and address family
  76. _ResetWithinScope rset(tPtr, now, myPhysicalAddress.ss_family, (InetAddress::IpScope)scope);
  77. RR->topology->eachPeer<_ResetWithinScope&>(rset);
  78. }
  79. else {
  80. // Otherwise just update DB to use to determine external surface info
  81. entry.mySurface = myPhysicalAddress;
  82. entry.ts = now;
  83. entry.trusted = trusted;
  84. }
  85. }
  86. std::vector<InetAddress> SelfAwareness::whoami()
  87. {
  88. std::vector<InetAddress> surfaceAddresses;
  89. Mutex::Lock _l(_phy_m);
  90. Hashtable<PhySurfaceKey, PhySurfaceEntry>::Iterator i(_phy);
  91. PhySurfaceKey* k = (PhySurfaceKey*)0;
  92. PhySurfaceEntry* e = (PhySurfaceEntry*)0;
  93. while (i.next(k, e)) {
  94. if (std::find(surfaceAddresses.begin(), surfaceAddresses.end(), e->mySurface) == surfaceAddresses.end()) {
  95. surfaceAddresses.push_back(e->mySurface);
  96. }
  97. }
  98. return surfaceAddresses;
  99. }
  100. void SelfAwareness::clean(int64_t now)
  101. {
  102. Mutex::Lock _l(_phy_m);
  103. Hashtable<PhySurfaceKey, PhySurfaceEntry>::Iterator i(_phy);
  104. PhySurfaceKey* k = (PhySurfaceKey*)0;
  105. PhySurfaceEntry* e = (PhySurfaceEntry*)0;
  106. while (i.next(k, e)) {
  107. if ((now - e->ts) >= ZT_SELFAWARENESS_ENTRY_TIMEOUT) {
  108. _phy.erase(*k);
  109. }
  110. }
  111. }
  112. } // namespace ZeroTier