diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-12-22 10:51:39 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-12-22 10:51:39 -0500 |
commit | 7cb804343b827ce048c2468d16f6887238790241 (patch) | |
tree | 58cc2b7a134d852296c3a9db314a6eac6c392cda /src/or/control.c | |
parent | 782b7f49d8a681113a48c6108174164e7df2f72c (diff) | |
parent | d0ed7cbf8b83f675dcd858abbdfda98eb3bafc88 (diff) | |
download | tor-7cb804343b827ce048c2468d16f6887238790241.tar.gz tor-7cb804343b827ce048c2468d16f6887238790241.zip |
Merge remote-tracking branch 'rransom/feature2411-v4'
Diffstat (limited to 'src/or/control.c')
-rw-r--r-- | src/or/control.c | 142 |
1 files changed, 110 insertions, 32 deletions
diff --git a/src/or/control.c b/src/or/control.c index 20caabf0c1..c9d3765ad3 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1780,6 +1780,88 @@ getinfo_helper_dir(control_connection_t *control_conn, return 0; } +/** Allocate and return a description of <b>circ</b>'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 *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", + circuit_purpose_to_controller_string(circ->_base.purpose)); + 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); + } + } + + 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)); + 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 @@ -1789,33 +1871,33 @@ 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) { - char *s, *path; + for (circ_ = _circuit_get_global_list(); circ_; circ_ = circ_->next) { + origin_circuit_t *circ; + char *s, *circdesc; size_t slen; const char *state; - const char *purpose; - if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close) + if (! CIRCUIT_IS_ORIGIN(circ_) || circ_->marked_for_close) continue; + circ = TO_ORIGIN_CIRCUIT(circ_); - path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ)); - - if (circ->state == CIRCUIT_STATE_OPEN) + if (circ->_base.state == CIRCUIT_STATE_OPEN) state = "BUILT"; - else if (strlen(path)) + else if (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(circ); + + slen = strlen(circdesc)+strlen(state)+30; s = tor_malloc(slen+1); - tor_snprintf(s, slen, "%lu %s%s%s PURPOSE=%s", - (unsigned long)TO_ORIGIN_CIRCUIT(circ)->global_identifier, - state, *path ? " " : "", path, purpose); + tor_snprintf(s, slen, "%lu %s%s%s", + (unsigned long)circ->global_identifier, + 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)); @@ -3237,7 +3319,7 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code) { const char *status; - char extended_buf[96]; + char reasons[64] = ""; if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS)) return 0; tor_assert(circ); @@ -3254,36 +3336,32 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, return 0; } - tor_snprintf(extended_buf, sizeof(extended_buf), "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); + 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(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); } { - 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\r\n", + "650 CIRC %lu %s%s%s%s\r\n", (unsigned long)circ->global_identifier, - status, sp, vpath, extended_buf); - tor_free(vpath); + status, sp, + circdesc, + reasons); + tor_free(circdesc); } return 0; |