1
//! Tor stream handling.
2
//!
3
//! A stream is an anonymized conversation; multiple streams can be
4
//! multiplexed over a single circuit.
5

            
6
pub(crate) mod cmdcheck;
7
pub(crate) mod flow_ctrl;
8
pub(crate) mod raw;
9

            
10
#[cfg(any(feature = "hs-service", feature = "relay"))]
11
pub(crate) mod incoming;
12

            
13
pub(crate) mod queue;
14

            
15
use futures::SinkExt as _;
16
use oneshot_fused_workaround as oneshot;
17
use postage::watch;
18
use safelog::sensitive;
19

            
20
use tor_async_utils::SinkCloseChannel as _;
21
use tor_cell::relaycell::flow_ctrl::XonKBpsEwma;
22
use tor_cell::relaycell::msg::{AnyRelayMsg, End, Resolved};
23
use tor_cell::relaycell::{RelayCellFormat, StreamId, UnparsedRelayMsg};
24
use tor_memquota::mq_queue::{self, MpscSpec};
25

            
26
use flow_ctrl::state::StreamRateLimit;
27

            
28
use crate::memquota::StreamAccount;
29
use crate::stream::flow_ctrl::xon_xoff::reader::XonXoffReaderCtrl;
30
use crate::{ClientTunnel, Error, HopLocation, Result};
31

            
32
#[cfg(any(feature = "hs-service", feature = "relay"))]
33
pub use incoming::{
34
    IncomingStream, IncomingStreamRequest, IncomingStreamRequestContext,
35
    IncomingStreamRequestDisposition, IncomingStreamRequestFilter,
36
};
37

            
38
pub use raw::StreamReceiver;
39

            
40
#[cfg_attr(docsrs, doc(cfg(any(feature = "hs-service", feature = "relay"))))]
41
#[cfg(any(feature = "hs-service", feature = "relay"))]
42
pub(crate) use incoming::{InboundDataCmdChecker, IncomingCmdChecker, StreamReqInfo};
43

            
44
use std::pin::Pin;
45
use std::sync::Arc;
46

            
47
/// Initial value for outbound flow-control window on streams.
48
pub(crate) const SEND_WINDOW_INIT: u16 = 500;
49
/// Initial value for inbound flow-control window on streams.
50
pub(crate) const RECV_WINDOW_INIT: u16 = 500;
51

            
52
/// Size of the buffer used between the reactor and a `StreamReader`.
53
///
54
/// FIXME(eta): We pick 2× the receive window, which is very conservative (we arguably shouldn't
55
///             get sent more than the receive window anyway!). We might do due to things that
56
///             don't count towards the window though.
57
pub(crate) const STREAM_READER_BUFFER: usize = (2 * RECV_WINDOW_INIT) as usize;
58

            
59
/// MPSC queue relating to a stream (either inbound or outbound), sender
60
pub(crate) type StreamMpscSender<T> = mq_queue::Sender<T, MpscSpec>;
61
/// MPSC queue relating to a stream (either inbound or outbound), receiver
62
pub(crate) type StreamMpscReceiver<T> = mq_queue::Receiver<T, MpscSpec>;
63

            
64
/// A behavior to perform when closing a stream.
65
///
66
/// We don't use `Option<End>` here, since the behavior of `SendNothing` is so surprising
67
/// that we shouldn't let it pass unremarked.
68
#[allow(clippy::enum_variant_names)]
69
#[derive(Clone, Debug)]
70
pub(crate) enum CloseStreamBehavior {
71
    /// Send nothing at all, so that the other side will not realize we have
72
    /// closed the stream.
73
    ///
74
    /// We should only do this for incoming onion service streams when we
75
    /// want to black-hole the client's requests.
76
    SendNothing,
77
    /// Send an End cell, if we haven't already sent one.
78
    SendEnd(End),
79
    /// Send a Resolved cell, if we haven't already sent one.
80
    SendResolved(Resolved),
81
}
82

            
83
impl Default for CloseStreamBehavior {
84
62
    fn default() -> Self {
85
62
        Self::SendEnd(End::new_misc())
86
62
    }
87
}
88

            
89
/// A collection of components that can be combined to implement a Tor stream,
90
/// or anything that requires a stream ID.
91
///
92
/// Not all components may be needed, depending on the purpose of the "stream".
93
/// For example we build `RELAY_RESOLVE` requests like we do data streams,
94
/// but they won't use the `StreamTarget` as they don't need to send additional
95
/// messages.
96
#[derive(Debug)]
97
pub(crate) struct StreamComponents {
98
    /// A [`Stream`](futures::Stream) of incoming relay messages for this Tor stream.
99
    pub(crate) stream_receiver: StreamReceiver,
100
    /// A handle that can communicate messages to the circuit reactor for this stream.
101
    pub(crate) target: StreamTarget,
102
    /// The memquota [account](tor_memquota::Account) to use for data on this stream.
103
    pub(crate) memquota: StreamAccount,
104
    /// The control information needed to add XON/XOFF flow control to the stream.
105
    pub(crate) xon_xoff_reader_ctrl: XonXoffReaderCtrl,
106
}
107

            
108
/// Internal handle, used to implement a stream on a particular tunnel.
109
///
110
/// The reader and the writer for a stream should hold a `StreamTarget` for the stream;
111
/// the reader should additionally hold an `mpsc::Receiver` to get
112
/// relay messages for the stream.
113
///
114
/// When all the `StreamTarget`s for a stream are dropped, the Reactor will
115
/// close the stream by sending an END message to the other side.
116
/// You can close a stream earlier by using [`StreamTarget::close`]
117
/// or [`StreamTarget::close_pending`].
118
#[derive(Clone, Debug)]
119
pub(crate) struct StreamTarget {
120
    /// Which hop of the circuit this stream is with.
121
    pub(crate) hop: Option<HopLocation>,
122
    /// Reactor ID for this stream.
123
    pub(crate) stream_id: StreamId,
124
    /// Encoding to use for relay cells sent on this stream.
125
    ///
126
    /// This is mostly irrelevant, except when deciding
127
    /// how many bytes we can pack in a DATA message.
128
    pub(crate) relay_cell_format: RelayCellFormat,
129
    /// A [`Stream`](futures::Stream) that provides updates to the rate limit for sending data.
130
    // TODO(arti#2068): we should consider making this an `Option`
131
    pub(crate) rate_limit_stream: watch::Receiver<StreamRateLimit>,
132
    /// Channel to send cells down.
133
    pub(crate) tx: StreamMpscSender<AnyRelayMsg>,
134
    /// Reference to the tunnel that this stream is on.
135
    pub(crate) tunnel: Tunnel,
136
}
137

            
138
/// A client or relay tunnel.
139
#[derive(Debug, Clone, derive_more::From)]
140
pub(crate) enum Tunnel {
141
    /// A client tunnel.
142
    Client(Arc<ClientTunnel>),
143
    /// A relay tunnel.
144
    #[cfg(feature = "relay")]
145
    Relay(Arc<crate::relay::RelayCirc>),
146
}
147

            
148
impl StreamTarget {
149
    /// Deliver a relay message for the stream that owns this StreamTarget.
150
    ///
151
    /// The StreamTarget will set the correct stream ID and pick the
152
    /// right hop, but will not validate that the message is well-formed
153
    /// or meaningful in context.
154
6498
    pub(crate) async fn send(&mut self, msg: AnyRelayMsg) -> Result<()> {
155
4332
        self.tx.send(msg).await.map_err(|_| Error::CircuitClosed)?;
156
4332
        Ok(())
157
4332
    }
158

            
159
    /// Close the pending stream that owns this StreamTarget, delivering the specified
160
    /// END message (if any)
161
    ///
162
    /// The stream is closed by sending a control message (`CtrlMsg::ClosePendingStream`)
163
    /// to the reactor.
164
    ///
165
    /// Returns a [`oneshot::Receiver`] that can be used to await the reactor's response.
166
    ///
167
    /// The StreamTarget will set the correct stream ID and pick the
168
    /// right hop, but will not validate that the message is well-formed
169
    /// or meaningful in context.
170
    ///
171
    /// Note that in many cases, the actual contents of an END message can leak unwanted
172
    /// information. Please consider carefully before sending anything but an
173
    /// [`End::new_misc()`](tor_cell::relaycell::msg::End::new_misc) message over a `ClientTunnel`.
174
    /// (For onion services, we send [`DONE`](tor_cell::relaycell::msg::EndReason::DONE) )
175
    ///
176
    /// In addition to sending the END message, this function also ensures
177
    /// the state of the stream map entry of this stream is updated
178
    /// accordingly.
179
    ///
180
    /// Normally, you shouldn't need to call this function, as streams are implicitly closed by the
181
    /// reactor when their corresponding `StreamTarget` is dropped. The only valid use of this
182
    /// function is for closing pending incoming streams (a stream is said to be pending if we have
183
    /// received the message initiating the stream but have not responded to it yet).
184
    ///
185
    /// **NOTE**: This function should be called at most once per request.
186
    /// Calling it twice is an error.
187
    #[cfg(any(feature = "hs-service", feature = "relay"))]
188
20
    pub(crate) fn close_pending(
189
20
        &self,
190
20
        message: crate::stream::CloseStreamBehavior,
191
20
    ) -> Result<oneshot::Receiver<Result<()>>> {
192
20
        match &self.tunnel {
193
12
            Tunnel::Client(t) => {
194
                cfg_if::cfg_if! {
195
                    if #[cfg(feature = "hs-service")] {
196
12
                        t.close_pending(self.stream_id, self.hop, message)
197
                    } else {
198
                        Err(tor_error::internal!("close_pending() called on client stream?!").into())
199
                    }
200
                }
201
            }
202
            #[cfg(feature = "relay")]
203
8
            Tunnel::Relay(t) => t.close_pending(self.stream_id, message),
204
        }
205
20
    }
