summaryrefslogtreecommitdiff
path: root/src/or/control.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-10-09 15:47:50 +0000
committerNick Mathewson <nickm@torproject.org>2006-10-09 15:47:50 +0000
commit26283e69ba88896d8aeb9141bdaeff15be916ec8 (patch)
tree377a1490710afcdd83ebd6e26559a74a1e0a6e9d /src/or/control.c
parentb76fd968b4d2deddf2f40f63dc04713f45649c68 (diff)
downloadtor-26283e69ba88896d8aeb9141bdaeff15be916ec8.tar.gz
tor-26283e69ba88896d8aeb9141bdaeff15be916ec8.zip
r8973@totoro: nickm | 2006-10-09 11:45:47 -0400
Touch up last patch (to add REASON to CIRC events): make some reasons more sensible, send reasons only to controllers that have enabled extended events, and clean up whitespace. svn:r8672
Diffstat (limited to 'src/or/control.c')
-rw-r--r--src/or/control.c168
1 files changed, 121 insertions, 47 deletions
diff --git a/src/or/control.c b/src/or/control.c
index 64439d3b46..e839cea621 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -144,9 +144,13 @@ static int disable_log_messages = 0;
static int authentication_cookie_is_set = 0;
static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
-typedef enum {
- SHORT_NAMES,LONG_NAMES,ALL_NAMES
-} name_type_t;
+#define SHORT_NAMES 1
+#define LONG_NAMES 2
+#define ALL_NAMES (SHORT_NAMES|LONG_NAMES)
+#define EXTENDED_FORMAT 4
+#define NONEXTENDED_FORMAT 8
+#define ALL_FORMATS (EXTENDED_FORMAT|NONEXTENDED_FORMAT)
+typedef int event_format_t;
static void connection_printf_to_buf(control_connection_t *conn,
const char *format, ...)
@@ -164,9 +168,12 @@ static void send_control0_error(control_connection_t *conn, uint16_t error,
const char *message);
static void send_control0_event(uint16_t event, uint32_t len,
const char *body);
-static void send_control1_event(uint16_t event, name_type_t which,
+static void send_control1_event(uint16_t event, event_format_t which,
const char *format, ...)
CHECK_PRINTF(3,4);
+static void send_control1_event_extended(uint16_t event, event_format_t which,
+ const char *format, ...)
+ CHECK_PRINTF(3,4);
static int handle_control_setconf(control_connection_t *conn, uint32_t len,
char *body);
static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
@@ -614,9 +621,12 @@ send_control0_event(uint16_t event, uint32_t len, const char *body)
}
/* Send an event to all v1 controllers that are listening for code
- * <b>event</b>. The event's body is given by <b>msg</b>. */
+ * <b>event</b>. The event's body is given by <b>msg</b>.
+ *
+ * docdoc which, is_extended */
static void
-send_control1_event_string(uint16_t event, name_type_t which, const char *msg)
+send_control1_event_string(uint16_t event, event_format_t which,
+ const char *msg)
{
connection_t **conns;
int n_conns, i;
@@ -629,11 +639,18 @@ send_control1_event_string(uint16_t event, name_type_t which, const char *msg)
!conns[i]->marked_for_close &&
conns[i]->state == CONTROL_CONN_STATE_OPEN_V1) {
control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
- if (which == SHORT_NAMES) {
- if (control_conn->use_long_names)
+ if (control_conn->use_long_names) {
+ if (!(which & LONG_NAMES))
+ continue;
+ } else {
+ if (!(which & SHORT_NAMES))
continue;
- } else if (which == LONG_NAMES) {
- if (! control_conn->use_long_names)
+ }
+ if (control_conn->use_extended_events) {
+ if (!(which & EXTENDED_FORMAT))
+ continue;
+ } else {
+ if (!(which & NONEXTENDED_FORMAT))
continue;
}
if (control_conn->event_mask & (1<<event)) {
@@ -645,24 +662,17 @@ send_control1_event_string(uint16_t event, name_type_t which, const char *msg)
}
}
-/* Send an event to all v1 controllers that are listening for code
- * <b>event</b>. The event's body is created by the printf-style format in
- * <b>format</b>, and other arguments as provided.
- *
- * Currently the length of the message is limited to 1024 (including the
- * ending \n\r\0. */
static void
-send_control1_event(uint16_t event, name_type_t which, const char *format, ...)
+send_control1_event_impl(uint16_t event, event_format_t which, int extended,
+ const char *format, va_list ap)
{
#define SEND_CONTROL1_EVENT_BUFFERSIZE 1024
int r;
char buf[SEND_CONTROL1_EVENT_BUFFERSIZE]; /* XXXX Length */
- va_list ap;
size_t len;
+ char *cp;
- va_start(ap, format);
r = tor_vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
if (r<0) {
log_warn(LD_BUG, "Unable to format event for controller.");
return;
@@ -676,7 +686,51 @@ send_control1_event(uint16_t event, name_type_t which, const char *format, ...)
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
}
- send_control1_event_string(event, which, buf);
+ if (extended && (cp = strchr(buf, '@'))) {
+ which &= ~ALL_FORMATS;
+ *cp = ' ';
+ send_control1_event_string(event, which|EXTENDED_FORMAT, buf);
+ memcpy(cp, "\r\n\0", 3);
+ send_control1_event_string(event, which|NONEXTENDED_FORMAT, buf);
+ } else {
+ send_control1_event_string(event, which|ALL_FORMATS, buf);
+ }
+}
+
+/* Send an event to all v1 controllers that are listening for code
+ * <b>event</b>. The event's body is created by the printf-style format in
+ * <b>format</b>, and other arguments as provided.
+ *
+ * Currently the length of the message is limited to 1024 (including the
+ * ending \n\r\0. */
+static void
+send_control1_event(uint16_t event, event_format_t which,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ send_control1_event_impl(event, which, 0, format, ap);
+ va_end(ap);
+}
+
+/* Send an event to all v1 controllers that are listening for code
+ * <b>event</b>. The event's body is created by the printf-style format in
+ * <b>format</b>, and other arguments as provided.
+ *
+ * If the format contains a single '@' character, it will be replaced with a
+ * space and all text after that character will be sent only to controllers
+ * that have enabled extended events.
+ *
+ * Currently the length of the message is limited to 1024 (including the
+ * ending \n\r\0. */
+static void
+send_control1_event_extended(uint16_t event, event_format_t which,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ send_control1_event_impl(event, which, 1, format, ap);
+ va_end(ap);
}
/** Given a text circuit <b>id</b>, return the corresponding circuit. */
@@ -1009,7 +1063,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
smartlist_free(events);
}
conn->event_mask = event_mask;
- conn->use_extended_events = extended;
+ if (extended)
+ conn->use_extended_events = 1;
control_update_global_event_mask();
send_control_done(conn);
@@ -2338,7 +2393,7 @@ handle_control_usefeature(control_connection_t *conn,
SMARTLIST_FOREACH(args, const char *, arg, {
if (!strcasecmp(arg, "VERBOSE_NAMES"))
verbose_names = 1;
- else if (!strcasecmp(arg, "EXTENDED_EVENTS"))
+ else if (!strcasecmp(arg, "EXTENDED_FORMAT"))
extended_events = 1;
else {
connection_printf_to_buf(conn, "552 Unrecognized feature \"%s\"\r\n",
@@ -2744,11 +2799,43 @@ connection_control_process_inbuf(control_connection_t *conn)
return connection_control_process_inbuf_v1(conn);
}
+static const char *
+circuit_end_reason_to_string(int reason)
+{
+ switch (reason) {
+ case END_CIRC_AT_ORIGIN:
+ /* This shouldn't get passed here; it's a catch-all reason. */
+ return "REASON=ORIGIN";
+ case END_CIRC_REASON_NONE:
+ /* This shouldn't get passed here; it's a catch-all reason. */
+ return "REASON=NONE";
+ case END_CIRC_REASON_TORPROTOCOL:
+ return "REASON=TORPROTOCOL";
+ case END_CIRC_REASON_INTERNAL:
+ return "REASON=INTERNAL";
+ case END_CIRC_REASON_REQUESTED:
+ return "REASON=REQUESTED";
+ case END_CIRC_REASON_HIBERNATING:
+ return "REASON=HIBERNATING";
+ case END_CIRC_REASON_RESOURCELIMIT:
+ return "REASON=RESOURCELIMIT";
+ case END_CIRC_REASON_CONNECTFAILED:
+ return "REASON=CONNECTFAILED";
+ case END_CIRC_REASON_OR_IDENTITY:
+ return "REASON=OR_IDENTITY";
+ case END_CIRC_REASON_OR_CONN_CLOSED:
+ return "REASON=OR_CONN_CLOSED";
+ default:
+ log_warn(LD_BUG, "Unrecognized reason code %d", (int)reason);
+ return NULL;
+ }
+}
+
/** Something has happened to circuit <b>circ</b>: tell any interested
* control connections. */
int
control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
- int rsn)
+ int reason_code)
{
char *path=NULL, *msg;
if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
@@ -2783,34 +2870,20 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
return 0;
}
- if(tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) {
- switch (rsn)
- {
- case END_CIRC_AT_ORIGIN: reason = " REASON=ORIGIN"; break;
- case END_CIRC_REASON_NONE: reason = " REASON=NONE"; break;
- case END_CIRC_REASON_TORPROTOCOL: reason = " REASON=TORPROTOCOL"; break;
- case END_CIRC_REASON_INTERNAL: reason = " REASON=INTERNAL"; break;
- case END_CIRC_REASON_REQUESTED: reason = " REASON=REQUESTED"; break;
- case END_CIRC_REASON_HIBERNATING: reason = " REASON=HIBERNATING"; break;
- case END_CIRC_REASON_RESOURCELIMIT: reason = " REASON=RESOURCELIMIT"; break;
- case END_CIRC_REASON_CONNECTFAILED: reason = " REASON=CONNECTFAILED"; break;
- case END_CIRC_REASON_OR_IDENTITY: reason = " REASON=OR_IDENTITY"; break;
- case END_CIRC_REASON_OR_CONN_CLOSED: reason = " REASON=OR_CONN_CLOSED"; break;
- default:
- log_warn(LD_BUG, "Unrecognized reason code %d", (int)rsn);
- }
+ if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) {
+ reason = circuit_end_reason_to_string(reason_code);
}
if (EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS)) {
- send_control1_event(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
- "650 CIRC %lu %s %s%s\r\n",
+ send_control1_event_extended(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
+ "650 CIRC %lu %s %s@%s\r\n",
(unsigned long)circ->global_identifier,
status, path, reason);
}
if (EVENT_IS_INTERESTING1L(EVENT_CIRCUIT_STATUS)) {
char *vpath = circuit_list_path_for_controller(circ);
- send_control1_event(EVENT_CIRCUIT_STATUS, LONG_NAMES,
- "650 CIRC %lu %s %s%s\r\n",
+ send_control1_event_extended(EVENT_CIRCUIT_STATUS, LONG_NAMES,
+ "650 CIRC %lu %s %s@%s\r\n",
(unsigned long)circ->global_identifier,
status, vpath, reason);
tor_free(vpath);
@@ -3097,7 +3170,7 @@ control_event_descriptors_changed(smartlist_t *routers)
size_t len = strlen(ids)+32;
msg = tor_malloc(len);
tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids);
- send_control1_event_string(EVENT_NEW_DESC, SHORT_NAMES, msg);
+ send_control1_event_string(EVENT_NEW_DESC, SHORT_NAMES|ALL_FORMATS, msg);
tor_free(ids);
tor_free(msg);
}
@@ -3114,7 +3187,7 @@ control_event_descriptors_changed(smartlist_t *routers)
len = strlen(ids)+32;
msg = tor_malloc(len);
tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids);
- send_control1_event_string(EVENT_NEW_DESC, LONG_NAMES, msg);
+ send_control1_event_string(EVENT_NEW_DESC, LONG_NAMES|ALL_FORMATS, msg);
tor_free(ids);
tor_free(msg);
SMARTLIST_FOREACH(names, char *, cp, tor_free(cp));
@@ -3180,7 +3253,8 @@ control_event_or_authdir_new_descriptor(const char *action,
buf = tor_malloc(totallen);
strlcpy(buf, firstline, totallen);
strlcpy(buf+strlen(firstline), esc, totallen);
- send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES, buf);
+ send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS,
+ buf);
tor_free(esc);
tor_free(buf);