Cannibalized HS circuit don't have their timestamp_dirty updated
Today, I encountered this behavior on a prop224 client when connecting to a service:
Aug 06 15:21:06.000 [info] connection_ap_handshake_attach_circuit(): pending-join circ 3551616045 already here, with intro ack. Stalling. (stream 2 sec old)
Aug 06 15:21:07.000 [info] circuit_expire_building(): Marking circ 3551616045 (state 4:open, purpose 11) as timed-out HS circ;
So my client was able to establish a rendezvous point but then just before being attached to a stream and ready to be used, it expires...
That specific circuit has been cannibalized and in circuit_launch_by_extend_info()
, a RP circuit calls circuit_extend_to_new_exit()
to extend to it which does not update the timestamp_dirty
and has this comment:
// XXX: Should cannibalized circuits be dirty or not? Not easy to say..
Sooooooo ultimately, down the rabbit hole, the circuit_expire_building()
function checks the timestamp_dirty
and has that comment:
/* rend and intro circs become dirty each time they
* make an introduction attempt. so timestamp_dirty
* will reflect the time since the last attempt.
... but that is true only if timestamp_dirty == 0
which is not true if the circuit was cannibalized.
In rend_service_rendezvous_has_opened()
, we have this:
if (!circuit->base_.timestamp_dirty)
circuit->base_.timestamp_dirty = time(NULL);
Ok, seems the solution is just to set the timestamp_dirty
every time when the RP/IP opens or we flag the circuit that it has been cannibalized and we can update the timestamp accordingly?
Btw, this affects legacy system as well.