206

            
207
    /// Queue a "close" for the stream corresponding to this StreamTarget.
208
    ///
209
    /// Unlike `close_pending`, this method does not allow the caller to provide an `END` message.
210
    ///
211
    /// Once this method has been called, no more messages may be sent with [`StreamTarget::send`],
212
    /// on this `StreamTarget`` or any clone of it.
213
    /// The reactor *will* try to flush any already-send messages before it closes the stream.
214
    ///
215
    /// You don't need to call this method if the stream is closing because all of its StreamTargets
216
    /// have been dropped.
217
16
    pub(crate) fn close(&mut self) {
218
16
        Pin::new(&mut self.tx).close_channel();
219
16
    }
220

            
221
    /// Called when a circuit-level protocol error has occurred and the
222
    /// tunnel needs to shut down.
223
    pub(crate) fn protocol_error(&mut self) {
224
        match &self.tunnel {
225
            Tunnel::Client(t) => t.terminate(),
226
            #[cfg(feature = "relay")]
227
            Tunnel::Relay(t) => t.terminate(),
228
        }
229
    }
230

            
231
    /// Request to send a SENDME cell for this stream.
232
    ///
233
    /// This sends a request to the circuit reactor to send a stream-level SENDME, but it does not
234
    /// block or wait for a response from the circuit reactor.
