use consensus ip:port for dir auths if different

Directory authorities and relays now interact properly with directory
authorities if they change addresses. In the past, they would continue
to upload votes, signatures, descriptors, etc to the hard-coded address
in the configuration. Now, if the directory authority is listed in
the consensus at a different address, they will direct queries to this
new address.

Specifically, these three activities have changed:

* Posting a vote, a signature, or a relay descriptor to all the dir auths.

* Dir auths fetching missing votes or signatures from all the dir auths.

* Dir auths fetching new descriptors from a specific dir auth when they
just learned about them from that dir auth's vote.

We already do this desired behavior (prefer the address in the consensus,
but fall back to the hard-coded dirservers info if needed) when fetching
missing certs.

There is a fifth case, in router_pick_trusteddirserver(), where clients
and relays are trying to reach a random dir auth to fetch something. I
left that case alone for now because the interaction with fallbackdirs
is complicated.

Implements ticket 40705.
This commit is contained in:
Roger Dingledine 2022-10-25 03:00:03 -04:00
parent 2033cc7b5e
commit c56980f5e5
3 changed files with 35 additions and 10 deletions

7
changes/ticket40705 Normal file
View File

@ -0,0 +1,7 @@
o Major features (dirauth):
- Directory authorities and relays now interact properly with
directory authorities if they change addresses. In the past, they
would continue to upload votes, signatures, descriptors, etc to
the hard-coded address in the configuration. Now, if the directory
authority is listed in the consensus at a different address, they
will direct queries to this new address. Implements ticket 40705.

View File

@ -242,7 +242,14 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
* harmless, and we may as well err on the side of getting things uploaded.
*/
SMARTLIST_FOREACH_BEGIN(dirservers, dir_server_t *, ds) {
routerstatus_t *rs = &(ds->fake_status);
const routerstatus_t *rs = router_get_consensus_status_by_id(ds->digest);
if (!rs) {
/* prefer to use the address in the consensus, but fall back to
* the hard-coded trusted_dir_server address if we don't have a
* consensus or this digest isn't in our consensus. */
rs = &ds->fake_status;
}
size_t upload_len = payload_len;
if ((type & ds->type) == 0)
@ -276,10 +283,8 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
}
if (purpose_needs_anonymity(dir_purpose, router_purpose, NULL)) {
indirection = DIRIND_ANONYMOUS;
} else if (!reachable_addr_allows_dir_server(ds,
FIREWALL_DIR_CONNECTION,
0)) {
if (reachable_addr_allows_dir_server(ds, FIREWALL_OR_CONNECTION, 0))
} else if (!reachable_addr_allows_rs(rs, FIREWALL_DIR_CONNECTION, 0)) {
if (reachable_addr_allows_rs(rs, FIREWALL_OR_CONNECTION, 0))
indirection = DIRIND_ONEHOP;
else
indirection = DIRIND_ANONYMOUS;
@ -590,7 +595,13 @@ directory_get_from_all_authorities(uint8_t dir_purpose,
continue;
if (!(ds->type & V3_DIRINFO))
continue;
const routerstatus_t *rs = &ds->fake_status;
const routerstatus_t *rs = router_get_consensus_status_by_id(ds->digest);
if (!rs) {
/* prefer to use the address in the consensus, but fall back to
* the hard-coded trusted_dir_server address if we don't have a
* consensus or this digest isn't in our consensus. */
rs = &ds->fake_status;
}
directory_request_t *req = directory_request_new(dir_purpose);
directory_request_set_routerstatus(req, rs);
directory_request_set_router_purpose(req, router_purpose);

View File

@ -2651,7 +2651,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
digestmap_t *map = NULL;
smartlist_t *no_longer_old = smartlist_new();
smartlist_t *downloadable = smartlist_new();
routerstatus_t *source = NULL;
const routerstatus_t *source = NULL;
int authdir = authdir_mode(options);
int n_delayed=0, n_have=0, n_would_reject=0, n_wouldnt_use=0,
n_inprogress=0, n_in_oldrouters=0;
@ -2667,10 +2667,17 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
networkstatus_voter_info_t *voter = smartlist_get(consensus->voters, 0);
tor_assert(voter);
ds = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
if (ds)
source = &(ds->fake_status);
else
if (ds) {
source = router_get_consensus_status_by_id(ds->digest);
if (!source) {
/* prefer to use the address in the consensus, but fall back to
* the hard-coded trusted_dir_server address if we don't have a
* consensus or this digest isn't in our consensus. */
source = &ds->fake_status;
}
} else {
log_warn(LD_DIR, "couldn't lookup source from vote?");
}
}
map = digestmap_new();