mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
avoid following through on a consensus fetch if we have one already arriving
This commit is contained in:
parent
ce8266d52d
commit
91c58013be
@ -2355,6 +2355,25 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
|
||||
/* we're a general conn */
|
||||
origin_circuit_t *circ=NULL;
|
||||
|
||||
/* Are we linked to a dir conn that aims to fetch a consensus?
|
||||
* We check here because this conn might no longer be needed. */
|
||||
if (base_conn->linked_conn &&
|
||||
base_conn->linked_conn->type == CONN_TYPE_DIR &&
|
||||
base_conn->linked_conn->purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
|
||||
|
||||
/* Yes we are. Is there a consensus fetch farther along than us? */
|
||||
if (networkstatus_consensus_is_already_downloading(
|
||||
TO_DIR_CONN(base_conn->linked_conn)->requested_resource)) {
|
||||
/* We're doing the "multiple consensus fetch attempts" game from
|
||||
* proposal 210, and we're late to the party. Just close this conn.
|
||||
* The circuit and TLS conn that we made will time out after a while
|
||||
* if nothing else wants to use them. */
|
||||
log_info(LD_DIR, "Closing extra consensus fetch (to %s) since one "
|
||||
"is already downloading.", base_conn->linked_conn->address);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->chosen_exit_name) {
|
||||
const node_t *node = node_get_by_nickname(conn->chosen_exit_name, 1);
|
||||
int opt = conn->chosen_exit_optional;
|
||||
|
@ -1349,27 +1349,46 @@ networkstatus_consensus_has_excess_connections(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is there a consensus fetch for flavor <b>resource</b> that's far
|
||||
* enough along to be attached to a circuit? */
|
||||
int
|
||||
networkstatus_consensus_is_already_downloading(const char *resource)
|
||||
{
|
||||
int answer = 0;
|
||||
|
||||
/* First, get a list of all the dir conns that are fetching a consensus,
|
||||
* fetching *this* consensus, and are in state "reading" (meaning they
|
||||
* have already flushed their request onto the socks connection). */
|
||||
smartlist_t *fetching_conns =
|
||||
connection_dir_list_by_purpose_resource_and_state(
|
||||
DIR_PURPOSE_FETCH_CONSENSUS, resource, DIR_CONN_STATE_CLIENT_READING);
|
||||
|
||||
/* Then, walk through each conn, to see if its linked socks connection
|
||||
* is in an attached state. We have to check this separately, since with
|
||||
* the optimistic data feature, fetches can send their request to the
|
||||
* socks connection and go into state 'reading', even before they're
|
||||
* attached to any circuit. */
|
||||
SMARTLIST_FOREACH_BEGIN(fetching_conns, dir_connection_t *, dirconn) {
|
||||
/* Do any of these other dir conns have a linked socks conn that is
|
||||
* attached to a circuit already? */
|
||||
connection_t *base = TO_CONN(dirconn);
|
||||
if (base->linked_conn &&
|
||||
base->linked_conn->type == CONN_TYPE_AP &&
|
||||
!AP_CONN_STATE_IS_UNATTACHED(base->linked_conn->state))
|
||||
answer = 1;
|
||||
} SMARTLIST_FOREACH_END(dirconn);
|
||||
smartlist_free(fetching_conns);
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
/* Is tor currently downloading a consensus of the usable flavor? */
|
||||
int
|
||||
networkstatus_consensus_is_downloading_usable_flavor(void)
|
||||
{
|
||||
const char *usable_resource = networkstatus_get_flavor_name(
|
||||
usable_consensus_flavor());
|
||||
const int consens_conn_usable_count =
|
||||
connection_dir_count_by_purpose_and_resource(
|
||||
DIR_PURPOSE_FETCH_CONSENSUS,
|
||||
usable_resource);
|
||||
|
||||
const int connect_consens_conn_usable_count =
|
||||
connection_dir_count_by_purpose_resource_and_state(
|
||||
DIR_PURPOSE_FETCH_CONSENSUS,
|
||||
usable_resource,
|
||||
DIR_CONN_STATE_CONNECTING);
|
||||
if (connect_consens_conn_usable_count < consens_conn_usable_count) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
const char *resource =
|
||||
networkstatus_get_flavor_name(usable_consensus_flavor());
|
||||
return networkstatus_consensus_is_already_downloading(resource);
|
||||
}
|
||||
|
||||
/** Given two router status entries for the same router identity, return 1 if
|
||||
|
@ -76,6 +76,7 @@ int networkstatus_consensus_can_use_multiple_directories(
|
||||
int networkstatus_consensus_can_use_extra_fallbacks(
|
||||
const or_options_t *options);
|
||||
int networkstatus_consensus_has_excess_connections(void);
|
||||
int networkstatus_consensus_is_already_downloading(const char *resource);
|
||||
int networkstatus_consensus_is_downloading_usable_flavor(void);
|
||||
|
||||
#define NSSET_FROM_CACHE 1
|
||||
|
Loading…
Reference in New Issue
Block a user