aboutsummaryrefslogtreecommitdiff
path: root/src/or/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/control.c')
-rw-r--r--src/or/control.c141
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&lt;&lt;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);