From 31db6f8f3687da87391c04cc0c0cd77c6ad888de Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Apr 2016 12:49:46 -0700 Subject: [PATCH] NetworkConfig refactor almost done. --- node/CertificateOfMembership.hpp | 2 +- node/Multicaster.cpp | 7 +--- node/NetworkConfig.hpp | 3 ++ node/Switch.cpp | 72 +++++++++++++++----------------- 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 34f7807e9..43c8c0af0 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -46,7 +46,7 @@ /** * Maximum number of qualifiers in a COM */ -#define ZT_NETWORK_COM_MAX_QUALIFIERS 32 +#define ZT_NETWORK_COM_MAX_QUALIFIERS 16 namespace ZeroTier { diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index dafa3d887..250da2eb7 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -238,11 +238,8 @@ void Multicaster::send( const CertificateOfMembership *com = (CertificateOfMembership *)0; { SharedPtr nw(RR->node->network(nwid)); - if (nw) { - SharedPtr nconf(nw->config2()); - if ((nconf)&&(nconf->com())&&(nconf->isPrivate())&&(p->needsOurNetworkMembershipCertificate(nwid,now,true))) - com = &(nconf->com()); - } + if ((nw)&&(nw->hasConfig())&&(nw->config().com())&&(nw->config().isPrivate())&&(p->needsOurNetworkMembershipCertificate(nwid,now,true))) + com = &(nw->config().com()); } Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_GATHER); diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index c499eb48a..c3cc9cd46 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -203,6 +203,9 @@ public: return r; } + const ZT_VirtualNetworkStaticDevice &staticDevice(unsigned int i) const { return _static[i]; } + unsigned int staticDeviceCount() const { return _staticCount; } + /** * @param fromPeer Peer attempting to bridge other Ethernet peers onto network * @return True if this network allows bridging diff --git a/node/Switch.cpp b/node/Switch.cpp index 968d1a4a8..b8181d964 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -307,8 +307,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { - SharedPtr nconf(network->config2()); - if (!nconf) + if (!network->hasConfig()) return; // Sanity check -- bridge loop? OS problem? @@ -316,7 +315,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c return; // Check to make sure this protocol is allowed on this network - if (!nconf->permitsEtherType(etherType)) { + if (!network->config().permitsEtherType(etherType)) { TRACE("%.16llx: ignored tap: %s -> %s: ethertype %s not allowed on network %.16llx",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),(unsigned long long)network->id()); return; } @@ -324,7 +323,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c // Check if this packet is from someone other than the tap -- i.e. bridged in bool fromBridged = false; if (from != network->mac()) { - if (!network->permitsBridging(RR->identity.address())) { + if (!network->config().permitsBridging(RR->identity.address())) { TRACE("%.16llx: %s -> %s %s not forwarded, bridging disabled or this peer not a bridge",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType)); return; } @@ -347,7 +346,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c * the 32-bit ADI field. In practice this uses our multicast pub/sub * system to implement a kind of extended/distributed ARP table. */ mg = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(((const unsigned char *)data) + 24,4,0)); - } else if (!nconf->enableBroadcast()) { + } else if (!network->config().enableBroadcast()) { // Don't transmit broadcasts if this network doesn't want them TRACE("%.16llx: dropped broadcast since ff:ff:ff:ff:ff:ff is not enabled",network->id()); return; @@ -363,7 +362,8 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c * themselves, they can look these addresses up with NDP and it will * work just fine. */ if ((reinterpret_cast(data)[6] == 0x3a)&&(reinterpret_cast(data)[40] == 0x87)) { // ICMPv6 neighbor solicitation - for(std::vector::const_iterator sip(nconf->staticIps().begin()),sipend(nconf->staticIps().end());sip!=sipend;++sip) { + std::vector sips(network->config().staticIps()); + for(std::vector::const_iterator sip(sips.begin());sip!=sips.end();++sip) { if ((sip->ss_family == AF_INET6)&&(Utils::ntoh((uint16_t)reinterpret_cast(&(*sip))->sin6_port) == 88)) { const uint8_t *my6 = reinterpret_cast(reinterpret_cast(&(*sip))->sin6_addr.s6_addr); if ((my6[0] == 0xfd)&&(my6[9] == 0x99)&&(my6[10] == 0x93)) { // ZT-RFC4193 == fd__:____:____:____:__99:93__:____:____ / 88 @@ -426,11 +426,11 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c //TRACE("%.16llx: MULTICAST %s -> %s %s %u",network->id(),from.toString().c_str(),mg.toString().c_str(),etherTypeName(etherType),len); RR->mc->send( - ((!nconf->isPublic())&&(nconf->com())) ? &(nconf->com()) : (const CertificateOfMembership *)0, - nconf->multicastLimit(), + ((!network->config().isPublic())&&(network->config().com())) ? &(network->config().com()) : (const CertificateOfMembership *)0, + network->config().multicastLimit(), RR->node->now(), network->id(), - nconf->activeBridges(), + network->config().activeBridges(), mg, (fromBridged) ? from : MAC(), etherType, @@ -445,13 +445,13 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this SharedPtr toPeer(RR->topology->getPeer(toZT)); - const bool includeCom = ( (nconf->isPrivate()) && (nconf->com()) && ((!toPeer)||(toPeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) ); + const bool includeCom = ( (network->config().isPrivate()) && (network->config().com()) && ((!toPeer)||(toPeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) ); if ((fromBridged)||(includeCom)) { Packet outp(toZT,RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); if (includeCom) { outp.append((unsigned char)0x01); // 0x01 -- COM included - nconf->com().serialize(outp); + network->config().com().serialize(outp); } else { outp.append((unsigned char)0x00); } @@ -483,25 +483,26 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c /* Create an array of up to ZT_MAX_BRIDGE_SPAM recipients for this bridged frame. */ bridges[0] = network->findBridgeTo(to); - if ((bridges[0])&&(bridges[0] != RR->identity.address())&&(network->permitsBridging(bridges[0]))) { + std::vector
activeBridges(network->config().activeBridges()); + if ((bridges[0])&&(bridges[0] != RR->identity.address())&&(network->config().permitsBridging(bridges[0]))) { /* We have a known bridge route for this MAC, send it there. */ ++numBridges; - } else if (!nconf->activeBridges().empty()) { + } else if (!activeBridges.empty()) { /* If there is no known route, spam to up to ZT_MAX_BRIDGE_SPAM active * bridges. If someone responds, we'll learn the route. */ - std::vector
::const_iterator ab(nconf->activeBridges().begin()); - if (nconf->activeBridges().size() <= ZT_MAX_BRIDGE_SPAM) { + std::vector
::const_iterator ab(activeBridges.begin()); + if (activeBridges.size() <= ZT_MAX_BRIDGE_SPAM) { // If there are <= ZT_MAX_BRIDGE_SPAM active bridges, spam them all - while (ab != nconf->activeBridges().end()) { + while (ab != activeBridges.end()) { bridges[numBridges++] = *ab; ++ab; } } else { // Otherwise pick a random set of them while (numBridges < ZT_MAX_BRIDGE_SPAM) { - if (ab == nconf->activeBridges().end()) - ab = nconf->activeBridges().begin(); - if (((unsigned long)RR->node->prng() % (unsigned long)nconf->activeBridges().size()) == 0) { + if (ab == activeBridges.end()) + ab = activeBridges.begin(); + if (((unsigned long)RR->node->prng() % (unsigned long)activeBridges.size()) == 0) { bridges[numBridges++] = *ab; ++ab; } else ++ab; @@ -513,9 +514,9 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c SharedPtr bridgePeer(RR->topology->getPeer(bridges[b])); Packet outp(bridges[b],RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); - if ( (nconf->isPrivate()) && (nconf->com()) && ((!bridgePeer)||(bridgePeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) ) { + if ( (network->config().isPrivate()) && (network->config().com()) && ((!bridgePeer)||(bridgePeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) ) { outp.append((unsigned char)0x01); // 0x01 -- COM included - nconf->com().serialize(outp); + network->config().com().serialize(outp); } else { outp.append((unsigned char)0); } @@ -783,31 +784,26 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) const uint64_t now = RR->node->now(); SharedPtr network; - SharedPtr nconf; if (nwid) { network = RR->node->network(nwid); - if (!network) + if ((!network)||(!network->hasConfig())) return false; // we probably just left this network, let its packets die - nconf = network->config2(); - if (!nconf) - return false; // sanity check: unconfigured network? why are we trying to talk to it? } Path *viaPath = peer->getBestPath(now); SharedPtr relay; - if (!viaPath) { + if ((!viaPath)&&(network)) { // See if this network has a preferred relay (if packet has an associated network) - if (nconf) { - unsigned int bestq = ~((unsigned int)0); - for(std::vector< std::pair >::const_iterator r(nconf->relays().begin());r!=nconf->relays().end();++r) { - if (r->first != peer->address()) { - SharedPtr rp(RR->topology->getPeer(r->first)); - if (rp) { - const unsigned int q = rp->relayQuality(now); - if (q < bestq) { // SUBTILE: < == don't use these if they are nil quality (unsigned int max), instead use a root - bestq = q; - rp.swap(relay); - } + unsigned int bestq = ~((unsigned int)0); + for(unsigned int ri=0;riconfig().staticDeviceCount();++ri) { + const ZT_VirtualNetworkStaticDevice &r = network->config().staticDevice(ri); + if ((r.address != peer->address().toInt())&&((r.flags & ZT_NETWORK_STATIC_DEVICE_IS_RELAY) != 0)) { + SharedPtr rp(RR->topology->getPeer(Address(r.address))); + if (rp) { + const unsigned int q = rp->relayQuality(now); + if (q < bestq) { // SUBTILE: < == don't use these if they are nil quality (unsigned int max), instead use a root + bestq = q; + rp.swap(relay); } } }