diff options
-rw-r--r-- | changes/bug19859 | 2 | ||||
-rw-r--r-- | src/feature/control/control_events.c | 12 | ||||
-rw-r--r-- | src/feature/control/control_fmt.c | 78 | ||||
-rw-r--r-- | src/feature/control/control_fmt.h | 2 |
4 files changed, 91 insertions, 3 deletions
diff --git a/changes/bug19859 b/changes/bug19859 new file mode 100644 index 0000000000..36908854df --- /dev/null +++ b/changes/bug19859 @@ -0,0 +1,2 @@ + o Minor features (controller): + - Add stream isolation data to STREAM event. Closes ticket 19859. diff --git a/src/feature/control/control_events.c b/src/feature/control/control_events.c index 12b73641b2..427edbdf3f 100644 --- a/src/feature/control/control_events.c +++ b/src/feature/control/control_events.c @@ -833,13 +833,19 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp, circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn)); if (circ && CIRCUIT_IS_ORIGIN(circ)) origin_circ = TO_ORIGIN_CIRCUIT(circ); - send_control_event(EVENT_STREAM_STATUS, - "650 STREAM %"PRIu64" %s %lu %s%s%s%s\r\n", + + { + char *conndesc = entry_connection_describe_status_for_controller(conn); + const char *sp = strlen(conndesc) ? " " : ""; + send_control_event(EVENT_STREAM_STATUS, + "650 STREAM %"PRIu64" %s %lu %s%s%s%s%s%s\r\n", (ENTRY_TO_CONN(conn)->global_identifier), status, origin_circ? (unsigned long)origin_circ->global_identifier : 0ul, - buf, reason_buf, addrport_buf, purpose); + buf, reason_buf, addrport_buf, purpose, sp, conndesc); + tor_free(conndesc); + } /* XXX need to specify its intended exit, etc? */ diff --git a/src/feature/control/control_fmt.c b/src/feature/control/control_fmt.c index e0e77eb2d0..9bae95b59f 100644 --- a/src/feature/control/control_fmt.c +++ b/src/feature/control/control_fmt.c @@ -165,6 +165,84 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) return rv; } +/** Allocate and return a description of <b>conn</b>'s current status. */ +char * +entry_connection_describe_status_for_controller(entry_connection_t *conn) +{ + char *rv; + smartlist_t *descparts = smartlist_new(); + + if (conn->socks_request != NULL) { + // Show username and/or password if available; used by IsolateSOCKSAuth. + if (conn->socks_request->usernamelen > 0) { + char* username_escaped = esc_for_log_len(conn->socks_request->username, + (size_t) conn->socks_request->usernamelen); + smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s", + username_escaped); + tor_free(username_escaped); + } + if (conn->socks_request->passwordlen > 0) { + char* password_escaped = esc_for_log_len(conn->socks_request->password, + (size_t) conn->socks_request->passwordlen); + smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s", + password_escaped); + tor_free(password_escaped); + } + + const char *client_protocol; + // Show the client protocol; used by IsolateClientProtocol. + switch (conn->socks_request->listener_type) + { + case CONN_TYPE_AP_LISTENER: + switch (conn->socks_request->socks_version) + { + case 4: client_protocol = "SOCKS4"; break; + case 5: client_protocol = "SOCKS5"; break; + default: client_protocol = "UNKNOWN"; + } + break; + case CONN_TYPE_AP_TRANS_LISTENER: client_protocol = "TRANS"; break; + case CONN_TYPE_AP_NATD_LISTENER: client_protocol = "NATD"; break; + case CONN_TYPE_AP_DNS_LISTENER: client_protocol = "DNS"; break; + default: client_protocol = "UNKNOWN"; + } + smartlist_add_asprintf(descparts, "CLIENT_PROTOCOL=%s", + client_protocol); + } + + // Show newnym epoch; used for stream isolation when NEWNYM is used. + smartlist_add_asprintf(descparts, "NYM_EPOCH=%u", + conn->nym_epoch); + + // Show session group; used for stream isolation of multiple listener ports. + smartlist_add_asprintf(descparts, "SESSION_GROUP=%d", + conn->entry_cfg.session_group); + + // Show isolation flags. + smartlist_add_asprintf(descparts, "ISO_DESTPORT=%d", + (conn->entry_cfg.isolation_flags & + ISO_DESTPORT) ? 1 : 0); + smartlist_add_asprintf(descparts, "ISO_DESTADDR=%d", + (conn->entry_cfg.isolation_flags & + ISO_DESTADDR) ? 1 : 0); + smartlist_add_asprintf(descparts, "ISO_SOCKSAUTH=%d", + (conn->entry_cfg.isolation_flags & + ISO_SOCKSAUTH) ? 1 : 0); + smartlist_add_asprintf(descparts, "ISO_CLIENTPROTO=%d", + (conn->entry_cfg.isolation_flags & + ISO_CLIENTPROTO) ? 1 : 0); + smartlist_add_asprintf(descparts, "ISO_CLIENTADDR=%d", + (conn->entry_cfg.isolation_flags & + ISO_CLIENTADDR) ? 1 : 0); + + rv = smartlist_join_strings(descparts, " ", 0, NULL); + + SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp)); + smartlist_free(descparts); + + return rv; +} + /** Return a longname the node whose identity is <b>id_digest</b>. If * node_get_by_id() returns NULL, base 16 encoding of <b>id_digest</b> is * returned instead. diff --git a/src/feature/control/control_fmt.h b/src/feature/control/control_fmt.h index 6446e37079..84ccbab948 100644 --- a/src/feature/control/control_fmt.h +++ b/src/feature/control/control_fmt.h @@ -17,6 +17,8 @@ int write_stream_target_to_buf(entry_connection_t *conn, char *buf, void orconn_target_get_name(char *buf, size_t len, or_connection_t *conn); char *circuit_describe_status_for_controller(origin_circuit_t *circ); +char *entry_connection_describe_status_for_controller( + entry_connection_t *conn); MOCK_DECL(const char *, node_describe_longname_by_id,(const char *id_digest)); |