[tor-commits] [tor/master] Log whenever a circuit's purpose is changed

nickm at torproject.org nickm at torproject.org
Wed Jan 11 17:10:18 UTC 2012


commit 104c50fedb1b9217fbb2a8cc5fcf9ec9c9be2674
Author: Robert Ransom <rransom.8774 at gmail.com>
Date:   Thu Nov 24 06:52:38 2011 -0800

    Log whenever a circuit's purpose is changed
---
 changes/feature3457  |    5 +++++
 src/or/circuituse.c  |   33 +++++++++++++++++++++++++++++++--
 src/or/circuituse.h  |    2 ++
 src/or/control.c     |    2 +-
 src/or/rendclient.c  |   15 +++++++++------
 src/or/rendmid.c     |   10 ++++++----
 src/or/rendservice.c |    6 +++---
 7 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/changes/feature3457 b/changes/feature3457
new file mode 100644
index 0000000..b06f959
--- /dev/null
+++ b/changes/feature3457
@@ -0,0 +1,5 @@
+  o Minor features:
+
+    - Log (at debug level) whenever a circuit's purpose is changed.
+
+
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 23efe05..46c0b8a 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -467,7 +467,7 @@ circuit_expire_building(void)
           control_event_circuit_status(TO_ORIGIN_CIRCUIT(victim),
                                        CIRC_EVENT_FAILED,
                                        END_CIRC_REASON_TIMEOUT);
-          victim->purpose = CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT;
+          circuit_change_purpose(victim, CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
           /* Record this failure to check for too many timeouts
            * in a row. This function does not record a time value yet
            * (we do that later); it only counts the fact that we did
@@ -1218,7 +1218,7 @@ circuit_launch_by_extend_info(uint8_t purpose,
       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));
-      circ->_base.purpose = 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. */
@@ -1925,3 +1925,32 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
   }
 }
 
+/** Change <b>circ</b>'s purpose to <b>new_purpose</b>. */
+void
+circuit_change_purpose(circuit_t *circ, uint8_t new_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)));
+
+  if (circ->purpose == new_purpose) return;
+
+  if (CIRCUIT_IS_ORIGIN(circ)) {
+    char old_purpose[80] = "";
+
+    strncpy(old_purpose, circuit_purpose_to_string(circ->purpose), 80-1);
+    old_purpose[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,
+              circ->purpose,
+              circuit_purpose_to_string(new_purpose),
+              new_purpose);
+  }
+
+  circ->purpose = new_purpose;
+}
+
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 9867fd8..ac67f43 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -50,6 +50,8 @@ int connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn,
                                                   crypt_path_t *cpath);
 int connection_ap_handshake_attach_circuit(entry_connection_t *conn);
 
+void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose);
+
 int hostname_in_track_host_exits(const or_options_t *options,
                                  const char *address);
 
diff --git a/src/or/control.c b/src/or/control.c
index 42eaed2..b3609d1 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -2550,7 +2550,7 @@ handle_control_setcircuitpurpose(control_connection_t *conn,
     }
   }
 
-  circ->_base.purpose = new_purpose;
+  circuit_change_purpose(TO_CIRCUIT(circ), new_purpose);
   connection_write_str_to_buf("250 OK\r\n", conn);
 
  done:
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 6a45207..dfb52d4 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -284,7 +284,8 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
   }
 
   /* Now, we wait for an ACK or NAK on this circuit. */
