mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-07 19:24:13 +00:00
Add support for designated multicast replicators to Multicaster::send().
This commit is contained in:
parent
f03fd57997
commit
d3d58ba8a7
@ -161,15 +161,57 @@ void Multicaster::send(
|
||||
void *tPtr,
|
||||
int64_t now,
|
||||
const SharedPtr<Network> &network,
|
||||
const Address &origin,
|
||||
const MulticastGroup &mg,
|
||||
const MAC &src,
|
||||
unsigned int etherType,
|
||||
const void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
unsigned long idxbuf[8194];
|
||||
unsigned long idxbuf[4096];
|
||||
unsigned long *indexes = idxbuf;
|
||||
|
||||
// If we're in hub-and-spoke designated multicast replication mode, see if we
|
||||
// have a multicast replicator active. If so, pick the best and send it
|
||||
// there. If we are a multicast replicator or if none are alive, fall back
|
||||
// to sender replication.
|
||||
{
|
||||
Address multicastReplicators[ZT_MAX_NETWORK_SPECIALISTS];
|
||||
const unsigned int multicastReplicatorCount = network->config().multicastReplicators(multicastReplicators);
|
||||
if (multicastReplicatorCount) {
|
||||
if (std::find(multicastReplicators,multicastReplicators + multicastReplicatorCount,RR->identity.address()) == (multicastReplicators + multicastReplicatorCount)) {
|
||||
SharedPtr<Peer> bestMulticastReplicator;
|
||||
SharedPtr<Path> bestMulticastReplicatorPath;
|
||||
unsigned int bestMulticastReplicatorLatency = 0xffff;
|
||||
for(unsigned int i=0;i<multicastReplicatorCount;++i) {
|
||||
const SharedPtr<Peer> p(RR->topology->getPeerNoCache(multicastReplicators[i]));
|
||||
if ((p)&&(p->isAlive(now))) {
|
||||
const SharedPtr<Path> pp(p->getBestPath(now,false));
|
||||
if ((pp)&&(pp->latency() < bestMulticastReplicatorLatency)) {
|
||||
bestMulticastReplicatorLatency = pp->latency();
|
||||
bestMulticastReplicatorPath = pp;
|
||||
bestMulticastReplicator = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestMulticastReplicator) {
|
||||
Packet outp(bestMulticastReplicator->address(),RR->identity.address(),Packet::VERB_MULTICAST_FRAME);
|
||||
outp.append((uint64_t)network->id());
|
||||
outp.append((uint8_t)0x04); // includes source MAC
|
||||
((src) ? src : MAC(RR->identity.address(),network->id())).appendTo(outp);
|
||||
mg.mac().appendTo(outp);
|
||||
outp.append((uint32_t)mg.adi());
|
||||
outp.append((uint16_t)etherType);
|
||||
outp.append(data,len);
|
||||
if (!network->config().disableCompression()) outp.compress();
|
||||
outp.armor(bestMulticastReplicator->key(),true);
|
||||
bestMulticastReplicatorPath->send(RR,tPtr,outp.data(),outp.size(),now);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Mutex::Lock _l(_groups_m);
|
||||
MulticastGroupStatus &gs = _groups[Multicaster::Key(network->id(),mg)];
|
||||
@ -214,7 +256,7 @@ void Multicaster::send(
|
||||
unsigned int count = 0;
|
||||
|
||||
for(unsigned int i=0;i<activeBridgeCount;++i) {
|
||||
if (activeBridges[i] != RR->identity.address()) {
|
||||
if ((activeBridges[i] != RR->identity.address())&&(activeBridges[i] != origin)) {
|
||||
out.sendOnly(RR,tPtr,activeBridges[i]); // optimization: don't use dedup log if it's a one-pass send
|
||||
if (++count >= limit)
|
||||
break;
|
||||
@ -224,7 +266,7 @@ void Multicaster::send(
|
||||
unsigned long idx = 0;
|
||||
while ((count < limit)&&(idx < gs.members.size())) {
|
||||
const Address ma(gs.members[indexes[idx++]].address);
|
||||
if (std::find(activeBridges,activeBridges + activeBridgeCount,ma) == (activeBridges + activeBridgeCount)) {
|
||||
if ((std::find(activeBridges,activeBridges + activeBridgeCount,ma) == (activeBridges + activeBridgeCount))&&(ma != origin)) {
|
||||
out.sendOnly(RR,tPtr,ma); // optimization: don't use dedup log if it's a one-pass send
|
||||
++count;
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ public:
|
||||
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
|
||||
* @param now Current time
|
||||
* @param network Network
|
||||
* @param origin Origin of multicast (to not return to sender) or NULL if none
|
||||
* @param mg Multicast group
|
||||
* @param src Source Ethernet MAC address or NULL to skip in packet and compute from ZT address (non-bridged mode)
|
||||
* @param etherType Ethernet frame type
|
||||
@ -142,6 +143,7 @@ public:
|
||||
void *tPtr,
|
||||
int64_t now,
|
||||
const SharedPtr<Network> &network,
|
||||
const Address &origin,
|
||||
const MulticastGroup &mg,
|
||||
const MAC &src,
|
||||
unsigned int etherType,
|
||||
|
@ -322,6 +322,16 @@ public:
|
||||
return r;
|
||||
}
|
||||
|
||||
inline unsigned int multicastReplicators(Address mr[ZT_MAX_NETWORK_SPECIALISTS]) const
|
||||
{
|
||||
unsigned int c = 0;
|
||||
for(unsigned int i=0;i<specialistCount;++i) {
|
||||
if ((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_MULTICAST_REPLICATOR) != 0)
|
||||
mr[c++] = specialists[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
inline std::vector<Address> alwaysContactAddresses() const
|
||||
{
|
||||
std::vector<Address> r;
|
||||
|
@ -391,7 +391,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
|
||||
tPtr,
|
||||
RR->node->now(),
|
||||
network,
|
||||
// network->config().activeBridges(),
|
||||
Address(),
|
||||
multicastGroup,
|
||||
(fromBridged) ? from : MAC(),
|
||||
etherType,
|
||||
|
Loading…
x
Reference in New Issue
Block a user