Logic simplification, cleanup, and memory use improvements in Membership. Also fix an issue that may cause network instability in some cases.

This commit is contained in:
Adam Ierymenko 2017-04-04 08:07:38 -07:00
parent 8a62ba07e5
commit eddbc7e757
10 changed files with 175 additions and 124 deletions

View file

@ -534,9 +534,9 @@ static _doZtFilterResult _doZtFilter(
}
if (inbound) {
if (membership) {
if ((src)&&(membership->hasCertificateOfOwnershipFor(nconf,src)))
if ((src)&&(membership->hasCertificateOfOwnershipFor<InetAddress>(nconf,src)))
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_IP_AUTHENTICATED;
if (membership->hasCertificateOfOwnershipFor(nconf,macSource))
if (membership->hasCertificateOfOwnershipFor<MAC>(nconf,macSource))
ownershipVerificationMask |= ZT_RULE_PACKET_CHARACTERISTICS_SENDER_MAC_AUTHENTICATED;
}
} else {
@ -1143,21 +1143,31 @@ int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToD
// _lock is NOT locked when this is called
try {
if ((nconf.issuedTo != RR->identity.address())||(nconf.networkId != _id))
return 0;
return 0; // invalid config that is not for us or not for this network
if (_config == nconf)
return 1; // OK config, but duplicate of what we already have
ZT_VirtualNetworkConfig ctmp;
bool oldPortInitialized;
{
{ // do things that require lock here, but unlock before calling callbacks
Mutex::Lock _l(_lock);
_config = nconf;
_lastConfigUpdate = RR->node->now();
_netconfFailure = NETCONF_FAILURE_NONE;
oldPortInitialized = _portInitialized;
_portInitialized = true;
_externalConfig(&ctmp);
Address *a = (Address *)0;
Membership *m = (Membership *)0;
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m))
m->resetPushState();
}
_portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
if (saveToDisk) {
@ -1299,10 +1309,9 @@ bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
if ( (_config.isPublic()) || ((m)&&(m->isAllowedOnNetwork(_config))) ) {
if (!m)
m = &(_membership(peer->address()));
if (m->shouldLikeMulticasts(now)) {
if (m->multicastLikeGate(now)) {
m->pushCredentials(RR,tPtr,now,peer->address(),_config,-1,false);
_announceMulticastGroupsTo(tPtr,peer->address(),_allMulticastGroups());
m->likingMulticasts(now);
}
return true;
}
@ -1338,6 +1347,7 @@ void Network::clean()
while (i.next(a,m)) {
if (!RR->topology->getPeerNoCache(*a))
_memberships.erase(*a);
else m->clean(now,_config);
}
}
}
@ -1546,8 +1556,7 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
}
// Make sure that all "network anchors" have Membership records so we will
// push multicasts to them. Note that _membership() also does this but in a
// piecemeal on-demand fashion.
// 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);
@ -1559,11 +1568,8 @@ void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMu
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m)) {
m->pushCredentials(RR,tPtr,now,*a,_config,-1,false);
if ( ((newMulticastGroup)||(m->shouldLikeMulticasts(now))) && (m->isAllowedOnNetwork(_config)) ) {
if (!newMulticastGroup)
m->likingMulticasts(now);
if ( ( m->multicastLikeGate(now) || (newMulticastGroup) ) && (m->isAllowedOnNetwork(_config)) )
_announceMulticastGroupsTo(tPtr,*a,groups);
}
}
}
}