summaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@ev0ke.net>2015-02-24 16:17:14 -0500
committerDavid Goulet <dgoulet@ev0ke.net>2015-04-21 14:15:02 -0400
commit7db58445fd00d5bbad72fd80497d20b7bc9a0297 (patch)
tree6cfb5f909e1ece90915ca9f10d3b869b2943df05 /src/or
parent084be23697e14b9ee26b3ac1eef2448af6368d10 (diff)
downloadtor-7db58445fd00d5bbad72fd80497d20b7bc9a0297.tar.gz
tor-7db58445fd00d5bbad72fd80497d20b7bc9a0297.zip
Control: add HS_DESC_CONTENT event
As defined in section 4.1.26 in the control-spec.txt, this new event replies the content of a successfully fetched HS descriptor. This also adds a unit test for the controller event. Signed-off-by: David Goulet <dgoulet@ev0ke.net>
Diffstat (limited to 'src/or')
-rw-r--r--src/or/control.c31
-rw-r--r--src/or/control.h7
-rw-r--r--src/or/directory.c13
3 files changed, 50 insertions, 1 deletions
diff --git a/src/or/control.c b/src/or/control.c
index 1bc833371d..e7d8b5cdef 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -943,6 +943,7 @@ static const struct control_event_t control_event_table[] = {
{ EVENT_CIRC_BANDWIDTH_USED, "CIRC_BW" },
{ EVENT_TRANSPORT_LAUNCHED, "TRANSPORT_LAUNCHED" },
{ EVENT_HS_DESC, "HS_DESC" },
+ { EVENT_HS_DESC_CONTENT, "HS_DESC_CONTENT" },
{ 0, NULL },
};
@@ -5414,6 +5415,36 @@ control_event_hs_descriptor_failed(const rend_data_t *rend_query,
id_digest, reason);
}
+/** send HS_DESC_CONTENT event after completion of a successful fetch from
+ * hs directory. */
+void
+control_event_hs_descriptor_content(const char *onion_address,
+ const char *desc_id,
+ const char *hsdir_id_digest,
+ const char *content)
+{
+ static const char *event_name = "HS_DESC_CONTENT";
+ char *esc_content = NULL;
+
+ if (!onion_address || !desc_id || !hsdir_id_digest || !content) {
+ log_warn(LD_BUG, "Called with onion_address==%p, desc_id==%p, "
+ "hsdir_id_digest==%p, content==%p", onion_address, desc_id,
+ hsdir_id_digest, content);
+ return;
+ }
+
+ write_escaped_data(content, strlen(content), &esc_content);
+
+ send_control_event(EVENT_HS_DESC_CONTENT, ALL_FORMATS,
+ "650 %s %s %s %s\r\n%s",
+ event_name,
+ onion_address,
+ desc_id,
+ node_describe_longname_by_id(hsdir_id_digest),
+ esc_content);
+ tor_free(esc_content);
+}
+
/** 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 dbb80b1f20..ae49284965 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -115,6 +115,10 @@ void control_event_hs_descriptor_received(const rend_data_t *rend_query,
void control_event_hs_descriptor_failed(const rend_data_t *rend_query,
const char *hs_dir,
const char *reason);
+void control_event_hs_descriptor_content(const char *onion_address,
+ const char *desc_id,
+ const char *hsdir_fp,
+ const char *content);
void control_free_all(void);
@@ -158,7 +162,8 @@ void control_free_all(void);
#define EVENT_CIRC_BANDWIDTH_USED 0x001D
#define EVENT_TRANSPORT_LAUNCHED 0x0020
#define EVENT_HS_DESC 0x0021
-#define EVENT_MAX_ 0x0021
+#define EVENT_HS_DESC_CONTENT 0x0022
+#define EVENT_MAX_ 0x0022
/* sizeof(control_connection_t.event_mask) in bits, currently a uint64_t */
#define EVENT_CAPACITY_ 0x0040
diff --git a/src/or/directory.c b/src/or/directory.c
index d2b6b86f6d..b6b0a5d7e0 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2102,6 +2102,11 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
control_event_hs_descriptor_failed(conn->rend_data, \
conn->identity_digest, \
reason) )
+ #define SEND_HS_DESC_FAILED_CONTENT() ( \
+ control_event_hs_descriptor_content(conn->rend_data->onion_address, \
+ conn->requested_resource, \
+ conn->identity_digest, \
+ "") )
tor_assert(conn->rend_data);
log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
"(%s))",
@@ -2117,6 +2122,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
/* We'll retry when connection_about_to_close_connection()
* cleans this dir conn up. */
SEND_HS_DESC_FAILED_EVENT("BAD_DESC");
+ SEND_HS_DESC_FAILED_CONTENT();
break;
case RCS_OKAY:
default:
@@ -2125,6 +2131,10 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
"descriptor.");
control_event_hs_descriptor_received(conn->rend_data,
conn->identity_digest);
+ control_event_hs_descriptor_content(conn->rend_data->onion_address,
+ 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);
break;
@@ -2136,6 +2146,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
log_info(LD_REND,"Fetching v2 rendezvous descriptor failed: "
"Retrying at another directory.");
SEND_HS_DESC_FAILED_EVENT("NOT_FOUND");
+ SEND_HS_DESC_FAILED_CONTENT();
break;
case 400:
log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
@@ -2143,6 +2154,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
"v2 rendezvous query? Retrying at another directory.",
escaped(reason));
SEND_HS_DESC_FAILED_EVENT("QUERY_REJECTED");
+ SEND_HS_DESC_FAILED_CONTENT();
break;
default:
log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
@@ -2152,6 +2164,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
status_code, escaped(reason), conn->base_.address,
conn->base_.port);
SEND_HS_DESC_FAILED_EVENT("UNEXPECTED");
+ SEND_HS_DESC_FAILED_CONTENT();
break;
}
}