diff options
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r-- | src/or/circuitbuild.c | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 0e033a5899..860cd27567 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -559,7 +559,9 @@ circuit_build_times_create_histogram(circuit_build_times_t *cbt, * Return the Pareto start-of-curve parameter Xm. * * Because we are not a true Pareto curve, we compute this as the - * weighted average of the N=3 most frequent build time bins. + * weighted average of the N most frequent build time bins. N is either + * 1 if we don't have enough circuit build time data collected, or + * determined by the consensus parameter cbtnummodes (default 3). */ static build_time_t circuit_build_times_get_xm(circuit_build_times_t *cbt) @@ -572,6 +574,9 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt) int n=0; int num_modes = circuit_build_times_default_num_xm_modes(); + tor_assert(nbins > 0); + tor_assert(num_modes > 0); + // Only use one mode if < 1000 buildtimes. Not enough data // for multiple. if (cbt->total_build_times < CBT_NCIRCUITS_TO_OBSERVE) @@ -579,6 +584,7 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt) nth_max_bin = (build_time_t*)tor_malloc_zero(num_modes*sizeof(build_time_t)); + /* Determine the N most common build times */ for (i = 0; i < nbins; i++) { if (histogram[i] >= histogram[nth_max_bin[0]]) { nth_max_bin[0] = i; @@ -600,6 +606,10 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt) histogram[nth_max_bin[n]]); } + /* The following assert is safe, because we don't get called when we + * haven't observed at least CBT_MIN_MIN_CIRCUITS_TO_OBSERVE circuits. */ + tor_assert(bin_counts > 0); + ret /= bin_counts; tor_free(histogram); tor_free(nth_max_bin); @@ -1813,7 +1823,7 @@ circuit_n_conn_done(or_connection_t *or_conn, int status) continue; } else { /* We expected a key. See if it's the right one. */ - if (memcmp(or_conn->identity_digest, + if (tor_memneq(or_conn->identity_digest, circ->n_hop->identity_digest, DIGEST_LEN)) continue; } @@ -2221,7 +2231,7 @@ circuit_extend(cell_t *cell, circuit_t *circ) /* Next, check if we're being asked to connect to the hop that the * extend cell came from. There isn't any reason for that, and it can * assist circular-path attacks. */ - if (!memcmp(id_digest, TO_OR_CIRCUIT(circ)->p_conn->identity_digest, + if (tor_memeq(id_digest, TO_OR_CIRCUIT(circ)->p_conn->identity_digest, DIGEST_LEN)) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Client asked me to extend back to the previous hop."); @@ -3502,7 +3512,7 @@ static INLINE entry_guard_t * is_an_entry_guard(const char *digest) { SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry, - if (!memcmp(digest, entry->identity, DIGEST_LEN)) + if (tor_memeq(digest, entry->identity, DIGEST_LEN)) return entry; ); return NULL; @@ -3834,7 +3844,7 @@ entry_guard_register_connect_status(const char *digest, int succeeded, SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e, { - if (!memcmp(e->identity, digest, DIGEST_LEN)) { + if (tor_memeq(e->identity, digest, DIGEST_LEN)) { entry = e; idx = e_sl_idx; break; @@ -4461,6 +4471,9 @@ typedef struct { tor_addr_t addr; /** TLS port for the bridge. */ uint16_t port; + /** Boolean: We are re-parsing our bridge list, and we are going to remove + * this one if we don't find it in the list of configured bridges. */ + unsigned marked_for_removal : 1; /** Expected identity digest, or all zero bytes if we don't know what the * digest should be. */ char identity[DIGEST_LEN]; @@ -4469,11 +4482,39 @@ typedef struct { } bridge_info_t; /** A list of configured bridges. Whenever we actually get a descriptor - * for one, we add it as an entry guard. */ + * for one, we add it as an entry guard. Note that the order of bridges + * in this list does not necessarily correspond to the order of bridges + * in the torrc. */ static smartlist_t *bridge_list = NULL; -/** Initialize the bridge list to empty, creating it if needed. */ +/** Mark every entry of the bridge list to be removed on our next call to + * sweep_bridge_list unless it has first been un-marked. */ void +mark_bridge_list(void) +{ + if (!bridge_list) + bridge_list = smartlist_create(); + SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, + b->marked_for_removal = 1); +} + +/** Remove every entry of the bridge list that was marked with + * mark_bridge_list if it has not subsequently been un-marked. */ +void +sweep_bridge_list(void) +{ + if (!bridge_list) + bridge_list = smartlist_create(); + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) { + if (b->marked_for_removal) { + SMARTLIST_DEL_CURRENT(bridge_list, b); + tor_free(b); + } + } SMARTLIST_FOREACH_END(b); +} + +/** Initialize the bridge list to empty, creating it if needed. */ +static void clear_bridge_list(void) { if (!bridge_list) @@ -4486,7 +4527,8 @@ clear_bridge_list(void) * (either by comparing keys if possible, else by comparing addr/port). * Else return NULL. */ static bridge_info_t * -get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port, +get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr, + uint16_t port, const char *digest) { if (!bridge_list) @@ -4497,7 +4539,7 @@ get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port, !tor_addr_compare(&bridge->addr, addr, CMP_EXACT) && bridge->port == port) return bridge; - if (!memcmp(bridge->identity, digest, DIGEST_LEN)) + if (tor_memeq(bridge->identity, digest, DIGEST_LEN)) return bridge; } SMARTLIST_FOREACH_END(bridge); @@ -4527,7 +4569,8 @@ routerinfo_is_a_configured_bridge(routerinfo_t *ri) * If it was a bridge, and we still don't know its digest, record it. */ void -learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest) +learned_router_identity(const tor_addr_t *addr, uint16_t port, + const char *digest) { bridge_info_t *bridge = get_configured_bridge_by_addr_port_digest(addr, port, digest); @@ -4539,11 +4582,20 @@ learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest) } /** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b> - * is set, it tells us the identity key too. */ + * is set, it tells us the identity key too. If we already had the + * bridge in our list, unmark it, and don't actually add anything new. */ void -bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest) +bridge_add_from_config(const tor_addr_t *addr, uint16_t port, + const char *digest) { - bridge_info_t *b = tor_malloc_zero(sizeof(bridge_info_t)); + bridge_info_t *b; + + if ((b = get_configured_bridge_by_addr_port_digest(addr, port, digest))) { + b->marked_for_removal = 0; + return; + } + + b = tor_malloc_zero(sizeof(bridge_info_t)); tor_addr_copy(&b->addr, addr); b->port = port; if (digest) @@ -4551,6 +4603,7 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest) b->fetch_status.schedule = DL_SCHED_BRIDGE; if (!bridge_list) bridge_list = smartlist_create(); + smartlist_add(bridge_list, b); } @@ -4578,7 +4631,7 @@ find_bridge_by_digest(const char *digest) { SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge, { - if (!memcmp(bridge->identity, digest, DIGEST_LEN)) + if (tor_memeq(bridge->identity, digest, DIGEST_LEN)) return bridge; }); return NULL; |