diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-10-09 15:47:50 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-10-09 15:47:50 +0000 |
commit | 26283e69ba88896d8aeb9141bdaeff15be916ec8 (patch) | |
tree | 377a1490710afcdd83ebd6e26559a74a1e0a6e9d /src/or/control.c | |
parent | b76fd968b4d2deddf2f40f63dc04713f45649c68 (diff) | |
download | tor-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.c | 168 |
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); |