mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-25 15:10:48 +01:00
hs-v3: Stall SOCKS connection when no live consensus available
Fixes #23481 Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
d71a00e91f
commit
6b4eace248
4 changed files with 63 additions and 12 deletions
|
@ -80,6 +80,7 @@
|
|||
#include "hs_client.h"
|
||||
#include "hs_circuit.h"
|
||||
#include "main.h"
|
||||
#include "networkstatus.h"
|
||||
#include "nodelist.h"
|
||||
#include "policies.h"
|
||||
#include "proto_http.h"
|
||||
|
@ -1561,18 +1562,37 @@ connection_ap_handle_onion(entry_connection_t *conn,
|
|||
if (addresstype == ONION_V2_HOSTNAME) {
|
||||
tor_assert(edge_conn->rend_data);
|
||||
rend_client_refetch_v2_renddesc(edge_conn->rend_data);
|
||||
/* Whatever the result of the refetch, we don't go further. */
|
||||
return 0;
|
||||
} else {
|
||||
tor_assert(addresstype == ONION_V3_HOSTNAME);
|
||||
tor_assert(edge_conn->hs_ident);
|
||||
hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
|
||||
}
|
||||
/* Attempt to fetch the hsv3 descriptor. Check the retval to see how it
|
||||
* went and act accordingly. */
|
||||
int ret = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
|
||||
switch (ret) {
|
||||
case HS_CLIENT_FETCH_MISSING_INFO:
|
||||
/* By going to the end, the connection is put in waiting for a circuit
|
||||
* state which means that it will be retried and consider as a pending
|
||||
* connection. */
|
||||
goto end;
|
||||
case HS_CLIENT_FETCH_LAUNCHED:
|
||||
case HS_CLIENT_FETCH_HAVE_DESC:
|
||||
return 0;
|
||||
case HS_CLIENT_FETCH_ERROR:
|
||||
case HS_CLIENT_FETCH_NO_HSDIRS:
|
||||
case HS_CLIENT_FETCH_NOT_ALLOWED:
|
||||
/* Can't proceed further and better close the SOCKS request. */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We have the descriptor! So launch a connection to the HS. */
|
||||
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
log_info(LD_REND, "Descriptor is here. Great.");
|
||||
|
||||
end:
|
||||
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
/* We'll try to attach it at the next event loop, or whenever
|
||||
* we call connection_ap_attach_pending() */
|
||||
connection_ap_mark_as_pending_circuit(conn);
|
||||
|
|
|
@ -152,7 +152,7 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
|
|||
/* ...and base64 it. */
|
||||
retval = ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
|
||||
if (BUG(retval < 0)) {
|
||||
return -1;
|
||||
return HS_CLIENT_FETCH_ERROR;
|
||||
}
|
||||
|
||||
/* Copy onion pk to a dir_ident so that we attach it to the dir conn */
|
||||
|
@ -180,7 +180,7 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
|
|||
memwipe(base64_blinded_pubkey, 0, sizeof(base64_blinded_pubkey));
|
||||
memwipe(&hs_conn_dir_ident, 0, sizeof(hs_conn_dir_ident));
|
||||
|
||||
return 1;
|
||||
return HS_CLIENT_FETCH_LAUNCHED;
|
||||
}
|
||||
|
||||
/** Return the HSDir we should use to fetch the descriptor of the hidden
|
||||
|
@ -236,7 +236,7 @@ fetch_v3_desc(const ed25519_public_key_t *onion_identity_pk)
|
|||
hsdir_rs = pick_hsdir_v3(onion_identity_pk);
|
||||
if (!hsdir_rs) {
|
||||
log_info(LD_REND, "Couldn't pick a v3 hsdir.");
|
||||
return 0;
|
||||
return HS_CLIENT_FETCH_NO_HSDIRS;
|
||||
}
|
||||
|
||||
return directory_launch_v3_desc_fetch(onion_identity_pk, hsdir_rs);
|
||||
|
@ -998,8 +998,7 @@ hs_client_any_intro_points_usable(const ed25519_public_key_t *service_pk,
|
|||
/** Launch a connection to a hidden service directory to fetch a hidden
|
||||
* service descriptor using <b>identity_pk</b> to get the necessary keys.
|
||||
*
|
||||
* On success, 1 is returned. If no hidden service is left to ask, return 0.
|
||||
* On error, -1 is returned. (retval is only used by unittests right now) */
|
||||
* A hs_client_fetch_status_t code is returned. */
|
||||
int
|
||||
hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
|
||||
{
|
||||
|
@ -1009,7 +1008,23 @@ hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
|
|||
if (!get_options()->FetchHidServDescriptors) {
|
||||
log_warn(LD_REND, "We received an onion address for a hidden service "
|
||||
"descriptor but we are configured to not fetch.");
|
||||
return 0;
|
||||
return HS_CLIENT_FETCH_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
/* Without a live consensus we can't do any client actions. It is needed to
|
||||
* compute the hashring for a service. */
|
||||
if (!networkstatus_get_live_consensus(approx_time())) {
|
||||
log_info(LD_REND, "Can't fetch descriptor for service %s because we "
|
||||
"are missing a live consensus. Stalling connection.",
|
||||
safe_str_client(ed25519_fmt(identity_pk)));
|
||||
return HS_CLIENT_FETCH_MISSING_INFO;
|
||||
}
|
||||
|
||||
if (!router_have_minimum_dir_info()) {
|
||||
log_info(LD_REND, "Can't fetch descriptor for service %s because we "
|
||||
"dont have enough descriptors. Stalling connection.",
|
||||
safe_str_client(ed25519_fmt(identity_pk)));
|
||||
return HS_CLIENT_FETCH_MISSING_INFO;
|
||||
}
|
||||
|
||||
/* Check if fetching a desc for this HS is useful to us right now */
|
||||
|
@ -1020,7 +1035,7 @@ hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
|
|||
cached_desc)) {
|
||||
log_info(LD_GENERAL, "We would fetch a v3 hidden service descriptor "
|
||||
"but we already have a usable descriptor.");
|
||||
return 0;
|
||||
return HS_CLIENT_FETCH_HAVE_DESC;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,22 @@
|
|||
#include "hs_descriptor.h"
|
||||
#include "hs_ident.h"
|
||||
|
||||
/* Status code of a descriptor fetch request. */
|
||||
typedef enum {
|
||||
/* Something internally went wrong. */
|
||||
HS_CLIENT_FETCH_ERROR = -1,
|
||||
/* The fetch request has been launched successfully. */
|
||||
HS_CLIENT_FETCH_LAUNCHED = 0,
|
||||
/* We already have a usable descriptor. No fetch. */
|
||||
HS_CLIENT_FETCH_HAVE_DESC = 1,
|
||||
/* No more HSDir available to query. */
|
||||
HS_CLIENT_FETCH_NO_HSDIRS = 2,
|
||||
/* The fetch request is not allowed. */
|
||||
HS_CLIENT_FETCH_NOT_ALLOWED = 3,
|
||||
/* We are missing information to be able to launch a request. */
|
||||
HS_CLIENT_FETCH_MISSING_INFO = 4,
|
||||
} hs_client_fetch_status_t;
|
||||
|
||||
void hs_client_note_connection_attempt_succeeded(
|
||||
const edge_connection_t *conn);
|
||||
|
||||
|
|
|
@ -815,7 +815,7 @@ test_entryconn_rewrite_onion_v3(void *arg)
|
|||
tt_int_op(retval, OP_EQ, 0);
|
||||
|
||||
/* Check connection state after rewrite */
|
||||
tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT);
|
||||
tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_CIRCUIT_WAIT);
|
||||
/* check that the address got rewritten */
|
||||
tt_str_op(conn->socks_request->address, OP_EQ,
|
||||
"p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad");
|
||||
|
|
Loading…
Add table
Reference in a new issue