aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.c4
-rw-r--r--src/common/compat_libevent.c2
-rw-r--r--src/common/tortls.c11
-rw-r--r--src/or/circuituse.c53
-rw-r--r--src/or/dirserv.c36
-rw-r--r--src/or/dirvote.c8
-rw-r--r--src/or/geoip.c4
-rw-r--r--src/or/main.c116
-rw-r--r--src/or/or.h15
-rw-r--r--src/or/router.c24
-rw-r--r--src/or/routerlist.c75
-rw-r--r--src/win32/orconfig.h2
12 files changed, 212 insertions, 138 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 26038c109..0fb169b73 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -355,12 +355,12 @@ tor_vasprintf(char **strp, const char *fmt, va_list args)
else
*strp = strp_tmp;
return r;
-#elif defined(MS_WINDOWS)
+#elif defined(_MSC_VER)
/* On Windows, _vsnprintf won't tell us the length of the string if it
* overflows, so we need to use _vcsprintf to tell how much to allocate */
int len, r;
char *res;
- len = _vcsprintf(fmt, args);
+ len = _vscprintf(fmt, args);
if (len < 0) {
*strp = NULL;
return -1;
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index 18e057f95..56ba3235b 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -11,9 +11,9 @@
**/
#include "orconfig.h"
+#include "compat.h"
#include "compat_libevent.h"
-#include "compat.h"
#include "util.h"
#include "log.h"
diff --git a/src/common/tortls.c b/src/common/tortls.c
index df77fb066..218f110d8 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -746,11 +746,11 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
/* If we reached this point, we just got a client hello. See if there is
* a cipher list. */
if (!(session = SSL_get_session((SSL *)ssl))) {
- log_warn(LD_NET, "No session on TLS?");
+ log_info(LD_NET, "No session on TLS?");
return 0;
}
if (!session->ciphers) {
- log_warn(LD_NET, "No ciphers on session");
+ log_info(LD_NET, "No ciphers on session");
return 0;
}
/* Now we need to see if there are any ciphers whose presence means we're
@@ -762,8 +762,7 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA) &&
strcmp(ciphername, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA) &&
strcmp(ciphername, "(NONE)")) {
- /* XXXX should be ld_debug */
- log_info(LD_NET, "Got a non-version-1 cipher called '%s'", ciphername);
+ log_debug(LD_NET, "Got a non-version-1 cipher called '%s'", ciphername);
// return 1;
goto dump_list;
}
@@ -779,8 +778,8 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
smartlist_add(elts, (char*)ciphername);
}
s = smartlist_join_strings(elts, ":", 0, NULL);
- log_info(LD_NET, "Got a non-version-1 cipher list from %s. It is: '%s'",
- address, s);
+ log_debug(LD_NET, "Got a non-version-1 cipher list from %s. It is: '%s'",
+ address, s);
tor_free(s);
smartlist_free(elts);
}
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 9eda9e248..7e47e6055 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -17,7 +17,7 @@ extern circuit_t *global_circuitlist; /* from circuitlist.c */
/********* END VARIABLES ************/
-static void circuit_expire_old_circuits(time_t now);
+static void circuit_expire_old_circuits_clientside(time_t now);
static void circuit_increment_failure_count(void);
long int lround(double x);
@@ -567,7 +567,7 @@ circuit_build_needed_circs(time_t now)
time_to_new_circuit = now + options->NewCircuitPeriod;
if (proxy_mode(get_options()))
addressmap_clean(now);
- circuit_expire_old_circuits(now);
+ circuit_expire_old_circuits_clientside(now);
#if 0 /* disable for now, until predict-and-launch-new can cull leftovers */
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
@@ -656,7 +656,7 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
* for too long and has no streams on it: mark it for close.
*/
static void
-circuit_expire_old_circuits(time_t now)
+circuit_expire_old_circuits_clientside(time_t now)
{
circuit_t *circ;
time_t cutoff;
@@ -696,6 +696,53 @@ circuit_expire_old_circuits(time_t now)
}
}
+/** How long do we wait before killing circuits with the properties
+ * described below?
+ *
+ * Probably we could choose a number here as low as 5 to 10 seconds,
+ * since these circs are used for begindir, and a) generally you either
+ * ask another begindir question right after or you don't for a long time,
+ * b) clients at least through 0.2.1.x choose from the whole set of
+ * directory mirrors at each choice, and c) re-establishing a one-hop
+ * circuit via create-fast is a light operation assuming the TLS conn is
+ * still there.
+ *
+ * I expect "b" to go away one day when we move to using directory
+ * guards, but I think "a" and "c" are good enough reasons that a low
+ * number is safe even then.
+ */
+#define IDLE_ONE_HOP_CIRC_TIMEOUT 60
+
+/** Find each non-origin circuit that has been unused for too long,
+ * has no streams on it, used a create_fast, and ends here: mark it
+ * for close.
+ */
+void
+circuit_expire_old_circuits_serverside(time_t now)
+{
+ circuit_t *circ;
+ or_circuit_t *or_circ;
+ time_t cutoff = now - IDLE_ONE_HOP_CIRC_TIMEOUT;
+
+ for (circ = global_circuitlist; circ; circ = circ->next) {
+ if (circ->marked_for_close || CIRCUIT_IS_ORIGIN(circ))
+ continue;
+ or_circ = TO_OR_CIRCUIT(circ);
+ /* If the circuit has been idle for too long, and there are no streams
+ * on it, and it ends here, and it used a create_fast, mark it for close.
+ */
+ if (or_circ->is_first_hop && !circ->n_conn &&
+ !or_circ->n_streams && !or_circ->resolving_streams &&
+ or_circ->p_conn &&
+ or_circ->p_conn->timestamp_last_added_nonpadding <= cutoff) {
+ log_info(LD_CIRC, "Closing circ_id %d (empty %d secs ago)",
+ or_circ->p_circ_id,
+ (int)(now - or_circ->p_conn->timestamp_last_added_nonpadding));
+ circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
+ }
+ }
+}
+
/** Number of testing circuits we want open before testing our bandwidth. */
#define NUM_PARALLEL_TESTING_CIRCS 4
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index b5c4c7b50..8b215011f 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -3091,8 +3091,24 @@ dirserv_orconn_tls_done(const char *address,
* skip testing. */
}
-/** Auth dir server only: if <b>try_all</b> is 1, launch connections to
- * all known routers; else we want to load balance such that we only
+/** Helper function for dirserv_test_reachability(). Start a TLS
+ * connection to <b>router</b>, and annotate it with when we started
+ * the test. */
+void
+dirserv_single_reachability_test(time_t now, routerinfo_t *router)
+{
+ tor_addr_t router_addr;
+ log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
+ router->nickname, router->address, router->or_port);
+ /* Remember when we started trying to determine reachability */
+ if (!router->testing_since)
+ router->testing_since = now;
+ tor_addr_from_ipv4h(&router_addr, router->addr);
+ connection_or_connect(&router_addr, router->or_port,
+ router->cache_info.identity_digest);
+}
+
+/** Auth dir server only: load balance such that we only
* try a few connections per call.
*
* The load balancing is such that if we get called once every ten
@@ -3100,7 +3116,7 @@ dirserv_orconn_tls_done(const char *address,
* bit over 20 minutes).
*/
void
-dirserv_test_reachability(time_t now, int try_all)
+dirserv_test_reachability(time_t now)
{
/* XXX decide what to do here; see or-talk thread "purging old router
* information, revocation." -NM
@@ -3117,25 +3133,17 @@ dirserv_test_reachability(time_t now, int try_all)
SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, router) {
const char *id_digest = router->cache_info.identity_digest;
- tor_addr_t router_addr;
if (router_is_me(router))
continue;
if (bridge_auth && router->purpose != ROUTER_PURPOSE_BRIDGE)
continue; /* bridge authorities only test reachability on bridges */
// if (router->cache_info.published_on > cutoff)
// continue;
- if (try_all || (((uint8_t)id_digest[0]) % 128) == ctr) {
- log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
- router->nickname, router->address, router->or_port);
- /* Remember when we started trying to determine reachability */
- if (!router->testing_since)
- router->testing_since = now;
- tor_addr_from_ipv4h(&router_addr, router->addr);
- connection_or_connect(&router_addr, router->or_port, id_digest);
+ if ((((uint8_t)id_digest[0]) % 128) == ctr) {
+ dirserv_single_reachability_test(now, router);
}
} SMARTLIST_FOREACH_END(router);
- if (!try_all) /* increment ctr */
- ctr = (ctr + 1) % 128;
+ ctr = (ctr + 1) % 128; /* increment ctr */
}
/** Given a fingerprint <b>fp</b> which is either set if we're looking for a
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index bae222a19..d5610131a 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -2685,6 +2685,9 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
goto err;
}
+ /* Fetch any new router descriptors we just learned about */
+ update_consensus_router_descriptor_downloads(time(NULL), 1, vote);
+
/* Now see whether we already have a vote from this authority. */
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
if (! memcmp(v->vote->cert->cache_info.identity_digest,
@@ -2693,7 +2696,8 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
networkstatus_voter_info_t *vi_old = get_voter(v->vote);
if (!memcmp(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
/* Ah, it's the same vote. Not a problem. */
- log_info(LD_DIR, "Discarding a vote we already have.");
+ log_info(LD_DIR, "Discarding a vote we already have (from %s).",
+ vi->address);
if (*status_out < 200)
*status_out = 200;
goto discard;
@@ -2720,7 +2724,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
goto err;
}
}
- });
+ });
pending_vote = tor_malloc_zero(sizeof(pending_vote_t));
pending_vote->vote_body = new_cached_dir(tor_strndup(vote_body,
diff --git a/src/or/geoip.c b/src/or/geoip.c
index b5a0374c4..ea11dc323 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -945,8 +945,8 @@ geoip_get_request_history(time_t now, geoip_client_action_t action)
strings = smartlist_create();
SMARTLIST_FOREACH(entries, c_hist_t *, ent, {
- char buf[32];
- tor_snprintf(buf, sizeof(buf), "%s=%u", ent->country, ent->total);
+ char *buf = NULL;
+ tor_asprintf(&buf, "%s=%u", ent->country, ent->total);
smartlist_add(strings, buf);
});
result = smartlist_join_strings(strings, ",", 0, NULL);
diff --git a/src/or/main.c b/src/or/main.c
index 74075b625..0ddb65a74 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -686,6 +686,15 @@ directory_info_has_arrived(time_t now, int from_cache)
consider_testing_reachability(1, 1);
}
+/** How long do we wait before killing OR connections with no circuits?
+ * In Tor versions up to 0.2.1.25 and 0.2.2.12-alpha, we waited 15 minutes
+ * before cancelling these connections, which caused fast relays to accrue
+ * many many idle connections. Hopefully 3 minutes is low enough that
+ * it kills most idle connections, without being so low that we cause
+ * clients to bounce on and off.
+ */
+#define IDLE_OR_CONN_TIMEOUT 180
+
/** Perform regular maintenance tasks for a single connection. This
* function gets run once per second per connection by run_scheduled_events.
*/
@@ -696,6 +705,8 @@ run_connection_housekeeping(int i, time_t now)
connection_t *conn = smartlist_get(connection_array, i);
or_options_t *options = get_options();
or_connection_t *or_conn;
+ int past_keepalive =
+ now >= conn->timestamp_lastwritten + options->KeepalivePeriod;
if (conn->outbuf && !buf_datalen(conn->outbuf) && conn->type == CONN_TYPE_OR)
TO_OR_CONN(conn)->timestamp_lastempty = now;
@@ -730,6 +741,9 @@ run_connection_housekeeping(int i, time_t now)
if (!connection_speaks_cells(conn))
return; /* we're all done here, the rest is just for OR conns */
+ /* If we haven't written to an OR connection for a while, then either nuke
+ the connection or send a keepalive, depending. */
+
or_conn = TO_OR_CONN(conn);
tor_assert(conn->outbuf);
@@ -745,56 +759,45 @@ run_connection_housekeeping(int i, time_t now)
"Tor gave up on the connection");
connection_mark_for_close(conn);
conn->hold_open_until_flushed = 1;
- return;
- }
-
- /* If we haven't written to an OR connection for a while, then either nuke
- the connection or send a keepalive, depending. */
- if (now >= conn->timestamp_lastwritten + options->KeepalivePeriod) {
- routerinfo_t *router = router_get_by_digest(or_conn->identity_digest);
- int maxCircuitlessPeriod = options->MaxCircuitDirtiness*3/2;
- if (!connection_state_is_open(conn)) {
- /* We never managed to actually get this connection open and happy. */
- log_info(LD_OR,"Expiring non-open OR connection to fd %d (%s:%d).",
- conn->s,conn->address, conn->port);
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
- } else if (we_are_hibernating() && !or_conn->n_circuits &&
- !buf_datalen(conn->outbuf)) {
- /* We're hibernating, there's no circuits, and nothing to flush.*/
- log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
- "[Hibernating or exiting].",
- conn->s,conn->address, conn->port);
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
- } else if (!clique_mode(options) && !or_conn->n_circuits &&
- now >= or_conn->timestamp_last_added_nonpadding +
- maxCircuitlessPeriod &&
- (!router || !server_mode(options) ||
- !router_is_clique_mode(router))) {
- log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
- "[Not in clique mode].",
- conn->s,conn->address, conn->port);
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
- } else if (
- now >= or_conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
- now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {
- log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
- "Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
- "flush; %d seconds since last write)",
- conn->s, conn->address, conn->port,
- (int)buf_datalen(conn->outbuf),
- (int)(now-conn->timestamp_lastwritten));
- connection_mark_for_close(conn);
- } else if (!buf_datalen(conn->outbuf)) {
- /* either in clique mode, or we've got a circuit. send a padding cell. */
- log_fn(LOG_DEBUG,LD_OR,"Sending keepalive to (%s:%d)",
- conn->address, conn->port);
- memset(&cell,0,sizeof(cell_t));
- cell.command = CELL_PADDING;
- connection_or_write_cell_to_buf(&cell, or_conn);
- }
+ } else if (past_keepalive && !connection_state_is_open(conn)) {
+ /* We never managed to actually get this connection open and happy. */
+ log_info(LD_OR,"Expiring non-open OR connection to fd %d (%s:%d).",
+ conn->s,conn->address, conn->port);
+ connection_mark_for_close(conn);
+ conn->hold_open_until_flushed = 1;
+ } else if (we_are_hibernating() && !or_conn->n_circuits &&
+ !buf_datalen(conn->outbuf)) {
+ /* We're hibernating, there's no circuits, and nothing to flush.*/
+ log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
+ "[Hibernating or exiting].",
+ conn->s,conn->address, conn->port);
+ connection_mark_for_close(conn);
+ conn->hold_open_until_flushed = 1;
+ } else if (!or_conn->n_circuits &&
+ now >= or_conn->timestamp_last_added_nonpadding +
+ IDLE_OR_CONN_TIMEOUT) {
+ log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
+ "[idle %d].", conn->s,conn->address, conn->port,
+ (int)(now - or_conn->timestamp_last_added_nonpadding));
+ connection_mark_for_close(conn);
+ conn->hold_open_until_flushed = 1;
+ } else if (
+ now >= or_conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
+ now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {
+ log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
+ "Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
+ "flush; %d seconds since last write)",
+ conn->s, conn->address, conn->port,
+ (int)buf_datalen(conn->outbuf),
+ (int)(now-conn->timestamp_lastwritten));
+ connection_mark_for_close(conn);
+ } else if (past_keepalive && !buf_datalen(conn->outbuf)) {
+ /* send a padding cell */
+ log_fn(LOG_DEBUG,LD_OR,"Sending keepalive to (%s:%d)",
+ conn->address, conn->port);
+ memset(&cell,0,sizeof(cell_t));
+ cell.command = CELL_PADDING;
+ connection_or_write_cell_to_buf(&cell, or_conn);
}
}
@@ -918,7 +921,7 @@ run_scheduled_events(time_t now)
if (now % 10 == 0 && (authdir_mode_tests_reachability(options)) &&
!we_are_hibernating()) {
/* try to determine reachability of the other Tor relays */
- dirserv_test_reachability(now, 0);
+ dirserv_test_reachability(now);
}
/** 1d. Periodically, we discount older stability information so that new
@@ -1138,6 +1141,10 @@ run_scheduled_events(time_t now)
if (have_dir_info && !we_are_hibernating())
circuit_build_needed_circs(now);
+ /* every 10 seconds, but not at the same second as other such events */
+ if (now % 10 == 5)
+ circuit_expire_old_circuits_serverside(now);
+
/** 5. We do housekeeping for each connection... */
connection_or_set_bad_connections();
for (i=0;i<smartlist_len(connection_array);i++) {
@@ -1479,11 +1486,6 @@ do_main_loop(void)
now = time(NULL);
directory_info_has_arrived(now, 1);
- if (authdir_mode_tests_reachability(get_options())) {
- /* the directory is already here, run startup things */
- dirserv_test_reachability(now, 1);
- }
-
if (server_mode(get_options())) {
/* launch cpuworkers. Need to do this *after* we've read the onion key. */
cpu_init();
@@ -1666,7 +1668,7 @@ dumpmemusage(int severity)
tor_log_mallinfo(severity);
}
-/** Write all statistics to the log, with log level 'severity'. Called
+/** Write all statistics to the log, with log level <b>severity</b>. Called
* in response to a SIGUSR1. */
static void
dumpstats(int severity)
diff --git a/src/or/or.h b/src/or/or.h
index 7c1e5a7a0..9c613d28d 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3230,6 +3230,8 @@ int circuit_conforms_to_options(const origin_circuit_t *circ,
void circuit_build_needed_circs(time_t now);
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
+void circuit_expire_old_circuits_serverside(time_t now);
+
void reset_bandwidth_test(void);
int circuit_enough_testing_circs(void);
@@ -3913,7 +3915,8 @@ void dirserv_orconn_tls_done(const char *address,
uint16_t or_port,
const char *digest_rcvd,
int as_advertised);
-void dirserv_test_reachability(time_t now, int try_all);
+void dirserv_single_reachability_test(time_t now, routerinfo_t *router);
+void dirserv_test_reachability(time_t now);
int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
int complain);
int dirserv_would_reject_router(routerstatus_t *rs);
@@ -4493,9 +4496,6 @@ const char *circuit_end_reason_to_control_string(int reason);
const char *socks4_response_code_to_string(uint8_t code);
const char *socks5_response_code_to_string(uint8_t code);
-enum bandwidth_weight_rule_t;
-const char *bandwidth_weight_rule_to_string(enum bandwidth_weight_rule_t rule);
-
/********************************* relay.c ***************************/
extern uint64_t stats_n_relay_cells_relayed;
@@ -4815,13 +4815,11 @@ int authdir_mode_publishes_statuses(or_options_t *options);
int authdir_mode_tests_reachability(or_options_t *options);
int authdir_mode_bridge(or_options_t *options);
-int clique_mode(or_options_t *options);
int server_mode(or_options_t *options);
int advertised_server_mode(void);
int proxy_mode(or_options_t *options);
void consider_publishable_server(int force);
-int router_is_clique_mode(routerinfo_t *router);
void router_upload_dir_desc_to_dirservers(int force);
void mark_my_descriptor_dirty_if_older_than(time_t when);
void mark_my_descriptor_dirty(void);
@@ -4975,6 +4973,9 @@ routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule);
+/* XXXX actually declared in reasons.c */
+const char *bandwidth_weight_rule_to_string(enum bandwidth_weight_rule_t rule);
+
/** Flags to be passed to control router_choose_random_node() to indicate what
* kind of nodes to pick according to what algorithm. */
typedef enum {
@@ -5086,6 +5087,8 @@ trusted_dir_server_t *add_trusted_dir_server(const char *nickname,
void authority_cert_free(authority_cert_t *cert);
void clear_trusted_dir_servers(void);
int any_trusted_dir_is_v1_authority(void);
+void update_consensus_router_descriptor_downloads(time_t now, int is_vote,
+ networkstatus_t *consensus);
void update_router_descriptor_downloads(time_t now);
void update_extrainfo_downloads(time_t now);
int router_have_minimum_dir_info(void);
diff --git a/src/or/router.c b/src/or/router.c
index 347d7f9ef..d105aeffa 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -948,16 +948,6 @@ authdir_mode_bridge(or_options_t *options)
{
return authdir_mode(options) && options->BridgeAuthoritativeDir != 0;
}
-/** Return true iff we once tried to stay connected to all ORs at once.
- * FFFF this function, and the notion of staying connected to ORs, is
- * nearly obsolete. One day there will be a proposal for getting rid of
- * it.
- */
-int
-clique_mode(or_options_t *options)
-{
- return authdir_mode_tests_reachability(options);
-}
/** Return true iff we are trying to be a server.
*/
@@ -1052,20 +1042,6 @@ consider_publishable_server(int force)
}
/*
- * Clique maintenance -- to be phased out.
- */
-
-/** Return true iff we believe this OR tries to keep connections open
- * to all other ORs. */
-int
-router_is_clique_mode(routerinfo_t *router)
-{
- if (router_digest_is_trusted_dir(router->cache_info.identity_digest))
- return 1;
- return 0;
-}
-
-/*
* OR descriptor generation.
*/
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 13123e441..f4db40d25 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -26,8 +26,8 @@ static void mark_all_trusteddirservers_up(void);
static int router_nickname_matches(routerinfo_t *router, const char *nickname);
static void trusted_dir_server_free(trusted_dir_server_t *ds);
static void launch_router_descriptor_downloads(smartlist_t *downloadable,
+ routerstatus_t *source,
time_t now);
-static void update_consensus_router_descriptor_downloads(time_t now);
static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
static void update_router_have_minimum_dir_info(void);
static const char *signed_descriptor_get_body_impl(signed_descriptor_t *desc,
@@ -184,15 +184,15 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store,
log_info(LD_DIR, "Skipping %s certificate for %s that we "
"already have.",
from_store ? "cached" : "downloaded",
- ds ? ds->nickname : "??");
+ ds ? ds->nickname : "an old or new authority");
/* a duplicate on a download should be treated as a failure, since it
* probably means we wanted a different secret key or we are trying to
* replace an expired cert that has not in fact been updated. */
if (!from_store) {
- log_warn(LD_DIR, "Got a certificate for %s that we already have. "
- "Maybe they haven't updated it. Waiting for a while.",
- ds ? ds->nickname : "??");
+ log_warn(LD_DIR, "Got a certificate for %s, but we already have it. "
+ "Maybe they haven't updated it. Waiting for a while.",
+ ds ? ds->nickname : "an old or new authority");
authority_cert_dl_failed(cert->cache_info.identity_digest, 404);
}
@@ -973,8 +973,9 @@ router_get_trusteddirserver_by_digest(const char *digest)
return NULL;
}
-/** Return the trusted_dir_server_t for the directory authority whose identity
- * key hashes to <b>digest</b>, or NULL if no such authority is known.
+/** Return the trusted_dir_server_t for the directory authority whose
+ * v3 identity key hashes to <b>digest</b>, or NULL if no such authority
+ * is known.
*/
trusted_dir_server_t *
trusteddirserver_get_by_v3_auth_digest(const char *digest)
@@ -3203,7 +3204,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
if (!in_consensus && (router->cache_info.published_on <=
old_router->cache_info.published_on)) {
/* Same key, but old. This one is not listed in the consensus. */
- log_debug(LD_DIR, "Skipping not-new descriptor for router '%s'",
+ log_debug(LD_DIR, "Not-new descriptor for router '%s'",
router->nickname);
/* Only journal this desc if we'll be serving it. */
if (!from_cache && should_cache_old_descriptors())
@@ -3246,9 +3247,15 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
/* We haven't seen a router with this identity before. Add it to the end of
* the list. */
routerlist_insert(routerlist, router);
- if (!from_cache)
+ if (!from_cache) {
+ if (authdir) {
+ /* launch an immediate reachability test, so we will have an opinion
+ * soon in case we're generating a consensus soon */
+ dirserv_single_reachability_test(time(NULL), router);
+ }
signed_desc_append_to_journal(&router->cache_info,
&routerlist->desc_store);
+ }
directory_set_dirty();
return ROUTER_ADDED_SUCCESSFULLY;
}
@@ -4102,7 +4109,8 @@ client_would_use_router(routerstatus_t *rs, time_t now, or_options_t *options)
* whether to delay fetching until we have more. If we don't want to delay,
* launch one or more requests to the appropriate directory authorities. */
static void
-launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now)
+launch_router_descriptor_downloads(smartlist_t *downloadable,
+ routerstatus_t *source, time_t now)
{
int should_delay = 0, n_downloadable;
or_options_t *options = get_options();
@@ -4172,7 +4180,7 @@ launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now)
req_plural, n_downloadable, rtr_plural, n_per_request);
smartlist_sort_digests(downloadable);
for (i=0; i < n_downloadable; i += n_per_request) {
- initiate_descriptor_downloads(NULL, DIR_PURPOSE_FETCH_SERVERDESC,
+ initiate_descriptor_downloads(source, DIR_PURPOSE_FETCH_SERVERDESC,
downloadable, i, i+n_per_request,
pds_flags);
}
@@ -4328,18 +4336,18 @@ update_router_descriptor_cache_downloads_v2(time_t now)
digestmap_free(map,NULL);
}
-/** For any descriptor that we want that's currently listed in the live
- * consensus, download it as appropriate. */
-static void
-update_consensus_router_descriptor_downloads(time_t now)
+/** For any descriptor that we want that's currently listed in
+ * <b>consensus</b>, download it as appropriate. */
+void
+update_consensus_router_descriptor_downloads(time_t now, int is_vote,
+ networkstatus_t *consensus)
{
or_options_t *options = get_options();
digestmap_t *map = NULL;
smartlist_t *no_longer_old = smartlist_create();
smartlist_t *downloadable = smartlist_create();
+ routerstatus_t *source = NULL;
int authdir = authdir_mode(options);
- networkstatus_t *consensus =
- networkstatus_get_reasonably_live_consensus(now);
int n_delayed=0, n_have=0, n_would_reject=0, n_wouldnt_use=0,
n_inprogress=0, n_in_oldrouters=0;
@@ -4348,10 +4356,24 @@ update_consensus_router_descriptor_downloads(time_t now)
if (!consensus)
goto done;
+ if (is_vote) {
+ /* where's it from, so we know whom to ask for descriptors */
+ trusted_dir_server_t *ds;
+ networkstatus_voter_info_t *voter = smartlist_get(consensus->voters, 0);
+ tor_assert(voter);
+ ds = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
+ if (ds)
+ source = &(ds->fake_status);
+ else
+ log_warn(LD_DIR, "couldn't lookup source from vote?");
+ }
+
map = digestmap_new();
list_pending_descriptor_downloads(map, 0);
- SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
+ SMARTLIST_FOREACH(consensus->routerstatus_list, void *, rsp,
{
+ routerstatus_t *rs =
+ is_vote ? &(((vote_routerstatus_t *)rsp)->status) : rsp;
signed_descriptor_t *sd;
if ((sd = router_get_by_descriptor_digest(rs->descriptor_digest))) {
routerinfo_t *ri;
@@ -4386,6 +4408,18 @@ update_consensus_router_descriptor_downloads(time_t now)
++n_wouldnt_use;
continue; /* We would never use it ourself. */
}
+ if (is_vote && source) {
+ char time_bufnew[ISO_TIME_LEN+1];
+ char time_bufold[ISO_TIME_LEN+1];
+ routerinfo_t *oldrouter = router_get_by_digest(rs->identity_digest);
+ format_iso_time(time_bufnew, rs->published_on);
+ if (oldrouter)
+ format_iso_time(time_bufold, oldrouter->cache_info.published_on);
+ log_info(LD_DIR, "Learned about %s (%s vs %s) from %s's vote (%s)",
+ rs->nickname, time_bufnew,
+ oldrouter ? time_bufold : "none",
+ source->nickname, oldrouter ? "known" : "unknown");
+ }
smartlist_add(downloadable, rs->descriptor_digest);
});
@@ -4419,7 +4453,7 @@ update_consensus_router_descriptor_downloads(time_t now)
smartlist_len(downloadable), n_delayed, n_have, n_in_oldrouters,
n_would_reject, n_wouldnt_use, n_inprogress);
- launch_router_descriptor_downloads(downloadable, now);
+ launch_router_descriptor_downloads(downloadable, source, now);
digestmap_free(map, NULL);
done:
@@ -4444,7 +4478,8 @@ update_router_descriptor_downloads(time_t now)
if (directory_fetches_dir_info_early(options)) {
update_router_descriptor_cache_downloads_v2(now);
}
- update_consensus_router_descriptor_downloads(now);
+ update_consensus_router_descriptor_downloads(now, 0,
+ networkstatus_get_reasonably_live_consensus(now));
/* XXXX021 we could be smarter here; see notes on bug 652. */
/* If we're a server that doesn't have a configured address, we rely on
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index ce6d854b4..9ebe2abc4 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -226,5 +226,5 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.2.2.10-alpha-dev"
+#define VERSION "0.2.2.13-alpha"