OutboundMulticast.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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: 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_OUTBOUNDMULTICAST_HPP
  14. #define ZT_OUTBOUNDMULTICAST_HPP
  15. #include <stdint.h>
  16. #include <vector>
  17. #include <algorithm>
  18. #include "Constants.hpp"
  19. #include "MAC.hpp"
  20. #include "MulticastGroup.hpp"
  21. #include "Address.hpp"
  22. #include "Packet.hpp"
  23. namespace ZeroTier {
  24. class CertificateOfMembership;
  25. class RuntimeEnvironment;
  26. /**
  27. * An outbound multicast packet
  28. *
  29. * This object isn't guarded by a mutex; caller must synchronize access.
  30. */
  31. class OutboundMulticast
  32. {
  33. public:
  34. /**
  35. * Create an uninitialized outbound multicast
  36. *
  37. * It must be initialized with init().
  38. */
  39. OutboundMulticast() {}
  40. /**
  41. * Initialize outbound multicast
  42. *
  43. * @param RR Runtime environment
  44. * @param timestamp Creation time
  45. * @param nwid Network ID
  46. * @param disableCompression Disable compression of frame payload
  47. * @param limit Multicast limit for desired number of packets to send
  48. * @param gatherLimit Number to lazily/implicitly gather with this frame or 0 for none
  49. * @param src Source MAC address of frame or NULL to imply compute from sender ZT address
  50. * @param dest Destination multicast group (MAC + ADI)
  51. * @param etherType 16-bit Ethernet type ID
  52. * @param payload Data
  53. * @param len Length of data
  54. * @throws std::out_of_range Data too large to fit in a MULTICAST_FRAME
  55. */
  56. void init(
  57. const RuntimeEnvironment *RR,
  58. uint64_t timestamp,
  59. uint64_t nwid,
  60. bool disableCompression,
  61. unsigned int limit,
  62. unsigned int gatherLimit,
  63. const MAC &src,
  64. const MulticastGroup &dest,
  65. unsigned int etherType,
  66. const void *payload,
  67. unsigned int len);
  68. /**
  69. * @return Multicast creation time
  70. */
  71. inline uint64_t timestamp() const { return _timestamp; }
  72. /**
  73. * @param now Current time
  74. * @return True if this multicast is expired (has exceeded transmit timeout)
  75. */
  76. inline bool expired(int64_t now) const { return ((now - _timestamp) >= ZT_MULTICAST_TRANSMIT_TIMEOUT); }
  77. /**
  78. * @return True if this outbound multicast has been sent to enough peers
  79. */
  80. inline bool atLimit() const { return (_alreadySentTo.size() >= _limit); }
  81. /**
  82. * Just send without checking log
  83. *
  84. * @param RR Runtime environment
  85. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  86. * @param toAddr Destination address
  87. */
  88. void sendOnly(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr);
  89. /**
  90. * Just send and log but do not check sent log
  91. *
  92. * @param RR Runtime environment
  93. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  94. * @param toAddr Destination address
  95. */
  96. inline void sendAndLog(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr)
  97. {
  98. _alreadySentTo.push_back(toAddr);
  99. sendOnly(RR,tPtr,toAddr);
  100. }
  101. /**
  102. * Log an address as having been used so we will not send there in the future
  103. *
  104. * @param toAddr Address to log as sent
  105. */
  106. inline void logAsSent(const Address &toAddr)
  107. {
  108. _alreadySentTo.push_back(toAddr);
  109. }
  110. /**
  111. * Try to send this to a given peer if it hasn't been sent to them already
  112. *
  113. * @param RR Runtime environment
  114. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  115. * @param toAddr Destination address
  116. * @return True if address is new and packet was sent to switch, false if duplicate
  117. */
  118. inline bool sendIfNew(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr)
  119. {
  120. if (std::find(_alreadySentTo.begin(),_alreadySentTo.end(),toAddr) == _alreadySentTo.end()) {
  121. sendAndLog(RR,tPtr,toAddr);
  122. return true;
  123. } else {
  124. return false;
  125. }
  126. }
  127. private:
  128. uint64_t _timestamp;
  129. uint64_t _nwid;
  130. MAC _macSrc;
  131. MAC _macDest;
  132. unsigned int _limit;
  133. unsigned int _frameLen;
  134. unsigned int _etherType;
  135. Packet _packet,_tmp;
  136. std::vector<Address> _alreadySentTo;
  137. uint8_t _frameData[ZT_MAX_MTU];
  138. };
  139. } // namespace ZeroTier
  140. #endif