Multicaster.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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: 2023-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 <algorithm>
  14. #include "Constants.hpp"
  15. #include "RuntimeEnvironment.hpp"
  16. #include "Multicaster.hpp"
  17. #include "Network.hpp"
  18. #include "Topology.hpp"
  19. #include "Switch.hpp"
  20. namespace ZeroTier {
  21. Multicaster::Multicaster(const RuntimeEnvironment *renv) :
  22. RR(renv),
  23. _groups(32) {}
  24. Multicaster::~Multicaster() {}
  25. void Multicaster::send(
  26. void *tPtr,
  27. int64_t now,
  28. const SharedPtr<Network> &network,
  29. const MulticastGroup &mg,
  30. const MAC &src,
  31. unsigned int etherType,
  32. const unsigned int existingBloomMultiplier,
  33. const uint8_t existingBloom[ZT_MULTICAST_BLOOM_FILTER_SIZE_BITS / 8],
  34. const void *const data,
  35. unsigned int len)
  36. {
  37. static const unsigned int PRIMES[16] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53 };
  38. if (unlikely(len > ZT_MAX_MTU)) return; // sanity check
  39. const NetworkConfig &config = network->config();
  40. if (config.multicastLimit == 0) return; // multicast disabled
  41. Address bridges[ZT_MAX_NETWORK_SPECIALISTS],multicastReplicators[ZT_MAX_NETWORK_SPECIALISTS];
  42. unsigned int bridgeCount = 0,multicastReplicatorCount = 0;
  43. for(unsigned int i=0;i<config.specialistCount;++i) {
  44. if ((config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
  45. bridges[bridgeCount++] = config.specialists[i];
  46. if ((config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_MULTICAST_REPLICATOR) != 0)
  47. multicastReplicators[multicastReplicatorCount++] = config.specialists[i];
  48. }
  49. std::vector< std::pair<int64_t,Address> > recipients;
  50. bool needMoar = false;
  51. for(unsigned int i=0;i<bridgeCount;++i)
  52. recipients.push_back(std::pair<int64_t,Address>(9223372036854775807LL,bridges[i]));
  53. {
  54. Mutex::Lock l2(_groups_l);
  55. _getMembersByTime(network->id(),mg,recipients);
  56. }
  57. std::sort(recipients.begin() + bridgeCount,recipients.end(),std::greater< std::pair<int64_t,Address> >());
  58. recipients.erase(std::unique(recipients.begin(),recipients.end()),recipients.end());
  59. if (recipients.size() > config.multicastLimit) {
  60. recipients.resize(config.multicastLimit);
  61. } else if (recipients.size() < config.multicastLimit) {
  62. needMoar = true;
  63. }
  64. _txQueue_l.lock();
  65. _OM *om = &(_txQueue[_txQueuePtr++ % ZT_TX_QUEUE_SIZE]);
  66. Mutex::Lock ql(om->lock);
  67. _txQueue_l.unlock();
  68. om->nwid = network->id();
  69. om->src = src;
  70. om->mg = mg;
  71. om->etherType = etherType;
  72. om->dataSize = len;
  73. memcpy(om->data,data,len);
  74. if (existingBloom) {
  75. om->bloomFilterMultiplier = existingBloomMultiplier;
  76. memcpy(om->bloomFilter,existingBloom,sizeof(om->bloomFilter));
  77. } else {
  78. om->bloomFilterMultiplier = 1;
  79. memset(om->bloomFilter,0,sizeof(om->bloomFilter));
  80. if (recipients.size() > 1) {
  81. unsigned int mult = 1;
  82. unsigned int bestMultColl = 0xffffffff;
  83. for(int k=0;k<16;++k) { // 16 == arbitrary limit on iterations for this search, also must be <= size of PRIMES
  84. unsigned int coll = 0;
  85. for(std::vector< std::pair<int64_t,Address> >::const_iterator r(recipients.begin());r!=recipients.end();++r) {
  86. const unsigned int bfi = mult * (unsigned int)r->second.toInt();
  87. const unsigned int byte = (bfi >> 3) % sizeof(om->bloomFilter);
  88. const uint8_t bit = 1 << (bfi & 7);
  89. coll += ((om->bloomFilter[byte] & bit) != 0);
  90. om->bloomFilter[byte] |= bit;
  91. }
  92. memset(om->bloomFilter,0,sizeof(om->bloomFilter));
  93. if (coll <= bestMultColl) {
  94. om->bloomFilterMultiplier = mult;
  95. if (coll == 0) // perfect score, no need to continue searching
  96. break;
  97. bestMultColl = coll;
  98. }
  99. mult = PRIMES[k];
  100. }
  101. }
  102. }
  103. if (multicastReplicatorCount > 0) {
  104. // SEND
  105. return;
  106. }
  107. SharedPtr<Peer> nextHops[2]; // these by definition are protocol version >= 11
  108. unsigned int nextHopsBestLatency[2] = { 0xffff,0xffff };
  109. for(std::vector< std::pair<int64_t,Address> >::const_iterator r(recipients.begin());r!=recipients.end();++r) {
  110. const unsigned int bfi = om->bloomFilterMultiplier * (unsigned int)r->second.toInt();
  111. const unsigned int bfbyte = (bfi >> 3) % sizeof(om->bloomFilter);
  112. const uint8_t bfbit = 1 << (bfi & 7);
  113. if ((om->bloomFilter[bfbyte] & bfbit) != 0) {
  114. continue;
  115. } else {
  116. SharedPtr<Peer> peer(RR->topology->get(r->second));
  117. if (peer) {
  118. if (peer->remoteVersionProtocol() < 11) {
  119. // SEND
  120. om->bloomFilter[bfbyte] |= bfbit;
  121. continue;
  122. } else {
  123. const unsigned int lat = peer->latency(now);
  124. for(unsigned int nh=0;nh<2;++nh) {
  125. if (lat <= nextHopsBestLatency[nh]) {
  126. nextHopsBestLatency[nh] = lat;
  127. nextHops[nh] = peer;
  128. break;
  129. }
  130. }
  131. }
  132. }
  133. }
  134. }
  135. for(unsigned int nh=0;nh<2;++nh) {
  136. if (nextHops[nh]) {
  137. const unsigned int bfi = om->bloomFilterMultiplier * (unsigned int)nextHops[nh]->address().toInt();
  138. om->bloomFilter[(bfi >> 3) % sizeof(om->bloomFilter)] |= 1 << (bfi & 7);
  139. }
  140. }
  141. for(unsigned int nh=0;nh<2;++nh) {
  142. if (nextHops[nh]) {
  143. }
  144. }
  145. }
  146. void Multicaster::clean(int64_t now)
  147. {
  148. }
  149. } // namespace ZeroTier