diff options
Diffstat (limited to 'node/Network.cpp')
-rw-r--r-- | node/Network.cpp | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/node/Network.cpp b/node/Network.cpp index e8a52e33..4cb5fb57 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -44,6 +44,8 @@ #include "Peer.hpp" #include "Trace.hpp" +#include <set> + namespace ZeroTier { namespace { @@ -1413,32 +1415,25 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu groups.push_back(*newMulticastGroup); else groups = _allMulticastGroups(); + std::vector<Address> alwaysAnnounceTo; + if ((newMulticastGroup)||((now - _lastAnnouncedMulticastGroupsUpstream) >= ZT_MULTICAST_ANNOUNCE_PERIOD)) { if (!newMulticastGroup) _lastAnnouncedMulticastGroupsUpstream = now; - // Announce multicast groups to upstream peers (roots, etc.) and also send - // them our COM so that MULTICAST_GATHER can be authenticated properly. + alwaysAnnounceTo = _config.alwaysContactAddresses(); + if (std::find(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),controller()) == alwaysAnnounceTo.end()) + alwaysAnnounceTo.push_back(controller()); const std::vector<Address> upstreams(RR->topology->upstreamAddresses()); for(std::vector<Address>::const_iterator a(upstreams.begin());a!=upstreams.end();++a) { - if (_config.com) { - Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); - _config.com.serialize(outp); - outp.append((uint8_t)0x00); - outp.append((uint16_t)0); // no capabilities - outp.append((uint16_t)0); // no tags - outp.append((uint16_t)0); // no revocations - outp.append((uint16_t)0); // no certificates of ownership - RR->sw->send(tPtr,outp,true); - } - _announceMulticastGroupsTo(tPtr,*a,groups); + if (std::find(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),*a) == alwaysAnnounceTo.end()) + alwaysAnnounceTo.push_back(*a); } + std::sort(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end()); - // Also announce to controller, and send COM to simplify and generalize behavior even though in theory it does not need it - const Address c(controller()); - if ( (std::find(upstreams.begin(),upstreams.end(),c) == upstreams.end()) && (!_memberships.contains(c)) ) { - if (_config.com) { - Packet outp(c,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); + for(std::vector<Address>::const_iterator a(alwaysAnnounceTo.begin());a!=alwaysAnnounceTo.end();++a) { + if ( (_config.com) && (!_memberships.contains(*a)) ) { // push COM to non-members so they can do multicast request auth + Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); _config.com.serialize(outp); outp.append((uint8_t)0x00); outp.append((uint16_t)0); // no capabilities @@ -1447,24 +1442,17 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu outp.append((uint16_t)0); // no certificates of ownership RR->sw->send(tPtr,outp,true); } - _announceMulticastGroupsTo(tPtr,c,groups); + _announceMulticastGroupsTo(tPtr,*a,groups); } } - // Make sure that all "network anchors" have Membership records so we will - // push multicasts to them. - const std::vector<Address> anchors(_config.anchors()); - for(std::vector<Address>::const_iterator a(anchors.begin());a!=anchors.end();++a) - _membership(*a); - - // Send credentials and multicast LIKEs to members, upstreams, and controller { Address *a = (Address *)0; Membership *m = (Membership *)0; Hashtable<Address,Membership>::Iterator i(_memberships); while (i.next(a,m)) { m->pushCredentials(RR,tPtr,now,*a,_config,-1,false); - if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config)) ) + if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config)) && (!std::binary_search(alwaysAnnounceTo.begin(),alwaysAnnounceTo.end(),*a)) ) _announceMulticastGroupsTo(tPtr,*a,groups); } } |