diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 67 | ||||
-rw-r--r-- | src/or/circuituse.c | 4 | ||||
-rw-r--r-- | src/or/command.c | 11 | ||||
-rw-r--r-- | src/or/config.c | 2 | ||||
-rw-r--r-- | src/or/connection.c | 22 | ||||
-rw-r--r-- | src/or/control.c | 45 | ||||
-rw-r--r-- | src/or/control.h | 4 | ||||
-rw-r--r-- | src/or/dircollate.c | 38 | ||||
-rw-r--r-- | src/or/dirvote.c | 72 | ||||
-rw-r--r-- | src/or/dirvote.h | 48 | ||||
-rw-r--r-- | src/or/entrynodes.c | 7 | ||||
-rw-r--r-- | src/or/hs_common.c | 15 | ||||
-rw-r--r-- | src/or/networkstatus.c | 2 | ||||
-rw-r--r-- | src/or/nodelist.c | 45 | ||||
-rw-r--r-- | src/or/nodelist.h | 4 | ||||
-rw-r--r-- | src/or/protover.c | 2 | ||||
-rw-r--r-- | src/or/relay.c | 6 | ||||
-rw-r--r-- | src/or/rendservice.c | 2 | ||||
-rw-r--r-- | src/or/routerlist.c | 6 | ||||
-rw-r--r-- | src/or/routerparse.c | 3 |
20 files changed, 184 insertions, 221 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 54446bb01d..c33dbbeb2d 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -418,7 +418,7 @@ onion_populate_cpath(origin_circuit_t *circ) circ->cpath->extend_info->identity_digest); /* If we don't know the node and its descriptor, we must be bootstrapping. */ - if (!node || !node_has_descriptor(node)) { + if (!node || !node_has_preferred_descriptor(node, 1)) { return 0; } } @@ -1758,7 +1758,7 @@ ap_stream_wants_exit_attention(connection_t *conn) * Return NULL if we can't find any suitable routers. */ static const node_t * -choose_good_exit_server_general(int need_uptime, int need_capacity) +choose_good_exit_server_general(router_crn_flags_t flags) { int *n_supported; int n_pending_connections = 0; @@ -1768,6 +1768,9 @@ choose_good_exit_server_general(int need_uptime, int need_capacity) const or_options_t *options = get_options(); const smartlist_t *the_nodes; const node_t *selected_node=NULL; + const int need_uptime = (flags & CRN_NEED_UPTIME) != 0; + const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0; + const int direct_conn = (flags & CRN_DIRECT_CONN) != 0; connections = get_connection_array(); @@ -1800,7 +1803,7 @@ choose_good_exit_server_general(int need_uptime, int need_capacity) */ continue; } - if (!node_has_descriptor(node)) { + if (!node_has_preferred_descriptor(node, direct_conn)) { n_supported[i] = -1; continue; } @@ -1913,7 +1916,8 @@ choose_good_exit_server_general(int need_uptime, int need_capacity) need_capacity?", fast":"", need_uptime?", stable":""); tor_free(n_supported); - return choose_good_exit_server_general(0, 0); + flags &= ~(CRN_NEED_UPTIME|CRN_NEED_CAPACITY); + return choose_good_exit_server_general(flags); } log_notice(LD_CIRC, "All routers are down or won't exit%s -- " "choosing a doomed exit at random.", @@ -2160,17 +2164,11 @@ pick_restricted_middle_node(router_crn_flags_t flags, * toward the preferences in 'options'. */ static const node_t * -choose_good_exit_server(origin_circuit_t *circ, int need_uptime, - int need_capacity, int is_internal, int need_hs_v3) +choose_good_exit_server(origin_circuit_t *circ, + router_crn_flags_t flags, int is_internal) { const or_options_t *options = get_options(); - router_crn_flags_t flags = CRN_NEED_DESC; - if (need_uptime) - flags |= CRN_NEED_UPTIME; - if (need_capacity) - flags |= CRN_NEED_CAPACITY; - if (need_hs_v3) - flags |= CRN_RENDEZVOUS_V3; + flags |= CRN_NEED_DESC; switch (TO_CIRCUIT(circ)->purpose) { case CIRCUIT_PURPOSE_C_HSDIR_GET: @@ -2184,7 +2182,7 @@ choose_good_exit_server(origin_circuit_t *circ, int need_uptime, if (is_internal) /* pick it like a middle hop */ return router_choose_random_node(NULL, options->ExcludeNodes, flags); else - return choose_good_exit_server_general(need_uptime,need_capacity); + return choose_good_exit_server_general(flags); case CIRCUIT_PURPOSE_C_ESTABLISH_REND: { /* Pick a new RP */ @@ -2309,15 +2307,22 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei, extend_info_describe(exit_ei)); exit_ei = extend_info_dup(exit_ei); } else { /* we have to decide one */ + router_crn_flags_t flags = CRN_NEED_DESC; + if (state->need_uptime) + flags |= CRN_NEED_UPTIME; + if (state->need_capacity) + flags |= CRN_NEED_CAPACITY; + if (is_hs_v3_rp_circuit) + flags |= CRN_RENDEZVOUS_V3; + if (state->onehop_tunnel) + flags |= CRN_DIRECT_CONN; const node_t *node = - choose_good_exit_server(circ, state->need_uptime, - state->need_capacity, state->is_internal, - is_hs_v3_rp_circuit); + choose_good_exit_server(circ, flags, state->is_internal); if (!node) { log_warn(LD_CIRC,"Failed to choose an exit server"); return -1; } - exit_ei = extend_info_from_node(node, 0); + exit_ei = extend_info_from_node(node, state->onehop_tunnel); if (BUG(exit_ei == NULL)) return -1; } @@ -2374,6 +2379,10 @@ circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *exit_ei) /** Return the number of routers in <b>routers</b> that are currently up * and available for building circuits through. + * + * (Note that this function may overcount or undercount, if we have + * descriptors that are not the type we would prefer to use for some + * particular router. See bug #25885.) */ MOCK_IMPL(STATIC int, count_acceptable_nodes, (smartlist_t *nodes)) @@ -2390,7 +2399,7 @@ count_acceptable_nodes, (smartlist_t *nodes)) if (! node->is_valid) // log_debug(LD_CIRC,"Nope, the directory says %d is not valid.",i); continue; - if (! node_has_descriptor(node)) + if (! node_has_any_descriptor(node)) continue; /* The node has a descriptor, so we can just check the ntor key directly */ if (!node_has_curve25519_onion_key(node)) @@ -2778,9 +2787,10 @@ extend_info_new(const char *nickname, * of the node (i.e. its IPv4 address) unless * <b>for_direct_connect</b> is true, in which case the preferred * address is used instead. May return NULL if there is not enough - * info about <b>node</b> to extend to it--for example, if there is no - * routerinfo_t or microdesc_t, or if for_direct_connect is true and none of - * the node's addresses are allowed by tor's firewall and IP version config. + * info about <b>node</b> to extend to it--for example, if the preferred + * routerinfo_t or microdesc_t is missing, or if for_direct_connect is + * true and none of the node's addresses is allowed by tor's firewall + * and IP version config. **/ extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect) @@ -2788,17 +2798,8 @@ extend_info_from_node(const node_t *node, int for_direct_connect) tor_addr_port_t ap; int valid_addr = 0; - const int is_bridge = node_is_a_configured_bridge(node); - const int we_use_mds = we_use_microdescriptors_for_circuits(get_options()); - - if ((is_bridge && for_direct_connect) || !we_use_mds) { - /* We need an ri in this case. */ - if (!node->ri) - return NULL; - } else { - /* Otherwise we need an md. */ - if (node->rs == NULL || node->md == NULL) - return NULL; + if (!node_has_preferred_descriptor(node, for_direct_connect)) { + return NULL; } /* Choose a preferred address first, but fall back to an allowed address. diff --git a/src/or/circuituse.c b/src/or/circuituse.c index fe28dd9a1a..47e29c28dd 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -2383,7 +2383,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, const node_t *r; int opt = conn->chosen_exit_optional; r = node_get_by_nickname(conn->chosen_exit_name, 0); - if (r && node_has_descriptor(r)) { + if (r && node_has_preferred_descriptor(r, conn->want_onehop ? 1 : 0)) { /* We might want to connect to an IPv6 bridge for loading descriptors so we use the preferred address rather than the primary. */ @@ -2393,7 +2393,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, "Discarding this circuit.", conn->chosen_exit_name); return -1; } - } else { /* ! (r && node_has_descriptor(r)) */ + } else { /* ! (r && node_has_preferred_descriptor(...)) */ log_debug(LD_DIR, "considering %d, %s", want_onehop, conn->chosen_exit_name); if (want_onehop && conn->chosen_exit_name[0] == '$') { diff --git a/src/or/command.c b/src/or/command.c index 4f99462f38..4fa05a18b4 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -495,6 +495,17 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) /* if we're a relay and treating connections with recent local * traffic better, then this is one of them. */ channel_timestamp_client(chan); + + /* Count all circuit bytes here for control port accuracy. We want + * to count even invalid/dropped relay cells, hence counting + * before the recognized check and the connection_edge_process_relay + * cell checks. + */ + origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); + + /* Count the payload bytes only. We don't care about cell headers */ + ocirc->n_read_circ_bw = tor_add_u32_nowrap(ocirc->n_read_circ_bw, + CELL_PAYLOAD_SIZE); } if (!CIRCUIT_IS_ORIGIN(circ) && diff --git a/src/or/config.c b/src/or/config.c index 206274cd38..9c0b321b56 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -2190,7 +2190,7 @@ options_act(const or_options_t *old_options) if (options->BandwidthRate != old_options->BandwidthRate || options->BandwidthBurst != old_options->BandwidthBurst || - options->BandwidthRate != old_options->BandwidthRate || + options->RelayBandwidthRate != old_options->RelayBandwidthRate || options->RelayBandwidthBurst != old_options->RelayBandwidthBurst) connection_bucket_adjust(options); diff --git a/src/or/connection.c b/src/or/connection.c index addf29ac5c..389199f18e 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -3592,25 +3592,15 @@ connection_buf_read_from_socket(connection_t *conn, ssize_t *max_to_read, /* change *max_to_read */ *max_to_read = at_most - n_read; - /* Update edge_conn->n_read and ocirc->n_read_circ_bw */ + /* Update edge_conn->n_read */ if (conn->type == CONN_TYPE_AP) { edge_connection_t *edge_conn = TO_EDGE_CONN(conn); - circuit_t *circ = circuit_get_by_edge_conn(edge_conn); - origin_circuit_t *ocirc; /* Check for overflow: */ if (PREDICT_LIKELY(UINT32_MAX - edge_conn->n_read > n_read)) edge_conn->n_read += (int)n_read; else edge_conn->n_read = UINT32_MAX; - - if (circ && CIRCUIT_IS_ORIGIN(circ)) { - ocirc = TO_ORIGIN_CIRCUIT(circ); - if (PREDICT_LIKELY(UINT32_MAX - ocirc->n_read_circ_bw > n_read)) - ocirc->n_read_circ_bw += (int)n_read; - else - ocirc->n_read_circ_bw = UINT32_MAX; - } } /* If CONN_BW events are enabled, update conn->n_read_conn_bw for @@ -3929,22 +3919,12 @@ connection_handle_write_impl(connection_t *conn, int force) if (n_written && conn->type == CONN_TYPE_AP) { edge_connection_t *edge_conn = TO_EDGE_CONN(conn); - circuit_t *circ = circuit_get_by_edge_conn(edge_conn); - origin_circuit_t *ocirc; /* Check for overflow: */ if (PREDICT_LIKELY(UINT32_MAX - edge_conn->n_written > n_written)) edge_conn->n_written += (int)n_written; else edge_conn->n_written = UINT32_MAX; - - if (circ && CIRCUIT_IS_ORIGIN(circ)) { - ocirc = TO_ORIGIN_CIRCUIT(circ); - if (PREDICT_LIKELY(UINT32_MAX - ocirc->n_written_circ_bw > n_written)) - ocirc->n_written_circ_bw += (int)n_written; - else - ocirc->n_written_circ_bw = UINT32_MAX; - } } /* If CONN_BW events are enabled, update conn->n_written_conn_bw for diff --git a/src/or/control.c b/src/or/control.c index 0539ddaca3..dda8872182 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1931,6 +1931,31 @@ getinfo_helper_listeners(control_connection_t *control_conn, return 0; } +/** Implementation helper for GETINFO: answers requests for information about + * the current time in both local and UTF forms. */ +STATIC int +getinfo_helper_current_time(control_connection_t *control_conn, + const char *question, + char **answer, const char **errmsg) +{ + (void)control_conn; + (void)errmsg; + + struct timeval now; + tor_gettimeofday(&now); + char timebuf[ISO_TIME_LEN+1]; + + if (!strcmp(question, "current-time/local")) + format_local_iso_time_nospace(timebuf, (time_t)now.tv_sec); + else if (!strcmp(question, "current-time/utc")) + format_iso_time_nospace(timebuf, (time_t)now.tv_sec); + else + return 0; + + *answer = tor_strdup(timebuf); + return 0; +} + /** Implementation helper for GETINFO: knows the answers for questions about * directory information. */ STATIC int @@ -3073,6 +3098,9 @@ static const getinfo_item_t getinfo_items[] = { DOC("config/defaults", "List of default values for configuration options. " "See also config/names"), + PREFIX("current-time/", current_time, "Current time."), + DOC("current-time/local", "Current time on the local system."), + DOC("current-time/utc", "Current UTC time."), PREFIX("downloads/networkstatus/", downloads, "Download statuses for networkstatus objects"), DOC("downloads/networkstatus/ns", @@ -3487,17 +3515,19 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len, smartlist_free(args); nodes = smartlist_new(); + int first_node = zero_circ; SMARTLIST_FOREACH_BEGIN(router_nicknames, const char *, n) { const node_t *node = node_get_by_nickname(n, 0); if (!node) { connection_printf_to_buf(conn, "552 No such router \"%s\"\r\n", n); goto done; } - if (!node_has_descriptor(node)) { + if (!node_has_preferred_descriptor(node, first_node)) { connection_printf_to_buf(conn, "552 No descriptor for \"%s\"\r\n", n); goto done; } smartlist_add(nodes, (void*)node); + first_node = 0; } SMARTLIST_FOREACH_END(n); if (!smartlist_len(nodes)) { connection_write_str_to_buf("512 No router names provided\r\n", conn); @@ -3510,14 +3540,15 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len, } /* now circ refers to something that is ready to be extended */ - int first_node = zero_circ; + first_node = zero_circ; SMARTLIST_FOREACH(nodes, const node_t *, node, { extend_info_t *info = extend_info_from_node(node, first_node); if (!info) { tor_assert_nonfatal(first_node); log_warn(LD_CONTROL, - "controller tried to connect to a node that doesn't have any " + "controller tried to connect to a node that lacks a suitable " + "descriptor, or which doesn't have any " "addresses that are allowed by the firewall configuration; " "circuit marked for closing."); circuit_mark_for_close(TO_CIRCUIT(circ), -END_CIRC_REASON_CONNECTFAILED); @@ -5800,8 +5831,6 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp, int control_event_stream_bandwidth(edge_connection_t *edge_conn) { - circuit_t *circ; - origin_circuit_t *ocirc; struct timeval now; char tbuf[ISO_TIME_USEC_LEN+1]; if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) { @@ -5817,12 +5846,6 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn) (unsigned long)edge_conn->n_written, tbuf); - circ = circuit_get_by_edge_conn(edge_conn); - if (circ && CIRCUIT_IS_ORIGIN(circ)) { - ocirc = TO_ORIGIN_CIRCUIT(circ); - ocirc->n_read_circ_bw += edge_conn->n_read; - ocirc->n_written_circ_bw += edge_conn->n_written; - } edge_conn->n_written = edge_conn->n_read = 0; } diff --git a/src/or/control.h b/src/or/control.h index 2fd3c553f3..2f312a6638 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -311,6 +311,10 @@ STATIC int getinfo_helper_dir( control_connection_t *control_conn, const char *question, char **answer, const char **errmsg); +STATIC int getinfo_helper_current_time( + control_connection_t *control_conn, + const char *question, char **answer, + const char **errmsg); #endif /* defined(CONTROL_PRIVATE) */ diff --git a/src/or/dircollate.c b/src/or/dircollate.c index ce4534ff6c..dec6f75154 100644 --- a/src/or/dircollate.c +++ b/src/or/dircollate.c @@ -25,7 +25,6 @@ #include "dircollate.h" #include "dirvote.h" -static void dircollator_collate_by_rsa(dircollator_t *dc); static void dircollator_collate_by_ed25519(dircollator_t *dc); /** Hashtable entry mapping a pair of digests (actually an ed25519 key and an @@ -208,49 +207,18 @@ dircollator_add_vote(dircollator_t *dc, networkstatus_t *v) void dircollator_collate(dircollator_t *dc, int consensus_method) { + (void) consensus_method; + tor_assert(!dc->is_collated); dc->all_rsa_sha1_lst = smartlist_new(); - if (consensus_method < MIN_METHOD_FOR_ED25519_ID_VOTING) - dircollator_collate_by_rsa(dc); - else - dircollator_collate_by_ed25519(dc); + dircollator_collate_by_ed25519(dc); smartlist_sort_digests(dc->all_rsa_sha1_lst); dc->is_collated = 1; } /** - * Collation function for RSA-only consensuses: collate the votes for each - * entry in <b>dc</b> by their RSA keys. - * - * The rule is: - * If an RSA identity key is listed by more than half of the authorities, - * include that identity, and treat all descriptors with that RSA identity - * as describing the same router. - */ -static void -dircollator_collate_by_rsa(dircollator_t *dc) -{ - const int total_authorities = dc->n_authorities; - - DIGESTMAP_FOREACH(dc->by_rsa_sha1, k, vote_routerstatus_t **, vrs_lst) { - int n = 0, i; - for (i = 0; i < dc->n_votes; ++i) { - if (vrs_lst[i] != NULL) - ++n; - } - - if (n <= total_authorities / 2) - continue; - - smartlist_add(dc->all_rsa_sha1_lst, (char *)k); - } DIGESTMAP_FOREACH_END; - - dc->by_collated_rsa_sha1 = dc->by_rsa_sha1; -} - -/** * Collation function for ed25519 consensuses: collate the votes for each * entry in <b>dc</b> by ed25519 key and by RSA key. * diff --git a/src/or/dirvote.c b/src/or/dirvote.c index c3cd0d3cd1..f3b8a19f00 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -549,12 +549,12 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method, tor_assert(most); - /* If we're producing "a" lines, vote on potential alternative (sets - * of) OR port(s) in the winning routerstatuses. + /* Vote on potential alternative (sets of) OR port(s) in the winning + * routerstatuses. * * XXX prop186 There's at most one alternative OR port (_the_ IPv6 * port) for now. */ - if (consensus_method >= MIN_METHOD_FOR_A_LINES && best_alt_orport_out) { + if (best_alt_orport_out) { smartlist_t *alt_orports = smartlist_new(); const tor_addr_port_t *most_alt_orport = NULL; @@ -664,13 +664,6 @@ compute_consensus_method(smartlist_t *votes) static int consensus_method_is_supported(int method) { - if (method == MIN_METHOD_FOR_ED25519_ID_IN_MD) { - /* This method was broken due to buggy code accidentally left in - * dircollate.c; do not actually use it. - */ - return 0; - } - return (method >= MIN_SUPPORTED_CONSENSUS_METHOD) && (method <= MAX_SUPPORTED_CONSENSUS_METHOD); } @@ -1455,19 +1448,14 @@ networkstatus_compute_consensus(smartlist_t *votes, n_versioning_servers); client_versions = compute_consensus_versions_list(combined_client_versions, n_versioning_clients); - if (consensus_method >= MIN_METHOD_FOR_PACKAGE_LINES) { - packages = compute_consensus_package_lines(votes); - } else { - packages = tor_strdup(""); - } + packages = compute_consensus_package_lines(votes); SMARTLIST_FOREACH(combined_server_versions, char *, cp, tor_free(cp)); SMARTLIST_FOREACH(combined_client_versions, char *, cp, tor_free(cp)); smartlist_free(combined_server_versions); smartlist_free(combined_client_versions); - if (consensus_method >= MIN_METHOD_FOR_ED25519_ID_VOTING) - smartlist_add_strdup(flags, "NoEdConsensus"); + smartlist_add_strdup(flags, "NoEdConsensus"); smartlist_sort_strings(flags); smartlist_uniq_strings(flags); @@ -1516,7 +1504,7 @@ networkstatus_compute_consensus(smartlist_t *votes, tor_free(flaglist); } - if (consensus_method >= MIN_METHOD_FOR_RECOMMENDED_PROTOCOLS) { + { int num_dirauth = get_n_authorities(V3_DIRINFO); int idx; for (idx = 0; idx < 4; ++idx) { @@ -1536,7 +1524,7 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_add_strdup(chunks, "\n"); } - if (consensus_method >= MIN_METHOD_FOR_SHARED_RANDOM) { + { int num_dirauth = get_n_authorities(V3_DIRINFO); /* Default value of this is 2/3 of the total number of authorities. For * instance, if we have 9 dirauth, the default value is 6. The following @@ -1601,7 +1589,7 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_free(dir_sources); } - if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW) { + { char *max_unmeasured_param = NULL; /* XXXX Extract this code into a common function. Or don't! see #19011 */ if (params) { @@ -1863,7 +1851,6 @@ networkstatus_compute_consensus(smartlist_t *votes, continue; if (ed_consensus > 0) { - tor_assert(consensus_method >= MIN_METHOD_FOR_ED25519_ID_VOTING); if (ed_consensus <= total_authorities / 2) { log_warn(LD_BUG, "Not enough entries had ed_consensus set; how " "can we have a consensus of %d?", ed_consensus); @@ -1890,10 +1877,8 @@ networkstatus_compute_consensus(smartlist_t *votes, rs_out.published_on = rs->status.published_on; rs_out.dir_port = rs->status.dir_port; rs_out.or_port = rs->status.or_port; - if (consensus_method >= MIN_METHOD_FOR_A_LINES) { - tor_addr_copy(&rs_out.ipv6_addr, &alt_orport.addr); - rs_out.ipv6_orport = alt_orport.port; - } + tor_addr_copy(&rs_out.ipv6_addr, &alt_orport.addr); + rs_out.ipv6_orport = alt_orport.port; rs_out.has_bandwidth = 0; rs_out.has_exitsummary = 0; @@ -1923,8 +1908,7 @@ networkstatus_compute_consensus(smartlist_t *votes, } else if (!strcmp(fl, "Unnamed")) { if (is_unnamed) smartlist_add(chosen_flags, (char*)fl); - } else if (!strcmp(fl, "NoEdConsensus") && - consensus_method >= MIN_METHOD_FOR_ED25519_ID_VOTING) { + } else if (!strcmp(fl, "NoEdConsensus")) { if (ed_consensus <= total_authorities/2) smartlist_add(chosen_flags, (char*)fl); } else { @@ -1951,8 +1935,7 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Starting with consensus method 24, we don't list servers * that are not valid in a consensus. See Proposal 272 */ - if (!is_valid && - consensus_method >= MIN_METHOD_FOR_EXCLUDING_INVALID_NODES) + if (!is_valid) continue; /* Pick the version. */ @@ -1973,8 +1956,7 @@ networkstatus_compute_consensus(smartlist_t *votes, /* If it's a guard and we have enough guardfraction votes, calculate its consensus guardfraction value. */ - if (is_guard && num_guardfraction_inputs > 2 && - consensus_method >= MIN_METHOD_FOR_GUARDFRACTION) { + if (is_guard && num_guardfraction_inputs > 2) { rs_out.has_guardfraction = 1; rs_out.guardfraction_percentage = median_uint32(measured_guardfraction, num_guardfraction_inputs); @@ -1991,8 +1973,7 @@ networkstatus_compute_consensus(smartlist_t *votes, rs_out.has_bandwidth = 1; rs_out.bw_is_unmeasured = 1; rs_out.bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths); - if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW && - n_authorities_measuring_bandwidth > 2) { + if (n_authorities_measuring_bandwidth > 2) { /* Cap non-measured bandwidths. */ if (rs_out.bandwidth_kb > max_unmeasured_bw_kb) { rs_out.bandwidth_kb = max_unmeasured_bw_kb; @@ -2132,8 +2113,7 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Now the weight line. */ if (rs_out.has_bandwidth) { char *guardfraction_str = NULL; - int unmeasured = rs_out.bw_is_unmeasured && - consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW; + int unmeasured = rs_out.bw_is_unmeasured; /* If we have guardfraction info, include it in the 'w' line. */ if (rs_out.has_guardfraction) { @@ -3835,8 +3815,7 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method) smartlist_add_asprintf(chunks, "onion-key\n%s", key); - if (consensus_method >= MIN_METHOD_FOR_NTOR_KEY && - ri->onion_curve25519_pkey) { + if (ri->onion_curve25519_pkey) { char kbuf[128]; base64_encode(kbuf, sizeof(kbuf), (const char*)ri->onion_curve25519_pkey->public_key, @@ -3846,8 +3825,7 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method) /* We originally put a lines in the micrdescriptors, but then we worked out * that we needed them in the microdesc consensus. See #20916. */ - if (consensus_method >= MIN_METHOD_FOR_A_LINES && - consensus_method < MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC && + if (consensus_method < MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC && !tor_addr_is_null(&ri->ipv6_addr) && ri->ipv6_orport) smartlist_add_asprintf(chunks, "a %s\n", fmt_addrport(&ri->ipv6_addr, ri->ipv6_orport)); @@ -3858,8 +3836,7 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method) if (summary && strcmp(summary, "reject 1-65535")) smartlist_add_asprintf(chunks, "p %s\n", summary); - if (consensus_method >= MIN_METHOD_FOR_P6_LINES && - ri->ipv6_exit_policy) { + if (ri->ipv6_exit_policy) { /* XXXX+++ This doesn't match proposal 208, which says these should * be taken unchanged from the routerinfo. That's bogosity, IMO: * the proposal should have said to do this instead.*/ @@ -3869,11 +3846,10 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method) tor_free(p6); } - if (consensus_method >= MIN_METHOD_FOR_ID_HASH_IN_MD) { + { char idbuf[ED25519_BASE64_LEN+1]; const char *keytype; - if (consensus_method >= MIN_METHOD_FOR_ED25519_ID_IN_MD && - ri->cache_info.signing_key_cert && + if (ri->cache_info.signing_key_cert && ri->cache_info.signing_key_cert->signing_key_included) { keytype = "ed25519"; ed25519_public_to_base64(idbuf, @@ -3951,13 +3927,7 @@ static const struct consensus_method_range_t { int low; int high; } microdesc_consensus_methods[] = { - {MIN_SUPPORTED_CONSENSUS_METHOD, MIN_METHOD_FOR_A_LINES - 1}, - {MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1}, - {MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1}, - {MIN_METHOD_FOR_NTOR_KEY, MIN_METHOD_FOR_ID_HASH_IN_MD - 1}, - {MIN_METHOD_FOR_ID_HASH_IN_MD, MIN_METHOD_FOR_ED25519_ID_IN_MD - 1}, - {MIN_METHOD_FOR_ED25519_ID_IN_MD, - MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC - 1}, + {MIN_SUPPORTED_CONSENSUS_METHOD, MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC - 1}, {MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC, MAX_SUPPORTED_CONSENSUS_METHOD}, {-1, -1} }; diff --git a/src/or/dirvote.h b/src/or/dirvote.h index deeb27bfe1..8a317deb47 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -56,57 +56,11 @@ #define ROUTERSTATUS_FORMAT_NO_CONSENSUS_METHOD 0 /** The lowest consensus method that we currently support. */ -#define MIN_SUPPORTED_CONSENSUS_METHOD 13 +#define MIN_SUPPORTED_CONSENSUS_METHOD 25 /** The highest consensus method that we currently support. */ #define MAX_SUPPORTED_CONSENSUS_METHOD 28 -/** Lowest consensus method where microdesc consensuses omit any entry - * with no microdesc. */ -#define MIN_METHOD_FOR_MANDATORY_MICRODESC 13 - -/** Lowest consensus method that contains "a" lines. */ -#define MIN_METHOD_FOR_A_LINES 14 - -/** Lowest consensus method where microdescs may include a "p6" line. */ -#define MIN_METHOD_FOR_P6_LINES 15 - -/** Lowest consensus method where microdescs may include an onion-key-ntor - * line */ -#define MIN_METHOD_FOR_NTOR_KEY 16 - -/** Lowest consensus method that ensures that authorities output an - * Unmeasured=1 flag for unmeasured bandwidths */ -#define MIN_METHOD_TO_CLIP_UNMEASURED_BW 17 - -/** Lowest consensus method where authorities may include an "id" line in - * microdescriptors. */ -#define MIN_METHOD_FOR_ID_HASH_IN_MD 18 - -/** Lowest consensus method where we include "package" lines*/ -#define MIN_METHOD_FOR_PACKAGE_LINES 19 - -/** Lowest consensus method where authorities may include - * GuardFraction information in microdescriptors. */ -#define MIN_METHOD_FOR_GUARDFRACTION 20 - -/** Lowest consensus method where authorities may include an "id" line for - * ed25519 identities in microdescriptors. (Broken; see - * consensus_method_is_supported() for more info.) */ -#define MIN_METHOD_FOR_ED25519_ID_IN_MD 21 - -/** Lowest consensus method where authorities vote on ed25519 ids and ensure - * ed25519 id consistency. */ -#define MIN_METHOD_FOR_ED25519_ID_VOTING 22 - -/** Lowest consensus method where authorities may include a shared random - * value(s). */ -#define MIN_METHOD_FOR_SHARED_RANDOM 23 - -/** Lowest consensus method where authorities drop all nodes that don't get - * the Valid flag. */ -#define MIN_METHOD_FOR_EXCLUDING_INVALID_NODES 24 - /** Lowest consensus method where authorities vote on required/recommended * protocols. */ #define MIN_METHOD_FOR_RECOMMENDED_PROTOCOLS 25 diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 88d1b94deb..96e6ccaace 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -185,14 +185,14 @@ should_apply_guardfraction(const networkstatus_t *ns) return options->UseGuardFraction; } -/** Return true iff we know a descriptor for <b>guard</b> */ +/** Return true iff we know a preferred descriptor for <b>guard</b> */ static int guard_has_descriptor(const entry_guard_t *guard) { const node_t *node = node_get_by_id(guard->identity); if (!node) return 0; - return node_has_descriptor(node); + return node_has_preferred_descriptor(node, 1); } /** @@ -2269,7 +2269,8 @@ entry_guard_pick_for_circuit(guard_selection_t *gs, // XXXX #20827 check Ed ID. if (! node) goto fail; - if (BUG(usage != GUARD_USAGE_DIRGUARD && !node_has_descriptor(node))) + if (BUG(usage != GUARD_USAGE_DIRGUARD && + !node_has_preferred_descriptor(node, 1))) goto fail; *chosen_node_out = node; diff --git a/src/or/hs_common.c b/src/or/hs_common.c index aa34b0e8fb..24eb7a104a 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -1279,8 +1279,10 @@ node_has_hsdir_index(const node_t *node) tor_assert(node_supports_v3_hsdir(node)); /* A node can't have an HSDir index without a descriptor since we need desc - * to get its ed25519 key */ - if (!node_has_descriptor(node)) { + * to get its ed25519 key. for_direct_connect should be zero, since we + * always use the consensus-indexed node's keys to build the hash ring, even + * if some of the consensus-indexed nodes are also bridges. */ + if (!node_has_preferred_descriptor(node, 0)) { return 0; } @@ -1611,12 +1613,17 @@ hs_pick_hsdir(smartlist_t *responsible_dirs, const char *req_key_str) hs_clean_last_hid_serv_requests(now); /* Only select those hidden service directories to which we did not send a - * request recently and for which we have a router descriptor here. */ + * request recently and for which we have a router descriptor here. + * + * Use for_direct_connect==0 even if we will be connecting to the node + * directly, since we always use the key information in the + * consensus-indexed node descriptors for building the index. + **/ SMARTLIST_FOREACH_BEGIN(responsible_dirs, routerstatus_t *, dir) { time_t last = hs_lookup_last_hid_serv_request(dir, req_key_str, 0, 0); const node_t *node = node_get_by_id(dir->identity_digest); if (last + hs_hsdir_requery_period(options) >= now || - !node || !node_has_descriptor(node)) { + !node || !node_has_preferred_descriptor(node, 0)) { SMARTLIST_DEL_CURRENT(responsible_dirs, dir); continue; } diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index e03d9e6fe5..5f19792c7d 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1528,7 +1528,7 @@ networkstatus_consensus_has_ipv6(const or_options_t* options) return cons->consensus_method >= MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS; } else { - return cons->consensus_method >= MIN_METHOD_FOR_A_LINES; + return 1; } } diff --git a/src/or/nodelist.c b/src/or/nodelist.c index 71eee3fa21..e7342f9799 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -43,6 +43,7 @@ #include "or.h" #include "address.h" #include "address_set.h" +#include "bridges.h" #include "config.h" #include "control.h" #include "dirserv.h" @@ -1130,15 +1131,44 @@ node_is_dir(const node_t *node) } } -/** Return true iff <b>node</b> has either kind of usable descriptor -- that - * is, a routerdescriptor or a microdescriptor. */ +/** Return true iff <b>node</b> has either kind of descriptor -- that + * is, a routerdescriptor or a microdescriptor. + * + * You should probably use node_has_preferred_descriptor() instead. + **/ int -node_has_descriptor(const node_t *node) +node_has_any_descriptor(const node_t *node) { return (node->ri || (node->rs && node->md)); } +/** Return true iff <b>node</b> has the kind of descriptor we would prefer to + * use for it, given our configuration and how we intend to use the node. + * + * If <b>for_direct_connect</b> is true, we intend to connect to the node + * directly, as the first hop of a circuit; otherwise, we intend to connect to + * it indirectly, or use it as if we were connecting to it indirectly. */ +int +node_has_preferred_descriptor(const node_t *node, + int for_direct_connect) +{ + const int is_bridge = node_is_a_configured_bridge(node); + const int we_use_mds = we_use_microdescriptors_for_circuits(get_options()); + + if ((is_bridge && for_direct_connect) || !we_use_mds) { + /* We need an ri in this case. */ + if (!node->ri) + return 0; + } else { + /* Otherwise we need an rs and an md. */ + if (node->rs == NULL || node->md == NULL) + return 0; + } + + return 1; +} + /** Return the router_purpose of <b>node</b>. */ int node_get_purpose(const node_t *node) @@ -1517,6 +1547,7 @@ node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out) { node_assert_ok(node); tor_assert(ap_out); + memset(ap_out, 0, sizeof(*ap_out)); /* Check ri first, because rewrite_node_address_for_bridge() updates * node->ri with the configured bridge address. @@ -1582,6 +1613,11 @@ node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out) node_assert_ok(node); tor_assert(ap_out); + /* Clear the address, as a safety precaution if calling functions ignore the + * return value */ + tor_addr_make_null(&ap_out->addr, AF_INET); + ap_out->port = 0; + /* Check ri first, because rewrite_node_address_for_bridge() updates * node->ri with the configured bridge address. */ @@ -2217,7 +2253,8 @@ compute_frac_paths_available(const networkstatus_t *consensus, nu); SMARTLIST_FOREACH_BEGIN(myexits_unflagged, const node_t *, node) { - if (node_has_descriptor(node) && node_exit_policy_rejects_all(node)) { + if (node_has_preferred_descriptor(node, 0) && + node_exit_policy_rejects_all(node)) { SMARTLIST_DEL_CURRENT(myexits_unflagged, node); /* this node is not actually an exit */ np--; diff --git a/src/or/nodelist.h b/src/or/nodelist.h index 53b18ab48a..1ffba2e8df 100644 --- a/src/or/nodelist.h +++ b/src/or/nodelist.h @@ -46,7 +46,9 @@ void node_get_verbose_nickname(const node_t *node, void node_get_verbose_nickname_by_id(const char *id_digest, char *verbose_name_out); int node_is_dir(const node_t *node); -int node_has_descriptor(const node_t *node); +int node_has_any_descriptor(const node_t *node); +int node_has_preferred_descriptor(const node_t *node, + int for_direct_connect); int node_get_purpose(const node_t *node); #define node_is_bridge(node) \ (node_get_purpose((node)) == ROUTER_PURPOSE_BRIDGE) diff --git a/src/or/protover.c b/src/or/protover.c index 6532f09c2f..18382ba7c9 100644 --- a/src/or/protover.c +++ b/src/or/protover.c @@ -715,7 +715,7 @@ protover_all_supported(const char *s, char **missing_out) versions->high = i; } /* If the last one to be unsupported is one less than the current - * one, we're in a continous range, so set the high field. */ + * one, we're in a continuous range, so set the high field. */ if ((versions->high && versions->high == i - 1) || /* Similarly, if the last high wasn't set and we're currently * one higher than the low, add current index as the highest diff --git a/src/or/relay.c b/src/or/relay.c index a33e0d1f36..8c248e6d98 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -374,6 +374,12 @@ circuit_package_relay_cell(cell_t *cell, circuit_t *circ, } relay_encrypt_cell_outbound(cell, TO_ORIGIN_CIRCUIT(circ), layer_hint); + + /* Update circ written totals for control port */ + origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); + ocirc->n_written_circ_bw = tor_add_u32_nowrap(ocirc->n_written_circ_bw, + CELL_PAYLOAD_SIZE); + } else { /* incoming cell */ if (CIRCUIT_IS_ORIGIN(circ)) { /* We should never package an _incoming_ cell from the circuit diff --git a/src/or/rendservice.c b/src/or/rendservice.c index cc22429777..1a93c36433 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -3596,7 +3596,7 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc, /* Don't upload descriptor if we succeeded in doing so last time. */ continue; node = node_get_by_id(hs_dir->identity_digest); - if (!node || !node_has_descriptor(node)) { + if (!node || !node_has_preferred_descriptor(node,0)) { log_info(LD_REND, "Not launching upload for for v2 descriptor to " "hidden service directory %s; we don't have its " "router descriptor. Queuing for later upload.", diff --git a/src/or/routerlist.c b/src/or/routerlist.c index bc3abb236f..1bfbd9f670 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2335,7 +2335,7 @@ router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime, SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) { if (!node->is_running || !node->is_valid) continue; - if (need_desc && !(node->ri || (node->rs && node->md))) + if (need_desc && !node_has_preferred_descriptor(node, direct_conn)) continue; if (node->ri && node->ri->purpose != ROUTER_PURPOSE_GENERAL) continue; @@ -2758,7 +2758,7 @@ frac_nodes_with_descriptors(const smartlist_t *sl, total <= 0.0) { int n_with_descs = 0; SMARTLIST_FOREACH(sl, const node_t *, node, { - if (node_has_descriptor(node)) + if (node_has_any_descriptor(node)) n_with_descs++; }); return ((double)n_with_descs) / (double)smartlist_len(sl); @@ -2766,7 +2766,7 @@ frac_nodes_with_descriptors(const smartlist_t *sl, present = 0.0; SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) { - if (node_has_descriptor(node)) + if (node_has_any_descriptor(node)) present += bandwidths[node_sl_idx]; } SMARTLIST_FOREACH_END(node); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 79499f2e6f..1834cfad24 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -2743,8 +2743,7 @@ routerstatus_parse_entry_from_string(memarea_t *area, /* These are implied true by having been included in a consensus made * with a given method */ rs->is_flagged_running = 1; /* Starting with consensus method 4. */ - if (consensus_method >= MIN_METHOD_FOR_EXCLUDING_INVALID_NODES) - rs->is_valid = 1; + rs->is_valid = 1; /* Starting with consensus method 24. */ } { const char *protocols = NULL, *version = NULL; |