Browse Source

Send CIRC2 event when a circuit is cannibalized

Robert Ransom 13 years ago
parent
commit
88e0026d2f
4 changed files with 34 additions and 4 deletions
  1. 2 1
      changes/feature3457
  2. 9 0
      src/or/circuituse.c
  3. 22 3
      src/or/control.c
  4. 1 0
      src/or/or.h

+ 2 - 1
changes/feature3457

@@ -3,6 +3,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.
+      circuit is cannibalized or its purpose is changed.  Implements
+      part of ticket 3457.
 
 

+ 9 - 0
src/or/circuituse.c

@@ -1215,14 +1215,23 @@ circuit_launch_by_extend_info(uint8_t purpose,
      * internal circs rather than exit circs? -RD */
     circ = circuit_find_to_cannibalize(purpose, extend_info, flags);
     if (circ) {
+      uint8_t old_purpose = circ->_base.purpose;
+      struct timeval old_timestamp_created;
+
       log_info(LD_CIRC,"Cannibalizing circ '%s' for purpose %d (%s)",
                build_state_get_exit_nickname(circ->build_state), purpose,
                circuit_purpose_to_string(purpose));
+
       circuit_change_purpose(TO_CIRCUIT(circ), purpose);
       /* reset the birth date of this circ, else expire_building
        * will see it and think it's been trying to build since it
        * began. */
       tor_gettimeofday(&circ->_base.timestamp_created);
+
+      control_event_circuit_status_2(circ, CIRC2_EVENT_CANNIBALIZED,
+                                     (int)old_purpose,
+                                     &old_timestamp_created);
+
       switch (purpose) {
         case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
         case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:

+ 22 - 3
src/or/control.c

@@ -3372,13 +3372,11 @@ control_event_circuit_status_2(origin_circuit_t *circ,
                                int arg1, const void *arg2)
 {
   const char *event_desc;
-  char event_tail[96] = "";
+  char event_tail[160] = "";
   if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS_2))
     return 0;
   tor_assert(circ);
 
-  (void)arg2; /* currently unused */
-
   switch (e)
     {
     case CIRC2_EVENT_PURPOSE_CHANGED:
@@ -3386,6 +3384,7 @@ control_event_circuit_status_2(origin_circuit_t *circ,
       event_desc = "PURPOSE_CHANGED";
 
       {
+        /* event_tail can currently be up to 68 chars long */
         const char *hs_state_str =
           circuit_purpose_to_controller_hs_state_string(arg1);
         tor_snprintf(event_tail, sizeof(event_tail),
@@ -3395,6 +3394,26 @@ control_event_circuit_status_2(origin_circuit_t *circ,
                      (hs_state_str != NULL) ? hs_state_str : "");
       }
 
+      break;
+    case CIRC2_EVENT_CANNIBALIZED:
+      /* arg1 is the previous purpose of the circuit. */
+      event_desc = "CANNIBALIZED";
+
+      {
+        /* event_tail can currently be up to 130 chars long */
+        const char *hs_state_str =
+          circuit_purpose_to_controller_hs_state_string(arg1);
+        const struct timeval *old_timestamp_created = arg2;
+
+        tor_snprintf(event_tail, sizeof(event_tail),
+                     " OLD_PURPOSE=%s%s%s OLD_TIME_CREATED=%ld,%ld",
+                     circuit_purpose_to_controller_string(arg1),
+                     (hs_state_str != NULL) ? " OLD_HS_STATE=" : "",
+                     (hs_state_str != NULL) ? hs_state_str : "",
+                     old_timestamp_created->tv_sec,
+                     old_timestamp_created->tv_usec);
+      }
+
       break;
     default:
       log_warn(LD_BUG, "Unrecognized status code %d", (int)e);

+ 1 - 0
src/or/or.h

@@ -3755,6 +3755,7 @@ typedef enum circuit_status_event_t {
  * The various types are defined in control-spec.txt . */
 typedef enum circuit_status_2_event_t {
   CIRC2_EVENT_PURPOSE_CHANGED           = 0,
+  CIRC2_EVENT_CANNIBALIZED              = 1,
 } circuit_status_2_event_t;
 
 /** Used to indicate the type of a stream event passed to the controller.