Clean up handling of COMs, network access control, and fix a backward compatiblity issue.

This commit is contained in:
Adam Ierymenko 2016-09-08 19:48:05 -07:00
parent 1f6b13b7fd
commit 16df2c3363
8 changed files with 86 additions and 58 deletions

View file

@ -877,7 +877,7 @@ void Network::multicastSubscribe(const MulticastGroup &mg)
return;
_myMulticastGroups.push_back(mg);
std::sort(_myMulticastGroups.begin(),_myMulticastGroups.end());
_announceMulticastGroups(&mg);
_pushStateToMembers(&mg);
}
}
@ -1062,6 +1062,36 @@ void Network::requestConfiguration()
_inboundConfigChunks.clear();
}
bool Network::gate(const SharedPtr<Peer> &peer,const Packet::Verb verb,const uint64_t packetId)
{
Mutex::Lock _l(_lock);
try {
if (_config) {
Membership &m = _membership(peer->address());
const bool allow = m.isAllowedOnNetwork(_config);
if (allow) {
const uint64_t now = RR->node->now();
m.sendCredentialsIfNeeded(RR,now,peer->address(),_config,(const Capability *)0);
if (m.shouldLikeMulticasts(now)) {
_announceMulticastGroupsTo(peer->address(),_allMulticastGroups());
m.likingMulticasts(now);
}
} else if (m.recentlyAllowedOnNetwork(_config)) {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
outp.append((uint8_t)verb);
outp.append(packetId);
outp.append((uint8_t)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
outp.append(_id);
RR->sw->send(outp,true);
}
return allow;
}
} catch ( ... ) {
TRACE("gate() check failed for peer %s: unexpected exception",peer->address().toString().c_str());
}
return false;
}
void Network::clean()
{
const uint64_t now = RR->node->now();
@ -1135,7 +1165,7 @@ void Network::learnBridgedMulticastGroup(const MulticastGroup &mg,uint64_t now)
const unsigned long tmp = (unsigned long)_multicastGroupsBehindMe.size();
_multicastGroupsBehindMe.set(mg,now);
if (tmp != _multicastGroupsBehindMe.size())
_announceMulticastGroups(&mg);
_pushStateToMembers(&mg);
}
void Network::destroy()
@ -1200,33 +1230,18 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
}
}
bool Network::_isAllowed(const SharedPtr<Peer> &peer) const
{
// Assumes _lock is locked
try {
if (_config) {
const Membership *const m = _memberships.get(peer->address());
if (m)
return m->isAllowedOnNetwork(_config);
}
} catch ( ... ) {
TRACE("isAllowed() check failed for peer %s: unexpected exception",peer->address().toString().c_str());
}
return false;
}
void Network::_announceMulticastGroups(const MulticastGroup *const onlyThis)
void Network::_pushStateToMembers(const MulticastGroup *const newMulticastGroup)
{
// Assumes _lock is locked
const uint64_t now = RR->node->now();
std::vector<MulticastGroup> groups;
if (onlyThis)
groups.push_back(*onlyThis);
if (newMulticastGroup)
groups.push_back(*newMulticastGroup);
else groups = _allMulticastGroups();
if ((onlyThis)||((now - _lastAnnouncedMulticastGroupsUpstream) >= ZT_MULTICAST_ANNOUNCE_PERIOD)) {
if (!onlyThis)
if ((newMulticastGroup)||((now - _lastAnnouncedMulticastGroupsUpstream) >= ZT_MULTICAST_ANNOUNCE_PERIOD)) {
if (!newMulticastGroup)
_lastAnnouncedMulticastGroupsUpstream = now;
// Announce multicast groups to upstream peers (roots, etc.) and also send
@ -1255,7 +1270,7 @@ void Network::_announceMulticastGroups(const MulticastGroup *const onlyThis)
// piecemeal on-demand fashion.
const std::vector<Address> anchors(_config.anchors());
for(std::vector<Address>::const_iterator a(anchors.begin());a!=anchors.end();++a)
_memberships[*a];
_membership(*a);
// Send MULTICAST_LIKE(s) to all members of this network
{
@ -1263,11 +1278,13 @@ void Network::_announceMulticastGroups(const MulticastGroup *const onlyThis)
Membership *m = (Membership *)0;
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m)) {
if ((onlyThis)||(m->shouldLikeMulticasts(now))) {
if (!onlyThis)
m->likingMulticasts(now);
if ( (m->recentlyAllowedOnNetwork(_config)) || (std::find(anchors.begin(),anchors.end(),*a) != anchors.end()) ) {
m->sendCredentialsIfNeeded(RR,RR->node->now(),*a,_config,(const Capability *)0);
_announceMulticastGroupsTo(*a,groups);
if ( ((newMulticastGroup)||(m->shouldLikeMulticasts(now))) && (m->isAllowedOnNetwork(_config)) ) {
if (!newMulticastGroup)
m->likingMulticasts(now);
_announceMulticastGroupsTo(*a,groups);
}
}
}
}
@ -1314,15 +1331,7 @@ std::vector<MulticastGroup> Network::_allMulticastGroups() const
Membership &Network::_membership(const Address &a)
{
// assumes _lock is locked
const unsigned long ms = _memberships.size();
Membership &m = _memberships[a];
if (ms != _memberships.size()) {
const uint64_t now = RR->node->now();
m.sendCredentialsIfNeeded(RR,now,a,_config,(const Capability *)0);
_announceMulticastGroupsTo(a,_allMulticastGroups());
m.likingMulticasts(now);
}
return m;
return _memberships[a];
}
} // namespace ZeroTier