aboutsummaryrefslogtreecommitdiff
path: root/src/feature/dirclient
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature/dirclient')
-rw-r--r--src/feature/dirclient/dir_server_st.h6
-rw-r--r--src/feature/dirclient/dirclient.c38
-rw-r--r--src/feature/dirclient/dlstatus.c17
3 files changed, 50 insertions, 11 deletions
diff --git a/src/feature/dirclient/dir_server_st.h b/src/feature/dirclient/dir_server_st.h
index ed6b00647e..ac45f3787b 100644
--- a/src/feature/dirclient/dir_server_st.h
+++ b/src/feature/dirclient/dir_server_st.h
@@ -16,6 +16,8 @@
#include "core/or/or.h"
#include "feature/nodelist/routerstatus_st.h"
+struct smartlist_t;
+
/** Represents information about a single trusted or fallback directory
* server. */
struct dir_server_t {
@@ -48,6 +50,10 @@ struct dir_server_t {
time_t addr_current_at; /**< When was the document that we derived the
* address information from published? */
+ /** Authority only. Can be null. If present, a list of auth_dirport_t
+ * representing HTTP dirports for this authority. */
+ struct smartlist_t *auth_dirports;
+
routerstatus_t fake_status; /**< Used when we need to pass this trusted
* dir_server_t to
* directory_request_set_routerstatus.
diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index 0b6a8101a5..4e9c8e2f45 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -1134,6 +1134,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.
@@ -1176,7 +1177,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
@@ -1191,6 +1192,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);
@@ -1209,7 +1241,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
}
}
@@ -1324,6 +1356,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/dirclient/dlstatus.c b/src/feature/dirclient/dlstatus.c
index 8be2983a5d..c21dd113b4 100644
--- a/src/feature/dirclient/dlstatus.c
+++ b/src/feature/dirclient/dlstatus.c
@@ -73,15 +73,14 @@ find_dl_min_delay(const download_status_t *dls, const or_options_t *options)
}
}
case DL_SCHED_BRIDGE:
- if (options->UseBridges && num_bridges_usable(0) > 0) {
- /* A bridge client that is sure that one or more of its bridges are
- * running can afford to wait longer to update bridge descriptors. */
- return options->TestingBridgeDownloadInitialDelay;
- } else {
- /* A bridge client which might have no running bridges, must try to
- * get bridge descriptors straight away. */
- return options->TestingBridgeBootstrapDownloadInitialDelay;
- }
+ /* Be conservative here: always return the 'during bootstrap' delay
+ * value, so we never delay while trying to fetch descriptors
+ * for new bridges. Once we do succeed at fetching a descriptor
+ * for our bridge, we will adjust its next_attempt_at based on
+ * the longer "TestingBridgeDownloadInitialDelay" value. See
+ * learned_bridge_descriptor() for details.
+ */
+ return options->TestingBridgeBootstrapDownloadInitialDelay;
default:
tor_assert(0);
}