mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Merge branch 'bug15814_027_04'
This commit is contained in:
commit
41efe22c03
@ -2149,7 +2149,7 @@ link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ,
|
|||||||
* that an attempt to connect to a hidden service just
|
* that an attempt to connect to a hidden service just
|
||||||
* succeeded. Tell rendclient.c. */
|
* succeeded. Tell rendclient.c. */
|
||||||
rend_client_note_connection_attempt_ended(
|
rend_client_note_connection_attempt_ended(
|
||||||
ENTRY_TO_EDGE_CONN(apconn)->rend_data->onion_address);
|
ENTRY_TO_EDGE_CONN(apconn)->rend_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpath) { /* we were given one; use it */
|
if (cpath) { /* we were given one; use it */
|
||||||
|
@ -102,8 +102,7 @@ connection_mark_unattached_ap_,(entry_connection_t *conn, int endreason,
|
|||||||
* but we should fix it someday anyway. */
|
* but we should fix it someday anyway. */
|
||||||
if ((edge_conn->on_circuit != NULL || edge_conn->edge_has_sent_end) &&
|
if ((edge_conn->on_circuit != NULL || edge_conn->edge_has_sent_end) &&
|
||||||
connection_edge_is_rendezvous_stream(edge_conn)) {
|
connection_edge_is_rendezvous_stream(edge_conn)) {
|
||||||
rend_client_note_connection_attempt_ended(
|
rend_client_note_connection_attempt_ended(edge_conn->rend_data);
|
||||||
edge_conn->rend_data->onion_address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_conn->marked_for_close) {
|
if (base_conn->marked_for_close) {
|
||||||
@ -1499,12 +1498,27 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Look up if we have client authorization configured for this hidden
|
||||||
|
* service. If we do, associate it with the rend_data. */
|
||||||
|
rend_service_authorization_t *client_auth =
|
||||||
|
rend_client_lookup_service_authorization(socks->address);
|
||||||
|
|
||||||
|
const char *cookie = NULL;
|
||||||
|
rend_auth_type_t auth_type = REND_NO_AUTH;
|
||||||
|
if (client_auth) {
|
||||||
|
log_info(LD_REND, "Using previously configured client authorization "
|
||||||
|
"for hidden service request.");
|
||||||
|
auth_type = client_auth->auth_type;
|
||||||
|
cookie = client_auth->descriptor_cookie;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill in the rend_data field so we can start doing a connection to
|
/* Fill in the rend_data field so we can start doing a connection to
|
||||||
* a hidden service. */
|
* a hidden service. */
|
||||||
rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data =
|
rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data =
|
||||||
tor_malloc_zero(sizeof(rend_data_t));
|
rend_data_client_create(socks->address, NULL, cookie, auth_type);
|
||||||
strlcpy(rend_data->onion_address, socks->address,
|
if (rend_data == NULL) {
|
||||||
sizeof(rend_data->onion_address));
|
return -1;
|
||||||
|
}
|
||||||
log_info(LD_REND,"Got a hidden service request for ID '%s'",
|
log_info(LD_REND,"Got a hidden service request for ID '%s'",
|
||||||
safe_str_client(rend_data->onion_address));
|
safe_str_client(rend_data->onion_address));
|
||||||
|
|
||||||
@ -1547,19 +1561,6 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look up if we have client authorization configured for this hidden
|
|
||||||
* service. If we do, associate it with the rend_data. */
|
|
||||||
rend_service_authorization_t *client_auth =
|
|
||||||
rend_client_lookup_service_authorization(
|
|
||||||
rend_data->onion_address);
|
|
||||||
if (client_auth) {
|
|
||||||
log_info(LD_REND, "Using previously configured client authorization "
|
|
||||||
"for hidden service request.");
|
|
||||||
memcpy(rend_data->descriptor_cookie,
|
|
||||||
client_auth->descriptor_cookie, REND_DESC_COOKIE_LEN);
|
|
||||||
rend_data->auth_type = client_auth->auth_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have the descriptor so launch a connection to the HS. */
|
/* We have the descriptor so launch a connection to the HS. */
|
||||||
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||||
log_info(LD_REND, "Descriptor is here. Great.");
|
log_info(LD_REND, "Descriptor is here. Great.");
|
||||||
|
@ -3389,25 +3389,21 @@ handle_control_hsfetch(control_connection_t *conn, uint32_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rend_query = tor_malloc_zero(sizeof(*rend_query));
|
rend_query = rend_data_client_create(hsaddress, desc_id, NULL,
|
||||||
|
REND_NO_AUTH);
|
||||||
|
if (rend_query == NULL) {
|
||||||
|
connection_printf_to_buf(conn, "551 Error creating the HS query\r\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (hsaddress) {
|
|
||||||
strncpy(rend_query->onion_address, hsaddress,
|
|
||||||
sizeof(rend_query->onion_address));
|
|
||||||
} else if (desc_id) {
|
|
||||||
/* Using a descriptor ID, we force the user to provide at least one
|
/* Using a descriptor ID, we force the user to provide at least one
|
||||||
* hsdir server using the SERVER= option. */
|
* hsdir server using the SERVER= option. */
|
||||||
if (!hsdirs || !smartlist_len(hsdirs)) {
|
if (desc_id && (!hsdirs || !smartlist_len(hsdirs))) {
|
||||||
connection_printf_to_buf(conn, "512 %s option is required\r\n",
|
connection_printf_to_buf(conn, "512 %s option is required\r\n",
|
||||||
opt_server);
|
opt_server);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memcpy(rend_query->descriptor_id, desc_id,
|
|
||||||
sizeof(rend_query->descriptor_id));
|
|
||||||
} else {
|
|
||||||
/* We can't get in here because of the first argument check. */
|
|
||||||
tor_assert(0);
|
|
||||||
}
|
|
||||||
/* We are about to trigger HSDir fetch so send the OK now because after
|
/* We are about to trigger HSDir fetch so send the OK now because after
|
||||||
* that 650 event(s) are possible so better to have the 250 OK before them
|
* that 650 event(s) are possible so better to have the 250 OK before them
|
||||||
* to avoid out of order replies. */
|
* to avoid out of order replies. */
|
||||||
@ -3423,7 +3419,7 @@ done:
|
|||||||
smartlist_free(args);
|
smartlist_free(args);
|
||||||
/* Contains data pointer that we don't own thus no cleanup. */
|
/* Contains data pointer that we don't own thus no cleanup. */
|
||||||
smartlist_free(hsdirs);
|
smartlist_free(hsdirs);
|
||||||
tor_free(rend_query);
|
rend_data_free(rend_query);
|
||||||
exit:
|
exit:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
10
src/or/or.h
10
src/or/or.h
@ -793,6 +793,11 @@ typedef struct rend_data_t {
|
|||||||
/** Onion address (without the .onion part) that a client requests. */
|
/** Onion address (without the .onion part) that a client requests. */
|
||||||
char onion_address[REND_SERVICE_ID_LEN_BASE32+1];
|
char onion_address[REND_SERVICE_ID_LEN_BASE32+1];
|
||||||
|
|
||||||
|
/** Descriptor ID for each replicas computed from the onion address. If
|
||||||
|
* the onion address is empty, this array MUST be empty. We keep them so
|
||||||
|
* we know when to purge our entry in the last hsdir request table. */
|
||||||
|
char descriptor_id[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS][DIGEST_LEN];
|
||||||
|
|
||||||
/** (Optional) descriptor cookie that is used by a client. */
|
/** (Optional) descriptor cookie that is used by a client. */
|
||||||
char descriptor_cookie[REND_DESC_COOKIE_LEN];
|
char descriptor_cookie[REND_DESC_COOKIE_LEN];
|
||||||
|
|
||||||
@ -800,8 +805,9 @@ typedef struct rend_data_t {
|
|||||||
rend_auth_type_t auth_type;
|
rend_auth_type_t auth_type;
|
||||||
|
|
||||||
/** Descriptor ID for a client request. The control port command HSFETCH
|
/** Descriptor ID for a client request. The control port command HSFETCH
|
||||||
* can use this. */
|
* uses this. It's set if the descriptor query should only use this
|
||||||
char descriptor_id[DIGEST_LEN];
|
* descriptor ID. */
|
||||||
|
char desc_id_fetch[DIGEST_LEN];
|
||||||
|
|
||||||
/** Hash of the hidden service's PK used by a service. */
|
/** Hash of the hidden service's PK used by a service. */
|
||||||
char rend_pk_digest[DIGEST_LEN];
|
char rend_pk_digest[DIGEST_LEN];
|
||||||
|
@ -474,9 +474,8 @@ rend_client_introduction_acked(origin_circuit_t *circ,
|
|||||||
|
|
||||||
/** Contains the last request times to hidden service directories for
|
/** Contains the last request times to hidden service directories for
|
||||||
* certain queries; each key is a string consisting of the
|
* certain queries; each key is a string consisting of the
|
||||||
* concatenation of a base32-encoded HS directory identity digest, a
|
* concatenation of a base32-encoded HS directory identity digest and
|
||||||
* base32-encoded HS descriptor ID, and a hidden service address
|
* base32-encoded HS descriptor ID; each value is a pointer to a time_t
|
||||||
* (without the ".onion" part); each value is a pointer to a time_t
|
|
||||||
* holding the time of the last request for that descriptor ID to that
|
* holding the time of the last request for that descriptor ID to that
|
||||||
* HS directory. */
|
* HS directory. */
|
||||||
static strmap_t *last_hid_serv_requests_ = NULL;
|
static strmap_t *last_hid_serv_requests_ = NULL;
|
||||||
@ -492,8 +491,7 @@ get_last_hid_serv_requests(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define LAST_HID_SERV_REQUEST_KEY_LEN (REND_DESC_ID_V2_LEN_BASE32 + \
|
#define LAST_HID_SERV_REQUEST_KEY_LEN (REND_DESC_ID_V2_LEN_BASE32 + \
|
||||||
REND_DESC_ID_V2_LEN_BASE32 + \
|
REND_DESC_ID_V2_LEN_BASE32)
|
||||||
REND_SERVICE_ID_LEN_BASE32)
|
|
||||||
|
|
||||||
/** Look up the last request time to hidden service directory <b>hs_dir</b>
|
/** Look up the last request time to hidden service directory <b>hs_dir</b>
|
||||||
* for descriptor ID <b>desc_id_base32</b>. If <b>set</b> is non-zero,
|
* for descriptor ID <b>desc_id_base32</b>. If <b>set</b> is non-zero,
|
||||||
@ -554,20 +552,23 @@ directory_clean_last_hid_serv_requests(time_t now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove all requests related to the hidden service named
|
/** Remove all requests related to the descriptor ID <b>desc_id</b> from the
|
||||||
* <b>onion_address</b> from the history of times of requests to
|
* history of times of requests to hidden service directories.
|
||||||
* hidden service directories.
|
* <b>desc_id</b> is an unencoded descriptor ID of size DIGEST_LEN.
|
||||||
*
|
*
|
||||||
* This is called from rend_client_note_connection_attempt_ended(), which
|
* This is called from rend_client_note_connection_attempt_ended(), which
|
||||||
* must be idempotent, so any future changes to this function must leave
|
* must be idempotent, so any future changes to this function must leave it
|
||||||
* it idempotent too.
|
* idempotent too. */
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
purge_hid_serv_from_last_hid_serv_requests(const char *onion_address)
|
purge_hid_serv_from_last_hid_serv_requests(const char *desc_id)
|
||||||
{
|
{
|
||||||
strmap_iter_t *iter;
|
strmap_iter_t *iter;
|
||||||
strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
|
strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
|
||||||
/* XXX023 tor_assert(strlen(onion_address) == REND_SERVICE_ID_LEN_BASE32); */
|
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
||||||
|
|
||||||
|
/* Key is stored with the base32 encoded desc_id. */
|
||||||
|
base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id,
|
||||||
|
DIGEST_LEN);
|
||||||
for (iter = strmap_iter_init(last_hid_serv_requests);
|
for (iter = strmap_iter_init(last_hid_serv_requests);
|
||||||
!strmap_iter_done(iter); ) {
|
!strmap_iter_done(iter); ) {
|
||||||
const char *key;
|
const char *key;
|
||||||
@ -575,9 +576,9 @@ purge_hid_serv_from_last_hid_serv_requests(const char *onion_address)
|
|||||||
strmap_iter_get(iter, &key, &val);
|
strmap_iter_get(iter, &key, &val);
|
||||||
/* XXX023 tor_assert(strlen(key) == LAST_HID_SERV_REQUEST_KEY_LEN); */
|
/* XXX023 tor_assert(strlen(key) == LAST_HID_SERV_REQUEST_KEY_LEN); */
|
||||||
if (tor_memeq(key + LAST_HID_SERV_REQUEST_KEY_LEN -
|
if (tor_memeq(key + LAST_HID_SERV_REQUEST_KEY_LEN -
|
||||||
REND_SERVICE_ID_LEN_BASE32,
|
REND_DESC_ID_V2_LEN_BASE32,
|
||||||
onion_address,
|
desc_id_base32,
|
||||||
REND_SERVICE_ID_LEN_BASE32)) {
|
REND_DESC_ID_V2_LEN_BASE32)) {
|
||||||
iter = strmap_iter_next_rmv(last_hid_serv_requests, iter);
|
iter = strmap_iter_next_rmv(last_hid_serv_requests, iter);
|
||||||
tor_free(val);
|
tor_free(val);
|
||||||
} else {
|
} else {
|
||||||
@ -791,8 +792,7 @@ end:
|
|||||||
* On success, 1 is returned. If no hidden service is left to ask, return 0.
|
* On success, 1 is returned. If no hidden service is left to ask, return 0.
|
||||||
* On error, -1 is returned. */
|
* On error, -1 is returned. */
|
||||||
static int
|
static int
|
||||||
fetch_v2_desc_by_addr(const rend_data_t *query,
|
fetch_v2_desc_by_addr(rend_data_t *query, smartlist_t *hsdirs)
|
||||||
smartlist_t *hsdirs)
|
|
||||||
{
|
{
|
||||||
char descriptor_id[DIGEST_LEN];
|
char descriptor_id[DIGEST_LEN];
|
||||||
int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
|
int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
|
||||||
@ -822,6 +822,16 @@ fetch_v2_desc_by_addr(const rend_data_t *query,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tor_memcmp(descriptor_id, query->descriptor_id[chosen_replica],
|
||||||
|
sizeof(descriptor_id)) != 0) {
|
||||||
|
/* Not equal from what we currently have so purge the last hid serv
|
||||||
|
* request cache and update the descriptor ID with the new value. */
|
||||||
|
purge_hid_serv_from_last_hid_serv_requests(
|
||||||
|
query->descriptor_id[chosen_replica]);
|
||||||
|
memcpy(query->descriptor_id[chosen_replica], descriptor_id,
|
||||||
|
sizeof(query->descriptor_id[chosen_replica]));
|
||||||
|
}
|
||||||
|
|
||||||
/* Trigger the fetch with the computed descriptor ID. */
|
/* Trigger the fetch with the computed descriptor ID. */
|
||||||
ret = fetch_v2_desc_by_descid(descriptor_id, query, hsdirs);
|
ret = fetch_v2_desc_by_descid(descriptor_id, query, hsdirs);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -848,8 +858,7 @@ end:
|
|||||||
* On success, 1 is returned. If no hidden service is left to ask, return 0.
|
* On success, 1 is returned. If no hidden service is left to ask, return 0.
|
||||||
* On error, -1 is returned. */
|
* On error, -1 is returned. */
|
||||||
int
|
int
|
||||||
rend_client_fetch_v2_desc(const rend_data_t *query,
|
rend_client_fetch_v2_desc(rend_data_t *query, smartlist_t *hsdirs)
|
||||||
smartlist_t *hsdirs)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -860,8 +869,8 @@ rend_client_fetch_v2_desc(const rend_data_t *query,
|
|||||||
|
|
||||||
if (query->onion_address[0] != '\0') {
|
if (query->onion_address[0] != '\0') {
|
||||||
ret = fetch_v2_desc_by_addr(query, hsdirs);
|
ret = fetch_v2_desc_by_addr(query, hsdirs);
|
||||||
} else if (query->descriptor_id[0] != '\0') {
|
} else if (!tor_digest_is_zero(query->desc_id_fetch)) {
|
||||||
ret = fetch_v2_desc_by_descid(query->descriptor_id, query, hsdirs);
|
ret = fetch_v2_desc_by_descid(query->desc_id_fetch, query, hsdirs);
|
||||||
} else {
|
} else {
|
||||||
/* Query data is invalid. */
|
/* Query data is invalid. */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -876,7 +885,7 @@ error:
|
|||||||
* one (possibly) working introduction point in it, start a connection to a
|
* one (possibly) working introduction point in it, start a connection to a
|
||||||
* hidden service directory to fetch a v2 rendezvous service descriptor. */
|
* hidden service directory to fetch a v2 rendezvous service descriptor. */
|
||||||
void
|
void
|
||||||
rend_client_refetch_v2_renddesc(const rend_data_t *rend_query)
|
rend_client_refetch_v2_renddesc(rend_data_t *rend_query)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
rend_cache_entry_t *e = NULL;
|
rend_cache_entry_t *e = NULL;
|
||||||
@ -963,7 +972,7 @@ rend_client_cancel_descriptor_fetches(void)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
rend_client_report_intro_point_failure(extend_info_t *failed_intro,
|
rend_client_report_intro_point_failure(extend_info_t *failed_intro,
|
||||||
const rend_data_t *rend_query,
|
rend_data_t *rend_query,
|
||||||
unsigned int failure_type)
|
unsigned int failure_type)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
@ -1213,28 +1222,28 @@ rend_client_desc_trynow(const char *query)
|
|||||||
"unavailable (try again later).",
|
"unavailable (try again later).",
|
||||||
safe_str_client(query));
|
safe_str_client(query));
|
||||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
|
connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
|
||||||
rend_client_note_connection_attempt_ended(query);
|
rend_client_note_connection_attempt_ended(rend_data);
|
||||||
}
|
}
|
||||||
} SMARTLIST_FOREACH_END(base_conn);
|
} SMARTLIST_FOREACH_END(base_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear temporary state used only during an attempt to connect to
|
/** Clear temporary state used only during an attempt to connect to the
|
||||||
* the hidden service named <b>onion_address</b>. Called when a
|
* hidden service with <b>rend_data</b>. Called when a connection attempt
|
||||||
* connection attempt has ended; it is possible for this to be called
|
* has ended; it is possible for this to be called multiple times while
|
||||||
* multiple times while handling an ended connection attempt, and
|
* handling an ended connection attempt, and any future changes to this
|
||||||
* any future changes to this function must ensure it remains
|
* function must ensure it remains idempotent. */
|
||||||
* idempotent.
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
rend_client_note_connection_attempt_ended(const char *onion_address)
|
rend_client_note_connection_attempt_ended(const rend_data_t *rend_data)
|
||||||
{
|
{
|
||||||
|
unsigned int have_onion = 0;
|
||||||
rend_cache_entry_t *cache_entry = NULL;
|
rend_cache_entry_t *cache_entry = NULL;
|
||||||
/* Ignore return value; we find an entry, or we don't. */
|
|
||||||
(void) rend_cache_lookup_entry(onion_address, -1, &cache_entry);
|
|
||||||
|
|
||||||
log_info(LD_REND, "Connection attempt for %s has ended; "
|
if (*rend_data->onion_address != '\0') {
|
||||||
"cleaning up temporary state.",
|
/* Ignore return value; we find an entry, or we don't. */
|
||||||
safe_str_client(onion_address));
|
(void) rend_cache_lookup_entry(rend_data->onion_address, -1,
|
||||||
|
&cache_entry);
|
||||||
|
have_onion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear the timed_out flag on all remaining intro points for this HS. */
|
/* Clear the timed_out flag on all remaining intro points for this HS. */
|
||||||
if (cache_entry != NULL) {
|
if (cache_entry != NULL) {
|
||||||
@ -1244,7 +1253,20 @@ rend_client_note_connection_attempt_ended(const char *onion_address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the HS's entries in last_hid_serv_requests. */
|
/* Remove the HS's entries in last_hid_serv_requests. */
|
||||||
purge_hid_serv_from_last_hid_serv_requests(onion_address);
|
if (have_onion) {
|
||||||
|
unsigned int replica;
|
||||||
|
for (replica = 0; replica < ARRAY_LENGTH(rend_data->descriptor_id);
|
||||||
|
replica++) {
|
||||||
|
const char *desc_id = rend_data->descriptor_id[replica];
|
||||||
|
purge_hid_serv_from_last_hid_serv_requests(desc_id);
|
||||||
|
}
|
||||||
|
log_info(LD_REND, "Connection attempt for %s has ended; "
|
||||||
|
"cleaning up temporary state.",
|
||||||
|
safe_str_client(rend_data->onion_address));
|
||||||
|
} else {
|
||||||
|
/* We only have an ID for a fetch. Probably used by HSFETCH. */
|
||||||
|
purge_hid_serv_from_last_hid_serv_requests(rend_data->desc_id_fetch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a newly allocated extend_info_t* for a randomly chosen introduction
|
/** Return a newly allocated extend_info_t* for a randomly chosen introduction
|
||||||
|
@ -19,9 +19,8 @@ void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
|
|||||||
int rend_client_introduction_acked(origin_circuit_t *circ,
|
int rend_client_introduction_acked(origin_circuit_t *circ,
|
||||||
const uint8_t *request,
|
const uint8_t *request,
|
||||||
size_t request_len);
|
size_t request_len);
|
||||||
void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query);
|
void rend_client_refetch_v2_renddesc(rend_data_t *rend_query);
|
||||||
int rend_client_fetch_v2_desc(const rend_data_t *query,
|
int rend_client_fetch_v2_desc(rend_data_t *query, smartlist_t *hsdirs);
|
||||||
smartlist_t *hsdirs);
|
|
||||||
void rend_client_cancel_descriptor_fetches(void);
|
void rend_client_cancel_descriptor_fetches(void);
|
||||||
void rend_client_purge_last_hid_serv_requests(void);
|
void rend_client_purge_last_hid_serv_requests(void);
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ void rend_client_purge_last_hid_serv_requests(void);
|
|||||||
#define INTRO_POINT_FAILURE_UNREACHABLE 2
|
#define INTRO_POINT_FAILURE_UNREACHABLE 2
|
||||||
|
|
||||||
int rend_client_report_intro_point_failure(extend_info_t *failed_intro,
|
int rend_client_report_intro_point_failure(extend_info_t *failed_intro,
|
||||||
const rend_data_t *rend_query,
|
rend_data_t *rend_query,
|
||||||
unsigned int failure_type);
|
unsigned int failure_type);
|
||||||
|
|
||||||
int rend_client_rendezvous_acked(origin_circuit_t *circ,
|
int rend_client_rendezvous_acked(origin_circuit_t *circ,
|
||||||
@ -41,7 +40,7 @@ int rend_client_receive_rendezvous(origin_circuit_t *circ,
|
|||||||
size_t request_len);
|
size_t request_len);
|
||||||
void rend_client_desc_trynow(const char *query);
|
void rend_client_desc_trynow(const char *query);
|
||||||
|
|
||||||
void rend_client_note_connection_attempt_ended(const char *onion_address);
|
void rend_client_note_connection_attempt_ended(const rend_data_t *rend_data);
|
||||||
|
|
||||||
extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
|
extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
|
||||||
int rend_client_any_intro_points_usable(const rend_cache_entry_t *entry);
|
int rend_client_any_intro_points_usable(const rend_cache_entry_t *entry);
|
||||||
|
@ -1404,3 +1404,100 @@ rend_data_dup(const rend_data_t *data)
|
|||||||
return tor_memdup(data, sizeof(rend_data_t));
|
return tor_memdup(data, sizeof(rend_data_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Compute descriptor ID for each replicas and save them. A valid onion
|
||||||
|
* address must be present in the <b>rend_data</b>.
|
||||||
|
*
|
||||||
|
* Return 0 on success else -1. */
|
||||||
|
static int
|
||||||
|
compute_desc_id(rend_data_t *rend_data)
|
||||||
|
{
|
||||||
|
int ret, replica;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
tor_assert(rend_data);
|
||||||
|
|
||||||
|
/* Compute descriptor ID for each replicas. */
|
||||||
|
for (replica = 0; replica < ARRAY_LENGTH(rend_data->descriptor_id);
|
||||||
|
replica++) {
|
||||||
|
ret = rend_compute_v2_desc_id(rend_data->descriptor_id[replica],
|
||||||
|
rend_data->onion_address,
|
||||||
|
rend_data->descriptor_cookie,
|
||||||
|
now, replica);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allocate and initialize a rend_data_t object for a service using the
|
||||||
|
* given arguments. Only the <b>onion_address</b> is not optional.
|
||||||
|
*
|
||||||
|
* Return a valid rend_data_t pointer. */
|
||||||
|
rend_data_t *
|
||||||
|
rend_data_service_create(const char *onion_address, const char *pk_digest,
|
||||||
|
const uint8_t *cookie, rend_auth_type_t auth_type)
|
||||||
|
{
|
||||||
|
rend_data_t *rend_data = tor_malloc_zero(sizeof(*rend_data));
|
||||||
|
|
||||||
|
/* We need at least one else the call is wrong. */
|
||||||
|
tor_assert(onion_address != NULL);
|
||||||
|
|
||||||
|
if (pk_digest) {
|
||||||
|
memcpy(rend_data->rend_pk_digest, pk_digest,
|
||||||
|
sizeof(rend_data->rend_pk_digest));
|
||||||
|
}
|
||||||
|
if (cookie) {
|
||||||
|
memcpy(rend_data->rend_cookie, cookie,
|
||||||
|
sizeof(rend_data->rend_cookie));
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(rend_data->onion_address, onion_address,
|
||||||
|
sizeof(rend_data->onion_address));
|
||||||
|
rend_data->auth_type = auth_type;
|
||||||
|
|
||||||
|
return rend_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allocate and initialize a rend_data_t object for a client request using
|
||||||
|
* the given arguments. Either an onion address or a descriptor ID is
|
||||||
|
* needed. Both can be given but only the onion address will be used to make
|
||||||
|
* the descriptor fetch.
|
||||||
|
*
|
||||||
|
* Return a valid rend_data_t pointer or NULL on error meaning the
|
||||||
|
* descriptor IDs couldn't be computed from the given data. */
|
||||||
|
rend_data_t *
|
||||||
|
rend_data_client_create(const char *onion_address, const char *desc_id,
|
||||||
|
const char *cookie, rend_auth_type_t auth_type)
|
||||||
|
{
|
||||||
|
rend_data_t *rend_data = tor_malloc_zero(sizeof(*rend_data));
|
||||||
|
|
||||||
|
/* We need at least one else the call is wrong. */
|
||||||
|
tor_assert(onion_address != NULL || desc_id != NULL);
|
||||||
|
|
||||||
|
if (cookie) {
|
||||||
|
memcpy(rend_data->descriptor_cookie, cookie,
|
||||||
|
sizeof(rend_data->descriptor_cookie));
|
||||||
|
}
|
||||||
|
if (desc_id) {
|
||||||
|
memcpy(rend_data->desc_id_fetch, desc_id,
|
||||||
|
sizeof(rend_data->desc_id_fetch));
|
||||||
|
}
|
||||||
|
if (onion_address) {
|
||||||
|
strlcpy(rend_data->onion_address, onion_address,
|
||||||
|
sizeof(rend_data->onion_address));
|
||||||
|
if (compute_desc_id(rend_data) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rend_data->auth_type = auth_type;
|
||||||
|
|
||||||
|
return rend_data;
|
||||||
|
|
||||||
|
error:
|
||||||
|
rend_data_free(rend_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -67,5 +67,13 @@ void rend_get_descriptor_id_bytes(char *descriptor_id_out,
|
|||||||
const char *secret_id_part);
|
const char *secret_id_part);
|
||||||
size_t rend_cache_get_total_allocation(void);
|
size_t rend_cache_get_total_allocation(void);
|
||||||
|
|
||||||
|
rend_data_t *rend_data_client_create(const char *onion_address,
|
||||||
|
const char *desc_id,
|
||||||
|
const char *cookie,
|
||||||
|
rend_auth_type_t auth_type);
|
||||||
|
rend_data_t *rend_data_service_create(const char *onion_address,
|
||||||
|
const char *pk_digest,
|
||||||
|
const uint8_t *cookie,
|
||||||
|
rend_auth_type_t auth_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1735,13 +1735,11 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
|
|||||||
hexcookie, serviceid);
|
hexcookie, serviceid);
|
||||||
tor_assert(launched->build_state);
|
tor_assert(launched->build_state);
|
||||||
/* Fill in the circuit's state. */
|
/* Fill in the circuit's state. */
|
||||||
launched->rend_data = tor_malloc_zero(sizeof(rend_data_t));
|
|
||||||
memcpy(launched->rend_data->rend_pk_digest,
|
launched->rend_data =
|
||||||
|
rend_data_service_create(service->service_id,
|
||||||
circuit->rend_data->rend_pk_digest,
|
circuit->rend_data->rend_pk_digest,
|
||||||
DIGEST_LEN);
|
parsed_req->rc, service->auth_type);
|
||||||
memcpy(launched->rend_data->rend_cookie, parsed_req->rc, REND_COOKIE_LEN);
|
|
||||||
strlcpy(launched->rend_data->onion_address, service->service_id,
|
|
||||||
sizeof(launched->rend_data->onion_address));
|
|
||||||
|
|
||||||
launched->build_state->service_pending_final_cpath_ref =
|
launched->build_state->service_pending_final_cpath_ref =
|
||||||
tor_malloc_zero(sizeof(crypt_path_reference_t));
|
tor_malloc_zero(sizeof(crypt_path_reference_t));
|
||||||
@ -2713,10 +2711,9 @@ rend_service_launch_establish_intro(rend_service_t *service,
|
|||||||
intro->extend_info = extend_info_dup(launched->build_state->chosen_exit);
|
intro->extend_info = extend_info_dup(launched->build_state->chosen_exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
launched->rend_data = tor_malloc_zero(sizeof(rend_data_t));
|
launched->rend_data = rend_data_service_create(service->service_id,
|
||||||
strlcpy(launched->rend_data->onion_address, service->service_id,
|
service->pk_digest, NULL,
|
||||||
sizeof(launched->rend_data->onion_address));
|
service->auth_type);
|
||||||
memcpy(launched->rend_data->rend_pk_digest, service->pk_digest, DIGEST_LEN);
|
|
||||||
launched->intro_key = crypto_pk_dup_key(intro->intro_key);
|
launched->intro_key = crypto_pk_dup_key(intro->intro_key);
|
||||||
if (launched->base_.state == CIRCUIT_STATE_OPEN)
|
if (launched->base_.state == CIRCUIT_STATE_OPEN)
|
||||||
rend_service_intro_has_opened(launched);
|
rend_service_intro_has_opened(launched);
|
||||||
|
Loading…
Reference in New Issue
Block a user