mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
Merge remote-tracking branch 'rransom/feature2411-v4'
This commit is contained in:
commit
7cb804343b
12
changes/feature2411
Normal file
12
changes/feature2411
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
|
@ -378,6 +378,63 @@ circuit_purpose_to_controller_string(uint8_t purpose)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return a string specifying the state of the hidden-service circuit
|
||||||
|
* purpose <b>purpose</b>, or NULL if <b>purpose</b> 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 <b>purpose</b>. */
|
/** Return a human-readable string for the circuit purpose <b>purpose</b>. */
|
||||||
const char *
|
const char *
|
||||||
circuit_purpose_to_string(uint8_t purpose)
|
circuit_purpose_to_string(uint8_t purpose)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
circuit_t * _circuit_get_global_list(void);
|
circuit_t * _circuit_get_global_list(void);
|
||||||
const char *circuit_state_to_string(int state);
|
const char *circuit_state_to_string(int state);
|
||||||
const char *circuit_purpose_to_controller_string(uint8_t purpose);
|
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);
|
const char *circuit_purpose_to_string(uint8_t purpose);
|
||||||
void circuit_dump_by_conn(connection_t *conn, int severity);
|
void circuit_dump_by_conn(connection_t *conn, int severity);
|
||||||
void circuit_set_p_circid_orconn(or_circuit_t *circ, circid_t id,
|
void circuit_set_p_circid_orconn(or_circuit_t *circ, circid_t id,
|
||||||
|
142
src/or/control.c
142
src/or/control.c
@ -1780,6 +1780,88 @@ getinfo_helper_dir(control_connection_t *control_conn,
|
|||||||
return 0;
|
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
|
/** Implementation helper for GETINFO: knows how to generate summaries of the
|
||||||
* current states of things we send events about. */
|
* current states of things we send events about. */
|
||||||
static int
|
static int
|
||||||
@ -1789,33 +1871,33 @@ getinfo_helper_events(control_connection_t *control_conn,
|
|||||||
{
|
{
|
||||||
(void) control_conn;
|
(void) control_conn;
|
||||||
if (!strcmp(question, "circuit-status")) {
|
if (!strcmp(question, "circuit-status")) {
|
||||||
circuit_t *circ;
|
circuit_t *circ_;
|
||||||
smartlist_t *status = smartlist_create();
|
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) {
|
||||||
char *s, *path;
|
origin_circuit_t *circ;
|
||||||
|
char *s, *circdesc;
|
||||||
size_t slen;
|
size_t slen;
|
||||||
const char *state;
|
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;
|
continue;
|
||||||
|
circ = TO_ORIGIN_CIRCUIT(circ_);
|
||||||
|
|
||||||
path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ));
|
if (circ->_base.state == CIRCUIT_STATE_OPEN)
|
||||||
|
|
||||||
if (circ->state == CIRCUIT_STATE_OPEN)
|
|
||||||
state = "BUILT";
|
state = "BUILT";
|
||||||
else if (strlen(path))
|
else if (circ->cpath)
|
||||||
state = "EXTENDED";
|
state = "EXTENDED";
|
||||||
else
|
else
|
||||||
state = "LAUNCHED";
|
state = "LAUNCHED";
|
||||||
|
|
||||||
purpose = circuit_purpose_to_controller_string(circ->purpose);
|
circdesc = circuit_describe_status_for_controller(circ);
|
||||||
slen = strlen(path)+strlen(state)+strlen(purpose)+30;
|
|
||||||
|
slen = strlen(circdesc)+strlen(state)+30;
|
||||||
s = tor_malloc(slen+1);
|
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,
|
(unsigned long)circ->global_identifier,
|
||||||
state, *path ? " " : "", path, purpose);
|
state, *circdesc ? " " : "", circdesc);
|
||||||
smartlist_add(status, s);
|
smartlist_add(status, s);
|
||||||
tor_free(path);
|
tor_free(circdesc);
|
||||||
}
|
}
|
||||||
*answer = smartlist_join_strings(status, "\r\n", 0, NULL);
|
*answer = smartlist_join_strings(status, "\r\n", 0, NULL);
|
||||||
SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
|
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)
|
int reason_code)
|
||||||
{
|
{
|
||||||
const char *status;
|
const char *status;
|
||||||
char extended_buf[96];
|
char reasons[64] = "";
|
||||||
if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
|
if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
|
||||||
return 0;
|
return 0;
|
||||||
tor_assert(circ);
|
tor_assert(circ);
|
||||||
@ -3254,36 +3336,32 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
|
|||||||
return 0;
|
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) {
|
if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) {
|
||||||
const char *reason_str = circuit_end_reason_to_control_string(reason_code);
|
const char *reason_str = circuit_end_reason_to_control_string(reason_code);
|
||||||
char *reason = NULL;
|
char unk_reason_buf[16];
|
||||||
size_t n=strlen(extended_buf);
|
|
||||||
if (!reason_str) {
|
if (!reason_str) {
|
||||||
reason = tor_malloc(16);
|
tor_snprintf(unk_reason_buf, 16, "UNKNOWN_%d", reason_code);
|
||||||
tor_snprintf(reason, 16, "UNKNOWN_%d", reason_code);
|
reason_str = unk_reason_buf;
|
||||||
reason_str = reason;
|
|
||||||
}
|
}
|
||||||
if (reason_code > 0 && reason_code & END_CIRC_REASON_FLAG_REMOTE) {
|
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);
|
" REASON=DESTROYED REMOTE_REASON=%s", reason_str);
|
||||||
} else {
|
} else {
|
||||||
tor_snprintf(extended_buf+n, sizeof(extended_buf)-n,
|
tor_snprintf(reasons, sizeof(reasons),
|
||||||
" REASON=%s", reason_str);
|
" REASON=%s", reason_str);
|
||||||
}
|
}
|
||||||
tor_free(reason);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char *vpath = circuit_list_path_for_controller(circ);
|
char *circdesc = circuit_describe_status_for_controller(circ);
|
||||||
const char *sp = strlen(vpath) ? " " : "";
|
const char *sp = strlen(circdesc) ? " " : "";
|
||||||
send_control_event(EVENT_CIRCUIT_STATUS, ALL_FORMATS,
|
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,
|
(unsigned long)circ->global_identifier,
|
||||||
status, sp, vpath, extended_buf);
|
status, sp,
|
||||||
tor_free(vpath);
|
circdesc,
|
||||||
|
reasons);
|
||||||
|
tor_free(circdesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user