Add network ID to upstream lookup, cleanup, release notes for 1.16.

This commit is contained in:
Adam Ierymenko 2025-07-15 13:54:10 -04:00
parent 697011df7b
commit 58c80ff0ab
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
10 changed files with 136 additions and 253 deletions

View file

@ -13,11 +13,11 @@
#include "Bond.hpp"
#include "Node.hpp"
#include "Switch.hpp"
#include <cinttypes> // for PRId64, etc. macros
#include <cmath>
#include <cstdio>
#include <string>
// FIXME: remove this suppression and actually fix warnings

View file

@ -27,7 +27,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
/**
@ -378,28 +377,6 @@ class NetworkConfig {
return false;
}
inline std::vector<Address> alwaysContactAddresses() const
{
std::vector<Address> r;
for (unsigned int i = 0; i < specialistCount; ++i) {
if ((specialists[i] & (ZT_NETWORKCONFIG_SPECIALIST_TYPE_NETWORK_RELAY | ZT_NETWORKCONFIG_SPECIALIST_TYPE_MULTICAST_REPLICATOR)) != 0) {
r.push_back(Address(specialists[i]));
}
}
return r;
}
inline unsigned int alwaysContactAddresses(Address ac[ZT_MAX_NETWORK_SPECIALISTS]) const
{
unsigned int c = 0;
for (unsigned int i = 0; i < specialistCount; ++i) {
if ((specialists[i] & (ZT_NETWORKCONFIG_SPECIALIST_TYPE_NETWORK_RELAY | ZT_NETWORKCONFIG_SPECIALIST_TYPE_MULTICAST_REPLICATOR)) != 0) {
ac[c++] = specialists[i];
}
}
return c;
}
inline void alwaysContactAddresses(Hashtable<Address, std::vector<InetAddress> >& a) const
{
for (unsigned int i = 0; i < specialistCount; ++i) {
@ -427,14 +404,6 @@ class NetworkConfig {
{
return (networkId != 0);
}
inline bool operator==(const NetworkConfig& nc) const
{
return (memcmp(this, &nc, sizeof(NetworkConfig)) == 0);
}
inline bool operator!=(const NetworkConfig& nc) const
{
return (! (*this == nc));
}
/**
* Add a specialist or mask flags if already present

View file

@ -15,7 +15,6 @@
#include "../version.h"
#include "Address.hpp"
#include "Buffer.hpp"
#include "Constants.hpp"
#include "ECC.hpp"
#include "Identity.hpp"
@ -184,6 +183,7 @@ Node::~Node()
Mutex::Lock _l(_networks_m);
_networks.clear(); // destroy all networks before shutdown
}
// Explicitly call destructors then free memory for all other objects.
if (RR->sa) {
RR->sa->~SelfAwareness();
}
@ -251,7 +251,7 @@ class _PingPeersThatNeedPing {
, _tPtr(tPtr)
, _alwaysContact(alwaysContact)
, _now(now)
, _bestCurrentUpstream(RR->topology->getUpstreamPeer())
, _bestCurrentUpstream(RR->topology->getUpstreamPeer(0))
{
}
@ -340,9 +340,9 @@ ZT_ResultCode Node::processBackgroundTasks(void* tptr, int64_t now, volatile int
try {
_lastPingCheck = now;
// Get designated VL1 upstreams
// Get designated VL1 upstreams (roots)
Hashtable<Address, std::vector<InetAddress> > alwaysContact;
RR->topology->getUpstreamsToContact(alwaysContact);
RR->topology->getRootsToContact(alwaysContact);
// Uncomment to dump stats
/*

View file

@ -119,4 +119,4 @@ void PacketMultiplexer::setUpPostDecodeReceiveThreads(unsigned int concurrency,
}
}
} // namespace ZeroTier
} // namespace ZeroTier

View file

@ -19,8 +19,8 @@
#include "InetAddress.hpp"
#include "Metrics.hpp"
#include "Network.hpp"
#include "Node.hpp"
#include "Packet.hpp"
#include "RingBuffer.hpp"
#include "SelfAwareness.hpp"
#include "Switch.hpp"
#include "Trace.hpp"

View file

@ -20,12 +20,10 @@
#include "AtomicCounter.hpp"
#include "Bond.hpp"
#include "Constants.hpp"
#include "Hashtable.hpp"
#include "Identity.hpp"
#include "InetAddress.hpp"
#include "Metrics.hpp"
#include "Mutex.hpp"
#include "Node.hpp"
#include "Packet.hpp"
#include "Path.hpp"
#include "RuntimeEnvironment.hpp"

View file

@ -14,7 +14,6 @@
#include "Switch.hpp"
#include "../include/ZeroTierOne.h"
#include "../version.h"
#include "Constants.hpp"
#include "InetAddress.hpp"
#include "Metrics.hpp"
@ -27,14 +26,12 @@
#include "Trace.hpp"
#include <algorithm>
#include <stdexcept>
#include <stdio.h>
#include <stdlib.h>
#include <utility>
namespace ZeroTier {
Switch::Switch(const RuntimeEnvironment* renv) : RR(renv), _lastBeaconResponse(0), _lastCheckedQueues(0), _lastUniteAttempt(8) // only really used on root servers and upstreams, and it'll grow there just fine
Switch::Switch(const RuntimeEnvironment* renv) : RR(renv), _lastBeaconResponse(0), _lastCheckedQueues(0), _lastUniteAttempt(8)
{
}

View file

@ -14,12 +14,11 @@
#include "Topology.hpp"
#include "Buffer.hpp"
#include "Constants.hpp"
#include "Network.hpp"
#include "NetworkConfig.hpp"
#include "Node.hpp"
#include "RuntimeEnvironment.hpp"
#include "Switch.hpp"
#include "Trace.hpp"
namespace ZeroTier {
@ -146,30 +145,40 @@ Identity Topology::getIdentity(void* tPtr, const Address& zta)
return Identity();
}
SharedPtr<Peer> Topology::getUpstreamPeer()
SharedPtr<Peer> Topology::getUpstreamPeer(const uint64_t nwid)
{
const int64_t now = RR->node->now();
unsigned int bestq = ~((unsigned int)0);
const SharedPtr<Peer>* best = (const SharedPtr<Peer>*)0;
Mutex::Lock _l2(_peers_m);
Mutex::Lock _l1(_upstreams_m);
for (std::vector<Address>::const_iterator a(_upstreamAddresses.begin()); a != _upstreamAddresses.end(); ++a) {
const SharedPtr<Peer>* p = _peers.get(*a);
if (p) {
const unsigned int q = (*p)->relayQuality(now);
if (q <= bestq) {
bestq = q;
best = p;
}
// If this is related to a network, check for a network specific relay.
if (nwid) {
SharedPtr<Network> network = RR->node->network(nwid);
if (network) {
//
}
}
if (! best) {
return SharedPtr<Peer>();
// If this is unrelated to a network OR there is no network-specific relay, send via a root.
{
Mutex::Lock _l2(_peers_m);
Mutex::Lock _l1(_upstreams_m);
for (std::vector<Address>::const_iterator a(_upstreamAddresses.begin()); a != _upstreamAddresses.end(); ++a) {
const SharedPtr<Peer>* p = _peers.get(*a);
if (p) {
const unsigned int q = (*p)->relayQuality(now);
if (q <= bestq) {
bestq = q;
best = p;
}
}
}
if (best) {
return *best;
}
}
return *best;
return SharedPtr<Peer>();
}
bool Topology::isUpstream(const Identity& id) const
@ -245,6 +254,38 @@ bool Topology::isProhibitedEndpoint(const Address& ztaddr, const InetAddress& ip
return false;
}
void Topology::getRootsToContact(Hashtable<Address, std::vector<InetAddress> >& eps) const
{
Mutex::Lock _l(_upstreams_m);
for (std::vector<World::Root>::const_iterator i(_planet.roots().begin()); i != _planet.roots().end(); ++i) {
if (i->identity != RR->identity) {
std::vector<InetAddress>& ips = eps[i->identity.address()];
for (std::vector<InetAddress>::const_iterator j(i->stableEndpoints.begin()); j != i->stableEndpoints.end(); ++j) {
if (std::find(ips.begin(), ips.end(), *j) == ips.end()) {
ips.push_back(*j);
}
}
}
}
for (std::vector<World>::const_iterator m(_moons.begin()); m != _moons.end(); ++m) {
for (std::vector<World::Root>::const_iterator i(m->roots().begin()); i != m->roots().end(); ++i) {
if (i->identity != RR->identity) {
std::vector<InetAddress>& ips = eps[i->identity.address()];
for (std::vector<InetAddress>::const_iterator j(i->stableEndpoints.begin()); j != i->stableEndpoints.end(); ++j) {
if (std::find(ips.begin(), ips.end(), *j) == ips.end()) {
ips.push_back(*j);
}
}
}
}
}
for (std::vector<std::pair<uint64_t, Address> >::const_iterator m(_moonSeeds.begin()); m != _moonSeeds.end(); ++m) {
eps[m->second];
}
}
bool Topology::addWorld(void* tPtr, const World& newWorld, bool alwaysAcceptNew)
{
if ((newWorld.type() != World::TYPE_PLANET) && (newWorld.type() != World::TYPE_MOON)) {

View file

@ -16,7 +16,6 @@
#include "../include/ZeroTierOne.h"
#include "Address.hpp"
#include "Constants.hpp"
#include "Hashtable.hpp"
#include "Identity.hpp"
#include "InetAddress.hpp"
@ -26,9 +25,7 @@
#include "World.hpp"
#include <algorithm>
#include <stdexcept>
#include <stdio.h>
#include <string.h>
#include <utility>
#include <vector>
@ -112,9 +109,10 @@ class Topology {
/**
* Get the current best upstream peer
*
* @param nwid Network ID or 0 if this is to send something unrelated to a specific network
* @return Upstream or NULL if none available
*/
SharedPtr<Peer> getUpstreamPeer();
SharedPtr<Peer> getUpstreamPeer(const uint64_t nwid);
/**
* @param id Identity to check
@ -155,35 +153,7 @@ class Topology {
*
* @param eps Hash table to fill with addresses and their stable endpoints
*/
inline void getUpstreamsToContact(Hashtable<Address, std::vector<InetAddress> >& eps) const
{
Mutex::Lock _l(_upstreams_m);
for (std::vector<World::Root>::const_iterator i(_planet.roots().begin()); i != _planet.roots().end(); ++i) {
if (i->identity != RR->identity) {
std::vector<InetAddress>& ips = eps[i->identity.address()];
for (std::vector<InetAddress>::const_iterator j(i->stableEndpoints.begin()); j != i->stableEndpoints.end(); ++j) {
if (std::find(ips.begin(), ips.end(), *j) == ips.end()) {
ips.push_back(*j);
}
}
}
}
for (std::vector<World>::const_iterator m(_moons.begin()); m != _moons.end(); ++m) {
for (std::vector<World::Root>::const_iterator i(m->roots().begin()); i != m->roots().end(); ++i) {
if (i->identity != RR->identity) {
std::vector<InetAddress>& ips = eps[i->identity.address()];
for (std::vector<InetAddress>::const_iterator j(i->stableEndpoints.begin()); j != i->stableEndpoints.end(); ++j) {
if (std::find(ips.begin(), ips.end(), *j) == ips.end()) {
ips.push_back(*j);
}
}
}
}
}
for (std::vector<std::pair<uint64_t, Address> >::const_iterator m(_moonSeeds.begin()); m != _moonSeeds.end(); ++m) {
eps[m->second];
}
}
void getRootsToContact(Hashtable<Address, std::vector<InetAddress> >& eps) const;
/**
* @return Vector of active upstream addresses (including roots)