aboutsummaryrefslogtreecommitdiff
path: root/src/or/control.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-12-22 10:51:39 -0500
committerNick Mathewson <nickm@torproject.org>2011-12-22 10:51:39 -0500
commit7cb804343b827ce048c2468d16f6887238790241 (patch)
tree58cc2b7a134d852296c3a9db314a6eac6c392cda /src/or/control.c
parent782b7f49d8a681113a48c6108174164e7df2f72c (diff)
parentd0ed7cbf8b83f675dcd858abbdfda98eb3bafc88 (diff)
downloadtor-7cb804343b827ce048c2468d16f6887238790241.tar
tor-7cb804343b827ce048c2468d16f6887238790241.tar.gz
Merge remote-tracking branch 'rransom/feature2411-v4'
Diffstat (limited to 'src/or/control.c')
-rw-r--r--src/or/control.c142
1 files changed, 110 insertions, 32 deletions
diff --git a/src/or/control.c b/src/or/control.c
index 20caabf0c..c9d3765ad 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;