diff options
Diffstat (limited to 'src')
38 files changed, 404 insertions, 176 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c index d8bc5f6025..c7799ec1a2 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -2189,23 +2189,6 @@ options_act,(const or_options_t *old_options)) } } - /* Validate that we actually have a configured transport for a Bridge line - * that has one. This is done here because we require the bridge and - * transport to be added to the global list before doing the validation. - * - * In an ideal world, pt_parse_transport_line() would actually return a - * transport_t object so we could inspect it and thus do this step at - * validation time. */ - SMARTLIST_FOREACH_BEGIN(bridge_list_get(), const bridge_info_t *, bi) { - const char *bi_transport_name = bridget_get_transport_name(bi); - if (bi_transport_name && (!transport_get_by_name(bi_transport_name) && - !managed_proxy_has_transport(bi_transport_name))) { - log_warn(LD_CONFIG, "Bridge line with transport %s is missing a " - "ClientTransportPlugin line", bi_transport_name); - return -1; - } - } SMARTLIST_FOREACH_END(bi); - if (options_act_server_transport(old_options) < 0) return -1; @@ -6651,20 +6634,28 @@ get_first_listener_addrport_string(int listener_type) static const port_cfg_t * portconf_get_first_advertised(int listener_type, int address_family) { + const port_cfg_t *first_port = NULL; + const port_cfg_t *first_port_explicit_addr = NULL; + if (address_family == AF_UNSPEC) return NULL; const smartlist_t *conf_ports = get_configured_ports(); SMARTLIST_FOREACH_BEGIN(conf_ports, const port_cfg_t *, cfg) { - if (cfg->type == listener_type && - !cfg->server_cfg.no_advertise) { + if (cfg->type == listener_type && !cfg->server_cfg.no_advertise) { if ((address_family == AF_INET && port_binds_ipv4(cfg)) || (address_family == AF_INET6 && port_binds_ipv6(cfg))) { - return cfg; + if (cfg->explicit_addr && !first_port_explicit_addr) { + first_port_explicit_addr = cfg; + } else if (!first_port) { + first_port = cfg; + } } } } SMARTLIST_FOREACH_END(cfg); - return NULL; + + /* Prefer the port with the explicit address if any. */ + return (first_port_explicit_addr) ? first_port_explicit_addr : first_port; } /** Return the first advertised port of type <b>listener_type</b> in diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 6abfe0ff39..77ab6f26c8 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -2151,7 +2151,8 @@ hs_service_callback(time_t now, const or_options_t *options) /* We need to at least be able to build circuits and that we actually have * a working network. */ if (!have_completed_a_circuit() || net_is_disabled() || - networkstatus_get_live_consensus(now) == NULL) { + !networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor())) { goto end; } diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 846e6e5f42..dd5e42c47f 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -1248,9 +1248,7 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn) * the v2 and v3 handshakes. */ /* But that should be happening any longer've disabled bufferevents. */ tor_assert_nonfatal_unreached_once(); -#ifndef ALL_BUGS_ARE_FATAL - FALLTHROUGH; -#endif + FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL; case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING: if (!(command_allowed_before_handshake(var_cell->command))) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index ea32a5bc57..c0c918abe4 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -2456,7 +2456,6 @@ onion_extend_cpath(origin_circuit_t *circ) choose_good_middle_server(purpose, state, circ->cpath, cur_len); if (r) { info = extend_info_from_node(r, 0); - tor_assert_nonfatal(info); } } diff --git a/src/core/or/circuitlist.c b/src/core/or/circuitlist.c index a912b267da..bd36683880 100644 --- a/src/core/or/circuitlist.c +++ b/src/core/or/circuitlist.c @@ -851,9 +851,7 @@ circuit_purpose_to_controller_hs_state_string(uint8_t purpose) "Unrecognized circuit purpose: %d", (int)purpose); tor_fragile_assert(); -#ifndef ALL_BUGS_ARE_FATAL - FALLTHROUGH; -#endif + FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL; case CIRCUIT_PURPOSE_OR: case CIRCUIT_PURPOSE_C_GENERAL: diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c index 8e2bb01661..96c3497c6f 100644 --- a/src/feature/client/bridges.c +++ b/src/feature/client/bridges.c @@ -175,6 +175,17 @@ bridget_get_transport_name(const bridge_info_t *bridge) return bridge->transport_name; } +/** + * Return true if @a bridge has a transport name for which we don't actually + * know a transport. + */ +bool +bridge_has_invalid_transport(const bridge_info_t *bridge) +{ + const char *tname = bridget_get_transport_name(bridge); + return tname && transport_get_by_name(tname) == NULL; +} + /** If we have a bridge configured whose digest matches <b>digest</b>, or a * bridge with no known digest whose address matches any of the * tor_addr_port_t's in <b>orports</b>, return that bridge. Else return @@ -656,6 +667,15 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge) DIR_PURPOSE_FETCH_SERVERDESC)) return; /* it's already on the way */ + if (bridge_has_invalid_transport(bridge)) { + download_status_mark_impossible(&bridge->fetch_status); + log_warn(LD_CONFIG, "Can't use bridge at %s: there is no configured " + "transport called \"%s\".", + safe_str_client(fmt_and_decorate_addr(&bridge->addr)), + bridget_get_transport_name(bridge)); + return; /* Can't use this bridge; it has not */ + } + if (routerset_contains_bridge(options->ExcludeNodes, bridge)) { download_status_mark_impossible(&bridge->fetch_status); log_warn(LD_APP, "Not using bridge at %s: it is in ExcludeNodes.", diff --git a/src/feature/client/bridges.h b/src/feature/client/bridges.h index 1b090e8649..f5ecc1b76d 100644 --- a/src/feature/client/bridges.h +++ b/src/feature/client/bridges.h @@ -24,6 +24,7 @@ const smartlist_t *bridge_list_get(void); const uint8_t *bridge_get_rsa_id_digest(const bridge_info_t *bridge); const tor_addr_port_t * bridge_get_addr_port(const bridge_info_t *bridge); const char *bridget_get_transport_name(const bridge_info_t *bridge); +bool bridge_has_invalid_transport(const bridge_info_t *bridge); bridge_info_t *get_configured_bridge_by_addr_port_digest( const tor_addr_t *addr, uint16_t port, diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index 9da1c259b4..232216c521 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -804,6 +804,9 @@ get_sampled_guard_for_bridge(guard_selection_t *gs, entry_guard_t *guard; if (BUG(!addrport)) return NULL; // LCOV_EXCL_LINE + if (bridge_has_invalid_transport(bridge)) { + return NULL; + } guard = get_sampled_guard_by_bridge_addr(gs, addrport); if (! guard || (id && tor_memneq(id, guard->identity, DIGEST_LEN))) return NULL; @@ -2317,9 +2320,7 @@ entry_guards_note_guard_success(guard_selection_t *gs, break; default: tor_assert_nonfatal_unreached(); -#ifndef ALL_BUGS_ARE_FATAL - FALLTHROUGH; -#endif + FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL; case GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD: if (guard->is_primary) { /* XXXX #20832 -- I don't actually like this logic. It seems to make diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c index a1f9bb28ae..fa4d919aa9 100644 --- a/src/feature/dirauth/dirvote.c +++ b/src/feature/dirauth/dirvote.c @@ -2975,7 +2975,7 @@ dirvote_perform_vote(void) if (!contents) return -1; - pending_vote = dirvote_add_vote(contents, 0, &msg, &status); + pending_vote = dirvote_add_vote(contents, 0, "self", &msg, &status); tor_free(contents); if (!pending_vote) { log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)", @@ -3169,6 +3169,7 @@ add_new_cert_if_needed(const struct authority_cert_t *cert) * only) */ pending_vote_t * dirvote_add_vote(const char *vote_body, time_t time_posted, + const char *where_from, const char **msg_out, int *status_out) { networkstatus_t *vote; @@ -3226,6 +3227,14 @@ dirvote_add_vote(const char *vote_body, time_t time_posted, goto err; } + if (time_posted) { /* they sent it to me via a POST */ + log_notice(LD_DIR, "%s posted a vote to me from %s.", + vi->nickname, where_from); + } else { /* I imported this one myself */ + log_notice(LD_DIR, "Retrieved %s's vote from %s.", + vi->nickname, where_from); + } + /* Check if we received it, as a post, after the cutoff when we * start asking other dir auths for it. If we do, the best plan * is to discard it, because using it greatly increases the chances @@ -3235,10 +3244,10 @@ dirvote_add_vote(const char *vote_body, time_t time_posted, char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1]; format_iso_time(tbuf1, time_posted); format_iso_time(tbuf2, voting_schedule.fetch_missing_votes); - log_warn(LD_DIR, "Rejecting posted vote from %s received at %s; " + log_warn(LD_DIR, "Rejecting %s's posted vote from %s received at %s; " "our cutoff for received votes is %s. Check your clock, " "CPU load, and network load. Also check the authority that " - "posted the vote.", vi->address, tbuf1, tbuf2); + "posted the vote.", vi->nickname, vi->address, tbuf1, tbuf2); *msg_out = "Posted vote received too late, would be dangerous to count it"; goto err; } @@ -3254,8 +3263,8 @@ dirvote_add_vote(const char *vote_body, time_t time_posted, networkstatus_voter_info_t *vi_old = get_voter(v->vote); if (fast_memeq(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 (from %s).", - vi->address); + log_notice(LD_DIR, "Discarding a vote we already have (from %s).", + vi->address); if (*status_out < 200) *status_out = 200; goto discard; @@ -3278,6 +3287,8 @@ dirvote_add_vote(const char *vote_body, time_t time_posted, *msg_out = "OK"; return v; } else { + log_notice(LD_DIR, "Discarding vote from %s because we have " + "a newer one already.", vi->address); *msg_out = "Already have a newer pending vote"; goto err; } @@ -3462,6 +3473,15 @@ dirvote_compute_consensuses(void) pending[flav].body = consensus_body; pending[flav].consensus = consensus; n_generated++; + + /* Write it out to disk too, for dir auth debugging purposes */ + { + char *filename; + tor_asprintf(&filename, "my-consensus-%s", flavor_name); + write_str_to_file(get_datadir_fname(filename), consensus_body, 0); + tor_free(filename); + } + consensus_body = NULL; consensus = NULL; } @@ -4219,8 +4239,7 @@ compare_routerinfo_addrs_by_family(const routerinfo_t *a, { const tor_addr_t *addr1 = (family==AF_INET) ? &a->ipv4_addr : &a->ipv6_addr; const tor_addr_t *addr2 = (family==AF_INET) ? &b->ipv4_addr : &b->ipv6_addr; - const int maskbits = (family==AF_INET) ? 32 : 64; - return tor_addr_compare_masked(addr1, addr2, maskbits, CMP_EXACT); + return tor_addr_compare(addr1, addr2, CMP_EXACT); } /** Helper for sorting: compares two ipv4 routerinfos first by ipv4 address, diff --git a/src/feature/dirauth/dirvote.h b/src/feature/dirauth/dirvote.h index 4f48e45dc3..f9441773a7 100644 --- a/src/feature/dirauth/dirvote.h +++ b/src/feature/dirauth/dirvote.h @@ -99,6 +99,7 @@ void dirvote_dirreq_get_status_vote(const char *url, smartlist_t *items, /* Storing signatures and votes functions */ struct pending_vote_t * dirvote_add_vote(const char *vote_body, time_t time_posted, + const char *where_from, const char **msg_out, int *status_out); int dirvote_add_signatures(const char *detached_signatures_body, @@ -149,11 +150,13 @@ dirvote_dirreq_get_status_vote(const char *url, smartlist_t *items, static inline struct pending_vote_t * dirvote_add_vote(const char *vote_body, time_t time_posted, + const char *where_from, const char **msg_out, int *status_out) { (void) vote_body; (void) time_posted; + (void) where_from; /* If the dirauth module is disabled, this should NEVER be called else we * failed to safeguard the dirauth module. */ tor_assert_nonfatal_unreached(); diff --git a/src/feature/dirauth/process_descs.c b/src/feature/dirauth/process_descs.c index b08ffeba07..a382f237c4 100644 --- a/src/feature/dirauth/process_descs.c +++ b/src/feature/dirauth/process_descs.c @@ -322,8 +322,9 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg, * and is non-zero (clients check that it's non-zero before using it). */ if (!routerinfo_has_curve25519_onion_key(router)) { log_fn(severity, LD_DIR, - "Descriptor from router %s is missing an ntor curve25519 onion " - "key.", router_describe(router)); + "Descriptor from router %s (platform %s) " + "is missing an ntor curve25519 onion key.", + router_describe(router), router->platform); if (msg) *msg = "Missing ntor curve25519 onion key. Please upgrade!"; return RTR_REJECT; @@ -761,6 +762,9 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source) goto fail; } + log_info(LD_DIR, "Assessing new descriptor: %s: %s", + ri->nickname, ri->platform); + /* Check whether this descriptor is semantically identical to the last one * from this server. (We do this here and not in router_add_to_routerlist * because we want to be able to accept the newest router descriptor that diff --git a/src/feature/dirauth/reachability.c b/src/feature/dirauth/reachability.c index eb88b4aa07..8717646314 100644 --- a/src/feature/dirauth/reachability.c +++ b/src/feature/dirauth/reachability.c @@ -110,14 +110,18 @@ dirserv_should_launch_reachability_test(const routerinfo_t *ri, if (!ri_old) { /* New router: Launch an immediate reachability test, so we will have an * opinion soon in case we're generating a consensus soon */ + log_info(LD_DIR, "descriptor for new router %s", router_describe(ri)); return 1; } if (ri_old->is_hibernating && !ri->is_hibernating) { /* It just came out of hibernation; launch a reachability test */ + log_info(LD_DIR, "out of hibernation: router %s", router_describe(ri)); return 1; } if (! routers_have_same_or_addrs(ri, ri_old)) { /* Address or port changed; launch a reachability test */ + log_info(LD_DIR, "address or port changed: router %s", + router_describe(ri)); return 1; } return 0; @@ -148,7 +152,7 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router) } /* IPv4. */ - log_debug(LD_OR,"Testing reachability of %s at %s:%u.", + log_info(LD_OR,"Testing reachability of %s at %s:%u.", router->nickname, fmt_addr(&router->ipv4_addr), router->ipv4_orport); chan = channel_tls_connect(&router->ipv4_addr, router->ipv4_orport, @@ -160,10 +164,10 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router) if (dirauth_get_options()->AuthDirHasIPv6Connectivity == 1 && !tor_addr_is_null(&router->ipv6_addr)) { char addrstr[TOR_ADDR_BUF_LEN]; - log_debug(LD_OR, "Testing reachability of %s at %s:%u.", - router->nickname, - tor_addr_to_str(addrstr, &router->ipv6_addr, sizeof(addrstr), 1), - router->ipv6_orport); + log_info(LD_OR, "Testing reachability of %s at %s:%u.", + router->nickname, + tor_addr_to_str(addrstr, &router->ipv6_addr, sizeof(addrstr), 1), + router->ipv6_orport); chan = channel_tls_connect(&router->ipv6_addr, router->ipv6_orport, router->cache_info.identity_digest, ed_id_key); diff --git a/src/feature/dircache/consdiffmgr.c b/src/feature/dircache/consdiffmgr.c index 10590cd6d2..21f536432c 100644 --- a/src/feature/dircache/consdiffmgr.c +++ b/src/feature/dircache/consdiffmgr.c @@ -177,6 +177,16 @@ typedef struct cdm_diff_t { /** Hashtable mapping flavor and source consensus digest to status. */ static HT_HEAD(cdm_diff_ht, cdm_diff_t) cdm_diff_ht = HT_INITIALIZER(); +#ifdef _WIN32 + // XXX(ahf): For tor#24857, a contributor suggested that on Windows, the CPU + // begins to spike at 100% once the number of files handled by the consensus + // diff manager becomes larger than 64. To see if the issue goes away, we + // hardcode this value to 64 now while we investigate a better solution. +# define CACHE_MAX_NUM 64 +#else +# define CACHE_MAX_NUM 128 +#endif + /** * Configuration for this module */ @@ -184,7 +194,7 @@ static consdiff_cfg_t consdiff_cfg = { // XXXX I'd like to make this number bigger, but it interferes with the // XXXX seccomp2 syscall filter, which tops out at BPF_MAXINS (4096) // XXXX rules. - /* .cache_max_num = */ 128 + /* .cache_max_num = */ CACHE_MAX_NUM }; static int consdiffmgr_ensure_space_for_files(int n); diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index 207ea6698b..00bb0abf23 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -1675,6 +1675,15 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, const char *msg = "[None]"; uint8_t purpose = authdir_mode_bridge(options) ? ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL; + + { + char *genreason = http_get_header(headers, "X-Desc-Gen-Reason: "); + log_info(LD_DIRSERV, + "New descriptor post, because: %s", + genreason ? genreason : "not specified"); + tor_free(genreason); + } + was_router_added_t r = dirserv_add_multiple_descriptors(body, body_len, purpose, conn->base_.address, &msg); tor_assert(msg); @@ -1699,7 +1708,8 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, !strcmp(url,"/tor/post/vote")) { /* v3 networkstatus vote */ const char *msg = "OK"; int status; - if (dirvote_add_vote(body, approx_time(), &msg, &status)) { + if (dirvote_add_vote(body, approx_time(), TO_CONN(conn)->address, + &msg, &status)) { write_short_http_response(conn, status, "Vote stored"); } else { tor_assert(msg); diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 74e68ac6be..a5dd856729 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -2419,8 +2419,8 @@ handle_response_fetch_status_vote(dir_connection_t *conn, const char *msg; int st; - log_info(LD_DIR,"Got votes (body size %d) from server %s", - (int)body_len, connection_describe_peer(TO_CONN(conn))); + log_notice(LD_DIR,"Got votes (body size %d) from server %s", + (int)body_len, connection_describe_peer(TO_CONN(conn))); if (status_code != 200) { log_warn(LD_DIR, "Received http status code %d (%s) from server " @@ -2430,7 +2430,7 @@ handle_response_fetch_status_vote(dir_connection_t *conn, conn->requested_resource); return -1; } - dirvote_add_vote(body, 0, &msg, &st); + dirvote_add_vote(body, 0, TO_CONN(conn)->address, &msg, &st); if (st > 299) { log_warn(LD_DIR, "Error adding retrieved vote: %s", msg); } else { @@ -2720,7 +2720,7 @@ handle_response_upload_vote(dir_connection_t *conn, switch (status_code) { case 200: { - log_notice(LD_DIR,"Uploaded a vote to dirserver %s", + log_notice(LD_DIR,"Uploaded my vote to dirserver %s", connection_describe_peer(TO_CONN(conn))); } break; diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c index 03e004c356..c1334a7d27 100644 --- a/src/feature/hs/hs_cache.c +++ b/src/feature/hs/hs_cache.c @@ -17,6 +17,7 @@ #include "feature/hs/hs_common.h" #include "feature/hs/hs_client.h" #include "feature/hs/hs_descriptor.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/rend/rendcache.h" @@ -739,7 +740,9 @@ cached_client_descriptor_has_expired(time_t now, /* We use the current consensus time to see if we should expire this * descriptor since we use consensus time for all other parts of the protocol * as well (e.g. to build the blinded key and compute time periods). */ - const networkstatus_t *ns = networkstatus_get_live_consensus(now); + const networkstatus_t *ns = + networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor()); /* If we don't have a recent consensus, consider this entry expired since we * will want to fetch a new HS desc when we get a live consensus. */ if (!ns) { diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index 7cec2e0dce..4b4e268542 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -30,6 +30,7 @@ #include "feature/hs/hs_descriptor.h" #include "feature/hs/hs_ident.h" #include "feature/nodelist/describe.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerset.h" @@ -1303,9 +1304,10 @@ can_client_refetch_desc(const ed25519_public_key_t *identity_pk, goto cannot; } - /* Without a live consensus we can't do any client actions. It is needed to - * compute the hashring for a service. */ - if (!networkstatus_get_live_consensus(approx_time())) { + /* Without a usable consensus we can't do any client actions. It is needed + * to compute the hashring for a service. */ + if (!networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor())) { log_info(LD_REND, "Can't fetch descriptor for service %s because we " "are missing a live consensus. Stalling connection.", safe_str_client(ed25519_fmt(identity_pk))); diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index 8f3a5dfdf8..fa27ac5223 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -28,6 +28,7 @@ #include "feature/hs/hs_service.h" #include "feature/hs_common/shared_random_client.h" #include "feature/nodelist/describe.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerset.h" @@ -277,7 +278,9 @@ hs_get_time_period_num(time_t now) if (now != 0) { current_time = now; } else { - networkstatus_t *ns = networkstatus_get_live_consensus(approx_time()); + networkstatus_t *ns = + networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); current_time = ns ? ns->valid_after : approx_time(); } @@ -1110,7 +1113,8 @@ hs_in_period_between_tp_and_srv,(const networkstatus_t *consensus, time_t now)) time_t srv_start_time, tp_start_time; if (!consensus) { - consensus = networkstatus_get_live_consensus(now); + consensus = networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor()); if (!consensus) { return 0; } @@ -1355,7 +1359,9 @@ hs_get_responsible_hsdirs(const ed25519_public_key_t *blinded_pk, sorted_nodes = smartlist_new(); /* Make sure we actually have a live consensus */ - networkstatus_t *c = networkstatus_get_live_consensus(approx_time()); + networkstatus_t *c = + networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); if (!c || smartlist_len(c->routerstatus_list) == 0) { log_warn(LD_REND, "No live consensus so we can't get the responsible " "hidden service directories."); diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index fee999cac5..07e3550986 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -24,6 +24,7 @@ #include "feature/hs_common/shared_random_client.h" #include "feature/keymgt/loadkey.h" #include "feature/nodelist/describe.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nickname.h" #include "feature/nodelist/node_select.h" @@ -2509,7 +2510,8 @@ should_rotate_descriptors(hs_service_t *service, time_t now) tor_assert(service); - ns = networkstatus_get_live_consensus(now); + ns = networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor()); if (ns == NULL) { goto no_rotation; } @@ -3196,8 +3198,9 @@ should_service_upload_descriptor(const hs_service_t *service, } /* Don't upload desc if we don't have a live consensus */ - if (!networkstatus_get_live_consensus(now)) { - msg = tor_strdup("No live consensus"); + if (!networkstatus_get_reasonably_live_consensus(now, + usable_consensus_flavor())) { + msg = tor_strdup("No reasonably live consensus"); log_cant_upload_desc(service, desc, msg, LOG_DESC_UPLOAD_REASON_NO_LIVE_CONSENSUS); goto cannot; diff --git a/src/feature/hs_common/shared_random_client.c b/src/feature/hs_common/shared_random_client.c index c2ea5afe32..4e8a2942fc 100644 --- a/src/feature/hs_common/shared_random_client.c +++ b/src/feature/hs_common/shared_random_client.c @@ -13,6 +13,7 @@ #include "app/config/config.h" #include "feature/dirauth/authmode.h" #include "feature/dirauth/voting_schedule.h" +#include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "lib/encoding/binascii.h" @@ -55,7 +56,9 @@ int get_voting_interval(void) { int interval; - networkstatus_t *consensus = networkstatus_get_live_consensus(time(NULL)); + networkstatus_t *consensus = + networkstatus_get_reasonably_live_consensus(time(NULL), + usable_consensus_flavor()); if (consensus) { /* Ideally we have a live consensus and we can just use that. */ @@ -147,7 +150,8 @@ sr_get_current(const networkstatus_t *ns) if (ns) { consensus = ns; } else { - consensus = networkstatus_get_live_consensus(approx_time()); + consensus = networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); } /* Ideally we would never be asked for an SRV without a live consensus. Make * sure this assumption is correct. */ @@ -170,7 +174,8 @@ sr_get_previous(const networkstatus_t *ns) if (ns) { consensus = ns; } else { - consensus = networkstatus_get_live_consensus(approx_time()); + consensus = networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); } /* Ideally we would never be asked for an SRV without a live consensus. Make * sure this assumption is correct. */ @@ -242,13 +247,14 @@ sr_state_get_start_time_of_current_protocol_run(void) int voting_interval = get_voting_interval(); time_t beginning_of_curr_round; - /* This function is not used for voting purposes, so if we have a live - consensus, use its valid-after as the beginning of the current round. - If we have no consensus but we're an authority, use our own - schedule. Otherwise, try using our view of the voting interval - to figure out when the current round _should_ be starting. - */ - networkstatus_t *ns = networkstatus_get_live_consensus(approx_time()); + /* This function is not used for voting purposes, so if we have a reasonably + * live consensus, use its valid-after as the beginning of the current + * round. If we have no consensus but we're an authority, use our own + * schedule. Otherwise, try using our view of the voting interval to figure + * out when the current round _should_ be starting. */ + networkstatus_t *ns = + networkstatus_get_reasonably_live_consensus(approx_time(), + usable_consensus_flavor()); if (ns) { beginning_of_curr_round = ns->valid_after; } else if (authdir_mode(get_options()) || ASSUME_AUTHORITY_SCHEDULING) { diff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c index cf7732b8dc..01dccd160b 100644 --- a/src/feature/nodelist/microdesc.c +++ b/src/feature/nodelist/microdesc.c @@ -129,8 +129,9 @@ microdesc_note_outdated_dirserver(const char *relay_digest) tor_assert(outdated_dirserver_list); /* If the list grows too big, clean it up */ - if (BUG(smartlist_len(outdated_dirserver_list) > - TOO_MANY_OUTDATED_DIRSERVERS)) { + if (smartlist_len(outdated_dirserver_list) > TOO_MANY_OUTDATED_DIRSERVERS) { + log_info(LD_GENERAL,"Too many outdated directory servers (%d). Resetting.", + smartlist_len(outdated_dirserver_list)); microdesc_reset_outdated_dirservers_list(); } diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index f263d0fe7c..cfa8b69f81 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -362,7 +362,7 @@ node_set_hsdir_index(node_t *node, const networkstatus_t *ns) tor_assert(node); tor_assert(ns); - if (!networkstatus_is_live(ns, now)) { + if (!networkstatus_consensus_reasonably_live(ns, now)) { static struct ratelim_t live_consensus_ratelim = RATELIM_INIT(30 * 60); log_fn_ratelim(&live_consensus_ratelim, LOG_INFO, LD_GENERAL, "Not setting hsdir index with a non-live consensus."); diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c index e8c29fa7ed..e007a3bd0d 100644 --- a/src/feature/relay/relay_config.c +++ b/src/feature/relay/relay_config.c @@ -151,7 +151,7 @@ describe_portnum(int port) /** Return a static buffer containing the human readable logging string that * describes the given port object. */ -static const char * +STATIC const char * describe_relay_port(const port_cfg_t *port) { IF_BUG_ONCE(!port) { @@ -198,6 +198,16 @@ describe_relay_port(const port_cfg_t *port) * First one binds to both v4 and v6 address but second one is specific to an * address superseding the global bind one. * + * Another example is this one: + * + * ORPort 9001 + * ORPort [4242::1]:9002 + * ORPort [4242::2]:9003 + * + * In this case, all IPv4 and IPv6 are kept since we do allow multiple ORPorts + * but the published port will be the first explicit one if any to be + * published or else the implicit. + * * The following is O(n^2) but it is done at bootstrap or config reload and * the list is not very long usually. */ STATIC void @@ -231,11 +241,14 @@ remove_duplicate_orports(smartlist_t *ports) if (next->type != CONN_TYPE_OR_LISTENER) { continue; } - /* Same address family and same port number, we have a match. */ - if (tor_addr_family(¤t->addr) == tor_addr_family(&next->addr) && - current->port == next->port) { - /* Remove current because next is explicitly set. */ - removing[i] = true; + /* Don't compare addresses of different family. */ + if (tor_addr_family(¤t->addr) != tor_addr_family(&next->addr)) { + continue; + } + + /* Same port, we keep the explicit one. */ + if (current->port == next->port) { + removing[j] = true; if (!current->explicit_addr && next->explicit_addr) { char *next_str = tor_strdup(describe_relay_port(next)); log_warn(LD_CONFIG, "Configuration port %s superseded by %s", diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h index 671399ac0a..d36863a1a1 100644 --- a/src/feature/relay/relay_config.h +++ b/src/feature/relay/relay_config.h @@ -88,6 +88,12 @@ STATIC void remove_duplicate_orports(struct smartlist_t *ports); STATIC int check_bridge_distribution_setting(const char *bd); STATIC int have_enough_mem_for_dircache(const struct or_options_t *options, size_t total_mem, char **msg); +#ifdef TOR_UNIT_TESTS + +struct port_cfg_t; +STATIC const char *describe_relay_port(const struct port_cfg_t *port); + +#endif /* TOR_UNIT_TESTS */ #endif /* defined(RELAY_CONFIG_PRIVATE) */ diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index 9c2c8b281c..2da2328b14 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -198,9 +198,13 @@ relay_addr_learn_from_dirauth(void) return; } const node_t *node = node_get_by_id(rs->identity_digest); - if (BUG(!node)) { - /* If there is a routerstatus_t, there is a node_t thus this should - * never fail. */ + if (!node) { + /* This can happen if we are still in the early starting stage where no + * descriptors we actually fetched and thus we have the routerstatus_t + * for the authority but not its descriptor which is needed to build a + * circuit and thus learn our address. */ + log_info(LD_GENERAL, "Can't build a circuit to an authority. Unable to " + "learn for now our address from them."); return; } extend_info_t *ei = extend_info_from_node(node, 1); diff --git a/src/feature/relay/relay_periodic.c b/src/feature/relay/relay_periodic.c index a857ea8d92..a917d90f1a 100644 --- a/src/feature/relay/relay_periodic.c +++ b/src/feature/relay/relay_periodic.c @@ -104,7 +104,7 @@ rotate_onion_key_callback(time_t now, const or_options_t *options) log_info(LD_GENERAL,"Rotating onion key."); rotate_onion_key(); cpuworkers_rotate_keyinfo(); - if (router_rebuild_descriptor(1)<0) { + if (!router_rebuild_descriptor(1)) { log_info(LD_CONFIG, "Couldn't rebuild router descriptor"); } if (advertised_server_mode() && !net_is_disabled()) diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index e018561556..eb1d5a63f1 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -1427,10 +1427,9 @@ consider_publishable_server(int force) return; rebuilt = router_rebuild_descriptor(0); - if (decide_if_publishable_server()) { + if (rebuilt && decide_if_publishable_server()) { set_server_advertised(1); - if (rebuilt == 0) - router_upload_dir_desc_to_dirservers(force); + router_upload_dir_desc_to_dirservers(force); } else { set_server_advertised(0); } @@ -1817,7 +1816,7 @@ router_get_my_extrainfo(void) { if (!server_mode(get_options())) return NULL; - if (router_rebuild_descriptor(0)) + if (!router_rebuild_descriptor(0)) return NULL; return desc_extrainfo; } @@ -2414,9 +2413,10 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) /** If <b>force</b> is true, or our descriptor is out-of-date, rebuild a fresh * routerinfo, signed server descriptor, and extra-info document for this OR. - * Return 0 on success, -1 on temporary error. + * + * Return true on success, else false on temporary error. */ -int +bool router_rebuild_descriptor(int force) { int err = 0; @@ -2424,13 +2424,13 @@ router_rebuild_descriptor(int force) extrainfo_t *ei; if (desc_clean_since && !force) - return 0; + return true; log_info(LD_OR, "Rebuilding relay descriptor%s", force ? " (forced)" : ""); err = router_build_fresh_descriptor(&ri, &ei); if (err < 0) { - return err; + return false; } routerinfo_free(desc_routerinfo); @@ -2446,7 +2446,7 @@ router_rebuild_descriptor(int force) } desc_dirty_reason = NULL; control_event_my_descriptor_changed(); - return 0; + return true; } /** Called when we have a new set of consensus parameters. */ diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index 2648bb5112..aa03c27142 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -102,7 +102,7 @@ int router_extrainfo_digest_is_me(const char *digest); int router_is_me(const routerinfo_t *router); bool router_addr_is_my_published_addr(const tor_addr_t *addr); int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e); -int router_rebuild_descriptor(int force); +bool router_rebuild_descriptor(int force); char *router_dump_router_to_string(routerinfo_t *router, const crypto_pk_t *ident_key, const crypto_pk_t *tap_key, diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index 71eeb8a6ec..3dda7cd46d 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -838,9 +838,7 @@ rend_client_report_intro_point_failure(extend_info_t *failed_intro, log_warn(LD_BUG, "Unknown failure type %u. Removing intro point.", failure_type); tor_fragile_assert(); -#ifndef ALL_BUGS_ARE_FATAL - FALLTHROUGH; -#endif + FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL; case INTRO_POINT_FAILURE_GENERIC: rend_cache_intro_failure_note(failure_type, (uint8_t *)failed_intro->identity_digest, diff --git a/src/lib/log/util_bug.h b/src/lib/log/util_bug.h index 6b27b36f03..684dc7c6dd 100644 --- a/src/lib/log/util_bug.h +++ b/src/lib/log/util_bug.h @@ -249,6 +249,17 @@ #endif /* defined(ALL_BUGS_ARE_FATAL) || ... */ +/** + * Use this macro after a nonfatal assertion, and before a case statement + * where you would want to fall through. + */ +#ifdef ALL_BUGS_ARE_FATAL +#define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL \ + abort() +#else +#define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL FALLTHROUGH +#endif + /** In older code, we used tor_fragile_assert() to mark optional failure * points. At these points, we could make some debug builds fail. * (But release builds would continue.) diff --git a/src/test/test_config.c b/src/test/test_config.c index 49d7b87410..4eb4ac9cf5 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -6868,8 +6868,95 @@ test_config_duplicate_orports(void *arg) /* This will remove the [::] and the extra [::1]. */ remove_duplicate_orports(ports); - // The explicit IPv6 port should have replaced the implicit IPv6 port. tt_int_op(smartlist_len(ports), OP_EQ, 2); + tt_str_op(describe_relay_port(smartlist_get(ports, 0)), OP_EQ, + "ORPort 9050"); + tt_str_op(describe_relay_port(smartlist_get(ports, 1)), OP_EQ, + "ORPort [::1]:9050"); + + /* Reset. Test different ORPort value. */ + SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p)); + smartlist_free(ports); + config_free_lines(config_port); + config_port = NULL; + ports = smartlist_new(); + + /* Implicit port and then specific IPv6 addresses but more than one. */ + config_line_append(&config_port, "ORPort", "9050"); // two implicit entries. + config_line_append(&config_port, "ORPort", "[4242::1]:9051"); + config_line_append(&config_port, "ORPort", "[4242::2]:9051"); + + // Parse IPv4, then IPv6. + port_parse_config(ports, config_port, "OR", CONN_TYPE_OR_LISTENER, "0.0.0.0", + 0, CL_PORT_SERVER_OPTIONS); + port_parse_config(ports, config_port, "OR", CONN_TYPE_OR_LISTENER, "[::]", + 0, CL_PORT_SERVER_OPTIONS); + + /* There should be 6 ports at this point that is: + * - 0.0.0.0:9050 + * - [::]:9050 + * - [4242::1]:9051 + * - [4242::1]:9051 + * - [4242::2]:9051 + * - [4242::2]:9051 + */ + tt_int_op(smartlist_len(ports), OP_EQ, 6); + + /* This will remove the [::] and the duplicates. */ + remove_duplicate_orports(ports); + + /* We have four address here, 1 IPv4 on 9050, IPv6 on 9050, IPv6 on 9051 and + * a different IPv6 on 9051. */ + tt_int_op(smartlist_len(ports), OP_EQ, 3); + tt_str_op(describe_relay_port(smartlist_get(ports, 0)), OP_EQ, + "ORPort 9050"); + tt_str_op(describe_relay_port(smartlist_get(ports, 1)), OP_EQ, + "ORPort [4242::1]:9051"); + tt_str_op(describe_relay_port(smartlist_get(ports, 2)), OP_EQ, + "ORPort 9050"); + + /* Reset. Test different ORPort value. */ + SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p)); + smartlist_free(ports); + config_free_lines(config_port); + config_port = NULL; + ports = smartlist_new(); + + /* Three different ports. */ + config_line_append(&config_port, "ORPort", "9050"); // two implicit entries. + config_line_append(&config_port, "ORPort", "[4242::1]:9051"); + config_line_append(&config_port, "ORPort", "[4242::2]:9052"); + + // Parse IPv4, then IPv6. + port_parse_config(ports, config_port, "OR", CONN_TYPE_OR_LISTENER, "0.0.0.0", + 0, CL_PORT_SERVER_OPTIONS); + port_parse_config(ports, config_port, "OR", CONN_TYPE_OR_LISTENER, "[::]", + 0, CL_PORT_SERVER_OPTIONS); + + /* There should be 6 ports at this point that is: + * - 0.0.0.0:9050 + * - [::]:9050 + * - [4242::1]:9051 + * - [4242::1]:9051 + * - [4242::2]:9052 + * - [4242::2]:9052 + */ + tt_int_op(smartlist_len(ports), OP_EQ, 6); + + /* This will remove the [::] and the duplicates. */ + remove_duplicate_orports(ports); + + /* We have four address here, 1 IPv4 on 9050, IPv6 on 9050, IPv6 on 9051 and + * IPv6 on 9052. */ + tt_int_op(smartlist_len(ports), OP_EQ, 4); + tt_str_op(describe_relay_port(smartlist_get(ports, 0)), OP_EQ, + "ORPort 9050"); + tt_str_op(describe_relay_port(smartlist_get(ports, 1)), OP_EQ, + "ORPort [4242::1]:9051"); + tt_str_op(describe_relay_port(smartlist_get(ports, 2)), OP_EQ, + "ORPort [4242::2]:9052"); + tt_str_op(describe_relay_port(smartlist_get(ports, 3)), OP_EQ, + "ORPort 9050"); done: SMARTLIST_FOREACH(ports,port_cfg_t *,pf,port_cfg_free(pf)); diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index f717f83932..28f07efbe8 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -2105,7 +2105,7 @@ test_dir_handle_get_status_vote_d(void* data) const char *msg_out = NULL; int status_out = 0; - struct pending_vote_t *pv = dirvote_add_vote(VOTE_BODY_V3, 0, + struct pending_vote_t *pv = dirvote_add_vote(VOTE_BODY_V3, 0, "foo", &msg_out, &status_out); tt_assert(pv); @@ -2487,7 +2487,7 @@ test_dir_handle_get_status_vote_next_authority(void* data) time_t now = 1441223455 -1; dirauth_sched_recalculate_timing(mock_options, now); - struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, + struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, "foo", &msg_out, &status_out); tt_assert(vote); @@ -2649,7 +2649,7 @@ test_dir_handle_get_status_vote_current_authority(void* data) time_t now = 1441223455; dirauth_sched_recalculate_timing(mock_options, now-1); - struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, + struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, "foo", &msg_out, &status_out); tt_assert(vote); @@ -2777,7 +2777,7 @@ test_dir_handle_get_status_vote_too_late(void* data) /* Next voting interval */ vote = dirvote_add_vote(VOTE_BODY_V3, - fetch_missing + vote_interval, + fetch_missing + vote_interval, "foo", &msg_out, &status_out); tt_assert(!vote); tt_int_op(status_out, OP_EQ, 400); @@ -2786,7 +2786,7 @@ test_dir_handle_get_status_vote_too_late(void* data) /* Just after fetch missing */ vote = dirvote_add_vote(VOTE_BODY_V3, - fetch_missing + 1, + fetch_missing + 1, "foo", &msg_out, &status_out); tt_assert(!vote); tt_int_op(status_out, OP_EQ, 400); @@ -2795,7 +2795,7 @@ test_dir_handle_get_status_vote_too_late(void* data) /* On fetch missing */ vote = dirvote_add_vote(VOTE_BODY_V3, - fetch_missing, + fetch_missing, "foo", &msg_out, &status_out); tt_assert(vote); @@ -2806,7 +2806,7 @@ test_dir_handle_get_status_vote_too_late(void* data) /* Between voting starts and fetch missing */ vote = dirvote_add_vote(VOTE_BODY_V3, - voting_starts + 1, + voting_starts + 1, "foo", &msg_out, &status_out); tt_assert(vote); @@ -2817,7 +2817,7 @@ test_dir_handle_get_status_vote_too_late(void* data) /* On voting starts */ vote = dirvote_add_vote(VOTE_BODY_V3, - voting_starts, + voting_starts, "foo", &msg_out, &status_out); tt_assert(vote); @@ -2828,7 +2828,7 @@ test_dir_handle_get_status_vote_too_late(void* data) /* Just before voting starts */ vote = dirvote_add_vote(VOTE_BODY_V3, - voting_starts - 1, + voting_starts - 1, "foo", &msg_out, &status_out); tt_assert(vote); diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c index f25bba3584..df96b2c791 100644 --- a/src/test/test_hs_cache.c +++ b/src/test/test_hs_cache.c @@ -462,9 +462,10 @@ test_hsdir_revision_counter_check(void *arg) static networkstatus_t mock_ns; static networkstatus_t * -mock_networkstatus_get_live_consensus(time_t now) +mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor) { (void) now; + (void) flavor; return &mock_ns; } @@ -485,8 +486,8 @@ test_client_cache(void *arg) /* Initialize HSDir cache subsystem */ init_test(); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* Set consensus time */ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", @@ -589,8 +590,8 @@ test_client_cache_decrypt(void *arg) /* Initialize HSDir cache subsystem */ hs_init(); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* Set consensus time */ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", @@ -645,7 +646,7 @@ test_client_cache_decrypt(void *arg) hs_free_all(); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } static void @@ -659,8 +660,8 @@ test_client_cache_remove(void *arg) hs_init(); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* Set consensus time. Lookup will not return the entry if it has expired * and it is checked against the consensus valid_after time. */ @@ -698,7 +699,7 @@ test_client_cache_remove(void *arg) hs_descriptor_free(desc1); hs_free_all(); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } struct testcase_t hs_cache[] = { diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index dc3b2ff72c..f59b3a59cd 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -67,16 +67,18 @@ static networkstatus_t mock_ns; /* Always return NULL. */ static networkstatus_t * -mock_networkstatus_get_live_consensus_false(time_t now) +mock_networkstatus_get_reasonably_live_consensus_false(time_t now, int flavor) { (void) now; + (void) flavor; return NULL; } static networkstatus_t * -mock_networkstatus_get_live_consensus(time_t now) +mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor) { (void) now; + (void) flavor; return &mock_ns; } @@ -380,8 +382,8 @@ test_client_pick_intro(void *arg) ed25519_keypair_t service_kp; hs_descriptor_t *desc = NULL; - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); (void) arg; @@ -634,15 +636,15 @@ test_descriptor_fetch(void *arg) get_options_mutable()->FetchHidServDescriptors = 1; /* 2. We don't have a live consensus. */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus_false); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus_false); ret = hs_client_refetch_hsdesc(&service_pk); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); tt_int_op(ret, OP_EQ, HS_CLIENT_FETCH_MISSING_INFO); /* From now on, return a live consensus. */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* 3. Not enough dir information. */ MOCK(router_have_minimum_dir_info, @@ -684,7 +686,7 @@ test_descriptor_fetch(void *arg) done: connection_free_minimal(ENTRY_TO_CONN(ec)); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); UNMOCK(router_have_minimum_dir_info); hs_free_all(); } @@ -882,8 +884,8 @@ test_desc_has_arrived_cleanup(void *arg) hs_init(); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_); MOCK(router_have_minimum_dir_info, @@ -955,7 +957,7 @@ test_desc_has_arrived_cleanup(void *arg) tor_free(desc_str); hs_free_all(); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); UNMOCK(connection_mark_unattached_ap_); UNMOCK(router_have_minimum_dir_info); } @@ -976,8 +978,8 @@ test_close_intro_circuits_new_desc(void *arg) /* This is needed because of the client cache expiration timestamp is based * on having a consensus. See cached_client_descriptor_has_expired(). */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* Set consensus time */ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", @@ -1103,7 +1105,7 @@ test_close_intro_circuits_new_desc(void *arg) hs_descriptor_free(desc1); hs_descriptor_free(desc2); hs_free_all(); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } static void @@ -1122,8 +1124,8 @@ test_close_intro_circuits_cache_clean(void *arg) /* This is needed because of the client cache expiration timestamp is based * on having a consensus. See cached_client_descriptor_has_expired(). */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* Set consensus time */ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", @@ -1188,7 +1190,7 @@ test_close_intro_circuits_cache_clean(void *arg) hs_descriptor_free(desc1); hs_free_all(); rend_cache_free_all(); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } static void @@ -1209,8 +1211,8 @@ test_socks_hs_errors(void *arg) (void) arg; - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_no_close); MOCK(read_file_to_str, mock_read_file_to_str); @@ -1358,7 +1360,7 @@ test_socks_hs_errors(void *arg) hs_free_all(); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); UNMOCK(connection_mark_unattached_ap_); UNMOCK(read_file_to_str); UNMOCK(tor_listdir); diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index b0f408d662..5032a82b9c 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -358,9 +358,10 @@ mock_networkstatus_get_latest_consensus(void) } static networkstatus_t * -mock_networkstatus_get_live_consensus(time_t now) +mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor) { (void) now; + (void) flavor; tt_assert(mock_ns); @@ -380,6 +381,8 @@ test_responsible_hsdirs(void *arg) MOCK(networkstatus_get_latest_consensus, mock_networkstatus_get_latest_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); ns = networkstatus_get_latest_consensus(); @@ -416,6 +419,8 @@ test_responsible_hsdirs(void *arg) smartlist_clear(ns->routerstatus_list); networkstatus_vote_free(mock_ns); cleanup_nodelist(); + + UNMOCK(networkstatus_get_reasonably_live_consensus); } static void @@ -465,6 +470,8 @@ test_desc_reupload_logic(void *arg) hs_init(); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); MOCK(router_have_minimum_dir_info, mock_router_have_minimum_dir_info); MOCK(get_or_state, @@ -909,9 +916,11 @@ static smartlist_t *service_responsible_hsdirs = NULL; static smartlist_t *client_responsible_hsdirs = NULL; static networkstatus_t * -mock_networkstatus_get_live_consensus_service(time_t now) +mock_networkstatus_get_reasonably_live_consensus_service(time_t now, + int flavor) { (void) now; + (void) flavor; if (mock_service_ns) { return mock_service_ns; @@ -927,13 +936,14 @@ mock_networkstatus_get_live_consensus_service(time_t now) static networkstatus_t * mock_networkstatus_get_latest_consensus_service(void) { - return mock_networkstatus_get_live_consensus_service(0); + return mock_networkstatus_get_reasonably_live_consensus_service(0, 0); } static networkstatus_t * -mock_networkstatus_get_live_consensus_client(time_t now) +mock_networkstatus_get_reasonably_live_consensus_client(time_t now, int flavor) { (void) now; + (void) flavor; if (mock_client_ns) { return mock_client_ns; @@ -949,7 +959,7 @@ mock_networkstatus_get_live_consensus_client(time_t now) static networkstatus_t * mock_networkstatus_get_latest_consensus_client(void) { - return mock_networkstatus_get_live_consensus_client(0); + return mock_networkstatus_get_reasonably_live_consensus_client(0, 0); } /* Mock function because we are not trying to test the close circuit that does @@ -1409,8 +1419,8 @@ run_reachability_scenario(const reachability_cfg_t *cfg, int num_scenario) * === Client setup === */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus_client); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus_client); MOCK(networkstatus_get_latest_consensus, mock_networkstatus_get_latest_consensus_client); @@ -1434,14 +1444,14 @@ run_reachability_scenario(const reachability_cfg_t *cfg, int num_scenario) tt_int_op(smartlist_len(client_responsible_hsdirs), OP_EQ, 6); UNMOCK(networkstatus_get_latest_consensus); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); /* * === Service setup === */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus_service); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus_service); MOCK(networkstatus_get_latest_consensus, mock_networkstatus_get_latest_consensus_service); @@ -1468,7 +1478,7 @@ run_reachability_scenario(const reachability_cfg_t *cfg, int num_scenario) tt_int_op(smartlist_len(service_responsible_hsdirs), OP_EQ, 8); UNMOCK(networkstatus_get_latest_consensus); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); /* Some testing of the values we just got from the client and service. */ tt_mem_op(&client_blinded_pk, OP_EQ, &service_blinded_pk, @@ -1719,8 +1729,8 @@ test_client_service_hsdir_set_sync(void *arg) MOCK(networkstatus_get_latest_consensus, mock_networkstatus_get_latest_consensus); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); MOCK(get_or_state, get_or_state_replacement); MOCK(hs_desc_encode_descriptor, diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index e61d33ecb3..66e8e2f473 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -84,16 +84,18 @@ static networkstatus_t mock_ns; static networkstatus_t * -mock_networkstatus_get_live_consensus(time_t now) +mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor) { (void) now; + (void) flavor; return &mock_ns; } static networkstatus_t * -mock_networkstatus_get_live_consensus_null(time_t now) +mock_networkstatus_get_reasonably_live_consensus_null(time_t now, int flavor) { (void) now; + (void) flavor; return NULL; } @@ -1378,8 +1380,8 @@ test_rotate_descriptors(void *arg) hs_init(); MOCK(get_or_state, get_or_state_replacement); MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); /* Descriptor rotation happens with a consensus with a new SRV. */ @@ -1467,7 +1469,7 @@ test_rotate_descriptors(void *arg) hs_free_all(); UNMOCK(get_or_state); UNMOCK(circuit_mark_for_close_); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } /** Test building descriptors: picking intro points, setting up their link @@ -1487,8 +1489,8 @@ test_build_update_descriptors(void *arg) MOCK(get_or_state, get_or_state_replacement); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); dummy_state = or_state_new(); @@ -1716,8 +1718,8 @@ test_build_descriptors(void *arg) MOCK(get_or_state, get_or_state_replacement); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); dummy_state = or_state_new(); @@ -1817,8 +1819,8 @@ test_upload_descriptors(void *arg) hs_init(); MOCK(get_or_state, get_or_state_replacement); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); dummy_state = or_state_new(); @@ -2554,8 +2556,8 @@ test_cannot_upload_descriptors(void *arg) hs_init(); MOCK(get_or_state, get_or_state_replacement); - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); dummy_state = or_state_new(); @@ -2631,17 +2633,17 @@ test_cannot_upload_descriptors(void *arg) /* 4. Testing missing live consensus. */ { - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus_null); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus_null); setup_full_capture_of_logs(LOG_INFO); run_upload_descriptor_event(now); expect_log_msg_containing( "Service [scrubbed] can't upload its current descriptor: " - "No live consensus"); + "No reasonably live consensus"); teardown_capture_of_logs(); /* Reset. */ - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); } /* 5. Test missing minimum directory information. */ @@ -2680,7 +2682,7 @@ test_cannot_upload_descriptors(void *arg) done: hs_free_all(); UNMOCK(count_desc_circuit_established); - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); UNMOCK(get_or_state); } diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c index 950cdd3d33..678f53234f 100644 --- a/src/test/test_shared_random.c +++ b/src/test/test_shared_random.c @@ -167,6 +167,15 @@ mock_networkstatus_get_live_consensus(time_t now) return &mock_consensus; } +/* Mock function to immediately return our local 'mock_consensus'. */ +static networkstatus_t * +mock_networkstatus_get_reasonably_live_consensus(time_t now, int flavor) +{ + (void) now; + (void) flavor; + return &mock_consensus; +} + static void test_get_state_valid_until_time(void *arg) { @@ -179,6 +188,8 @@ test_get_state_valid_until_time(void *arg) MOCK(networkstatus_get_live_consensus, mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC", &mock_consensus.fresh_until); @@ -235,7 +246,7 @@ test_get_state_valid_until_time(void *arg) } done: - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } /** Test the function that calculates the start time of the current SRV @@ -251,6 +262,8 @@ test_get_start_time_of_current_run(void *arg) MOCK(networkstatus_get_live_consensus, mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC", &mock_consensus.fresh_until); @@ -335,6 +348,7 @@ test_get_start_time_of_current_run(void *arg) /* Next test is testing it without a consensus to use the testing voting * interval . */ UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); /* Now let's alter the voting schedule and check the correctness of the * function. Voting interval of 10 seconds, means that an SRV protocol run @@ -366,8 +380,8 @@ test_get_start_time_functions(void *arg) (void) arg; int retval; - MOCK(networkstatus_get_live_consensus, - mock_networkstatus_get_live_consensus); + MOCK(networkstatus_get_reasonably_live_consensus, + mock_networkstatus_get_reasonably_live_consensus); retval = parse_rfc1123_time("Mon, 20 Apr 2015 01:00:00 UTC", &mock_consensus.fresh_until); @@ -388,7 +402,7 @@ test_get_start_time_functions(void *arg) start_time_of_protocol_run); done: - UNMOCK(networkstatus_get_live_consensus); + UNMOCK(networkstatus_get_reasonably_live_consensus); } static void diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h index c29c37c974..93ba701f18 100644 --- a/src/win32/orconfig.h +++ b/src/win32/orconfig.h @@ -217,7 +217,7 @@ #define USING_TWOS_COMPLEMENT /* Version number of package */ -#define VERSION "0.4.5.3-rc" +#define VERSION "0.4.5.3-rc-dev" #define HAVE_STRUCT_SOCKADDR_IN6 #define HAVE_STRUCT_IN6_ADDR |