Path.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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_PATH_HPP
  14. #define ZT_PATH_HPP
  15. #include "Constants.hpp"
  16. #include "InetAddress.hpp"
  17. #include "SharedPtr.hpp"
  18. #include "Utils.hpp"
  19. #include "Mutex.hpp"
  20. #include "Meter.hpp"
  21. #include <cstdint>
  22. #include <cstring>
  23. #include <cstdlib>
  24. #include <stdexcept>
  25. #include <algorithm>
  26. #include <set>
  27. namespace ZeroTier {
  28. class RuntimeEnvironment;
  29. template<unsigned int MF,unsigned int MFP,unsigned int GCT,unsigned int GCS>
  30. class Defragmenter;
  31. /**
  32. * A path across the physical network
  33. */
  34. class Path
  35. {
  36. friend class SharedPtr<Path>;
  37. // Allow defragmenter to access fragment-in-flight info stored in Path for performance reasons.
  38. template<unsigned int MF,unsigned int MFP,unsigned int GCT,unsigned int GCS>
  39. friend class Defragmenter;
  40. public:
  41. ZT_INLINE Path(const int64_t l,const InetAddress &r) noexcept : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
  42. _localSocket(l),
  43. _lastIn(0),
  44. _lastOut(0),
  45. _latency(-1),
  46. _addr(r)
  47. {
  48. }
  49. /**
  50. * Send a packet via this path (last out time is also updated)
  51. *
  52. * @param RR Runtime environment
  53. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  54. * @param data Packet data
  55. * @param len Packet length
  56. * @param now Current time
  57. * @return True if transport reported success
  58. */
  59. bool send(const RuntimeEnvironment *RR,void *tPtr,const void *data,unsigned int len,int64_t now) noexcept;
  60. /**
  61. * Explicitly update last sent time
  62. *
  63. * @param now Time of send
  64. * @param bytes Bytes sent
  65. */
  66. ZT_INLINE void sent(const int64_t now,const unsigned int bytes) noexcept
  67. {
  68. _lastOut.store(now);
  69. _outMeter.log(now,bytes);
  70. }
  71. /**
  72. * Called when a packet is received from this remote path, regardless of content
  73. *
  74. * @param now Time of receive
  75. * @param bytes Bytes received
  76. */
  77. ZT_INLINE void received(const int64_t now,const unsigned int bytes) noexcept
  78. {
  79. _lastIn.store(now);
  80. _inMeter.log(now,bytes);
  81. }
  82. /**
  83. * Update latency with a new measurement
  84. *
  85. * @param newMeasurement New latency measurement in milliseconds
  86. */
  87. ZT_INLINE void updateLatency(const unsigned int newMeasurement) noexcept
  88. {
  89. int lat = _latency;
  90. if (lat > 0) {
  91. _latency = (lat + newMeasurement) / 2;
  92. } else {
  93. _latency = newMeasurement;
  94. }
  95. }
  96. /**
  97. * @return Latency in milliseconds or -1 if unknown
  98. */
  99. ZT_INLINE int latency() const noexcept { return _latency; }
  100. /**
  101. * Check path aliveness
  102. *
  103. * @param now Current time
  104. */
  105. ZT_INLINE bool alive(const int64_t now) const noexcept { return ((now - _lastIn.load()) < ZT_PATH_ALIVE_TIMEOUT); }
  106. /**
  107. * @return Physical address
  108. */
  109. ZT_INLINE const InetAddress &address() const noexcept { return _addr; }
  110. /**
  111. * @return Local socket as specified by external code
  112. */
  113. ZT_INLINE int64_t localSocket() const noexcept { return _localSocket; }
  114. /**
  115. * @return Last time we received anything
  116. */
  117. ZT_INLINE int64_t lastIn() const noexcept { return _lastIn.load(); }
  118. /**
  119. * @return Last time we sent something
  120. */
  121. ZT_INLINE int64_t lastOut() const noexcept { return _lastOut.load(); }
  122. private:
  123. const int64_t _localSocket;
  124. std::atomic<int64_t> _lastIn;
  125. std::atomic<int64_t> _lastOut;
  126. std::atomic<int> _latency;
  127. const InetAddress _addr;
  128. Meter<> _inMeter;
  129. Meter<> _outMeter;
  130. // These fields belong to Defragmenter but are kept in Path for performance
  131. // as it's much faster this way than having Defragmenter maintain another
  132. // mapping from paths to inbound message IDs.
  133. std::set<uint64_t> _inboundFragmentedMessages;
  134. Mutex _inboundFragmentedMessages_l;
  135. std::atomic<int> __refCount;
  136. };
  137. } // namespace ZeroTier
  138. #endif