From b149ab00d788f559b576b60b813cbe0d3b260dbb Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 23 Jun 2011 12:02:03 -0700 Subject: [PATCH 1/7] Separate circuit-close reasons from circ description --- src/or/control.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 109eb8857b..05a2c66540 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3233,7 +3233,8 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code) { const char *status; - char extended_buf[96]; + char purpose[32]; + char reasons[64] = ""; if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS)) return 0; tor_assert(circ); @@ -3250,23 +3251,22 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, return 0; } - tor_snprintf(extended_buf, sizeof(extended_buf), "PURPOSE=%s", + tor_snprintf(purpose, sizeof(purpose), "PURPOSE=%s", circuit_purpose_to_controller_string(circ->_base.purpose)); if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) { const char *reason_str = circuit_end_reason_to_control_string(reason_code); char *reason = NULL; - size_t n=strlen(extended_buf); if (!reason_str) { reason = tor_malloc(16); tor_snprintf(reason, 16, "UNKNOWN_%d", reason_code); reason_str = reason; } if (reason_code > 0 && reason_code & END_CIRC_REASON_FLAG_REMOTE) { - tor_snprintf(extended_buf+n, sizeof(extended_buf)-n, + tor_snprintf(reasons, sizeof(reasons), " REASON=DESTROYED REMOTE_REASON=%s", reason_str); } else { - tor_snprintf(extended_buf+n, sizeof(extended_buf)-n, + tor_snprintf(reasons, sizeof(reasons), " REASON=%s", reason_str); } tor_free(reason); @@ -3276,9 +3276,11 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, char *vpath = circuit_list_path_for_controller(circ); const char *sp = strlen(vpath) ? " " : ""; send_control_event(EVENT_CIRCUIT_STATUS, ALL_FORMATS, - "650 CIRC %lu %s%s%s %s\r\n", + "650 CIRC %lu %s%s%s %s%s\r\n", (unsigned long)circ->global_identifier, - status, sp, vpath, extended_buf); + status, sp, vpath, + purpose, + reasons); tor_free(vpath); } From 9ce76adfe8ccf873302cc8690fac266f966ea8b5 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 23 Jun 2011 12:02:27 -0700 Subject: [PATCH 2/7] Split circuit-description code into a separate function --- src/or/control.c | 56 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 05a2c66540..735492271a 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1777,6 +1777,38 @@ getinfo_helper_dir(control_connection_t *control_conn, return 0; } +/** Allocate and return a description of circ's current status, + * including its path (if any). */ +static char * +circuit_describe_status_for_controller(origin_circuit_t *circ) +{ + char *rv; + smartlist_t *descparts = smartlist_create(); + + { + char *vpath = circuit_list_path_for_controller(circ); + if (*vpath) { + smartlist_add(descparts, vpath); + } else { + tor_free(vpath); /* empty path; don't put an extra space in the result */ + } + } + + { + char *purpose = NULL; + tor_asprintf(&purpose, "PURPOSE=%s", + circuit_purpose_to_controller_string(circ->_base.purpose)); + smartlist_add(descparts, purpose); + } + + rv = smartlist_join_strings(descparts, " ", 0, NULL); + + SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp)); + smartlist_free(descparts); + + return rv; +} + /** Implementation helper for GETINFO: knows how to generate summaries of the * current states of things we send events about. */ static int @@ -3233,7 +3265,6 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code) { const char *status; - char purpose[32]; char reasons[64] = ""; if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS)) return 0; @@ -3251,16 +3282,12 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, return 0; } - tor_snprintf(purpose, sizeof(purpose), "PURPOSE=%s", - circuit_purpose_to_controller_string(circ->_base.purpose)); - if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) { const char *reason_str = circuit_end_reason_to_control_string(reason_code); - char *reason = NULL; + char unk_reason_buf[16]; if (!reason_str) { - reason = tor_malloc(16); - tor_snprintf(reason, 16, "UNKNOWN_%d", reason_code); - reason_str = reason; + tor_snprintf(unk_reason_buf, 16, "UNKNOWN_%d", reason_code); + reason_str = unk_reason_buf; } if (reason_code > 0 && reason_code & END_CIRC_REASON_FLAG_REMOTE) { tor_snprintf(reasons, sizeof(reasons), @@ -3269,19 +3296,18 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, tor_snprintf(reasons, sizeof(reasons), " REASON=%s", reason_str); } - tor_free(reason); } { - char *vpath = circuit_list_path_for_controller(circ); - const char *sp = strlen(vpath) ? " " : ""; + char *circdesc = circuit_describe_status_for_controller(circ); + const char *sp = strlen(circdesc) ? " " : ""; send_control_event(EVENT_CIRCUIT_STATUS, ALL_FORMATS, - "650 CIRC %lu %s%s%s %s%s\r\n", + "650 CIRC %lu %s%s%s%s\r\n", (unsigned long)circ->global_identifier, - status, sp, vpath, - purpose, + status, sp, + circdesc, reasons); - tor_free(vpath); + tor_free(circdesc); } return 0; From b7c765b1b196433f38b94353edbc1655f5da1017 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 23 Jun 2011 14:34:56 -0700 Subject: [PATCH 3/7] Report circuit build_state flags in CIRC events --- changes/feature2411 | 7 +++++++ src/or/control.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 changes/feature2411 diff --git a/changes/feature2411 b/changes/feature2411 new file mode 100644 index 0000000000..b60fbfd6ad --- /dev/null +++ b/changes/feature2411 @@ -0,0 +1,7 @@ + o Minor features: + + - Report flags that control a circuit's path selection to + controllers in CIRC events and in replies to 'GETINFO + circuit-status'. Implements part of ticket 2411. + + diff --git a/src/or/control.c b/src/or/control.c index 735492271a..3dda9979fb 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1794,6 +1794,34 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) } } + { + char *buildflags = NULL; + cpath_build_state_t *build_state = circ->build_state; + smartlist_t *flaglist = smartlist_create(); + char *flaglist_joined; + + if (build_state->onehop_tunnel) + smartlist_add(flaglist, (void *)"ONEHOP_TUNNEL"); + if (build_state->is_internal) + smartlist_add(flaglist, (void *)"IS_INTERNAL"); + if (build_state->need_capacity) + smartlist_add(flaglist, (void *)"NEED_CAPACITY"); + if (build_state->need_uptime) + smartlist_add(flaglist, (void *)"NEED_UPTIME"); + + /* Only emit a BUILD_FLAGS argument if it will have a non-empty value. */ + if (smartlist_len(flaglist)) { + flaglist_joined = smartlist_join_strings(flaglist, ",", 0, NULL); + + tor_asprintf(&buildflags, "BUILD_FLAGS=%s", flaglist_joined); + smartlist_add(descparts, buildflags); + + tor_free(flaglist_joined); + } + + smartlist_free(flaglist); + } + { char *purpose = NULL; tor_asprintf(&purpose, "PURPOSE=%s", From c818f1f25d0ee55b9597f0ca064a3436897f733a Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 23 Jun 2011 14:59:06 -0700 Subject: [PATCH 4/7] Use the new circ-description function for GETINFO circuit-status --- src/or/control.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 3dda9979fb..620b2f5656 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1849,30 +1849,29 @@ getinfo_helper_events(control_connection_t *control_conn, circuit_t *circ; smartlist_t *status = smartlist_create(); for (circ = _circuit_get_global_list(); circ; circ = circ->next) { - char *s, *path; + char *s, *circdesc; size_t slen; const char *state; - const char *purpose; if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close) continue; - path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ)); - if (circ->state == CIRCUIT_STATE_OPEN) state = "BUILT"; - else if (strlen(path)) + else if (TO_ORIGIN_CIRCUIT(circ)->cpath) state = "EXTENDED"; else state = "LAUNCHED"; - purpose = circuit_purpose_to_controller_string(circ->purpose); - slen = strlen(path)+strlen(state)+strlen(purpose)+30; + circdesc = circuit_describe_status_for_controller( + TO_ORIGIN_CIRCUIT(circ)); + + slen = strlen(circdesc)+strlen(state)+30; s = tor_malloc(slen+1); - tor_snprintf(s, slen, "%lu %s%s%s PURPOSE=%s", + tor_snprintf(s, slen, "%lu %s%s%s", (unsigned long)TO_ORIGIN_CIRCUIT(circ)->global_identifier, - state, *path ? " " : "", path, purpose); + state, *circdesc ? " " : "", circdesc); smartlist_add(status, s); - tor_free(path); + tor_free(circdesc); } *answer = smartlist_join_strings(status, "\r\n", 0, NULL); SMARTLIST_FOREACH(status, char *, cp, tor_free(cp)); From 8d5200c6b527443040520786397d1ffd81b42e23 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 23 Jun 2011 15:02:16 -0700 Subject: [PATCH 5/7] Use fewer TO_ORIGIN_CIRCUIT casts in getinfo_helper_events --- src/or/control.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 620b2f5656..29573099ae 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1846,29 +1846,30 @@ getinfo_helper_events(control_connection_t *control_conn, { (void) control_conn; if (!strcmp(question, "circuit-status")) { - circuit_t *circ; + circuit_t *circ_; smartlist_t *status = smartlist_create(); - for (circ = _circuit_get_global_list(); circ; circ = circ->next) { + for (circ_ = _circuit_get_global_list(); circ_; circ_ = circ_->next) { + origin_circuit_t *circ; char *s, *circdesc; size_t slen; const char *state; - if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close) + if (! CIRCUIT_IS_ORIGIN(circ_) || circ_->marked_for_close) continue; + circ = TO_ORIGIN_CIRCUIT(circ_); - if (circ->state == CIRCUIT_STATE_OPEN) + if (circ->_base.state == CIRCUIT_STATE_OPEN) state = "BUILT"; - else if (TO_ORIGIN_CIRCUIT(circ)->cpath) + else if (circ->cpath) state = "EXTENDED"; else state = "LAUNCHED"; - circdesc = circuit_describe_status_for_controller( - TO_ORIGIN_CIRCUIT(circ)); + circdesc = circuit_describe_status_for_controller(circ); slen = strlen(circdesc)+strlen(state)+30; s = tor_malloc(slen+1); tor_snprintf(s, slen, "%lu %s%s%s", - (unsigned long)TO_ORIGIN_CIRCUIT(circ)->global_identifier, + (unsigned long)circ->global_identifier, state, *circdesc ? " " : "", circdesc); smartlist_add(status, s); tor_free(circdesc); From c7d01b0541a10a51b5e41f3e68eabb90fca3067a Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 23 Jun 2011 17:28:59 -0700 Subject: [PATCH 6/7] Report HS circ states stored in circ purpose field in CIRC events --- changes/feature2411 | 4 ++++ src/or/circuitlist.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ src/or/circuitlist.h | 1 + src/or/control.c | 13 ++++++++++ 4 files changed, 75 insertions(+) diff --git a/changes/feature2411 b/changes/feature2411 index b60fbfd6ad..e029162164 100644 --- a/changes/feature2411 +++ b/changes/feature2411 @@ -4,4 +4,8 @@ controllers in CIRC events and in replies to 'GETINFO circuit-status'. Implements part of ticket 2411. + - Report the current state of a hidden-service-related circuit to + controllers in CIRC events and in replies to 'GETINFO + circuit-status'. Implements part of ticket 2411. + diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 25b80f11f3..daf2eeff7b 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -378,6 +378,63 @@ circuit_purpose_to_controller_string(uint8_t purpose) } } +/** Return a string specifying the state of the hidden-service circuit + * purpose purpose, or NULL if purpose is not a + * hidden-service-related circuit purpose. */ +const char * +circuit_purpose_to_controller_hs_state_string(uint8_t purpose) +{ + switch (purpose) + { + default: + log_fn(LOG_WARN, LD_BUG, + "Unrecognized circuit purpose: %d", + (int)purpose); + tor_fragile_assert(); + /* fall through */ + + case CIRCUIT_PURPOSE_OR: + case CIRCUIT_PURPOSE_C_GENERAL: + case CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT: + case CIRCUIT_PURPOSE_TESTING: + case CIRCUIT_PURPOSE_CONTROLLER: + return NULL; + + case CIRCUIT_PURPOSE_INTRO_POINT: + return "OR_HSSI_ESTABLISHED"; + case CIRCUIT_PURPOSE_REND_POINT_WAITING: + return "OR_HSCR_ESTABLISHED"; + case CIRCUIT_PURPOSE_REND_ESTABLISHED: + return "OR_HS_R_JOINED"; + + case CIRCUIT_PURPOSE_C_INTRODUCING: + return "HSCI_CONNECTING"; + case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT: + return "HSCI_INTRO_SENT"; + case CIRCUIT_PURPOSE_C_INTRODUCE_ACKED: + return "HSCI_DONE"; + + case CIRCUIT_PURPOSE_C_ESTABLISH_REND: + return "HSCR_CONNECTING"; + case CIRCUIT_PURPOSE_C_REND_READY: + return "HSCR_ESTABLISHED_IDLE"; + case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED: + return "HSCR_ESTABLISHED_WAITING"; + case CIRCUIT_PURPOSE_C_REND_JOINED: + return "HSCR_JOINED"; + + case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: + return "HSSI_CONNECTING"; + case CIRCUIT_PURPOSE_S_INTRO: + return "HSSI_ESTABLISHED"; + + case CIRCUIT_PURPOSE_S_CONNECT_REND: + return "HSSR_CONNECTING"; + case CIRCUIT_PURPOSE_S_REND_JOINED: + return "HSSR_JOINED"; + } +} + /** Return a human-readable string for the circuit purpose purpose. */ const char * circuit_purpose_to_string(uint8_t purpose) diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index 7b01ca3ae2..8ed089c81d 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -15,6 +15,7 @@ circuit_t * _circuit_get_global_list(void); const char *circuit_state_to_string(int state); const char *circuit_purpose_to_controller_string(uint8_t purpose); +const char *circuit_purpose_to_controller_hs_state_string(uint8_t purpose); const char *circuit_purpose_to_string(uint8_t purpose); void circuit_dump_by_conn(connection_t *conn, int severity); void circuit_set_p_circid_orconn(or_circuit_t *circ, circid_t id, diff --git a/src/or/control.c b/src/or/control.c index 29573099ae..6b7f9dc7a0 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1829,6 +1829,19 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) smartlist_add(descparts, purpose); } + { + char *hs_state_arg = NULL; + const char *hs_state = + circuit_purpose_to_controller_hs_state_string(circ->_base.purpose); + + if (hs_state != NULL) { + tor_asprintf(&hs_state_arg, "HS_STATE=%s", + hs_state); + + smartlist_add(descparts, hs_state_arg); + } + } + rv = smartlist_join_strings(descparts, " ", 0, NULL); SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp)); From d0ed7cbf8b83f675dcd858abbdfda98eb3bafc88 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Fri, 24 Jun 2011 05:18:21 -0700 Subject: [PATCH 7/7] List service address in CIRC events for HS-related circs --- changes/feature2411 | 7 ++++--- src/or/control.c | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/changes/feature2411 b/changes/feature2411 index e029162164..633a5cebd3 100644 --- a/changes/feature2411 +++ b/changes/feature2411 @@ -4,8 +4,9 @@ controllers in CIRC events and in replies to 'GETINFO circuit-status'. Implements part of ticket 2411. - - Report the current state of a hidden-service-related circuit to - controllers in CIRC events and in replies to 'GETINFO - circuit-status'. Implements part of ticket 2411. + - Report the hidden service address and current state of a + hidden-service-related circuit to controllers in CIRC events and + in replies to 'GETINFO circuit-status'. Implements part of + ticket 2411. diff --git a/src/or/control.c b/src/or/control.c index 6b7f9dc7a0..42eaed2765 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1842,6 +1842,15 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) } } + if (circ->rend_data != NULL) { + char *rend_query_arg = NULL; + + tor_asprintf(&rend_query_arg, "REND_QUERY=%s", + circ->rend_data->onion_address); + + smartlist_add(descparts, rend_query_arg); + } + rv = smartlist_join_strings(descparts, " ", 0, NULL); SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));