Propagating the error means will cause the reactor to shut down (there's
not much the control message sender can do about it, so there's no point
in sending it the error).
As a result, by the time the `reject` future resolves, the stream has
been removed from the reactor's stream map and the corresponding END
cell has been sent.
Fixes#998.
`ClientCirc::allow_stream_requests` is now `async` and waits until the
`AwaitIncomingStream` control message is processed by the reactor.
This guarantees that by the time the `allow_stream_requests` future
resolves, the reactor is ready to process BEGIN/BEGIN_DIR/RESOLVE cells.
Previously, the client tasks from allow_stream_requests tests had to
sleep before sending the BEGIN cell to give the reactor time to process
the `AwaitIncomingStream` control message (which tells the reactor to
expect incoming BEGIN/BEGIN_DIR/RESOLVE cells on the circuit).
Fixes#994
The implementation here is perhaps excessively simple: we put
a `oneshot::Sender` in the `Reactor` object, and a
`Shared<oneshot::Receiver>` in the circuit or channel. When
the reactor is dropped, any copy of the `Shared<Receiver>` will
yield `Err(Cancelled)`.
I'm marking these methods as experimental because I'm not sure I've
thought of all the implications here, and we might want to change
things around.
Down the road, these methods might want to yield a `Result<>`
indicating why the reactor was shut down.
This feature was inspired by a request from Saksham Mittal, and a
felt need while working on !1472.
This will enable hidden services to send `RENDEZVOUS1` messages to the
`N`th hop of the circuit rather than the `N + 1`th virtual one (which
can only used after the client and service have completed the
introduction handshake).
This also deprecates `start_conversation_last_hop`.
Closes#959
`HopNum` will be used in `ClientCirc`'s public API when we refactor
`ClientCirc::start_conversation_last_hop` to use the provided hop rather
than always using the last one.
This `sleep` is to give the reactor task a chance to process the
`AwaitIncomingStream` message. With an 100ms, this test sometimes fails
because for some reason the reactor doesn't get a chance to process the
`AwaitIncomingStream` control command before the BEGIN cell from the
client task is received. This bumps the sleep time to 200ms for now
(TODO: follow-up with an MR with a less flaky approach).
While trying to repro the issue, I found another corner case for which
I've added a TODO HSS.
This updates the reactor to call the incoming stream handler even for
streams for which we have a stream map entry of `EndSent`. If we've
sent an END message for a stream but have not yet received an END
message back from the other party, but we later receive a BEGIN from
them, it is safe to assume we cam remove the stream from the stream map
and handle the new incoming stream request.
This adds a new `AwaitIncomingStream` control message for registering an
interest in an incoming stream.
This also adds a `ClosePendingStream` control message for explicitly
closing a stream with a given END message (needed for implementing
`IncomingStream::reject`).
This adds a new `add_ent_with_id` function for adding a new entry to the
`StreamMap`. The existing `add_ent` function auto-generates a new stream
ID, which is not good if we're a hidden service, as stream IDs are
supposed to be chosen by the OP (client). When accepting a new stream,
services, exit relays, and dir auths need to use the stream ID received
in the BEGIN cell (instead of generating a new stream ID).
When accepting a new stream, hidden services, exit relays and dirauths
don't wait for a `CONNECTED` cell from the initiator.
This commit adds constructors for building `DataStream`s and
`DataCmdChecker`s that can immediately receive data cells (and don't
expect to receive `CONNECTED` cells at all).
The build found a stale private doc comment as well as an exception
that needed to be made in check_doc_features.
The check_doc_features change solidifies a decision that things marked
with cfg(fuzzing) aren't part of the documented API.