diff --git a/doc/tor.1.txt b/doc/tor.1.txt index bc18b2fbfa..9020a8028a 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -928,6 +928,10 @@ is non-zero): seconds, we exit. If we get a second SIGINT, we exit immedi- ately. (Default: 30 seconds) +**HeartbeatPeriod** __N__ **minutes**|**hours**|**days**|**weeks**:: + Log a heartbeat message every **HeartbeatPeriod** seconds. This is + a log level __info__ message, designed to let you know your Tor + instance is still alive and doing useful things. (Default: 6 hours) **AccountingMax** __N__ **bytes**|**KB**|**MB**|**GB**|**TB**:: Never send more than the specified number of bytes in a given accounting diff --git a/src/common/torlog.h b/src/common/torlog.h index 1fe5806d16..4192a881cb 100644 --- a/src/common/torlog.h +++ b/src/common/torlog.h @@ -92,8 +92,10 @@ #define LD_HIST (1u<<18) /** OR handshaking */ #define LD_HANDSHAKE (1u<<19) +/** Heartbeat messages */ +#define LD_HEARTBEAT (1u<<20) /** Number of logging domains in the code. */ -#define N_LOGGING_DOMAINS 20 +#define N_LOGGING_DOMAINS 21 /** This log message is not safe to send to a callback-based logger * immediately. Used as a flag, not a log domain. */ diff --git a/src/or/Makefile.am b/src/or/Makefile.am index b6637ba631..a49a86a607 100644 --- a/src/or/Makefile.am +++ b/src/or/Makefile.am @@ -52,7 +52,8 @@ libtor_a_SOURCES = \ routerparse.c \ $(evdns_source) \ $(tor_platform_source) \ - config_codedigest.c + config_codedigest.c \ + status.c #libtor_a_LIBADD = ../common/libor.a ../common/libor-crypto.a \ # ../common/libor-event.a diff --git a/src/or/config.c b/src/or/config.c index 65bc1d5fc6..e2b2b5ce5d 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -267,6 +267,7 @@ static config_var_t _option_vars[] = { #endif OBSOLETE("Group"), V(HardwareAccel, BOOL, "0"), + V(HeartbeatPeriod, INTERVAL, "6 hours"), V(AccelName, STRING, NULL), V(AccelDir, FILENAME, NULL), V(HashedControlPassword, LINELIST, NULL), @@ -2915,6 +2916,10 @@ compute_publishserverdescriptor(or_options_t *options) * will generate too many circuits and potentially overload the network. */ #define MIN_CIRCUIT_STREAM_TIMEOUT 10 +/** Lowest allowable value for HeartbeatPeriod; if this is too low, we might + * expose more information than we're comfortable with. */ +#define MIN_HEARTBEAT_PERIOD (30*60) + /** Return 0 if every setting in options is reasonable, and a * permissible transition from old_options. Else return -1. * Should have no side effects, except for normalizing the contents of @@ -3376,6 +3381,14 @@ options_validate(or_options_t *old_options, or_options_t *options, "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT); options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT; } + + if (options->HeartbeatPeriod && + options->HeartbeatPeriod < MIN_HEARTBEAT_PERIOD) { + log_warn(LD_CONFIG, "HeartbeatPeriod option is too short; " + "raising to %d seconds.", MIN_HEARTBEAT_PERIOD); + options->HeartbeatPeriod = MIN_HEARTBEAT_PERIOD; + } + if (options->KeepalivePeriod < 1) REJECT("KeepalivePeriod option must be positive."); diff --git a/src/or/main.c b/src/or/main.c index c6fd2c0593..6e3cb2b386 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1050,6 +1050,7 @@ run_scheduled_events(time_t now) static time_t time_to_check_port_forwarding = 0; static int should_init_bridge_stats = 1; static time_t time_to_retry_dns_init = 0; + static time_t time_last_written_heartbeat = 0; or_options_t *options = get_options(); int is_server = server_mode(options); int i; @@ -1440,6 +1441,12 @@ run_scheduled_events(time_t now) now); time_to_check_port_forwarding = now+PORT_FORWARDING_CHECK_INTERVAL; } + + /** 11. write the heartbeat message */ + if (options->HeartbeatPeriod && + time_last_written_heartbeat + options->HeartbeatPeriod < now) + log_heartbeat(now); + time_last_written_heartbeat = now; } /** Timer: used to invoke second_elapsed_callback() once per second. */ diff --git a/src/or/or.h b/src/or/or.h index 9bf46e9793..4f3fef036f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2718,6 +2718,9 @@ typedef struct { config_line_t *HidServAuth; /**< List of configuration lines for client-side * authorizations for hidden services */ char *ContactInfo; /**< Contact info to be published in the directory. */ + + int HeartbeatPeriod; /**< Log heartbeat messages after this many seconds + * have passed. */ char *HTTPProxy; /**< hostname[:port] to use as http proxy, if any. */ tor_addr_t HTTPProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */ diff --git a/src/or/status.c b/src/or/status.c new file mode 100644 index 0000000000..0cd9a07226 --- /dev/null +++ b/src/or/status.c @@ -0,0 +1,27 @@ +/* Copyright (c) 2010, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file status.c + * \brief Keep status information and log the heartbeat messages. + **/ + +#include "or.h" + + +/****************************************************************************/ + + + +#define BEAT(x) log_fn(LOG_NOTICE, LD_HEARTBEAT, (x) ) + +void +log_heartbeat(time_t now) { + or_options_t *opt = get_options(); + + (void) now; + log_fn(LOG_NOTICE, LD_HEARTBEAT, "This is the Tor heartbeat message."); + if (!server_mode(opt)) + BEAT("you are a client, hahaha"); + +}