diff options
Diffstat (limited to 'src/or/control.c')
-rw-r--r-- | src/or/control.c | 141 |
1 files changed, 92 insertions, 49 deletions
diff --git a/src/or/control.c b/src/or/control.c index 913d18a7f..ad2f2788f 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -12,10 +12,14 @@ #include "or.h" #include "buffers.h" +#include "channel.h" +#include "channeltls.h" #include "circuitbuild.h" #include "circuitlist.h" +#include "circuitstats.h" #include "circuituse.h" #include "config.h" +#include "confparse.h" #include "connection.h" #include "connection_edge.h" #include "connection_or.h" @@ -23,6 +27,7 @@ #include "directory.h" #include "dirserv.h" #include "dnsserv.h" +#include "entrynodes.h" #include "geoip.h" #include "hibernate.h" #include "main.h" @@ -50,7 +55,7 @@ * because it is used both as a list of v0 event types, and as indices * into the bitfield to determine which controllers want which events. */ -#define _EVENT_MIN 0x0001 +#define EVENT_MIN_ 0x0001 #define EVENT_CIRCUIT_STATUS 0x0001 #define EVENT_STREAM_STATUS 0x0002 #define EVENT_OR_CONN_STATUS 0x0003 @@ -76,8 +81,8 @@ #define EVENT_BUILDTIMEOUT_SET 0x0017 #define EVENT_SIGNAL 0x0018 #define EVENT_CONF_CHANGED 0x0019 -#define _EVENT_MAX 0x0019 -/* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */ +#define EVENT_MAX_ 0x0019 +/* If EVENT_MAX_ ever hits 0x0020, we need to make the mask wider. */ /** Bitfield: The bit 1<<e is set if <b>any</b> open control * connection is interested in events of type <b>e</b>. We use this @@ -592,7 +597,7 @@ send_control_event_string(uint16_t event, event_format_t which, { smartlist_t *conns = get_connection_array(); (void)which; - tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX); + tor_assert(event >= EVENT_MIN_ && event <= EVENT_MAX_); SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { if (conn->type == CONN_TYPE_CONTROL && @@ -1215,9 +1220,9 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, connection_mark_for_close(TO_CONN(conn)); return 0; ok: - log_info(LD_CONTROL, "Authenticated control connection (%d)", conn->_base.s); + log_info(LD_CONTROL, "Authenticated control connection (%d)", conn->base_.s); send_control_done(conn); - conn->_base.state = CONTROL_CONN_STATE_OPEN; + conn->base_.state = CONTROL_CONN_STATE_OPEN; tor_free(password); if (sl) { /* clean up */ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); @@ -1243,6 +1248,27 @@ handle_control_saveconf(control_connection_t *conn, uint32_t len, return 0; } +struct signal_t { + int sig; + const char *signal_name; +}; + +static const struct signal_t signal_table[] = { + { SIGHUP, "RELOAD" }, + { SIGHUP, "HUP" }, + { SIGINT, "SHUTDOWN" }, + { SIGUSR1, "DUMP" }, + { SIGUSR1, "USR1" }, + { SIGUSR2, "DEBUG" }, + { SIGUSR2, "USR2" }, + { SIGTERM, "HALT" }, + { SIGTERM, "TERM" }, + { SIGTERM, "INT" }, + { SIGNEWNYM, "NEWNYM" }, + { SIGCLEARDNSCACHE, "CLEARDNSCACHE"}, + { 0, NULL }, +}; + /** Called when we get a SIGNAL command. React to the provided signal, and * report success or failure. (If the signal results in a shutdown, success * may not be reported.) */ @@ -1250,7 +1276,8 @@ static int handle_control_signal(control_connection_t *conn, uint32_t len, const char *body) { - int sig; + int sig = -1; + int i; int n = 0; char *s; @@ -1259,27 +1286,19 @@ handle_control_signal(control_connection_t *conn, uint32_t len, while (body[n] && ! TOR_ISSPACE(body[n])) ++n; s = tor_strndup(body, n); - if (!strcasecmp(s, "RELOAD") || !strcasecmp(s, "HUP")) - sig = SIGHUP; - else if (!strcasecmp(s, "SHUTDOWN") || !strcasecmp(s, "INT")) - sig = SIGINT; - else if (!strcasecmp(s, "DUMP") || !strcasecmp(s, "USR1")) - sig = SIGUSR1; - else if (!strcasecmp(s, "DEBUG") || !strcasecmp(s, "USR2")) - sig = SIGUSR2; - else if (!strcasecmp(s, "HALT") || !strcasecmp(s, "TERM")) - sig = SIGTERM; - else if (!strcasecmp(s, "NEWNYM")) - sig = SIGNEWNYM; - else if (!strcasecmp(s, "CLEARDNSCACHE")) - sig = SIGCLEARDNSCACHE; - else { + + for (i = 0; signal_table[i].signal_name != NULL; ++i) { + if (!strcasecmp(s, signal_table[i].signal_name)) { + sig = signal_table[i].sig; + break; + } + } + + if (sig < 0) connection_printf_to_buf(conn, "552 Unrecognized signal code \"%s\"\r\n", s); - sig = -1; - } tor_free(s); - if (sig<0) + if (sig < 0) return 0; send_control_done(conn); @@ -1306,7 +1325,7 @@ handle_control_takeownership(control_connection_t *conn, uint32_t len, log_info(LD_CONTROL, "Control connection %d has taken ownership of this " "Tor instance.", - (int)(conn->_base.s)); + (int)(conn->base_.s)); send_control_done(conn); return 0; @@ -1440,6 +1459,16 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, *answer = smartlist_join_strings(event_names, " ", 0, NULL); smartlist_free(event_names); + } else if (!strcmp(question, "signal/names")) { + smartlist_t *signal_names = smartlist_new(); + int j; + for (j = 0; signal_table[j].signal_name != NULL; ++j) { + smartlist_add(signal_names, (char*)signal_table[j].signal_name); + } + + *answer = smartlist_join_strings(signal_names, " ", 0, NULL); + + smartlist_free(signal_names); } else if (!strcmp(question, "features/names")) { *answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS"); } else if (!strcmp(question, "address")) { @@ -1614,10 +1643,13 @@ getinfo_helper_dir(control_connection_t *control_conn, const char *question, char **answer, const char **errmsg) { - const routerinfo_t *ri; + const node_t *node; + const routerinfo_t *ri = NULL; (void) control_conn; if (!strcmpstart(question, "desc/id/")) { - ri = router_get_by_hexdigest(question+strlen("desc/id/")); + node = node_get_by_hex_id(question+strlen("desc/id/")); + if (node) + ri = node->ri; if (ri) { const char *body = signed_descriptor_get_body(&ri->cache_info); if (body) @@ -1626,7 +1658,9 @@ getinfo_helper_dir(control_connection_t *control_conn, } else if (!strcmpstart(question, "desc/name/")) { /* XXX023 Setting 'warn_if_unnamed' here is a bit silly -- the * warning goes to the user, not to the controller. */ - ri = router_get_by_nickname(question+strlen("desc/name/"),1); + node = node_get_by_nickname(question+strlen("desc/name/"), 1); + if (node) + ri = node->ri; if (ri) { const char *body = signed_descriptor_get_body(&ri->cache_info); if (body) @@ -1688,8 +1722,9 @@ getinfo_helper_dir(control_connection_t *control_conn, *answer = tor_strndup(md->body, md->bodylen); } } else if (!strcmpstart(question, "desc-annotations/id/")) { - ri = router_get_by_hexdigest(question+ - strlen("desc-annotations/id/")); + node = node_get_by_hex_id(question+strlen("desc-annotations/id/")); + if (node) + ri = node->ri; if (ri) { const char *annotations = signed_descriptor_get_annotations(&ri->cache_info); @@ -1847,11 +1882,11 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) } smartlist_add_asprintf(descparts, "PURPOSE=%s", - circuit_purpose_to_controller_string(circ->_base.purpose)); + circuit_purpose_to_controller_string(circ->base_.purpose)); { const char *hs_state = - circuit_purpose_to_controller_hs_state_string(circ->_base.purpose); + circuit_purpose_to_controller_hs_state_string(circ->base_.purpose); if (hs_state != NULL) { smartlist_add_asprintf(descparts, "HS_STATE=%s", hs_state); @@ -1865,7 +1900,7 @@ circuit_describe_status_for_controller(origin_circuit_t *circ) { char tbuf[ISO_TIME_USEC_LEN+1]; - format_iso_time_nospace_usec(tbuf, &circ->_base.timestamp_created); + format_iso_time_nospace_usec(tbuf, &circ->base_.timestamp_created); smartlist_add_asprintf(descparts, "TIME_CREATED=%s", tbuf); } @@ -1889,7 +1924,7 @@ getinfo_helper_events(control_connection_t *control_conn, if (!strcmp(question, "circuit-status")) { circuit_t *circ_; smartlist_t *status = smartlist_new(); - 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 *circdesc; const char *state; @@ -1897,7 +1932,7 @@ getinfo_helper_events(control_connection_t *control_conn, continue; circ = TO_ORIGIN_CIRCUIT(circ_); - if (circ->_base.state == CIRCUIT_STATE_OPEN) + if (circ->base_.state == CIRCUIT_STATE_OPEN) state = "BUILT"; else if (circ->cpath) state = "EXTENDED"; @@ -1974,7 +2009,7 @@ getinfo_helper_events(control_connection_t *control_conn, if (base_conn->type != CONN_TYPE_OR || base_conn->marked_for_close) continue; conn = TO_OR_CONN(base_conn); - if (conn->_base.state == OR_CONN_STATE_OPEN) + if (conn->base_.state == OR_CONN_STATE_OPEN) state = "CONNECTED"; else if (conn->nickname) state = "LAUNCHED"; @@ -2130,10 +2165,14 @@ static const getinfo_item_t getinfo_items[] = { PREFIX("config/", config, "Current configuration values."), DOC("config/names", "List of configuration options, types, and documentation."), + DOC("config/defaults", + "List of default values for configuration options. " + "See also config/names"), ITEM("info/names", misc, "List of GETINFO options, types, and documentation."), ITEM("events/names", misc, "Events that the controller can ask for with SETEVENTS."), + ITEM("signal/names", misc, "Signal names recognized by the SIGNAL command"), ITEM("features/names", misc, "What arguments can USEFEATURE take?"), PREFIX("desc/id/", dir, "Router descriptors by ID."), PREFIX("desc/name/", dir, "Router descriptors by nickname."), @@ -2497,7 +2536,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len, goto done; } } else { - if (circ->_base.state == CIRCUIT_STATE_OPEN) { + if (circ->base_.state == CIRCUIT_STATE_OPEN) { int err_reason = 0; circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_BUILDING); if ((err_reason = circuit_send_next_onion_skin(circ)) < 0) { @@ -2630,7 +2669,7 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len, TO_CONN(edge_conn)->state = AP_CONN_STATE_CONTROLLER_WAIT; } - if (circ && (circ->_base.state != CIRCUIT_STATE_OPEN)) { + if (circ && (circ->base_.state != CIRCUIT_STATE_OPEN)) { connection_write_str_to_buf( "551 Can't attach stream to non-open origin circuit\r\n", conn); @@ -3198,7 +3237,7 @@ connection_control_closed(control_connection_t *conn) static int is_valid_initial_command(control_connection_t *conn, const char *cmd) { - if (conn->_base.state == CONTROL_CONN_STATE_OPEN) + if (conn->base_.state == CONTROL_CONN_STATE_OPEN) return 1; if (!strcasecmp(cmd, "PROTOCOLINFO")) return (!conn->have_sent_protocolinfo && @@ -3243,8 +3282,8 @@ connection_control_process_inbuf(control_connection_t *conn) char *args; tor_assert(conn); - tor_assert(conn->_base.state == CONTROL_CONN_STATE_OPEN || - conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH); + tor_assert(conn->base_.state == CONTROL_CONN_STATE_OPEN || + conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH); if (!conn->incoming_cmd) { conn->incoming_cmd = tor_malloc(1024); @@ -3252,7 +3291,7 @@ connection_control_process_inbuf(control_connection_t *conn) conn->incoming_cmd_cur_len = 0; } - if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH && + if (conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH && peek_connection_has_control0_command(TO_CONN(conn))) { /* Detect v0 commands and send a "no more v0" message. */ size_t body_len; @@ -3351,7 +3390,7 @@ connection_control_process_inbuf(control_connection_t *conn) return 0; } - if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH && + if (conn->base_.state == CONTROL_CONN_STATE_NEEDAUTH && !is_valid_initial_command(conn, conn->incoming_cmd)) { connection_write_str_to_buf("514 Authentication required.\r\n", conn); connection_mark_for_close(TO_CONN(conn)); @@ -3755,7 +3794,7 @@ orconn_target_get_name(char *name, size_t len, or_connection_t *conn) DIGEST_LEN); } else { tor_snprintf(name, len, "%s:%d", - conn->_base.address, conn->_base.port); + conn->base_.address, conn->base_.port); } } @@ -3787,8 +3826,12 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp, log_warn(LD_BUG, "Unrecognized status code %d", (int)tp); return 0; } - ncircs = circuit_count_pending_on_or_conn(conn); - ncircs += conn->n_circuits; + if (conn->chan) { + ncircs = circuit_count_pending_on_channel(TLS_CHAN_TO_BASE(conn->chan)); + } else { + ncircs = 0; + } + ncircs += connection_or_get_num_circuits(conn); if (ncircs && (tp == OR_CONN_EVENT_FAILED || tp == OR_CONN_EVENT_CLOSED)) { tor_snprintf(ncircs_buf, sizeof(ncircs_buf), "%sNCIRCS=%d", reason ? " " : "", ncircs); @@ -3817,7 +3860,7 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn) send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_FORMATS, "650 STREAM_BW "U64_FORMAT" %lu %lu\r\n", - U64_PRINTF_ARG(edge_conn->_base.global_identifier), + U64_PRINTF_ARG(edge_conn->base_.global_identifier), (unsigned long)edge_conn->n_read, (unsigned long)edge_conn->n_written); @@ -3846,7 +3889,7 @@ control_event_stream_bandwidth_used(void) send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_FORMATS, "650 STREAM_BW "U64_FORMAT" %lu %lu\r\n", - U64_PRINTF_ARG(edge_conn->_base.global_identifier), + U64_PRINTF_ARG(edge_conn->base_.global_identifier), (unsigned long)edge_conn->n_read, (unsigned long)edge_conn->n_written); |