[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Choose the correct dirport when contacting an authority.
commit ae0aff87ce321b2765a30472af9a2a310441408f
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Tue Feb 23 15:25:51 2021 -0500
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).
---
src/feature/dirclient/dirclient.c | 38 ++++++++++++++++++++++++++++++++++++--
src/feature/nodelist/dirlist.c | 39 ++++++++++++++++++++++++++++++++++++++-
src/feature/nodelist/dirlist.h | 6 ++++++
3 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index a5dd856729..257cf2c72d 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -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:
diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c
index c9d0a991e5..cc2795a5f5 100644
--- a/src/feature/nodelist/dirlist.c
+++ b/src/feature/nodelist/dirlist.c
@@ -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)
diff --git a/src/feature/nodelist/dirlist.h b/src/feature/nodelist/dirlist.h
index 70bbb780d1..c17589c12e 100644
--- a/src/feature/nodelist/dirlist.h
+++ b/src/feature/nodelist/dirlist.h
@@ -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);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits