diff --git a/changes/bug1297a b/changes/bug1297a new file mode 100644 index 0000000000..459ef6534d --- /dev/null +++ b/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. + diff --git a/src/or/or.h b/src/or/or.h index 9cac5f3548..6ccd95727c 100644 --- a/src/or/or.h +++ b/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; diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 77e11c2a07..a5423394f7 100644 --- a/src/or/rendclient.c +++ b/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. */