mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-02 01:08:19 +00:00
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:
parent
68cc5ea523
commit
7c85a638b0
@ -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
|
||||
|
8
main.cpp
8
main.cpp
@ -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);
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user