aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--Makefile.am8
-rw-r--r--changes/ticket259499
-rw-r--r--changes/ticket259519
-rw-r--r--changes/ticket259529
-rw-r--r--doc/tor.1.txt35
-rw-r--r--src/common/log.c25
-rw-r--r--src/common/torlog.h2
-rw-r--r--src/or/config.c2
-rw-r--r--src/or/control.c22
-rw-r--r--src/or/control.h1
-rw-r--r--src/or/dirauth/dirvote.c6
-rw-r--r--src/or/dirauth/mode.h38
-rw-r--r--src/or/dirauth/shared_random.c1
-rw-r--r--src/or/directory.c3
-rw-r--r--src/or/include.am1
-rw-r--r--src/or/main.c132
-rw-r--r--src/or/networkstatus.c3
-rw-r--r--src/or/nodelist.c2
-rw-r--r--src/or/router.c10
-rw-r--r--src/or/router.h1
-rw-r--r--src/or/routerlist.c1
22 files changed, 243 insertions, 81 deletions
diff --git a/.travis.yml b/.travis.yml
index 6ea11ce9d8..aab6f6b3d5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -160,7 +160,9 @@ script:
after_failure:
## `make check` will leave a log file with more details of test failures.
- - cat test-suite.log
+ - if [[ "$DISTCHECK" == "" ]]; then cat test-suite.log; fi
+ ## `make distcheck` puts it somewhere different.
+ - if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog; fi
after_success:
## If this build was one that produced coverage, upload it.
diff --git a/Makefile.am b/Makefile.am
index 163b650bb0..97a39031a9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -274,3 +274,11 @@ if USE_RUST
distclean-local: distclean-rust
endif
+# This relies on some internal details of how automake implements
+# distcheck. We check two directories because automake-1.15 changed
+# from $(distdir)/_build to $(distdir)/_build/sub.
+show-distdir-testlog:
+ @if test -d "$(distdir)/_build/sub"; then \
+ cat $(distdir)/_build/sub/$(TEST_SUITE_LOG); \
+ else \
+ cat $(distdir)/_build/$(TEST_SUITE_LOG); fi
diff --git a/changes/ticket25949 b/changes/ticket25949
new file mode 100644
index 0000000000..fd87373418
--- /dev/null
+++ b/changes/ticket25949
@@ -0,0 +1,9 @@
+ o Minor features (mainloop):
+ - Move responsibility for
+ honoring delayed SIGNEWNYM requests
+ from a once-per-second callback to a callback that is only scheduled as
+ needed. Once enough items are removed from our once-per-second
+ callback, we can eliminate it entirely to conserve CPU when idle.
+ Closes ticket
+ 25949.
+
diff --git a/changes/ticket25951 b/changes/ticket25951
new file mode 100644
index 0000000000..b6cfc2091c
--- /dev/null
+++ b/changes/ticket25951
@@ -0,0 +1,9 @@
+ o Minor features (mainloop):
+ - Move responsibility for
+ flushing log callbacks
+ from a once-per-second callback to a callback that is only scheduled as
+ needed. Once enough items are removed from our once-per-second
+ callback, we can eliminate it entirely to conserve CPU when idle.
+ Closes ticket
+ 25951.
+
diff --git a/changes/ticket25952 b/changes/ticket25952
new file mode 100644
index 0000000000..e4dd56df06
--- /dev/null
+++ b/changes/ticket25952
@@ -0,0 +1,9 @@
+ o Minor features (mainloop):
+ - Move responsibility for
+ warning relay operators about unreachable ports
+ from a once-per-second callback to a callback that is only scheduled as
+ needed. Once enough items are removed from our once-per-second
+ callback, we can eliminate it entirely to conserve CPU when idle.
+ Closes ticket
+ 25952.
+
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 9471db9362..4d22c2e61e 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -543,13 +543,21 @@ GENERAL OPTIONS
(Default: 1)
[[FetchUselessDescriptors]] **FetchUselessDescriptors** **0**|**1**::
- If set to 1, Tor will fetch every consensus flavor, descriptor, and
- certificate that it hears about. Otherwise, it will avoid fetching useless
- descriptors: flavors that it is not using to build circuits, and authority
- certificates it does not trust. This option is useful if you're using a
+ If set to 1, Tor will fetch every consensus flavor, and all server
+ descriptors and authority certificates referenced by those consensuses,
+ except for extra info descriptors. When this option is 1, Tor will also
+ keep fetching descriptors, even when idle.
+ If set to 0, Tor will avoid fetching useless descriptors: flavors that it
+ is not using to build circuits, and authority certificates it does not
+ trust. When Tor hasn't built any application circuits, it will go idle,
+ and stop fetching descriptors. This option is useful if you're using a
tor client with an external parser that uses a full consensus.
- This option fetches all documents, **DirCache** fetches and serves
- all documents. (Default: 0)
+ This option fetches all documents except extrainfo descriptors,
+ **DirCache** fetches and serves all documents except extrainfo
+ descriptors, **DownloadExtraInfo*** fetches extrainfo documents, and serves
+ them if **DirCache** is on, and **UseMicrodescriptors** changes the
+ flavour of consensues and descriptors that is fetched and used for
+ building circuits. (Default: 0)
[[HTTPProxy]] **HTTPProxy** __host__[:__port__]::
Tor will make all its directory requests through this host:port (or host:80
@@ -1642,9 +1650,8 @@ The following options are useful only for clients (that is, if
in order to build its circuits. Using microdescriptors makes Tor clients
download less directory information, thus saving bandwidth. Directory
caches need to fetch regular descriptors and microdescriptors, so this
- option doesn't save any bandwidth for them. If this option is set to
- "auto" (recommended) then it is on for all clients that do not set
- FetchUselessDescriptors. (Default: auto)
+ option doesn't save any bandwidth for them. For legacy reasons, auto is
+ accepted, but it has the same effect as 1. (Default: auto)
[[PathBiasCircThreshold]] **PathBiasCircThreshold** __NUM__ +
@@ -2390,10 +2397,12 @@ details.)
some entry in the policy is accepted.
[[DirCache]] **DirCache** **0**|**1**::
- When this option is set, Tor caches all current directory documents and
- accepts client requests for them. Setting DirPort is not required for this,
- because clients connect via the ORPort by default. Setting either DirPort
- or BridgeRelay and setting DirCache to 0 is not supported. (Default: 1)
+ When this option is set, Tor caches all current directory documents except
+ extra info documents, and accepts client requests for them. If
+ **DownloadExtraInfo** is set, cached extra info documents are also cached.
+ Setting **DirPort** is not required for **DirCache**, because clients
+ connect via the ORPort by default. Setting either DirPort or BridgeRelay
+ and setting DirCache to 0 is not supported. (Default: 1)
[[MaxConsensusAgeForDiffs]] **MaxConsensusAgeForDiffs** __N__ **minutes**|**hours**|**days**|**weeks**::
When this option is nonzero, Tor caches will not try to generate
diff --git a/src/common/log.c b/src/common/log.c
index 922e9dd38f..ebd50f62d3 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -170,6 +170,9 @@ typedef struct pending_log_message_t {
/** Log messages waiting to be replayed onto callback-based logs */
static smartlist_t *pending_cb_messages = NULL;
+/** Callback to invoke when pending_cb_messages becomes nonempty. */
+static pending_callback_callback pending_cb_cb = NULL;
+
/** Log messages waiting to be replayed once the logging system is initialized.
*/
static smartlist_t *pending_startup_messages = NULL;
@@ -538,6 +541,9 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len,
smartlist_add(pending_cb_messages,
pending_log_message_new(severity,domain,NULL,msg_after_prefix));
*callbacks_deferred = 1;
+ if (smartlist_len(pending_cb_messages) == 1 && pending_cb_cb) {
+ pending_cb_cb();
+ }
}
} else {
lf->callback(severity, domain, msg_after_prefix);
@@ -825,6 +831,7 @@ logs_free_all(void)
logfiles = NULL;
messages = pending_cb_messages;
pending_cb_messages = NULL;
+ pending_cb_cb = NULL;
messages2 = pending_startup_messages;
pending_startup_messages = NULL;
UNLOCK_LOGS();
@@ -988,6 +995,24 @@ add_temp_log(int min_severity)
}
/**
+ * Register "cb" as the callback to call when there are new pending log
+ * callbacks to be flushed with flush_pending_log_callbacks().
+ *
+ * Note that this callback, if present, can be invoked from any thread.
+ *
+ * This callback must not log.
+ *
+ * It is intentional that this function contains the name "callback" twice: it
+ * sets a "callback" to be called on the condition that there is a "pending
+ * callback".
+ **/
+void
+logs_set_pending_callback_callback(pending_callback_callback cb)
+{
+ pending_cb_cb = cb;
+}
+
+/**
* Add a log handler to send messages in <b>severity</b>
* to the function <b>cb</b>.
*/
diff --git a/src/common/torlog.h b/src/common/torlog.h
index ac632ff521..de389883c0 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -154,6 +154,8 @@ int add_android_log(const log_severity_list_t *severity,
const char *android_identity_tag);
#endif // HAVE_ANDROID_LOG_H.
int add_callback_log(const log_severity_list_t *severity, log_callback cb);
+typedef void (*pending_callback_callback)(void);
+void logs_set_pending_callback_callback(pending_callback_callback cb);
void logs_set_domain_logging(int enabled);
int get_min_log_level(void);
void switch_logs_debug(void);
diff --git a/src/or/config.c b/src/or/config.c
index a2b84991a0..23f1d4f5a3 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -112,6 +112,7 @@
#include "procmon.h"
#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
#ifdef HAVE_SYSTEMD
# if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
@@ -1552,6 +1553,7 @@ options_act_reversible(const or_options_t *old_options, char **msg)
tor_malloc_zero(sizeof(log_severity_list_t));
close_temp_logs();
add_callback_log(severity, control_event_logmsg);
+ logs_set_pending_callback_callback(control_event_logmsg_pending);
control_adjust_event_log_severity();
tor_free(severity);
tor_log_update_sigsafe_err_fds();
diff --git a/src/or/control.c b/src/or/control.c
index bc7597707f..4557d467b9 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -803,6 +803,9 @@ queued_event_free_(queued_event_t *ev)
static void
queued_events_flush_all(int force)
{
+ /* Make sure that we get all the pending log events, if there are any. */
+ flush_pending_log_callbacks();
+
if (PREDICT_UNLIKELY(queued_control_events == NULL)) {
return;
}
@@ -6186,7 +6189,7 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
int event;
/* Don't even think of trying to add stuff to a buffer from a cpuworker
- * thread. */
+ * thread. (See #25987 for plan to fix.) */
if (! in_main_thread())
return;
@@ -6232,6 +6235,23 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
}
}
+/**
+ * Logging callback: called when there is a queued pending log callback.
+ */
+void
+control_event_logmsg_pending(void)
+{
+ if (! in_main_thread()) {
+ /* We can't handle this case yet, since we're using a
+ * mainloop_event_t to invoke queued_events_flush_all. We ought to
+ * use a different mechanism instead: see #25987.
+ **/
+ return;
+ }
+ tor_assert(flush_queued_events_event);
+ mainloop_event_activate(flush_queued_events_event);
+}
+
/** Called whenever we receive new router descriptors: tell any
* interested control connections. <b>routers</b> is a list of
* routerinfo_t's.
diff --git a/src/or/control.h b/src/or/control.h
index 2f312a6638..7f8a0bdb5f 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -60,6 +60,7 @@ int control_event_conn_bandwidth(connection_t *conn);
int control_event_conn_bandwidth_used(void);
int control_event_circuit_cell_stats(void);
void control_event_logmsg(int severity, uint32_t domain, const char *msg);
+void control_event_logmsg_pending(void);
int control_event_descriptors_changed(smartlist_t *routers);
int control_event_address_mapped(const char *from, const char *to,
time_t expires, const char *error,
diff --git a/src/or/dirauth/dirvote.c b/src/or/dirauth/dirvote.c
index 66a530b6db..cbc3ff7829 100644
--- a/src/or/dirauth/dirvote.c
+++ b/src/or/dirauth/dirvote.c
@@ -9,7 +9,6 @@
#include "dircollate.h"
#include "directory.h"
#include "dirserv.h"
-#include "dirvote.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
@@ -23,9 +22,12 @@
#include "routerparse.h"
#include "entrynodes.h" /* needed for guardfraction methods */
#include "torcert.h"
-#include "shared_random_state.h"
#include "voting_schedule.h"
+#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
+#include "dirauth/shared_random_state.h"
+
/**
* \file dirvote.c
* \brief Functions to compute directory consensus, and schedule voting.
diff --git a/src/or/dirauth/mode.h b/src/or/dirauth/mode.h
new file mode 100644
index 0000000000..8a0d3142f1
--- /dev/null
+++ b/src/or/dirauth/mode.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file mode.h
+ * \brief Standalone header file for directory authority mode.
+ **/
+
+#ifndef TOR_DIRAUTH_MODE_H
+#define TOR_DIRAUTH_MODE_H
+
+#ifdef HAVE_MODULE_DIRAUTH
+
+#include "router.h"
+
+/* Return true iff we believe ourselves to be a v3 authoritative directory
+ * server. */
+static inline int
+authdir_mode_v3(const or_options_t *options)
+{
+ return authdir_mode(options) && options->V3AuthoritativeDir != 0;
+}
+
+#else /* HAVE_MODULE_DIRAUTH */
+
+/* Without the dirauth module, we can't be a v3 directory authority, ever. */
+
+static inline int
+authdir_mode_v3(const or_options_t *options)
+{
+ (void) options;
+ return 0;
+}
+
+#endif /* HAVE_MODULE_DIRAUTH */
+
+#endif /* TOR_MODE_H */
+
diff --git a/src/or/dirauth/shared_random.c b/src/or/dirauth/shared_random.c
index f7ff5c58bb..0a89fa8d2d 100644
--- a/src/or/dirauth/shared_random.c
+++ b/src/or/dirauth/shared_random.c
@@ -101,6 +101,7 @@
#include "voting_schedule.h"
#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
/* String prefix of shared random values in votes/consensuses. */
static const char previous_srv_str[] = "shared-rand-previous-value";
diff --git a/src/or/directory.c b/src/or/directory.c
index 2c5ee23f3a..76caab6a3c 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -40,7 +40,6 @@
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
-#include "dirauth/shared_random.h"
#if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
#if !defined(OpenBSD)
@@ -49,6 +48,8 @@
#endif
#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
+#include "dirauth/shared_random.h"
/**
* \file directory.c
diff --git a/src/or/include.am b/src/or/include.am
index 9cae7d0039..bc0b9d2bfb 100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@ -279,6 +279,7 @@ ORHEADERS = \
ORHEADERS += \
src/or/dirauth/dircollate.h \
src/or/dirauth/dirvote.h \
+ src/or/dirauth/mode.h \
src/or/dirauth/shared_random.h \
src/or/dirauth/shared_random_state.h
diff --git a/src/or/main.c b/src/or/main.c
index cf0df9ba79..08dfeb80f0 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -103,7 +103,6 @@
#include "routerlist.h"
#include "routerparse.h"
#include "scheduler.h"
-#include "dirauth/shared_random.h"
#include "statefile.h"
#include "status.h"
#include "tor_api.h"
@@ -119,6 +118,8 @@
#include <event2/event.h>
#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
+#include "dirauth/shared_random.h"
#ifdef HAVE_SYSTEMD
# if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
@@ -188,6 +189,8 @@ static uint64_t stats_n_main_loop_idle = 0;
static time_t time_of_last_signewnym = 0;
/** Is there a signewnym request we're currently waiting to handle? */
static int signewnym_is_pending = 0;
+/** Mainloop event for the deferred signewnym call. */
+static mainloop_event_t *handle_deferred_signewnym_ev = NULL;
/** How many times have we called newnym? */
static unsigned newnym_epoch = 0;
@@ -1316,6 +1319,16 @@ signewnym_impl(time_t now)
control_event_signal(SIGNEWNYM);
}
+/** Callback: run a deferred signewnym. */
+static void
+handle_deferred_signewnym_cb(mainloop_event_t *event, void *arg)
+{
+ (void)event;
+ (void)arg;
+ log_info(LD_CONTROL, "Honoring delayed NEWNYM request");
+ signewnym_impl(time(NULL));
+}
+
/** Return the number of times that signewnym has been called. */
unsigned
get_signewnym_epoch(void)
@@ -1350,6 +1363,7 @@ CALLBACK(heartbeat);
CALLBACK(hs_service);
CALLBACK(launch_descriptor_fetches);
CALLBACK(launch_reachability_tests);
+CALLBACK(reachability_warnings);
CALLBACK(record_bridge_stats);
CALLBACK(rend_cache_failure_clean);
CALLBACK(reset_padding_counts);
@@ -1393,6 +1407,8 @@ STATIC periodic_event_item_t periodic_events[] = {
CALLBACK(check_onion_keys_expiry_time, PERIODIC_EVENT_ROLE_ROUTER, 0),
CALLBACK(expire_old_ciruits_serverside, PERIODIC_EVENT_ROLE_ROUTER,
PERIODIC_EVENT_FLAG_NEED_NET),
+ CALLBACK(reachability_warnings, PERIODIC_EVENT_ROLE_ROUTER,
+ PERIODIC_EVENT_FLAG_NEED_NET),
CALLBACK(retry_dns, PERIODIC_EVENT_ROLE_ROUTER, 0),
CALLBACK(rotate_onion_key, PERIODIC_EVENT_ROLE_ROUTER, 0),
@@ -1699,17 +1715,6 @@ run_scheduled_events(time_t now)
*/
consider_hibernation(now);
- /* 0b. If we've deferred a signewnym, make sure it gets handled
- * eventually. */
- if (signewnym_is_pending &&
- time_of_last_signewnym + MAX_SIGNEWNYM_RATE <= now) {
- log_info(LD_CONTROL, "Honoring delayed NEWNYM request");
- signewnym_impl(now);
- }
-
- /* 0c. If we've deferred log messages for the controller, handle them now */
- flush_pending_log_callbacks();
-
/* Maybe enough time elapsed for us to reconsider a circuit. */
circuit_upgrade_circuits_from_guard_wait();
@@ -2330,6 +2335,54 @@ expire_old_ciruits_serverside_callback(time_t now, const or_options_t *options)
return 11;
}
+/**
+ * Callback: Send warnings if Tor doesn't find its ports reachable.
+ */
+static int
+reachability_warnings_callback(time_t now, const or_options_t *options)
+{
+ (void) now;
+
+ if (get_uptime() < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
+ return (int)(TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT - get_uptime());
+ }
+
+ if (server_mode(options) &&
+ !net_is_disabled() &&
+ have_completed_a_circuit()) {
+ /* every 20 minutes, check and complain if necessary */
+ const routerinfo_t *me = router_get_my_routerinfo();
+ if (me && !check_whether_orport_reachable(options)) {
+ char *address = tor_dup_ip(me->addr);
+ log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that "
+ "its ORPort is reachable. Relays do not publish descriptors "
+ "until their ORPort and DirPort are reachable. Please check "
+ "your firewalls, ports, address, /etc/hosts file, etc.",
+ address, me->or_port);
+ control_event_server_status(LOG_WARN,
+ "REACHABILITY_FAILED ORADDRESS=%s:%d",
+ address, me->or_port);
+ tor_free(address);
+ }
+
+ if (me && !check_whether_dirport_reachable(options)) {
+ char *address = tor_dup_ip(me->addr);
+ log_warn(LD_CONFIG,
+ "Your server (%s:%d) has not managed to confirm that its "
+ "DirPort is reachable. Relays do not publish descriptors "
+ "until their ORPort and DirPort are reachable. Please check "
+ "your firewalls, ports, address, /etc/hosts file, etc.",
+ address, me->dir_port);
+ control_event_server_status(LOG_WARN,
+ "REACHABILITY_FAILED DIRADDRESS=%s:%d",
+ address, me->dir_port);
+ tor_free(address);
+ }
+ }
+
+ return TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT;
+}
+
static int dns_honesty_first_time = 1;
/**
@@ -2457,7 +2510,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
size_t bytes_written;
size_t bytes_read;
int seconds_elapsed;
- const or_options_t *options = get_options();
(void)timer;
(void)arg;
@@ -2480,43 +2532,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
control_event_circ_bandwidth_used();
control_event_circuit_cell_stats();
- if (server_mode(options) &&
- !net_is_disabled() &&
- seconds_elapsed > 0 &&
- have_completed_a_circuit() &&
- get_uptime() / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
- (get_uptime()+seconds_elapsed) /
- TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
- /* every 20 minutes, check and complain if necessary */
- const routerinfo_t *me = router_get_my_routerinfo();
- if (me && !check_whether_orport_reachable(options)) {
- char *address = tor_dup_ip(me->addr);
- log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that "
- "its ORPort is reachable. Relays do not publish descriptors "
- "until their ORPort and DirPort are reachable. Please check "
- "your firewalls, ports, address, /etc/hosts file, etc.",
- address, me->or_port);
- control_event_server_status(LOG_WARN,
- "REACHABILITY_FAILED ORADDRESS=%s:%d",
- address, me->or_port);
- tor_free(address);
- }
-
- if (me && !check_whether_dirport_reachable(options)) {
- char *address = tor_dup_ip(me->addr);
- log_warn(LD_CONFIG,
- "Your server (%s:%d) has not managed to confirm that its "
- "DirPort is reachable. Relays do not publish descriptors "
- "until their ORPort and DirPort are reachable. Please check "
- "your firewalls, ports, address, /etc/hosts file, etc.",
- address, me->dir_port);
- control_event_server_status(LOG_WARN,
- "REACHABILITY_FAILED DIRADDRESS=%s:%d",
- address, me->dir_port);
- tor_free(address);
- }
- }
-
/** If more than this many seconds have elapsed, probably the clock
* jumped: doesn't count. */
#define NUM_JUMPED_SECONDS_BEFORE_WARN 100
@@ -3075,10 +3090,20 @@ process_signal(int sig)
case SIGNEWNYM: {
time_t now = time(NULL);
if (time_of_last_signewnym + MAX_SIGNEWNYM_RATE > now) {
- signewnym_is_pending = 1;
+ const time_t delay_sec =
+ time_of_last_signewnym + MAX_SIGNEWNYM_RATE - now;
+ if (! signewnym_is_pending) {
+ signewnym_is_pending = 1;
+ if (!handle_deferred_signewnym_ev) {
+ handle_deferred_signewnym_ev =
+ mainloop_event_postloop_new(handle_deferred_signewnym_cb, NULL);
+ }
+ const struct timeval delay_tv = { delay_sec, 0 };
+ mainloop_event_schedule(handle_deferred_signewnym_ev, &delay_tv);
+ }
log_notice(LD_CONTROL,
- "Rate limiting NEWNYM request: delaying by %d second(s)",
- (int)(MAX_SIGNEWNYM_RATE+time_of_last_signewnym-now));
+ "Rate limiting NEWNYM request: delaying by %d second(s)",
+ (int)(delay_sec));
} else {
signewnym_impl(now);
}
@@ -3617,6 +3642,7 @@ tor_free_all(int postfork)
mainloop_event_free(directory_all_unreachable_cb_event);
mainloop_event_free(schedule_active_linked_connections_event);
mainloop_event_free(postloop_cleanup_ev);
+ mainloop_event_free(handle_deferred_signewnym_ev);
#ifdef HAVE_SYSTEMD_209
periodic_timer_free(systemd_watchdog_timer);
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index ac3e94e884..a7a76b236c 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -63,13 +63,14 @@
#include "routerlist.h"
#include "routerparse.h"
#include "scheduler.h"
-#include "dirauth/shared_random.h"
#include "transports.h"
#include "torcert.h"
#include "channelpadding.h"
#include "voting_schedule.h"
#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
+#include "dirauth/shared_random.h"
/** Most recently received and validated v3 "ns"-flavored consensus network
* status. */
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 675cbb0056..bc9a79940b 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -66,6 +66,8 @@
#include <string.h>
+#include "dirauth/mode.h"
+
static void nodelist_drop_node(node_t *node, int remove_from_ht);
#define node_free(val) \
FREE_AND_NULL(node_t, node_free_, (val))
diff --git a/src/or/router.c b/src/or/router.c
index 93b61b69ef..cc1979bcc9 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -35,6 +35,8 @@
#include "transports.h"
#include "routerset.h"
+#include "dirauth/mode.h"
+
/**
* \file router.c
* \brief Miscellaneous relay functionality, including RSA key maintenance,
@@ -1612,14 +1614,6 @@ authdir_mode(const or_options_t *options)
{
return options->AuthoritativeDir != 0;
}
-/** Return true iff we believe ourselves to be a v3 authoritative
- * directory server.
- */
-int
-authdir_mode_v3(const or_options_t *options)
-{
- return authdir_mode(options) && options->V3AuthoritativeDir != 0;
-}
/** Return true iff we are an authoritative directory server that is
* authoritative about receiving and serving descriptors of type
* <b>purpose</b> on its dirport.
diff --git a/src/or/router.h b/src/or/router.h
index e5efe577e3..03eca9c65d 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -55,7 +55,6 @@ void router_perform_bandwidth_test(int num_circs, time_t now);
int net_is_disabled(void);
int authdir_mode(const or_options_t *options);
-int authdir_mode_v3(const or_options_t *options);
int authdir_mode_handles_descs(const or_options_t *options, int purpose);
int authdir_mode_publishes_statuses(const or_options_t *options);
int authdir_mode_tests_reachability(const or_options_t *options);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 7eb9ec7990..914cf4ef16 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -122,6 +122,7 @@
#include "torcert.h"
#include "dirauth/dirvote.h"
+#include "dirauth/mode.h"
// #define DEBUG_ROUTERLIST