Browse Source

Set timestamp_dirty on HS circuits as circuit_expire_building requires

Fixes part of #1297; bugfix on 48e0228f1e031a709c1deb149c7dfd187c3609cf,
when circuit_expire_building was changed to assume that timestamp_dirty
was set when a circuit changed purpose to _C_REND_READY.  (It wasn't.)
Robert Ransom 13 years ago
parent
commit
112d204fad
3 changed files with 24 additions and 0 deletions
  1. 8 0
      changes/bug1297a
  2. 5 0
      src/or/or.h
  3. 11 0
      src/or/rendclient.c

+ 8 - 0
changes/bug1297a

@@ -0,0 +1,8 @@
+  o Major bugfixes:
+    - Apply circuit timeouts to opened hidden-service-related circuits
+      based on the correct start time.  Previously, we would apply the
+      circuit build timeout based on time since the circuit's
+      creation; it was supposed to be applied based on time since the
+      circuit entered its current state.  Bugfix on 0.0.6; fixes part
+      of bug 1297.
+

+ 5 - 0
src/or/or.h

@@ -2143,6 +2143,11 @@ typedef struct circuit_t {
    * in time in order to indicate that a circuit shouldn't be used for new
    * streams, but that it can stay alive as long as it has streams on it.
    * That's a kludge we should fix.
+   *
+   * XXX023 The CBT code uses this field to record when HS-related
+   * circuits entered certain states.  This usage probably won't
+   * interfere with this field's primary purpose, but we should
+   * document it more thoroughly to make sure of that.
    */
   time_t timestamp_dirty;
 

+ 11 - 0
src/or/rendclient.c

@@ -275,6 +275,10 @@ 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;
+  /* Set timestamp_dirty, because circuit_expire_building expects it
+   * to specify when a circuit entered the _C_INTRODUCE_ACK_WAIT
+   * state. */
+  introcirc->_base.timestamp_dirty = time(NULL);
 
   return 0;
  perm_err:
@@ -329,6 +333,10 @@ rend_client_introduction_acked(origin_circuit_t *circ,
                circ->rend_data->onion_address, CIRCUIT_PURPOSE_C_REND_READY);
     if (rendcirc) { /* remember the ack */
       rendcirc->_base.purpose = 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. */
+      rendcirc->_base.timestamp_dirty = time(NULL);
     } else {
       log_info(LD_REND,"...Found no rend circ. Dropping on the floor.");
     }
@@ -674,6 +682,9 @@ 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;
+  /* 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);
   /* XXXX023 This is a pretty brute-force approach. It'd be better to
    * attach only the connections that are waiting on this circuit, rather
    * than trying to attach them all. See comments bug 743. */