mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-21 22:03:52 -07:00
Fix and modernize API peer list function.
This commit is contained in:
parent
31eb950750
commit
bab9a7f508
4 changed files with 114 additions and 89 deletions
|
@ -115,6 +115,12 @@ struct UniqueID
|
||||||
static_assert(sizeof(SHA384Hash) == 48,"SHA384Hash contains unnecessary padding");
|
static_assert(sizeof(SHA384Hash) == 48,"SHA384Hash contains unnecessary padding");
|
||||||
static_assert(sizeof(UniqueID) == 16,"UniqueID contains unnecessary padding");
|
static_assert(sizeof(UniqueID) == 16,"UniqueID contains unnecessary padding");
|
||||||
|
|
||||||
|
template<unsigned long S>
|
||||||
|
struct Blob
|
||||||
|
{
|
||||||
|
uint8_t data[S];
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
174
core/Node.cpp
174
core/Node.cpp
|
@ -58,12 +58,6 @@ struct _NodeObjects
|
||||||
Topology topology;
|
Topology topology;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _sortPeerPtrsByAddress
|
|
||||||
{
|
|
||||||
ZT_INLINE bool operator()(const SharedPtr< Peer > &a, const SharedPtr< Peer > &b) const
|
|
||||||
{ return (a->address() < b->address()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
Node::Node(
|
Node::Node(
|
||||||
|
@ -152,6 +146,7 @@ Node::Node(
|
||||||
Node::~Node()
|
Node::~Node()
|
||||||
{
|
{
|
||||||
ZT_SPEW("node destructor run");
|
ZT_SPEW("node destructor run");
|
||||||
|
|
||||||
m_networks_l.lock();
|
m_networks_l.lock();
|
||||||
m_networks_l.unlock();
|
m_networks_l.unlock();
|
||||||
m_networks.clear();
|
m_networks.clear();
|
||||||
|
@ -367,9 +362,7 @@ ZT_ResultCode Node::multicastUnsubscribe(
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Node::address() const
|
uint64_t Node::address() const
|
||||||
{
|
{ return RR->identity.address().toInt(); }
|
||||||
return RR->identity.address().toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Node::status(ZT_NodeStatus *status) const
|
void Node::status(ZT_NodeStatus *status) const
|
||||||
{
|
{
|
||||||
|
@ -380,88 +373,109 @@ void Node::status(ZT_NodeStatus *status) const
|
||||||
status->online = m_online ? 1 : 0;
|
status->online = m_online ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct p_ZT_PeerListPrivate : public ZT_PeerList
|
||||||
|
{
|
||||||
|
// Actual containers for the memory, hidden from external users.
|
||||||
|
std::vector< ZT_Peer > p_peers;
|
||||||
|
std::list< std::vector<ZT_Path> > p_paths;
|
||||||
|
std::list< Identity > p_identities;
|
||||||
|
std::list< Blob<ZT_LOCATOR_MARSHAL_SIZE_MAX> > p_locators;
|
||||||
|
};
|
||||||
|
static void p_peerListFreeFunction(const void *pl)
|
||||||
|
{
|
||||||
|
if (pl)
|
||||||
|
delete reinterpret_cast<p_ZT_PeerListPrivate *>(const_cast<void *>(pl));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct p_sortPeerPtrsByAddress
|
||||||
|
{
|
||||||
|
ZT_INLINE bool operator()(const SharedPtr< Peer > &a, const SharedPtr< Peer > &b) const noexcept
|
||||||
|
{ return (a->address() < b->address()); }
|
||||||
|
};
|
||||||
|
|
||||||
ZT_PeerList *Node::peers() const
|
ZT_PeerList *Node::peers() const
|
||||||
{
|
{
|
||||||
Vector< SharedPtr< Peer > > peers, rootPeers;
|
p_ZT_PeerListPrivate *pl = nullptr;
|
||||||
RR->topology->allPeers(peers, rootPeers);
|
try {
|
||||||
|
pl = new p_ZT_PeerListPrivate;
|
||||||
|
pl->freeFunction = p_peerListFreeFunction;
|
||||||
|
|
||||||
std::sort(peers.begin(), peers.end(), _sortPeerPtrsByAddress());
|
Vector< SharedPtr< Peer > > peers, rootPeers;
|
||||||
|
RR->topology->allPeers(peers, rootPeers);
|
||||||
|
std::sort(peers.begin(), peers.end(), p_sortPeerPtrsByAddress());
|
||||||
|
std::sort(rootPeers.begin(), rootPeers.end());
|
||||||
|
int64_t now = m_now;
|
||||||
|
|
||||||
const unsigned int bufSize =
|
for (Vector< SharedPtr< Peer > >::iterator pi(peers.begin()); pi != peers.end(); ++pi) {
|
||||||
sizeof(ZT_PeerList) +
|
pl->p_peers.push_back(ZT_Peer());
|
||||||
(sizeof(ZT_Peer) * peers.size()) +
|
ZT_Peer &p = pl->p_peers.back();
|
||||||
((sizeof(ZT_Path) * ZT_MAX_PEER_NETWORK_PATHS) * peers.size()) +
|
Peer &pp = **pi;
|
||||||
(sizeof(Identity) * peers.size()) +
|
|
||||||
(ZT_LOCATOR_MARSHAL_SIZE_MAX * peers.size());
|
|
||||||
char *buf = (char *)malloc(bufSize);
|
|
||||||
if (!buf)
|
|
||||||
return nullptr;
|
|
||||||
Utils::zero(buf, bufSize);
|
|
||||||
ZT_PeerList *pl = reinterpret_cast<ZT_PeerList *>(buf);
|
|
||||||
buf += sizeof(ZT_PeerList);
|
|
||||||
pl->freeFunction = reinterpret_cast<void (*)(const void *)>(free);
|
|
||||||
pl->peers = reinterpret_cast<ZT_Peer *>(buf);
|
|
||||||
buf += sizeof(ZT_Peer) * peers.size();
|
|
||||||
ZT_Path *peerPath = reinterpret_cast<ZT_Path *>(buf);
|
|
||||||
buf += (sizeof(ZT_Path) * ZT_MAX_PEER_NETWORK_PATHS) * peers.size();
|
|
||||||
Identity *identities = reinterpret_cast<Identity *>(buf);
|
|
||||||
buf += sizeof(Identity) * peers.size();
|
|
||||||
uint8_t *locatorBuf = reinterpret_cast<uint8_t *>(buf);
|
|
||||||
|
|
||||||
const int64_t now = m_now;
|
p.address = pp.address();
|
||||||
|
pl->p_identities.push_back(pp.identity());
|
||||||
|
p.identity = reinterpret_cast<const ZT_Identity *>(&(pl->p_identities.back()));
|
||||||
|
p.fingerprint = &(pl->p_identities.back().fingerprint());
|
||||||
|
if (pp.remoteVersionKnown()) {
|
||||||
|
p.versionMajor = (int)pp.remoteVersionMajor();
|
||||||
|
p.versionMinor = (int)pp.remoteVersionMinor();
|
||||||
|
p.versionRev = (int)pp.remoteVersionRevision();
|
||||||
|
p.versionProto = (int)pp.remoteVersionProtocol();
|
||||||
|
} else {
|
||||||
|
p.versionMajor = -1;
|
||||||
|
p.versionMinor = -1;
|
||||||
|
p.versionRev = -1;
|
||||||
|
p.versionProto = -1;
|
||||||
|
}
|
||||||
|
p.latency = pp.latency();
|
||||||
|
p.root = std::binary_search(rootPeers.begin(), rootPeers.end(), *pi) ? 1 : 0;
|
||||||
|
|
||||||
pl->peerCount = 0;
|
p.networks = nullptr;
|
||||||
for (Vector< SharedPtr< Peer > >::iterator pi(peers.begin()); pi != peers.end(); ++pi) {
|
p.networkCount = 0; // TODO: networks this peer belongs to
|
||||||
ZT_Peer *const p = pl->peers + pl->peerCount;
|
|
||||||
|
|
||||||
p->address = (*pi)->address().toInt();
|
Vector< SharedPtr<Path> > ztPaths;
|
||||||
identities[pl->peerCount] = (*pi)->identity(); // need to make a copy in case peer gets deleted
|
pp.getAllPaths(ztPaths);
|
||||||
p->identity = identities + pl->peerCount;
|
if (ztPaths.empty()) {
|
||||||
p->fingerprint.address = p->address;
|
pl->p_paths.push_back(std::vector< ZT_Path >());
|
||||||
Utils::copy< ZT_FINGERPRINT_HASH_SIZE >(p->fingerprint.hash, (*pi)->identity().fingerprint().hash);
|
std::vector< ZT_Path > &apiPaths = pl->p_paths.back();
|
||||||
if ((*pi)->remoteVersionKnown()) {
|
apiPaths.resize(ztPaths.size());
|
||||||
p->versionMajor = (int)(*pi)->remoteVersionMajor();
|
for (unsigned long i = 0; i < (unsigned long)ztPaths.size(); ++i) {
|
||||||
p->versionMinor = (int)(*pi)->remoteVersionMinor();
|
SharedPtr< Path > &ztp = ztPaths[i];
|
||||||
p->versionRev = (int)(*pi)->remoteVersionRevision();
|
ZT_Path &apip = apiPaths[i];
|
||||||
} else {
|
apip.endpoint.type = ZT_ENDPOINT_TYPE_IP_UDP;
|
||||||
p->versionMajor = -1;
|
Utils::copy< sizeof(struct sockaddr_storage) >(&(apip.endpoint.value.ss), &(ztp->address().as.ss));
|
||||||
p->versionMinor = -1;
|
apip.lastSend = ztp->lastOut();
|
||||||
p->versionRev = -1;
|
apip.lastReceive = ztp->lastIn();
|
||||||
}
|
apip.alive = ztp->alive(now) ? 1 : 0;
|
||||||
p->latency = (*pi)->latency();
|
apip.preferred = (i == 0) ? 1 : 0;
|
||||||
p->root = (std::find(rootPeers.begin(), rootPeers.end(), *pi) != rootPeers.end()) ? 1 : 0;
|
}
|
||||||
|
p.paths = apiPaths.data();
|
||||||
|
p.pathCount = (unsigned int)apiPaths.size();
|
||||||
|
} else {
|
||||||
|
p.paths = nullptr;
|
||||||
|
p.pathCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
p->networkCount = 0;
|
const SharedPtr< const Locator > loc(pp.locator());
|
||||||
// TODO: enumerate network memberships
|
if (loc) {
|
||||||
|
pl->p_locators.push_back(Blob< ZT_LOCATOR_MARSHAL_SIZE_MAX >());
|
||||||
Vector< SharedPtr< Path > > paths;
|
Blob< ZT_LOCATOR_MARSHAL_SIZE_MAX > &lb = pl->p_locators.back();
|
||||||
(*pi)->getAllPaths(paths);
|
Utils::zero< ZT_LOCATOR_MARSHAL_SIZE_MAX >(lb.data);
|
||||||
p->pathCount = (unsigned int)paths.size();
|
const int ls = loc->marshal(lb.data);
|
||||||
p->paths = peerPath;
|
if (ls > 0) {
|
||||||
for (Vector< SharedPtr< Path > >::iterator path(paths.begin()); path != paths.end(); ++path) {
|
p.locatorSize = (unsigned int)ls;
|
||||||
ZT_Path *const pp = peerPath++;
|
p.locator = lb.data;
|
||||||
pp->endpoint.type = ZT_ENDPOINT_TYPE_IP_UDP; // only type supported right now
|
}
|
||||||
Utils::copy< sizeof(sockaddr_storage) >(&pp->endpoint.value.ss, &((*path)->address().as.ss));
|
|
||||||
pp->lastSend = (*path)->lastOut();
|
|
||||||
pp->lastReceive = (*path)->lastIn();
|
|
||||||
pp->alive = (*path)->alive(now) ? 1 : 0;
|
|
||||||
pp->preferred = (p->pathCount == 0) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SharedPtr< const Locator > loc((*pi)->locator());
|
|
||||||
if (loc) {
|
|
||||||
const int ls = loc->marshal(locatorBuf);
|
|
||||||
if (ls > 0) {
|
|
||||||
p->locatorSize = (unsigned int)ls;
|
|
||||||
p->locator = locatorBuf;
|
|
||||||
locatorBuf += ls;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++pl->peerCount;
|
pl->peers = pl->p_peers.data();
|
||||||
}
|
pl->peerCount = (unsigned long)pl->p_peers.size();
|
||||||
|
|
||||||
return pl;
|
return pl;
|
||||||
|
} catch ( ... ) {
|
||||||
|
delete pl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
|
ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
|
||||||
|
@ -482,7 +496,7 @@ ZT_VirtualNetworkList *Node::networks() const
|
||||||
char *const buf = (char *)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * m_networks.size()));
|
char *const buf = (char *)::malloc(sizeof(ZT_VirtualNetworkList) + (sizeof(ZT_VirtualNetworkConfig) * m_networks.size()));
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
ZT_VirtualNetworkList *nl = (ZT_VirtualNetworkList *)buf; // NOLINT(modernize-use-auto,hicpp-use-auto)
|
ZT_VirtualNetworkList *nl = (ZT_VirtualNetworkList *)buf;
|
||||||
nl->freeFunction = reinterpret_cast<void (*)(const void *)>(free);
|
nl->freeFunction = reinterpret_cast<void (*)(const void *)>(free);
|
||||||
nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList));
|
nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList));
|
||||||
|
|
||||||
|
|
|
@ -1578,7 +1578,7 @@ typedef struct
|
||||||
/**
|
/**
|
||||||
* SHA-384 of identity public key(s)
|
* SHA-384 of identity public key(s)
|
||||||
*/
|
*/
|
||||||
ZT_Fingerprint fingerprint;
|
const ZT_Fingerprint *fingerprint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote major version or -1 if not known
|
* Remote major version or -1 if not known
|
||||||
|
@ -1595,6 +1595,11 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
int versionRev;
|
int versionRev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote protocol version or -1 if not known
|
||||||
|
*/
|
||||||
|
int versionProto;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Last measured latency in milliseconds or -1 if unknown
|
* Last measured latency in milliseconds or -1 if unknown
|
||||||
*/
|
*/
|
||||||
|
@ -1605,20 +1610,15 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
int root;
|
int root;
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of networks in which this peer is authenticated
|
|
||||||
*/
|
|
||||||
unsigned int networkCount;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Network IDs for networks (array size: networkCount)
|
* Network IDs for networks (array size: networkCount)
|
||||||
*/
|
*/
|
||||||
uint64_t *networks;
|
uint64_t *networks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of paths (size of paths[])
|
* Number of networks in which this peer is authenticated
|
||||||
*/
|
*/
|
||||||
unsigned int pathCount;
|
unsigned int networkCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Known network paths to peer (array size: pathCount).
|
* Known network paths to peer (array size: pathCount).
|
||||||
|
@ -1629,6 +1629,11 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
ZT_Path *paths;
|
ZT_Path *paths;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of paths (size of paths[])
|
||||||
|
*/
|
||||||
|
unsigned int pathCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of locator in bytes or 0 if none
|
* Size of locator in bytes or 0 if none
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -37,7 +37,7 @@ func newPeerFromCPeer(cp *C.ZT_Peer) (p *Peer, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.Fingerprint = newFingerprintFromCFingerprint(&(cp.fingerprint))
|
p.Fingerprint = newFingerprintFromCFingerprint(cp.fingerprint)
|
||||||
p.Version[0] = int(cp.versionMajor)
|
p.Version[0] = int(cp.versionMajor)
|
||||||
p.Version[1] = int(cp.versionMinor)
|
p.Version[1] = int(cp.versionMinor)
|
||||||
p.Version[2] = int(cp.versionRev)
|
p.Version[2] = int(cp.versionRev)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue