From 29c18f5b71d73a03b9895fbbf97a3a5a16099a50 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Wed, 9 Oct 2013 11:13:06 -0400 Subject: add hidden service descriptor async control event --- src/or/control.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/or/control.h | 14 +++++++- src/or/directory.c | 19 ++++++++--- src/or/rendclient.c | 4 +++ src/or/router.c | 23 ++++++++++++++ src/or/router.h | 1 + 6 files changed, 147 insertions(+), 6 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 49212de65..42fbf2f91 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -940,6 +940,7 @@ static const struct control_event_t control_event_table[] = { { EVENT_TB_EMPTY, "TB_EMPTY" }, { EVENT_CIRC_BANDWIDTH_USED, "CIRC_BW" }, { EVENT_TRANSPORT_LAUNCHED, "TRANSPORT_LAUNCHED" }, + { EVENT_HS_DESC, "HS_DESC" }, { 0, NULL }, }; @@ -1549,7 +1550,7 @@ munge_extrainfo_into_routerinfo(const char *ri_body, outp += router_sig-ri_body; for (i=0; i < 2; ++i) { - const char *kwd = i?"\nwrite-history ":"\nread-history "; + const char *kwd = i ? "\nwrite-history " : "\nread-history "; const char *cp, *eol; if (!(cp = tor_memstr(ei_body, ei_len, kwd))) continue; @@ -4998,6 +4999,95 @@ control_event_transport_launched(const char *mode, const char *transport_name, mode, transport_name, fmt_addr(addr), port); } +/** Convert rendezvous auth type to string for HS_DESC control events + */ +const char * +rend_auth_type_to_string(rend_auth_type_t auth_type) +{ + const char *str; + + switch (auth_type) { + case REND_NO_AUTH: + str = "NO_AUTH"; + break; + case REND_BASIC_AUTH: + str = "BASIC_AUTH"; + break; + case REND_STEALTH_AUTH: + str = "STEALTH_AUTH"; + break; + default: + str = "UNKNOWN"; + } + + return str; +} + +/** send HS_DESC requested event. + * + * rend_query is used to fetch requested onion address and auth type. + * hs_dir is the description of contacting hs directory. + * desc_id_base32 is the ID of requested hs descriptor. + */ +void +control_event_hs_descriptor_requested(const rend_data_t *rend_query, + const char *hs_dir, + const char *desc_id_base32) +{ + tor_assert(hs_dir); + send_control_event(EVENT_HS_DESC, ALL_FORMATS, + "650 HS_DESC REQUESTED %s %s %s %s\r\n", + rend_query->onion_address, + rend_auth_type_to_string(rend_query->auth_type), + hs_dir, + desc_id_base32); +} + +/** send HS_DESC event after got response from hs directory. + * + * NOTE: this is an internal function used by following functions: + * control_event_hs_descriptor_received + * control_event_hs_descriptor_failed + * + * So do not call this function directly. + */ +void +control_event_hs_descriptor_receive_end(const char *action, + const rend_data_t *rend_query, + const char *hs_dir) +{ + send_control_event(EVENT_HS_DESC, ALL_FORMATS, + "650 HS_DESC %s %s %s %s\r\n", + action, + rend_query->onion_address, + rend_auth_type_to_string(rend_query->auth_type), + hs_dir); +} + +/** send HS_DESC RECEIVED event + * + * called when a we successfully received a hidden service descriptor. + */ +void +control_event_hs_descriptor_received(const rend_data_t *rend_query, + const char *hs_dir) +{ + tor_assert(hs_dir); + control_event_hs_descriptor_receive_end("RECEIVED", rend_query, hs_dir); +} + +/** send HS_DESC FAILED event + * + * called when request for hidden service descriptor returned failure. + */ +void +control_event_hs_descriptor_failed(const rend_data_t *rend_query, + const char *hs_dir) +{ + tor_assert(hs_dir); + control_event_hs_descriptor_receive_end("FAILED", rend_query, hs_dir); +} + /** Free any leftover allocated memory of the control.c subsystem. */ void control_free_all(void) diff --git a/src/or/control.h b/src/or/control.h index c8db643b7..be3cc2420 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -99,6 +99,17 @@ void control_event_clients_seen(const char *controller_str); void control_event_transport_launched(const char *mode, const char *transport_name, tor_addr_t *addr, uint16_t port); +const char *rend_auth_type_to_string(rend_auth_type_t auth_type); +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); +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); void control_free_all(void); @@ -140,7 +151,8 @@ void control_free_all(void); #define EVENT_TB_EMPTY 0x001C #define EVENT_CIRC_BANDWIDTH_USED 0x001D #define EVENT_TRANSPORT_LAUNCHED 0x0020 -#define EVENT_MAX_ 0x0020 +#define EVENT_HS_DESC 0x0021 +#define EVENT_MAX_ 0x0021 /* If EVENT_MAX_ ever hits 0x0040, we need to make the mask into a * different structure. */ diff --git a/src/or/directory.c b/src/or/directory.c index 12c5b189f..2b93625f2 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1660,17 +1660,17 @@ connection_dir_client_reached_eof(dir_connection_t *conn) char *body; char *headers; char *reason = NULL; - size_t body_len=0, orig_len=0; + size_t body_len = 0, orig_len = 0; int status_code; - time_t date_header=0; + time_t date_header = 0; long delta; compress_method_t compression; int plausible; - int skewed=0; + int skewed = 0; int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC || conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO || conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC); - int was_compressed=0; + int was_compressed = 0; time_t now = time(NULL); int src_code; @@ -2275,6 +2275,10 @@ connection_dir_client_reached_eof(dir_connection_t *conn) } if (conn->base_.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) { + #define SEND_HS_DESC_FAILED_EVENT() ( \ + control_event_hs_descriptor_failed(conn->rend_data, \ + node_describe_by_id( \ + conn->identity_digest)) ) tor_assert(conn->rend_data); log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d " "(%s))", @@ -2287,6 +2291,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) "Retrying at another directory."); /* We'll retry when connection_about_to_close_connection() * cleans this dir conn up. */ + SEND_HS_DESC_FAILED_EVENT(); break; case -1: /* We already have a v0 descriptor here. Ignoring this one @@ -2299,6 +2304,9 @@ connection_dir_client_reached_eof(dir_connection_t *conn) /* success. notify pending connections about this. */ log_info(LD_REND, "Successfully fetched v2 rendezvous " "descriptor."); + control_event_hs_descriptor_received(conn->rend_data, + node_describe_by_id( + conn->identity_digest)); conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC; rend_client_desc_trynow(conn->rend_data->onion_address); break; @@ -2309,12 +2317,14 @@ connection_dir_client_reached_eof(dir_connection_t *conn) * connection_about_to_close_connection() cleans this conn up. */ log_info(LD_REND,"Fetching v2 rendezvous descriptor failed: " "Retrying at another directory."); + SEND_HS_DESC_FAILED_EVENT(); break; case 400: log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: " "http status 400 (%s). Dirserver didn't like our " "v2 rendezvous query? Retrying at another directory.", escaped(reason)); + SEND_HS_DESC_FAILED_EVENT(); break; default: log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: " @@ -2323,6 +2333,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) "Retrying at another directory.", status_code, escaped(reason), conn->base_.address, conn->base_.port); + SEND_HS_DESC_FAILED_EVENT(); break; } } diff --git a/src/or/rendclient.c b/src/or/rendclient.c index f00303f18..de28bd1fc 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -26,6 +26,7 @@ #include "router.h" #include "routerlist.h" #include "routerset.h" +#include "control.h" static extend_info_t *rend_client_get_random_intro_impl( const rend_cache_entry_t *rend_query, @@ -694,6 +695,9 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query) (rend_query->auth_type == REND_NO_AUTH ? "[none]" : escaped_safe_str_client(descriptor_cookie_base64)), routerstatus_describe(hs_dir)); + control_event_hs_descriptor_requested(rend_query, + routerstatus_describe(hs_dir), + desc_id_base32); return 1; } diff --git a/src/or/router.c b/src/or/router.c index 959e5e34c..de78895c8 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -2926,6 +2926,29 @@ node_describe(const node_t *node) return node_get_description(buf, node); } +/** Return a human-readable description of the node whose identity is + * identity_digest. If node_get_by_id() returns NULL, base 16 encoding + * of identity_digest is returned instead. + * + * This function is not thread-safe. Each call to this function invalidates + * previous values returned by this function. + */ +const char * +node_describe_by_id(const char *identity_digest) +{ + static char buf[NODE_DESC_BUF_LEN]; + const node_t *node = NULL; + + node = node_get_by_id(identity_digest); + if (!node) { + buf[0] = '$'; + base16_encode(buf+1, HEX_DIGEST_LEN+1, identity_digest, DIGEST_LEN); + return buf; + } else { + return node_get_description(buf, node); + } +} + /** Return a human-readable description of the routerstatus_t rs. * * This function is not thread-safe. Each call to this function invalidates diff --git a/src/or/router.h b/src/or/router.h index 1079ec78c..08cda733c 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -133,6 +133,7 @@ const char *routerstatus_get_description(char *buf, const routerstatus_t *rs); const char *extend_info_get_description(char *buf, const extend_info_t *ei); const char *router_describe(const routerinfo_t *ri); const char *node_describe(const node_t *node); +const char *node_describe_by_id(const char *id_digest); const char *routerstatus_describe(const routerstatus_t *ri); const char *extend_info_describe(const extend_info_t *ei); -- cgit v1.2.3