commit 296b8d0b10cc8e5d42c88284ed1b37b510f4a5bc Author: Robert Ransom rransom.8774@gmail.com Date: Thu Nov 24 06:54:55 2011 -0800
Add CIRC2 control-port event, and send it when a circ's purpose changes --- changes/feature3457 | 3 ++ src/or/circuituse.c | 16 +++++++++--- src/or/control.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++---- src/or/control.h | 3 ++ src/or/or.h | 6 ++++ 5 files changed, 83 insertions(+), 9 deletions(-)
diff --git a/changes/feature3457 b/changes/feature3457 index b06f959..2180f98 100644 --- a/changes/feature3457 +++ b/changes/feature3457 @@ -2,4 +2,7 @@
- Log (at debug level) whenever a circuit's purpose is changed.
+ - Allow controllers to request an event notification whenever a + circuit's purpose is changed. Implements part of ticket 3457. +
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 46c0b8a..1b91100 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1929,6 +1929,7 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose) { + uint8_t old_purpose; /* Don't allow an OR circ to become an origin circ or vice versa. */ tor_assert(!!(CIRCUIT_IS_ORIGIN(circ)) == !!(CIRCUIT_PURPOSE_IS_ORIGIN(new_purpose))); @@ -1936,21 +1937,28 @@ circuit_change_purpose(circuit_t *circ, uint8_t new_purpose) if (circ->purpose == new_purpose) return;
if (CIRCUIT_IS_ORIGIN(circ)) { - char old_purpose[80] = ""; + char old_purpose_desc[80] = "";
- strncpy(old_purpose, circuit_purpose_to_string(circ->purpose), 80-1); - old_purpose[80-1] = '\0'; + strncpy(old_purpose_desc, circuit_purpose_to_string(circ->purpose), 80-1); + old_purpose_desc[80-1] = '\0';
log_debug(LD_CIRC, "changing purpose of origin circ %d " "from "%s" (%d) to "%s" (%d)", TO_ORIGIN_CIRCUIT(circ)->global_identifier, - old_purpose, + old_purpose_desc, circ->purpose, circuit_purpose_to_string(new_purpose), new_purpose); }
+ old_purpose = circ->purpose; circ->purpose = new_purpose; + + if (CIRCUIT_IS_ORIGIN(circ)) { + control_event_circuit_status_2(TO_ORIGIN_CIRCUIT(circ), + CIRC2_EVENT_PURPOSE_CHANGED, + (int)old_purpose, NULL); + } }
diff --git a/src/or/control.c b/src/or/control.c index b3609d1..c575ff6 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -54,7 +54,7 @@ #define EVENT_STREAM_STATUS 0x0002 #define EVENT_OR_CONN_STATUS 0x0003 #define EVENT_BANDWIDTH_USED 0x0004 -#define EVENT_LOG_OBSOLETE 0x0005 /* Can reclaim this. */ +#define EVENT_CIRCUIT_STATUS_2 0x0005 #define EVENT_NEW_DESC 0x0006 #define EVENT_DEBUG_MSG 0x0007 #define EVENT_INFO_MSG 0x0008 @@ -272,8 +272,7 @@ control_adjust_event_log_severity(void) break; } } - if (EVENT_IS_INTERESTING(EVENT_LOG_OBSOLETE) || - EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL)) { + if (EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL)) { if (min_log_event > EVENT_NOTICE_MSG) min_log_event = EVENT_NOTICE_MSG; if (max_log_event < EVENT_ERR_MSG) @@ -925,6 +924,7 @@ struct control_event_t { }; static const struct control_event_t control_event_table[] = { { EVENT_CIRCUIT_STATUS, "CIRC" }, + { EVENT_CIRCUIT_STATUS_2, "CIRC2" }, { EVENT_STREAM_STATUS, "STREAM" }, { EVENT_OR_CONN_STATUS, "ORCONN" }, { EVENT_BANDWIDTH_USED, "BW" }, @@ -3308,8 +3308,8 @@ connection_control_process_inbuf(control_connection_t *conn) goto again; }
-/** Something has happened to circuit <b>circ</b>: tell any interested - * control connections. */ +/** Something major 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 reason_code) @@ -3329,6 +3329,7 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, case CIRC_EVENT_CLOSED: status = "CLOSED"; break; default: log_warn(LD_BUG, "Unrecognized status code %d", (int)tp); + tor_fragile_assert(); return 0; }
@@ -3363,6 +3364,59 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, return 0; }
+/** Something minor has happened to circuit <b>circ</b>: tell any + * interested control connections. */ +int +control_event_circuit_status_2(origin_circuit_t *circ, + circuit_status_2_event_t e, + int arg1, const void *arg2) +{ + const char *event_desc; + char event_tail[96] = ""; + if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS_2)) + return 0; + tor_assert(circ); + + (void)arg2; /* currently unused */ + + switch (e) + { + case CIRC2_EVENT_PURPOSE_CHANGED: + /* arg1 is the previous purpose of the circuit. */ + event_desc = "PURPOSE_CHANGED"; + + { + const char *hs_state_str = + circuit_purpose_to_controller_hs_state_string(arg1); + tor_snprintf(event_tail, sizeof(event_tail), + " OLD_PURPOSE=%s%s%s", + circuit_purpose_to_controller_string(arg1), + (hs_state_str != NULL) ? " OLD_HS_STATE=" : "", + (hs_state_str != NULL) ? hs_state_str : ""); + } + + break; + default: + log_warn(LD_BUG, "Unrecognized status code %d", (int)e); + tor_fragile_assert(); + return 0; + } + + { + char *circdesc = circuit_describe_status_for_controller(circ); + const char *sp = strlen(circdesc) ? " " : ""; + send_control_event(EVENT_CIRCUIT_STATUS_2, ALL_FORMATS, + "650 CIRC2 %lu %s%s%s%s\r\n", + (unsigned long)circ->global_identifier, + event_desc, sp, + circdesc, + event_tail); + tor_free(circdesc); + } + + return 0; +} + /** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer * <b>buf</b>, determine the address:port combination requested on * <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on diff --git a/src/or/control.h b/src/or/control.h index 0d9acd2..e5d136b 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -37,6 +37,9 @@ int control_event_is_interesting(int event);
int control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t e, int reason); +int control_event_circuit_status_2(origin_circuit_t *circ, + circuit_status_2_event_t e, + int arg1, const void *arg2); int control_event_stream_status(entry_connection_t *conn, stream_status_event_t e, int reason); diff --git a/src/or/or.h b/src/or/or.h index 67ba62b..85d812a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3751,6 +3751,12 @@ typedef enum circuit_status_event_t { CIRC_EVENT_CLOSED = 4, } circuit_status_event_t;
+/** Used to indicate the type of a CIRC2 event passed to the controller. + * The various types are defined in control-spec.txt . */ +typedef enum circuit_status_2_event_t { + CIRC2_EVENT_PURPOSE_CHANGED = 0, +} circuit_status_2_event_t; + /** Used to indicate the type of a stream event passed to the controller. * The various types are defined in control-spec.txt */ typedef enum stream_status_event_t {
tor-commits@lists.torproject.org