diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/Constants.hpp | 5 | ||||
-rw-r--r-- | node/Node.cpp | 41 | ||||
-rw-r--r-- | node/Node.hpp | 6 | ||||
-rw-r--r-- | node/Peer.hpp | 40 | ||||
-rw-r--r-- | node/Topology.hpp | 31 |
5 files changed, 109 insertions, 14 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp index 641b25bb..394c89eb 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -254,6 +254,11 @@ error_no_ZT_ARCH #define ZT_AUTOCONFIGURE_CHECK_DELAY 15000 /** + * Delay between updates of status file in home directory + */ +#define ZT_STATUS_OUTPUT_PERIOD 120000 + +/** * Minimum delay in Node service loop * * This is the shortest of the check delays/periods. diff --git a/node/Node.cpp b/node/Node.cpp index 830ee354..85029e81 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -74,8 +74,9 @@ struct _NodeImpl RuntimeEnvironment renv; std::string reasonForTerminationStr; Node::ReasonForTermination reasonForTermination; - bool started; - bool running; + volatile bool started; + volatile bool running; + volatile bool updateStatusNow; volatile bool terminateNow; // Helper used to rapidly terminate from run() @@ -104,6 +105,7 @@ Node::Node(const char *hp,const char *urlPrefix,const char *configAuthorityIdent impl->reasonForTermination = Node::NODE_RUNNING; impl->started = false; impl->running = false; + impl->updateStatusNow = false; impl->terminateNow = false; } @@ -236,6 +238,8 @@ Node::ReasonForTermination Node::run() } try { + std::string statusPath(_r->homePath + ZT_PATH_SEPARATOR_S + "status"); + uint64_t lastPingCheck = 0; uint64_t lastTopologyClean = Utils::now(); // don't need to do this immediately uint64_t lastNetworkFingerprintCheck = 0; @@ -243,6 +247,7 @@ Node::ReasonForTermination Node::run() uint64_t networkConfigurationFingerprint = _r->sysEnv->getNetworkConfigurationFingerprint(); uint64_t lastMulticastCheck = 0; uint64_t lastMulticastAnnounceAll = 0; + uint64_t lastStatusUpdate = 0; long lastDelayDelta = 0; LOG("%s starting version %s",_r->identity.address().toString().c_str(),versionString()); @@ -373,6 +378,20 @@ Node::ReasonForTermination Node::run() _r->topology->clean(); // happens in background } + if (((now - lastStatusUpdate) >= ZT_STATUS_OUTPUT_PERIOD)||(impl->updateStatusNow)) { + lastStatusUpdate = now; + impl->updateStatusNow = false; + FILE *statusf = ::fopen(statusPath.c_str(),"w"); + if (statusf) { + try { + _r->topology->eachPeer(Topology::DumpPeerStatistics(statusf)); + } catch ( ... ) { + TRACE("unexpected exception updating status dump"); + } + ::fclose(statusf); + } + } + try { unsigned long delay = std::min((unsigned long)ZT_MIN_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks()); uint64_t start = Utils::now(); @@ -391,11 +410,6 @@ Node::ReasonForTermination Node::run() return impl->terminateBecause(Node::NODE_NORMAL_TERMINATION,"normal termination"); } -/** - * Obtain a human-readable reason for node termination - * - * @return Reason for node termination or NULL if run() has not returned - */ const char *Node::reasonForTermination() const throw() { @@ -404,19 +418,18 @@ const char *Node::reasonForTermination() const return ((_NodeImpl *)_impl)->reasonForTerminationStr.c_str(); } -/** - * Cause run() to return with NODE_NORMAL_TERMINATION - * - * This can be called from a signal handler or another thread to signal a - * running node to shut down. Shutdown may take a few seconds, so run() - * may not return instantly. Multiple calls are ignored. - */ void Node::terminate() throw() { ((_NodeImpl *)_impl)->terminateNow = true; } +void Node::updateStatusNow() + throw() +{ + ((_NodeImpl *)_impl)->updateStatusNow = true; +} + class _VersionStringMaker { public: diff --git a/node/Node.hpp b/node/Node.hpp index 1cc9a746..df6b946f 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -99,6 +99,12 @@ public: throw(); /** + * Update the status file in the home directory on next service loop + */ + void updateStatusNow() + throw(); + + /** * Get the ZeroTier version in major.minor.revision string format * * @return Version in string form diff --git a/node/Peer.hpp b/node/Peer.hpp index 5da19468..ef33d519 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -233,6 +233,46 @@ public: } /** + * @return IPv4 direct address or null InetAddress if none + */ + inline InetAddress ipv4Path() const + throw() + { + return _ipv4p.addr; + } + + /** + * @return IPv6 direct address or null InetAddress if none + */ + inline InetAddress ipv6Path() const + throw() + { + return _ipv4p.addr; + } + + /** + * @return IPv4 direct address or null InetAddress if none + */ + inline InetAddress ipv4ActivePath(uint64_t now) const + throw() + { + if (_ipv4p.isActive(now)) + return _ipv4p.addr; + return InetAddress(); + } + + /** + * @return IPv6 direct address or null InetAddress if none + */ + inline InetAddress ipv6ActivePath(uint64_t now) const + throw() + { + if (_ipv6p.isActive(now)) + return _ipv6p.addr; + return InetAddress(); + } + + /** * @return 256-bit encryption key */ inline const unsigned char *cryptKey() const diff --git a/node/Topology.hpp b/node/Topology.hpp index 95124497..7baebad0 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -28,6 +28,8 @@ #ifndef _ZT_TOPOLOGY_HPP #define _ZT_TOPOLOGY_HPP +#include <stdio.h> +#include <string.h> #include <map> #include <set> #include <list> @@ -292,6 +294,35 @@ public: std::vector< SharedPtr<Peer> > &_v; }; + /** + * Dump peer I/O statistics to an open FILE (for status reporting and debug) + */ + class DumpPeerStatistics + { + public: + DumpPeerStatistics(FILE *out) : + _out(out), + _now(Utils::now()) + { + fprintf(_out,"Peer Direct IPv4 Direct IPv6 Latency(ms)"ZT_EOL_S); + } + + inline void operator()(Topology &t,const SharedPtr<Peer> &p) + { + InetAddress v4(p->ipv4ActivePath(_now)); + InetAddress v6(p->ipv6ActivePath(_now)); + fprintf(_out,"%-10s %-21s %-51s %u"ZT_EOL_S, + p->address().toString().c_str(), + ((v4) ? v4.toString().c_str() : "(none)"), + ((v6) ? v6.toString().c_str() : "(none)"), + p->latency()); + } + + private: + FILE *_out; + uint64_t _now; + }; + protected: virtual void main() throw(); |