diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-06 14:58:34 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-06 14:58:34 -0400 |
commit | 7c85a638b054f115cbb3c00d45e32cbf6db2a56c (patch) | |
tree | 7e6907d4b75f98bf806ab805ac22aefb8dd753a6 /node | |
parent | 68cc5ea523402a29dca414e285decc1a5d1a9c15 (diff) | |
download | infinitytier-7c85a638b054f115cbb3c00d45e32cbf6db2a56c.tar.gz infinitytier-7c85a638b054f115cbb3c00d45e32cbf6db2a56c.zip |
Added creation and periodic update of a file called "status" in the home directory that contains peer link status. Useful for debugging and statistics. Send it SIGHUP to force an update now. Otherwise it updates every 120 seconds.
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(); |