mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Choose the correct dirport when contacting an authority.
This is part of an implementation for proposal 330. This implementation doesn't handle authdirs' IPv6 dirports (yet).
This commit is contained in:
@@ -1164,6 +1164,7 @@ directory_request_set_routerstatus(directory_request_t *req,
|
||||
{
|
||||
req->routerstatus = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: update the addresses, ports, and identities in <b>req</b>
|
||||
* from the routerstatus object in <b>req</b>. Return 0 on success.
|
||||
@@ -1206,7 +1207,7 @@ directory_request_set_dir_from_routerstatus(directory_request_t *req)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* At this point, if we are a client making a direct connection to a
|
||||
/* At this point, if we are a client making a direct connection to a
|
||||
* directory server, we have selected a server that has at least one address
|
||||
* allowed by ClientUseIPv4/6 and Reachable{"",OR,Dir}Addresses. This
|
||||
* selection uses the preference in ClientPreferIPv6{OR,Dir}Port, if
|
||||
@@ -1221,6 +1222,37 @@ directory_request_set_dir_from_routerstatus(directory_request_t *req)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* One last thing: If we're talking to an authority, we might want to use
|
||||
* a special HTTP port for it based on our purpose.
|
||||
*/
|
||||
if (req->indirection == DIRIND_DIRECT_CONN && status->is_authority) {
|
||||
const dir_server_t *ds = router_get_trusteddirserver_by_digest(
|
||||
status->identity_digest);
|
||||
if (ds) {
|
||||
const tor_addr_port_t *v4 = NULL;
|
||||
if (authdir_mode_v3(get_options())) {
|
||||
// An authority connecting to another authority should always
|
||||
// prefer the VOTING usage, if one is specifically configured.
|
||||
v4 = trusted_dir_server_get_dirport_exact(
|
||||
ds, AUTH_USAGE_VOTING, AF_INET);
|
||||
}
|
||||
if (! v4) {
|
||||
// Everybody else should prefer a usage dependent on their
|
||||
// the dir_purpose.
|
||||
auth_dirport_usage_t usage =
|
||||
auth_dirport_usage_for_purpose(req->dir_purpose);
|
||||
v4 = trusted_dir_server_get_dirport(ds, usage, AF_INET);
|
||||
}
|
||||
tor_assert_nonfatal(v4);
|
||||
if (v4) {
|
||||
// XXXX We could, if we wanted, also select a v6 address. But a v4
|
||||
// address must exist here, and we as a relay are required to support
|
||||
// ipv4. So we just that.
|
||||
tor_addr_port_copy(&use_dir_ap, v4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
directory_request_set_or_addr_port(req, &use_or_ap);
|
||||
directory_request_set_dir_addr_port(req, &use_dir_ap);
|
||||
directory_request_set_directory_id_digest(req, status->identity_digest);
|
||||
@@ -1239,7 +1271,7 @@ directory_initiate_request,(directory_request_t *request))
|
||||
tor_assert_nonfatal(
|
||||
! directory_request_dir_contact_info_specified(request));
|
||||
if (directory_request_set_dir_from_routerstatus(request) < 0) {
|
||||
return;
|
||||
return; // or here XXXX
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1363,6 +1395,8 @@ directory_initiate_request,(directory_request_t *request))
|
||||
entry_guard_cancel(&guard_state);
|
||||
}
|
||||
|
||||
// XXXX This is the case where we replace.
|
||||
|
||||
switch (connection_connect(TO_CONN(conn), conn->base_.address, &addr,
|
||||
port, &socket_error)) {
|
||||
case -1:
|
||||
|
||||
@@ -297,6 +297,42 @@ router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Return an appropriate usage value describing which authdir port to use
|
||||
* for a given directory connection purpose.
|
||||
*/
|
||||
auth_dirport_usage_t
|
||||
auth_dirport_usage_for_purpose(int purpose)
|
||||
{
|
||||
switch (purpose) {
|
||||
case DIR_PURPOSE_FETCH_SERVERDESC:
|
||||
case DIR_PURPOSE_FETCH_EXTRAINFO:
|
||||
case DIR_PURPOSE_FETCH_CONSENSUS:
|
||||
case DIR_PURPOSE_FETCH_CERTIFICATE:
|
||||
case DIR_PURPOSE_FETCH_MICRODESC:
|
||||
return AUTH_USAGE_DOWNLOAD;
|
||||
|
||||
case DIR_PURPOSE_UPLOAD_DIR:
|
||||
return AUTH_USAGE_UPLOAD;
|
||||
|
||||
case DIR_PURPOSE_UPLOAD_VOTE:
|
||||
case DIR_PURPOSE_UPLOAD_SIGNATURES:
|
||||
case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
|
||||
case DIR_PURPOSE_FETCH_STATUS_VOTE:
|
||||
return AUTH_USAGE_VOTING;
|
||||
|
||||
case DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2:
|
||||
case DIR_PURPOSE_SERVER:
|
||||
case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
|
||||
case DIR_PURPOSE_FETCH_RENDDESC_V2:
|
||||
case DIR_PURPOSE_UPLOAD_HSDESC:
|
||||
case DIR_PURPOSE_FETCH_HSDESC:
|
||||
case DIR_PURPOSE_HAS_FETCHED_HSDESC:
|
||||
default:
|
||||
tor_assert_nonfatal_unreached();
|
||||
return AUTH_USAGE_LEGACY;
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a directory server at <b>address</b>:<b>port</b>, with OR identity
|
||||
* key <b>digest</b> which has DIGEST_LEN bytes. If <b>address</b> is NULL,
|
||||
* add ourself. If <b>is_authority</b>, this is a directory authority. Return
|
||||
@@ -373,6 +409,7 @@ dir_server_new(int is_authority,
|
||||
ent->fake_status.ipv4_dirport = ent->ipv4_dirport;
|
||||
ent->fake_status.ipv4_orport = ent->ipv4_orport;
|
||||
ent->fake_status.ipv6_orport = ent->ipv6_orport;
|
||||
ent->fake_status.is_authority = !! is_authority;
|
||||
|
||||
return ent;
|
||||
}
|
||||
@@ -465,7 +502,7 @@ trusted_dir_server_add_dirport(dir_server_t *ds,
|
||||
* Helper for trusted_dir_server_get_dirport: only return the exact requested
|
||||
* usage type.
|
||||
*/
|
||||
static const tor_addr_port_t *
|
||||
const tor_addr_port_t *
|
||||
trusted_dir_server_get_dirport_exact(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family)
|
||||
|
||||
@@ -40,6 +40,8 @@ smartlist_t *router_get_trusted_dir_servers_mutable(void);
|
||||
smartlist_t *router_get_fallback_dir_servers_mutable(void);
|
||||
void mark_all_dirservers_up(smartlist_t *server_list);
|
||||
|
||||
auth_dirport_usage_t auth_dirport_usage_for_purpose(int purpose);
|
||||
|
||||
dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
|
||||
dir_server_t *router_get_fallback_dirserver_by_digest(
|
||||
const char *digest);
|
||||
@@ -53,6 +55,10 @@ MOCK_DECL(int, router_digest_is_trusted_dir_type,
|
||||
const tor_addr_port_t *trusted_dir_server_get_dirport(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family);
|
||||
const tor_addr_port_t *trusted_dir_server_get_dirport_exact(
|
||||
const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family);
|
||||
|
||||
bool router_addr_is_trusted_dir_type(const tor_addr_t *addr,
|
||||
dirinfo_type_t type);
|
||||
|
||||
Reference in New Issue
Block a user