-  introcirc->_base.purpose = CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT;
+  circuit_change_purpose(TO_CIRCUIT(introcirc),
+                         CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
   /* Set timestamp_dirty, because circuit_expire_building expects it
    * to specify when a circuit entered the _C_INTRODUCE_ACK_WAIT
    * state. */
@@ -344,7 +345,8 @@ rend_client_introduction_acked(origin_circuit_t *circ,
                circ->rend_data->onion_address, CIRCUIT_PURPOSE_C_REND_READY);
     if (rendcirc) { /* remember the ack */
       tor_assert(!(rendcirc->build_state->onehop_tunnel));
-      rendcirc->_base.purpose = CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED;
+      circuit_change_purpose(TO_CIRCUIT(rendcirc),
+                             CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED);
       /* Set timestamp_dirty, because circuit_expire_building expects
        * it to specify when a circuit entered the
        * _C_REND_READY_INTRO_ACKED state. */
@@ -353,11 +355,12 @@ rend_client_introduction_acked(origin_circuit_t *circ,
       log_info(LD_REND,"...Found no rend circ. Dropping on the floor.");
     }
     /* close the circuit: we won't need it anymore. */
-    circ->_base.purpose = CIRCUIT_PURPOSE_C_INTRODUCE_ACKED;
+    circuit_change_purpose(TO_CIRCUIT(circ),
+                           CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
     circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
   } else {
     /* It's a NAK; the introduction point didn't relay our request. */
-    circ->_base.purpose = CIRCUIT_PURPOSE_C_INTRODUCING;
+    circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_INTRODUCING);
     /* Remove this intro point from the set of viable introduction
      * points. If any remain, extend to a new one and try again.
      * If none remain, refetch the service descriptor.
@@ -810,7 +813,7 @@ rend_client_rendezvous_acked(origin_circuit_t *circ, const uint8_t *request,
   }
   log_info(LD_REND,"Got rendezvous ack. This circuit is now ready for "
            "rendezvous.");
-  circ->_base.purpose = CIRCUIT_PURPOSE_C_REND_READY;
+  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_REND_READY);
   /* Set timestamp_dirty, because circuit_expire_building expects it
    * to specify when a circuit entered the _C_REND_READY state. */
   circ->_base.timestamp_dirty = time(NULL);
@@ -874,7 +877,7 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
   hop->dh_handshake_state = NULL;
 
   /* All is well. Extend the circuit. */
-  circ->_base.purpose = CIRCUIT_PURPOSE_C_REND_JOINED;
+  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_REND_JOINED);
   hop->state = CPATH_STATE_OPEN;
   /* set the windows to default. these are the windows
    * that alice thinks bob has.
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 04edd8e..d740980 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -9,6 +9,7 @@
 
 #include "or.h"
 #include "circuitlist.h"
+#include "circuituse.h"
 #include "config.h"
 #include "relay.h"
 #include "rendmid.h"
@@ -109,7 +110,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
   }
 
   /* Now, set up this circuit. */
-  circ->_base.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
+  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_INTRO_POINT);
   memcpy(circ->rend_token, pk_digest, DIGEST_LEN);
 
   log_info(LD_REND,
@@ -249,7 +250,7 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
     goto err;
   }
 
-  circ->_base.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
+  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_REND_POINT_WAITING);
   memcpy(circ->rend_token, request, REND_COOKIE_LEN);
 
   base16_encode(hexid,9,(char*)request,4);
@@ -324,8 +325,9 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
            "Completing rendezvous: circuit %d joins circuit %d (cookie %s)",
            circ->p_circ_id, rend_circ->p_circ_id, hexid);
 
-  circ->_base.purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED;
-  rend_circ->_base.purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED;
+  circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_REND_ESTABLISHED);
+  circuit_change_purpose(TO_CIRCUIT(rend_circ),
+                         CIRCUIT_PURPOSE_REND_ESTABLISHED);
   memset(circ->rend_token, 0, REND_COOKIE_LEN);
 
   rend_circ->rend_splice = circ;
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index e0c1a8c..9297f17 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1428,7 +1428,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
                "circuit, but we already have enough. Redefining purpose to "
                "general; leaving as internal.");
 
-      TO_CIRCUIT(circuit)->purpose = CIRCUIT_PURPOSE_C_GENERAL;
+      circuit_change_purpose(TO_CIRCUIT(circuit), CIRCUIT_PURPOSE_C_GENERAL);
 
       {
         rend_data_t *rend_data = circuit->rend_data;
@@ -1520,7 +1520,7 @@ rend_service_intro_established(origin_circuit_t *circuit,
     goto err;
   }
   service->desc_is_dirty = time(NULL);
-  circuit->_base.purpose = CIRCUIT_PURPOSE_S_INTRO;
+  circuit_change_purpose(TO_CIRCUIT(circuit), CIRCUIT_PURPOSE_S_INTRO);
 
   base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32 + 1,
                 circuit->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN);
@@ -1609,7 +1609,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
   circuit->build_state->pending_final_cpath = NULL; /* prevent double-free */
 
   /* Change the circuit purpose. */
-  circuit->_base.purpose = CIRCUIT_PURPOSE_S_REND_JOINED;
+  circuit_change_purpose(TO_CIRCUIT(circuit), CIRCUIT_PURPOSE_S_REND_JOINED);
 
   return;
  err:





More information about the tor-commits mailing list