tor-proto: We sometimes send 2 END cells for the same circuit
tor_proto::circuit::test::accept_stream_after_reject sometimes fails with (it is quite hard to repro):
thread 'tokio-runtime-worker' panicked at 'Hang on! We're sending an END on a stream where we already sent an END‽', crates/tor-proto/src/circuit/streammap.rs:
246:17
thread 'circuit::test::accept_stream_after_reject' panicked at 'called `Option::unwrap()` on a `None` value', crates/tor-proto/src/circuit.rs:1992:60
This test uses IncomingStream::reject(end)
, which sends a ClosePendingStream
control message to the reactor telling it to send an END message on a stream. The reactor also has a mechanism where it implicitly sends an END cell when the stream is dropped. If the stream is dropped, you can no longer call reject()
on it, so the reactor will only send one END cell. However, if you call reject()
and later drop the stream, and the reactor doesn't process the ClosePendingStream
message in time, it is possible for the reactor to get confused and send 2 END cells for the same stream:
-
stream.reject(end);
is called -
stream
is dropped - the reactor notices
stream
was dropped (we have aStreamEnt::Open { rx, ... }
and we recv'dNone
fromrx
). The reactor sends an END cell to the other party - in the next
run_once()
execution, the reactor notices theClosePendingStream
message, and panics because it realizes it has already sent an END cell for the circuit!
Edited by gabi-250