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.

This commit is contained in:
Adam Ierymenko 2013-07-06 14:58:34 -04:00
parent 68cc5ea523
commit 7c85a638b0
7 changed files with 120 additions and 15 deletions

View File

@ -2,6 +2,10 @@ Building ZeroTier One on different platforms:
(See RUNNING.txt for what to do next.)
Developers note: there is currently no management of dependencies on *nix
platforms, so you should make clean ; make if you change a header. Will
do this eventually.
-- MacOS
make -f Makefile.mac

View File

@ -70,12 +70,18 @@ static void sighandlerQuit(int sig)
static void sighandlerUsr(int sig)
{
}
static void sighandlerHup(int sig)
{
Node *n = node;
if (n)
n->updateStatusNow();
}
#endif
int main(int argc,char **argv)
{
#ifndef _WIN32
signal(SIGHUP,SIG_IGN);
signal(SIGHUP,&sighandlerHup);
signal(SIGPIPE,SIG_IGN);
signal(SIGUSR1,&sighandlerUsr);
signal(SIGUSR2,&sighandlerUsr);

View File

@ -253,6 +253,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
*

View File

@ -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:

View File

@ -98,6 +98,12 @@ public:
void terminate()
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
*

View File

@ -232,6 +232,46 @@ public:
return ((_ipv4p.isActive(now))||(_ipv6p.isActive(now)));
}
/**
* @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
*/

View File

@ -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();