Control: unbolt rend_data from HS desc event

The HS_DESC event was using rend_data_t from the dir connection to reply the
onion address and authentication type. With the new HSFETCH command, it's
now possible to fetch a descriptor only using the descriptor id thus
resulting in not having an onion address in any HS_DESC event.

This patch removes rend_query from the hs desc control functions and replace
it by an onion address string and an auth type.

On a successful fetch, the service id is taken from the fetched descriptor.
For that, an extra parameter is added to "store as a client" function that
contains the cache entry stored.

This will make the control event functions scale more easily over time if
other values not present in rend_data_t are needed since the rend_data from
the dir connection might not contained everything we need.

Signed-off-by: David Goulet <dgoulet@ev0ke.net>
This commit is contained in:
David Goulet 2015-03-11 14:52:28 -04:00
parent 59f8dced11
commit 28cf9f2186
6 changed files with 92 additions and 37 deletions

View File

@ -5343,6 +5343,31 @@ node_describe_longname_by_id,(const char *id_digest))
return longname;
}
/** Return either the onion address if the given pointer is a non empty
* string else the unknown string. */
static const char *
rend_hsaddress_str_or_unknown(const char *onion_address)
{
static const char *str_unknown = "UNKNOWN";
const char *str_ret = str_unknown;
/* No valid pointer, unknown it is. */
if (!onion_address) {
goto end;
}
/* Empty onion address thus we don't know, unknown it is. */
if (onion_address[0] == '\0') {
goto end;
}
/* All checks are good so return the given onion address. */
str_ret = onion_address;
end:
return str_ret;
}
/** send HS_DESC requested event.
*
* <b>rend_query</b> is used to fetch requested onion address and auth type.
@ -5363,7 +5388,7 @@ control_event_hs_descriptor_requested(const rend_data_t *rend_query,
send_control_event(EVENT_HS_DESC, ALL_FORMATS,
"650 HS_DESC REQUESTED %s %s %s %s\r\n",
rend_query->onion_address,
rend_hsaddress_str_or_unknown(rend_query->onion_address),
rend_auth_type_to_string(rend_query->auth_type),
node_describe_longname_by_id(id_digest),
desc_id_base32);
@ -5379,15 +5404,16 @@ control_event_hs_descriptor_requested(const rend_data_t *rend_query,
*/
void
control_event_hs_descriptor_receive_end(const char *action,
const rend_data_t *rend_query,
const char *onion_address,
rend_auth_type_t auth_type,
const char *id_digest,
const char *reason)
{
char *reason_field = NULL;
if (!action || !rend_query || !id_digest) {
log_warn(LD_BUG, "Called with action==%p, rend_query==%p, "
"id_digest==%p", action, rend_query, id_digest);
if (!action || !id_digest || !onion_address) {
log_warn(LD_BUG, "Called with action==%p, id_digest==%p "
"onion_address==%p", action, id_digest, onion_address);
return;
}
@ -5398,8 +5424,8 @@ control_event_hs_descriptor_receive_end(const char *action,
send_control_event(EVENT_HS_DESC, ALL_FORMATS,
"650 HS_DESC %s %s %s %s%s\r\n",
action,
rend_query->onion_address,
rend_auth_type_to_string(rend_query->auth_type),
rend_hsaddress_str_or_unknown(onion_address),
rend_auth_type_to_string(auth_type),
node_describe_longname_by_id(id_digest),
reason_field ? reason_field : "");
@ -5411,16 +5437,16 @@ control_event_hs_descriptor_receive_end(const char *action,
* called when a we successfully received a hidden service descriptor.
*/
void
control_event_hs_descriptor_received(const rend_data_t *rend_query,
control_event_hs_descriptor_received(const char *onion_address,
rend_auth_type_t auth_type,
const char *id_digest)
{
if (!rend_query || !id_digest) {
log_warn(LD_BUG, "Called with rend_query==%p, id_digest==%p",
rend_query, id_digest);
if (!id_digest) {
log_warn(LD_BUG, "Called with id_digest==%p", id_digest);
return;
}
control_event_hs_descriptor_receive_end("RECEIVED", rend_query,
id_digest, NULL);
control_event_hs_descriptor_receive_end("RECEIVED", onion_address,
auth_type, id_digest, NULL);
}
/** Send HS_DESC event to inform controller that query <b>rend_query</b>
@ -5429,16 +5455,16 @@ control_event_hs_descriptor_received(const rend_data_t *rend_query,
* field.
*/
void
control_event_hs_descriptor_failed(const rend_data_t *rend_query,
control_event_hs_descriptor_failed(const char *onion_address,
rend_auth_type_t auth_type,
const char *id_digest,
const char *reason)
{
if (!rend_query || !id_digest) {
log_warn(LD_BUG, "Called with rend_query==%p, id_digest==%p",
rend_query, id_digest);
if (!id_digest) {
log_warn(LD_BUG, "Called with id_digest==%p", id_digest);
return;
}
control_event_hs_descriptor_receive_end("FAILED", rend_query,
control_event_hs_descriptor_receive_end("FAILED", onion_address, auth_type,
id_digest, reason);
}
@ -5465,7 +5491,7 @@ control_event_hs_descriptor_content(const char *onion_address,
send_control_event(EVENT_HS_DESC_CONTENT, ALL_FORMATS,
"650 %s %s %s %s\r\n%s",
event_name,
onion_address,
rend_hsaddress_str_or_unknown(onion_address),
desc_id,
node_describe_longname_by_id(hsdir_id_digest),
esc_content);

View File

@ -107,13 +107,16 @@ void control_event_hs_descriptor_requested(const rend_data_t *rend_query,
const char *desc_id_base32,
const char *hs_dir);
void control_event_hs_descriptor_receive_end(const char *action,
const rend_data_t *rend_query,
const char *hs_dir,
const char *reason);
void control_event_hs_descriptor_received(const rend_data_t *rend_query,
const char *hs_dir);
void control_event_hs_descriptor_failed(const rend_data_t *rend_query,
const char *hs_dir,
const char *onion_address,
rend_auth_type_t auth_type,
const char *id_digest,
const char *reason);
void control_event_hs_descriptor_received(const char *onion_address,
rend_auth_type_t auth_type,
const char *id_digest);
void control_event_hs_descriptor_failed(const char *onion_address,
rend_auth_type_t auth_type,
const char *id_digest,
const char *reason);
void control_event_hs_descriptor_content(const char *onion_address,
const char *desc_id,

View File

@ -2099,7 +2099,8 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
if (conn->base_.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
#define SEND_HS_DESC_FAILED_EVENT(reason) ( \
control_event_hs_descriptor_failed(conn->rend_data, \
control_event_hs_descriptor_failed(conn->rend_data->onion_address, \
conn->rend_data->auth_type, \
conn->identity_digest, \
reason) )
#define SEND_HS_DESC_FAILED_CONTENT() ( \
@ -2113,8 +2114,12 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
(int)body_len, status_code, escaped(reason));
switch (status_code) {
case 200:
{
rend_cache_entry_t *entry = NULL;
switch (rend_cache_store_v2_desc_as_client(body,
conn->requested_resource, conn->rend_data)) {
conn->requested_resource, conn->rend_data,
&entry)) {
case RCS_BADDESC:
case RCS_NOTDIR: /* Impossible */
log_warn(LD_REND,"Fetching v2 rendezvous descriptor failed. "
@ -2126,20 +2131,29 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
break;
case RCS_OKAY:
default:
{
char service_id[REND_SERVICE_ID_LEN_BASE32 + 1];
/* Should never be NULL here for an OKAY returned code. */
tor_assert(entry);
rend_get_service_id(entry->parsed->pk, service_id);
/* success. notify pending connections about this. */
log_info(LD_REND, "Successfully fetched v2 rendezvous "
"descriptor.");
control_event_hs_descriptor_received(conn->rend_data,
control_event_hs_descriptor_received(service_id,
conn->rend_data->auth_type,
conn->identity_digest);
control_event_hs_descriptor_content(conn->rend_data->onion_address,
control_event_hs_descriptor_content(service_id,
conn->requested_resource,
conn->identity_digest,
body);
conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2;
rend_client_desc_trynow(conn->rend_data->onion_address);
rend_client_desc_trynow(service_id);
break;
}
}
break;
}
case 404:
/* Not there. We'll retry when
* connection_about_to_close_connection() cleans this conn up. */

View File

@ -1136,12 +1136,14 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
* If the descriptor's descriptor ID doesn't match <b>desc_id_base32</b>,
* reject it.
*
* Return an appropriate rend_cache_store_status_t.
* Return an appropriate rend_cache_store_status_t. If entry is not NULL,
* set it with the cache entry pointer of the descriptor.
*/
rend_cache_store_status_t
rend_cache_store_v2_desc_as_client(const char *desc,
const char *desc_id_base32,
const rend_data_t *rend_query)
const rend_data_t *rend_query,
rend_cache_entry_t **entry)
{
/*XXXX this seems to have a bit of duplicate code with
* rend_cache_store_v2_desc_as_dir(). Fix that. */
@ -1289,9 +1291,15 @@ rend_cache_store_v2_desc_as_client(const char *desc,
rend_cache_increment_allocation(rend_cache_entry_allocation(e));
log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
safe_str_client(service_id), (int)encoded_size);
if (entry) {
*entry = e;
}
return RCS_OKAY;
okay:
if (entry) {
*entry = e;
}
retval = RCS_OKAY;
err:

View File

@ -50,7 +50,8 @@ typedef enum {
rend_cache_store_status_t rend_cache_store_v2_desc_as_dir(const char *desc);
rend_cache_store_status_t rend_cache_store_v2_desc_as_client(const char *desc,
const char *desc_id_base32,
const rend_data_t *rend_query);
const rend_data_t *rend_query,
rend_cache_entry_t **entry);
int rend_encode_v2_descriptors(smartlist_t *descs_out,
rend_service_descriptor_t *desc, time_t now,
uint8_t period, rend_auth_type_t auth_type,

View File

@ -159,7 +159,8 @@ test_hs_desc_event(void *arg)
/* test received event */
rend_query.auth_type = 1;
control_event_hs_descriptor_received(&rend_query, HSDIR_EXIST_ID);
control_event_hs_descriptor_received(rend_query.onion_address,
rend_query.auth_type, HSDIR_EXIST_ID);
expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\
STR_HSDIR_EXIST_LONGNAME"\r\n";
tt_assert(received_msg);
@ -168,7 +169,8 @@ test_hs_desc_event(void *arg)
/* test failed event */
rend_query.auth_type = 2;
control_event_hs_descriptor_failed(&rend_query, HSDIR_NONE_EXIST_ID,
control_event_hs_descriptor_failed(rend_query.onion_address,
rend_query.auth_type, HSDIR_NONE_EXIST_ID,
"QUERY_REJECTED");
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\
STR_HSDIR_NONE_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
@ -178,7 +180,8 @@ test_hs_desc_event(void *arg)
/* test invalid auth type */
rend_query.auth_type = 999;
control_event_hs_descriptor_failed(&rend_query, HSDIR_EXIST_ID,
control_event_hs_descriptor_failed(rend_query.onion_address,
rend_query.auth_type, HSDIR_EXIST_ID,
"QUERY_REJECTED");
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\
STR_HSDIR_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";