diff options
-rw-r--r-- | include/ZeroTierOne.h | 45 | ||||
-rw-r--r-- | node/Node.cpp | 36 | ||||
-rw-r--r-- | node/Peer.cpp | 8 | ||||
-rw-r--r-- | node/Peer.hpp | 13 | ||||
-rw-r--r-- | node/Topology.hpp | 9 |
5 files changed, 67 insertions, 44 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 10b6d37f..4f743f78 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -99,6 +99,11 @@ extern "C" { #define ZT1_MAX_NETWORK_MULTICAST_SUBSCRIPTIONS 4096 /** + * Maximum number of direct network paths to a given peer + */ +#define ZT1_MAX_PEER_NETWORK_PATHS 4 + +/** * Feature flag: ZeroTier One was built to be thread-safe -- concurrent processXXX() calls are okay */ #define ZT1_FEATURE_FLAG_THREAD_SAFE 0x00000001 @@ -501,34 +506,14 @@ typedef struct struct sockaddr_storage address; /** - * Time since last send in milliseconds or -1 for never - */ - long lastSend; - - /** - * Time since last receive in milliseconds or -1 for never - */ - long lastReceive; - - /** - * Time since last ping sent in milliseconds or -1 for never + * Time of last send in milliseconds or 0 for never */ - long lastPing; + uint64_t lastSend; /** - * Time since last firewall opener sent in milliseconds or -1 for never + * Time of last receive in milliseconds or 0 for never */ - long lastFirewallOpener; - - /** - * Total bytes sent - */ - uint64_t bytesSent; - - /** - * Total bytes received - */ - uint64_t bytesReceived; + uint64_t lastReceive; /** * Is path fixed? (i.e. not learned, static) @@ -540,7 +525,7 @@ typedef struct * What trust hierarchy role does this peer have? */ enum ZT1_PeerRole { - ZT1_PEER_ROLE_NODE = 0, // ordinary node + ZT1_PEER_ROLE_LEAF = 0, // ordinary node ZT1_PEER_ROLE_HUB = 1, // locally federated hub ZT1_PEER_ROLE_SUPERNODE = 2 // planetary supernode }; @@ -551,7 +536,7 @@ enum ZT1_PeerRole { typedef struct { /** - * ZeroTier binary address (40 bits) + * ZeroTier address (40 bits) */ uint64_t address; @@ -581,14 +566,14 @@ typedef struct enum ZT1_PeerRole role; /** - * Array of network paths to peer + * Number of paths (size of paths[]) */ - ZT1_PeerPhysicalPath *paths; + unsigned int pathCount; /** - * Number of paths (size of paths[]) + * Known network paths to peer */ - unsigned long pathCount; + ZT1_PeerPhysicalPath paths[ZT1_MAX_PEER_NETWORK_PATHS]; } ZT1_Peer; /** diff --git a/node/Node.cpp b/node/Node.cpp index e0eb0c6c..4b6f76ee 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -324,6 +324,42 @@ void Node::status(ZT1_NodeStatus *status) ZT1_PeerList *Node::peers() { + std::map< Address,SharedPtr<Peer> > peers(RR->topology->allPeers()); + + char *buf = (char *)::malloc(sizeof(ZT1_PeerList) + (sizeof(ZT1_Peer) * peers.size())); + if (!buf) + return (ZT1_PeerList *)0; + ZT1_PeerList *pl = (ZT1_PeerList *)buf; + pl->peers = (ZT1_Peer *)(buf + sizeof(ZT1_PeerList)); + + pl->peerCount = 0; + for(std::map< Address,SharedPtr<Peer> >::iterator pi(peers.begin());pi!=peers.end();++pi) { + ZT1_Peer *p = &(pl->peers[pl->peerCount++]); + p->address = pi->second->address().toInt(); + if (pi->second->remoteVersionKnown()) { + p->versionMajor = pi->second->remoteVersionMajor(); + p->versionMinor = pi->second->remoteVersionMinor(); + p->versionRev = pi->second->remoteVersionRevision(); + } else { + p->versionMajor = -1; + p->versionMinor = -1; + p->versionRev = -1; + } + p->latency = pi->second->latency(); + p->role = RR->topology->isSupernode(pi->second->address()) ? ZT1_PEER_ROLE_SUPERNODE : ZT1_PEER_ROLE_LEAF; + + std::vector<Path> paths(pi->second->paths()); + p->pathCount = 0; + for(std::vector<Path>::iterator path(paths.begin());path!=paths.end();++path) { + memcpy(&(p->paths[p->pathCount].address),&(path->address()),sizeof(struct sockaddr_storage)); + p->paths[p->pathCount].lastSend = path->lastSend(); + p->paths[p->pathCount].lastReceive = path->lastReceived(); + p->paths[p->pathCount].fixed = path->fixed() ? 1 : 0; + ++p->pathCount; + } + } + + return pl; } ZT1_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) diff --git a/node/Peer.cpp b/node/Peer.cpp index 3270a231..8639da8f 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -87,13 +87,13 @@ void Peer::received( if ((verb == Packet::VERB_OK)&&(inReVerb == Packet::VERB_HELLO)) { // Learn paths if they've been confirmed via a HELLO Path *slot = (Path *)0; - if (np < ZT_PEER_MAX_PATHS) { + if (np < ZT1_MAX_PEER_NETWORK_PATHS) { // Add new path slot = &(_paths[np++]); } else { // Replace oldest non-fixed path uint64_t slotLRmin = 0xffffffffffffffffULL; - for(unsigned int p=0;p<ZT_PEER_MAX_PATHS;++p) { + for(unsigned int p=0;p<ZT1_MAX_PEER_NETWORK_PATHS;++p) { if ((!_paths[p].fixed())&&(_paths[p].lastReceived() <= slotLRmin)) { slotLRmin = _paths[p].lastReceived(); slot = &(_paths[p]); @@ -218,13 +218,13 @@ void Peer::addPath(const Path &newp) } Path *slot = (Path *)0; - if (np < ZT_PEER_MAX_PATHS) { + if (np < ZT1_MAX_PEER_NETWORK_PATHS) { // Add new path slot = &(_paths[np++]); } else { // Replace oldest non-fixed path uint64_t slotLRmin = 0xffffffffffffffffULL; - for(unsigned int p=0;p<ZT_PEER_MAX_PATHS;++p) { + for(unsigned int p=0;p<ZT1_MAX_PEER_NETWORK_PATHS;++p) { if ((!_paths[p].fixed())&&(_paths[p].lastReceived() <= slotLRmin)) { slotLRmin = _paths[p].lastReceived(); slot = &(_paths[p]); diff --git a/node/Peer.hpp b/node/Peer.hpp index c4de75e6..65307e9e 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -49,11 +49,6 @@ #include "AtomicCounter.hpp" #include "NonCopyable.hpp" -/** - * Maximum number of paths a peer can have - */ -#define ZT_PEER_MAX_PATHS 3 - namespace ZeroTier { /** @@ -192,7 +187,7 @@ public: /** * @return All known direct paths to this peer */ - std::vector<Path> paths() const + inline std::vector<Path> paths() const { std::vector<Path> pp; for(unsigned int p=0,np=_numPaths;p<np;++p) @@ -347,10 +342,10 @@ public: } inline unsigned int remoteVersionProtocol() const throw() { return _vProto; } - inline unsigned int remoteVersionMajor() const throw() { return _vMajor; } inline unsigned int remoteVersionMinor() const throw() { return _vMinor; } inline unsigned int remoteVersionRevision() const throw() { return _vRevision; } + inline bool remoteVersionKnown() const throw() { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); } /** * Check whether this peer's version is both known and is at least what is specified @@ -378,8 +373,6 @@ public: return false; } - inline bool remoteVersionKnown() const throw() { return ((_vMajor > 0)||(_vMinor > 0)||(_vRevision > 0)); } - /** * Get most recently active UDP path addresses for IPv4 and/or IPv6 * @@ -451,7 +444,7 @@ private: uint16_t _vMinor; uint16_t _vRevision; Identity _id; - Path _paths[ZT_PEER_MAX_PATHS]; + Path _paths[ZT1_MAX_PEER_NETWORK_PATHS]; unsigned int _numPaths; unsigned int _latency; diff --git a/node/Topology.hpp b/node/Topology.hpp index 242ef93b..63c81016 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -188,6 +188,15 @@ public: } /** + * @return All currently active peers by address + */ + inline std::map< Address,SharedPtr<Peer> > allPeers() const + { + Mutex::Lock _l(_lock); + return _activePeers; + } + + /** * Validate a root topology dictionary against the identities specified in Defaults * * @param rt Root topology dictionary |