235
    /// An error is only returned if we are unable to send the request.
236
    /// This means that if the circuit reactor is unable to send the SENDME, we are not notified of
237
    /// this here and an error will not be returned.
238
    pub(crate) fn send_sendme(&mut self) -> Result<()> {
239
        match &self.tunnel {
240
            Tunnel::Client(t) => t.send_sendme(self.stream_id, self.hop),
241
            #[cfg(feature = "relay")]
242
            Tunnel::Relay(t) => t.send_sendme(self.stream_id),
243
        }
244
    }
245

            
246
    /// Inform the circuit reactor that there has been a change in the drain rate for this stream.
247
    ///
248
    /// Typically the circuit reactor would send this new rate in an XON message to the other end of
249
    /// the stream.
250
    /// But it may decide not to, and may discard this update.
251
    /// For example the stream may have a large amount of buffered data, and the reactor may not
252
    /// want to send an XON while the buffer is large.
253
    ///
254
    /// This sends a message to inform the circuit reactor of the new drain rate,
255
    /// but it does not block or wait for a response from the reactor.
256
    /// An error is only returned if we are unable to send the update.
257
    pub(crate) fn drain_rate_update(&mut self, rate: XonKBpsEwma) -> Result<()> {
258
        match &mut self.tunnel {
259
            Tunnel::Client(t) => t.drain_rate_update(self.stream_id, self.hop, rate),
260
            #[cfg(feature = "relay")]
261
            Tunnel::Relay(t) => t.drain_rate_update(self.stream_id, rate),
262
        }
263
    }
264

            
265
    /// Return a reference to the tunnel that this `StreamTarget` is using.
266
    #[cfg(any(feature = "experimental-api", feature = "stream-ctrl"))]
267
124
    pub(crate) fn tunnel(&self) -> &Tunnel {
268
124
        &self.tunnel
269
124
    }
270

            
271
    /// Return the kind of relay cell in use on this `StreamTarget`.
272
124
    pub(crate) fn relay_cell_format(&self) -> RelayCellFormat {
273
124
        self.relay_cell_format
274
124
    }
275

            
276
    /// A [`Stream`](futures::Stream) that provides updates to the rate limit for sending data.
277
124
    pub(crate) fn rate_limit_stream(&self) -> &watch::Receiver<StreamRateLimit> {
278
124
        &self.rate_limit_stream
279
124
    }
280
}
281

            
282
/// Return the stream ID of `msg`, if it has one.
283
///
284
/// Returns `Ok(None)` if `msg` is a meta cell.
285
556
pub(crate) fn msg_streamid(msg: &UnparsedRelayMsg) -> Result<Option<StreamId>> {
286
556
    let cmd = msg.cmd();
287
556
    let streamid = msg.stream_id();
288
556
    if !cmd.accepts_streamid_val(streamid) {
289
4
        return Err(Error::CircProto(format!(
290
4
            "Invalid stream ID {} for relay command {}",
291
4
            sensitive(StreamId::get_or_zero(streamid)),
292
4
            msg.cmd()
293
4
        )));
294
552
    }
295

            
296
552
    Ok(streamid)
297
556
}