1
//! Handler for CREATE* cells.
2

            
3
use crate::FlowCtrlParameters;
4
use crate::ccparams::{
5
    Algorithm, AlgorithmDiscriminants, CongestionControlParams, CongestionWindowParams,
6
    FixedWindowParams, RoundTripEstimatorParams, VegasParams,
7
};
8
use crate::channel::Channel;
9
use crate::circuit::CircuitRxSender;
10
use crate::circuit::UniqId;
11
use crate::circuit::celltypes::{CreateRequest, CreateResponse};
12
use crate::circuit::circhop::{HopNegotiationType, HopSettings};
13
use crate::client::circuit::CircParameters;
14
use crate::client::circuit::padding::PaddingController;
15
use crate::crypto::binding::CircuitBinding;
16
use crate::crypto::cell::CryptInit as _;
17
use crate::crypto::cell::{InboundRelayLayer, OutboundRelayLayer, RelayLayer, tor1};
18
use crate::crypto::handshake::RelayHandshakeError;
19
use crate::crypto::handshake::ServerHandshake as _;
20
use crate::crypto::handshake::fast::CreateFastServer;
21
use crate::crypto::handshake::ntor::{NtorSecretKey, NtorServer};
22
use crate::memquota::SpecificAccount as _;
23
use crate::memquota::{ChannelAccount, CircuitAccount};
24
use crate::relay::channel_provider::ChannelProvider;
25
use crate::relay::reactor::Reactor;
26
use crate::relay::{IncomingStreamRequestFilter, RelayCirc};
27
use smallvec::SmallVec;
28
use std::sync::{Arc, RwLock, Weak};
29
use tor_cell::chancell::ChanMsg as _;
30
use tor_cell::chancell::CircId;
31
use tor_cell::chancell::msg::{
32
    CreateFast, Created2, CreatedFast, Destroy, DestroyReason, HandshakeType,
33
};
34
use tor_cell::relaycell::RelayCmd;
35
use tor_error::{Bug, ErrorKind, HasKind, debug_report, internal, into_internal};
36
use tor_linkspec::OwnedChanTarget;
37
use tor_llcrypto::cipher::aes::Aes128Ctr;
38
use tor_llcrypto::d::Sha1;
39
use tor_llcrypto::pk::ed25519::Ed25519Identity;
40
use tor_llcrypto::pk::rsa::RsaIdentity;
41
use tor_memquota::mq_queue::ChannelSpec as _;
42
use tor_memquota::mq_queue::MpscSpec;
43
use tor_relay_crypto::pk::{RelayNtorKeypair, RelayNtorKeys};
44
use tor_rtcompat::SpawnExt as _;
45
use tor_rtcompat::{DynTimeProvider, Runtime};
46
use tracing::warn;
47

            
48
/// Everything needed to handle CREATE* messages on channels.
49
#[derive(derive_more::Debug)]
50
pub struct CreateRequestHandler {
51
    /// Something that can launch channels. Typically the `ChanMgr`.
52
    chan_provider: Weak<dyn ChannelProvider<BuildSpec = OwnedChanTarget> + Send + Sync>,
53
    /// Circuit-related network parameters.
54
    circ_net_params: RwLock<CircNetParameters>,
55
    /// The circuit extension keys.
56
    #[debug(skip)]
57
    ntor_keys: RwLock<RelayNtorKeys>,
58
    /// An [`IncomingStreamRequestFilter`] factory for checking whether the user wants
59
    /// this request, or wants to reject it immediately.
60
    ///
61
    /// Used for obtaining a current [`IncomingStreamRequestFilter`]
62
    /// for building a circuit reactor.
63
    //
64
    // TODO(relay): it's likely this will end up changing quite a bit once we start
65
    // figuring out exactly how the config/reconfigure() logic and IncomingStreamRequestFilter
66
    // should function for relays.
67
    #[debug(skip)]
68
    incoming_filter_factory: Box<dyn IncomingStreamRequestFilterFactory + Send + Sync>,
69
    /// The allowed incoming stream commands.
70
    ///
71
    /// Used for rejecting BEGIN and RESOLVE if we are not configured to be an exit.
72
    ///
73
    // TODO(relay): we might use this for rejecting BEGIN_DIR too,
74
    // if we decide to allow relays to opt out of being dir mirrors.
75
    // See https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/4107/diffs#note_3426447
76
    allowed_stream_cmds: SmallVec<[RelayCmd; 3]>,
77
}
78

            
79
impl CreateRequestHandler {
80
    /// Build a new [`CreateRequestHandler`].
81
22
    pub fn new(
82
22
        chan_provider: Weak<dyn ChannelProvider<BuildSpec = OwnedChanTarget> + Send + Sync>,
83
22
        circ_net_params: CircNetParameters,
84
22
        ntor_keys: RelayNtorKeys,
85
22
        incoming_filter_factory: Box<dyn IncomingStreamRequestFilterFactory + Send + Sync>,
86
22
        allowed_stream_cmds: &[RelayCmd],
87
22
    ) -> Self {
88
22
        Self {
89
22
            chan_provider,
90
22
            circ_net_params: RwLock::new(circ_net_params),
91
22
            ntor_keys: RwLock::new(ntor_keys),
92
22
            incoming_filter_factory,
93
22
            allowed_stream_cmds: allowed_stream_cmds.into(),
94
22
        }
95
22
    }
96

            
97
    /// Update the circuit parameters from a network consensus.
98
    pub fn update_params(&self, circ_net_params: CircNetParameters) {
99
        *self.circ_net_params.write().expect("rwlock poisoned") = circ_net_params;
100
    }
101

            
102
    /// Update the handler with a new set of circuit extension keys.
103
    ///
104
    /// This is called periodically by the relay key rotation task.
105
    pub fn update_ntor_keys(&self, ntor_keys: RelayNtorKeys) {
106
        *self.ntor_keys.write().expect("rwlock poisoned") = ntor_keys;
107
    }
108

            
109
    /// Handle a CREATE* cell.
110
    ///
111
    /// This intentionally does not return a [`crate::Error`] so that we don't accidentally shut
112
    /// down the channel reactor when we really should be returning a DESTROY. Shutting down a
113
    /// channel may cause us to leak information about paths of circuits travelling through this
114
    /// relay. This is especially important here since we're handling data that is controllable from
115
    /// the other end of the circuit.
116
    #[allow(clippy::too_many_arguments)]
117
    pub(crate) fn handle_create<R: Runtime>(
118
        &self,
119
        runtime: &R,
120
        channel: &Arc<Channel>,
121
        our_ed25519_id: &Ed25519Identity,
122
        our_rsa_id: &RsaIdentity,
123
        circ_id: CircId,
124
        msg: &CreateRequest,
125
        memquota: &ChannelAccount,
126
        circ_unique_id: UniqId,
127
    ) -> Result<(CreateResponse, RelayCircComponents), Destroy> {
128
        let result = self.handle_create_inner(
129
            runtime,
130
            channel,
131
            our_ed25519_id,
132
            our_rsa_id,
133
            circ_id,
134
            msg,
135
            memquota,
136
            circ_unique_id,
137
        );
138

            
139
        match result {
140
            Ok(x) => Ok(x),
141
            Err(e) => {
142
                // TODO(relay): The log messages throughout could be very noisy, so should have rate limiting.
143
                let cmd = msg.cmd();
144
                debug_report!(&e, %cmd, "Failed to handle circuit create request");
145

            
146
                // `tor-spec/tearing-down-circuits.md`:
147
                //
148
                // > Implementations SHOULD always use the NONE reason to avoid side channels: [...]
149
                Err(Destroy::new(DestroyReason::NONE))
150
            }
151
        }
152
    }
153

            
154
    /// See [`Self::handle_create`].
155
    #[allow(clippy::too_many_arguments)]
156
    fn handle_create_inner<R: Runtime>(
157
        &self,
158
        runtime: &R,
159
        channel: &Arc<Channel>,
160
        our_ed25519_id: &Ed25519Identity,
161
        our_rsa_id: &RsaIdentity,
162
        circ_id: CircId,
163
        msg: &CreateRequest,
164
        memquota: &ChannelAccount,
165
        circ_unique_id: UniqId,
166
    ) -> Result<(CreateResponse, RelayCircComponents), HandleCreateError> {
167
        // Perform the handshake crypto and build the response.
168
        let handshake_components = match msg {
169
            CreateRequest::CreateFast(msg) => self.handle_create_fast(msg)?,
170
            CreateRequest::Create2(msg) => match msg.handshake_type() {
171
                HandshakeType::NTOR_V3 => self.handle_create2_ntorv3(msg.body(), our_ed25519_id)?,
172
                HandshakeType::NTOR => self.handle_create2_ntor(msg.body(), our_rsa_id)?,
173
                x @ HandshakeType::TAP | x => {
174
                    return Err(HandleCreateError::Create2HandshakeType(x));
175
                }
176
            },
177
        };
178

            
179
        let memquota = CircuitAccount::new(memquota)?;
180

            
181
        // We use a large mpsc queue here since a circuit should never block the channel,
182
        // and we hope that memquota will help us if an attacker intentionally fills this buffer.
183
        // We use `10_000_000` since `usize::MAX` causes `futures::channel::mpsc` to panic.
184
        // TODO(relay): We should switch to an unbounded queue, but the circuit reactor is expecting
185
        // a bounded queue.
186
        let time_provider = DynTimeProvider::new(runtime.clone());
187
        let account = memquota.as_raw_account();
188
        let (sender, receiver) =
189
            MpscSpec::new(10_000_000).new_mq(time_provider.clone(), account)?;
190
        let (sender, receiver) = crate::circuit::circ_sender::channel(sender, receiver);
191

            
192
        // TODO(relay): Do we really want a client padding machine here?
193
        let (padding_ctrl, padding_stream) =
194
            crate::client::circuit::padding::new_padding(DynTimeProvider::new(runtime.clone()));
195

            
196
        // Upgrade the channel provider, which in practice is the `ChanMgr` so this should not fail.
197
        let Some(chan_provider) = self.chan_provider.upgrade() else {
198
            return Err(internal!("Unable to upgrade weak `ChannelProvider`").into());
199
        };
200

            
201
        // Create an IncomingStreamRequestFilter for this circuit.
202
        // This will get applied to every stream request (BEGIN, BEGIN_DIR, RESOLVE)
203
        // arriving on the circuit.
204
        //
205
        // Note: once built, a circuit reactor's IncomingStreamRequestFilter cannot be changed
206
        // (it's fixed for the entire duration of the circuit).
207
        let incoming_filter = self.incoming_filter_factory.current_filter();
208

            
209
        // Build the relay circuit reactor.
210
        let (reactor, circ, _incoming_streams) = Reactor::new(
211
            runtime.clone(),
212
            channel,
213
            circ_id,
214
            circ_unique_id,
215
            receiver,
216
            handshake_components.crypto_in,
217
            handshake_components.crypto_out,
218
            &handshake_components.hop_settings,
219
            chan_provider,
220
            padding_ctrl.clone(),
221
            padding_stream,
222
            incoming_filter,
223
            &self.allowed_stream_cmds,
224
            &memquota,
225
        )
226
        .map_err(into_internal!("Failed to start circuit reactor"))?;
227

            
228
        // TODO(relay): send the incoming_streams stream to the handler in arti-relay
229

            
230
        // Start the reactor in a task.
231
        let () = runtime.spawn(async {
232
            match reactor.run().await {
233
                Ok(()) => {}
234
                Err(e) => {
235
                    debug_report!(e, "Relay circuit reactor exited with an error");
236
                }
237
            }
238
        })?;
239

            
240
        Ok((
241
            handshake_components.response,
242
            RelayCircComponents {
243
                circ,
244
                sender,
245
                padding_ctrl,
246
            },
247
        ))
248
    }
249

            
250
    /// The handshake code for a CREATE_FAST request.
251
    fn handle_create_fast(
252
        &self,
253
        msg: &CreateFast,
254
    ) -> Result<CompletedHandshakeComponents, HandleCreateError> {
255
        // TODO(relay): We might want to offload this to a CPU worker in the future.
256
        let (keygen, handshake_msg) = CreateFastServer::server(
257
            &mut rand::rng(),
258
            // The CREATE_FAST handshake doesn't accept or return extensions,
259
            // so this `AuxDataReply` is a no-op.
260
            &mut |_: &()| Some(()),
261
            // The CREATE_FAST handshake doesn't use any keys.
262
            &[()],
263
            msg.handshake(),
264
        )?;
265

            
266
        let crypt = tor1::CryptStatePair::<Aes128Ctr, Sha1>::construct(keygen)
267
            .map_err(into_internal!("Circuit crypt state construction failed"))?;
268

            
269
        let circ_params = self
270
            .circ_net_params
271
            .read()
272
            .expect("rwlock poisoned")
273
            // CREATE_FAST always uses fixed-window flow control.
274
            .as_circ_parameters(AlgorithmDiscriminants::FixedWindow)?;
275

            
276
        // TODO(relay): I don't think that this is the right way to do this. It works for
277
        // CREATE_FAST, but we might want to rethink it for CREATE2.
278
        let protos = tor_protover::Protocols::default();
279
        let hop_settings =
280
            HopSettings::from_params_and_caps(HopNegotiationType::None, &circ_params, &protos)
281
                .map_err(into_internal!("Unable to build `HopSettings`"))?;
282

            
283
        let response = CreatedFast::new(handshake_msg);
284
        let response = CreateResponse::CreatedFast(response);
285

            
286
        let (crypto_out, crypto_in, _binding) = split_relay_layer(crypt);
287

            
288
        Ok(CompletedHandshakeComponents {
289
            response,
290
            hop_settings,
291
            crypto_out,
292
            crypto_in,
293
        })
294
    }
295

            
296
    /// The handshake code for a CREATE2 ntor (non-v3) request.
297
    fn handle_create2_ntor(
298
        &self,
299
        msg_body: &[u8],
300
        our_rsa_id: &RsaIdentity,
301
    ) -> Result<CompletedHandshakeComponents, HandleCreateError> {
302
        let ntor_keys = self.ntor_keys(|k| {
303
            NtorSecretKey::new(k.secret().clone(), *k.public().inner(), *our_rsa_id)
304
        });
305

            
306
        // TODO(relay): We might want to offload this to a CPU worker in the future.
307
        let (keygen, handshake_msg) = NtorServer::server(
308
            &mut rand::rng(),
309
            // The ntor (non-v3) handshake doesn't accept or return extensions,
310
            // so this `AuxDataReply` is a no-op.
311
            &mut |_: &()| Some(()),
312
            ntor_keys.as_ref(),
313
            msg_body,
314
        )?;
315

            
316
        let crypt = tor1::CryptStatePair::<Aes128Ctr, Sha1>::construct(keygen)
317
            .map_err(into_internal!("Circuit crypt state construction failed"))?;
318

            
319
        let (crypto_out, crypto_in, _binding) = split_relay_layer(crypt);
320

            
321
        let circ_params = self
322
            .circ_net_params
323
            .read()
324
            .expect("rwlock poisoned")
325
            // CREATE2 with ntor (non-v3) always uses fixed-window flow control.
326
            .as_circ_parameters(AlgorithmDiscriminants::FixedWindow)?;
327

            
328
        // TODO(relay): I don't think that this is the right way to do this. It works for
329
        // ntor, but won't work well for ntor-v3.
330
        let protos = tor_protover::Protocols::default();
331
        let hop_settings =
332
            HopSettings::from_params_and_caps(HopNegotiationType::None, &circ_params, &protos)
333
                .map_err(into_internal!("Unable to build `HopSettings`"))?;
334

            
335
        let response = Created2::new(handshake_msg);
336
        let response = CreateResponse::Created2(response);
337

            
338
        Ok(CompletedHandshakeComponents {
339
            response,
340
            hop_settings,
341
            crypto_out,
342
            crypto_in,
343
        })
344
    }
345

            
346
    /// The handshake code for a CREATE2 ntor-v3 request.
347
    fn handle_create2_ntorv3(
348
        &self,
349
        _msg_body: &[u8],
350
        _our_ed25519_id: &Ed25519Identity,
351
    ) -> Result<CompletedHandshakeComponents, HandleCreateError> {
352
        Err(HandleCreateError::Create2HandshakeType(
353
            HandshakeType::NTOR_V3,
354
        ))
355
    }
356

            
357
    /// Helper to get the ntor keypairs after some transformation `map`.
358
    ///
359
    /// The `map` transformation must be fast since it blocks a read lock.
360
    /// The returned keys are sorted with the most recent key first.
361
    ///
362
    /// It would be nice if this just returned an iterator,
363
    /// but the read lock prevents this.
364
    fn ntor_keys<T>(&self, map: impl FnMut(&RelayNtorKeypair) -> T) -> impl AsRef<[T]> {
365
        let ntor_keys = self.ntor_keys.read().expect("rwlock poisoned");
366
        let ntor_keys = [Some(ntor_keys.latest()), ntor_keys.previous()];
367
        ntor_keys
368
            .into_iter()
369
            .flatten()
370
            .map(map)
371
            .collect::<SmallVec<[T; 2]>>()
372
    }
373
}
374

            
375
/// Helper function to split a `RelayLayer` into forward and backward type-erased trait objects.
376
fn split_relay_layer<F, B>(
377
    crypt: impl RelayLayer<F, B>,
378
) -> (
379
    Box<dyn OutboundRelayLayer + Send>,
380
    Box<dyn InboundRelayLayer + Send>,
381
    CircuitBinding,
382
)
383
where
384
    F: OutboundRelayLayer + Send + 'static,
385
    B: InboundRelayLayer + Send + 'static,
386
{
387
    let (crypto_out, crypto_in, binding) = crypt.split_relay_layer();
388
    let (crypto_out, crypto_in) = (Box::new(crypto_out), Box::new(crypto_in));
389

            
390
    (crypto_out, crypto_in, binding)
391
}
392

            
393
/// An error that occurred while handling a CREATE* request.
394
#[derive(Debug, thiserror::Error)]
395
enum HandleCreateError {
396
    /// Circuit relay handshake failed.
397
    #[error("Circuit relay handshake failed")]
398
    Handshake(#[from] RelayHandshakeError),
399
    /// The requested handshake type is unsupported.
400
    #[error("Unsupported handshake type {0}")]
401
    Create2HandshakeType(HandshakeType),
402
    /// A memquota error.
403
    #[error("Memquota error")]
404
    Memquota(#[from] tor_memquota::Error),
405
    /// Error when spawning a task.
406
    #[error("Runtime task spawn error")]
407
    Spawn(#[from] futures::task::SpawnError),
408
    /// An internal error.
409
    ///
410
    /// Note that other variants (such as `Handshake` containing a [`RelayHandshakeError`])
411
    /// may themselves contain internal errors.
412
    #[error("Internal error")]
413
    Internal(#[from] tor_error::Bug),
414
}
415

            
416
impl HasKind for HandleCreateError {
417
    fn kind(&self) -> ErrorKind {
418
        match self {
419
            Self::Handshake(e) => e.kind(),
420
            Self::Create2HandshakeType(_) => ErrorKind::NotImplemented,
421
            Self::Memquota(e) => e.kind(),
422
            Self::Spawn(e) => e.kind(),
423
            Self::Internal(_) => ErrorKind::Internal,
424
        }
425
    }
426
}
427

            
428
/// The components of a completed CREATE* handshake.
429
struct CompletedHandshakeComponents {
430
    /// The message to send in response.
431
    response: CreateResponse,
432
    /// The negotiated hop settings.
433
    hop_settings: HopSettings,
434
    /// Outbound onion crypto.
435
    crypto_out: Box<dyn OutboundRelayLayer + Send>,
436
    /// Inbound onion crypto.
437
    crypto_in: Box<dyn InboundRelayLayer + Send>,
438
}
439

            
440
/// A collection of objects built for a new relay circuit.
441
pub(crate) struct RelayCircComponents {
442
    /// The relay circuit handle.
443
    pub(crate) circ: Arc<RelayCirc>,
444
    /// Used to send data from the channel to the circuit reactor.
445
    pub(crate) sender: CircuitRxSender,
446
    /// The circuit's padding controller.
447
    pub(crate) padding_ctrl: PaddingController,
448
}
449

            
450
/// Congestion control network parameters.
451
#[derive(Debug, Clone)]
452
#[allow(clippy::exhaustive_structs)]
453
pub struct CongestionControlNetParams {
454
    /// Fixed-window algorithm parameters.
455
    pub fixed_window: FixedWindowParams,
456

            
457
    /// Vegas algorithm parameters for exit circuits.
458
    // NOTE: In this module we are handling CREATE* cells,
459
    // which only happens for non-hs circuits.
460
    // So we don't need to store the vegas hs parameters here.
461
    pub vegas_exit: VegasParams,
462

            
463
    /// Congestion window parameters.
464
    pub cwnd: CongestionWindowParams,
465

            
466
    /// RTT calculation parameters.
467
    pub rtt: RoundTripEstimatorParams,
468

            
469
    /// Flow control parameters to use for all streams on this circuit.
470
    pub flow_ctrl: FlowCtrlParameters,
471
}
472

            
473
impl CongestionControlNetParams {
474
    #[cfg(test)]
475
    // These have been copied from C-tor.
476
22
    pub(crate) fn defaults_for_tests() -> Self {
477
22
        Self {
478
22
            fixed_window: FixedWindowParams::defaults_for_tests(),
479
22
            vegas_exit: VegasParams::defaults_for_tests(),
480
22
            cwnd: CongestionWindowParams::defaults_for_tests(),
481
22
            rtt: RoundTripEstimatorParams::defaults_for_tests(),
482
22
            flow_ctrl: FlowCtrlParameters::defaults_for_tests(),
483
22
        }
484
22
    }
485
}
486

            
487
/// Network consensus parameters for handling incoming circuits.
488
///
489
/// Unlike `CircParameters`,
490
/// this is unopinionated and contains all relevant consensus parameters,
491
/// which is needed when handling an incoming CREATE* request where the
492
/// circuit origin chooses the type/settings
493
/// (for example congestion control type) of the circuit.
494
#[derive(Debug, Clone)]
495
#[allow(clippy::exhaustive_structs)]
496
pub struct CircNetParameters {
497
    /// Whether we should include ed25519 identities when we send EXTEND2 cells.
498
    pub extend_by_ed25519_id: bool,
499

            
500
    /// Congestion control network parameters.
501
    pub cc: CongestionControlNetParams,
502
}
503

            
504
impl CircNetParameters {
505
    /// Convert the [`CircNetParameters`] into a [`CircParameters`].
506
    ///
507
    /// We expect the circuit creation handshake to know what congestion control algorithm was
508
    /// negotiated, and provide that as `algorithm`.
509
    //
510
    // We disable `unused` warnings at the root of tor-proto,
511
    // but it's nice to have here so we re-enable it.
512
    #[warn(unused)]
513
    fn as_circ_parameters(&self, algorithm: AlgorithmDiscriminants) -> Result<CircParameters, Bug> {
514
        // Unpack everything to make sure that we aren't missing anything
515
        // (otherwise clippy would warn).
516
        let Self {
517
            extend_by_ed25519_id,
518
            cc:
519
                CongestionControlNetParams {
520
                    fixed_window,
521
                    vegas_exit,
522
                    cwnd,
523
                    rtt,
524
                    flow_ctrl,
525
                },
526
        } = self;
527

            
528
        let algorithm = match algorithm {
529
            AlgorithmDiscriminants::FixedWindow => Algorithm::FixedWindow(*fixed_window),
530
            AlgorithmDiscriminants::Vegas => Algorithm::Vegas(*vegas_exit),
531
        };
532

            
533
        // TODO(arti#2442): The builder pattern here seems like a footgun.
534
        let cc = CongestionControlParams::builder()
535
            .alg(algorithm)
536
            .fixed_window_params(*fixed_window)
537
            .cwnd_params(*cwnd)
538
            .rtt_params(rtt.clone())
539
            .build()
540
            .map_err(into_internal!("Could not build `CongestionControlParams`"))?;
541

            
542
        Ok(CircParameters::new(
543
            *extend_by_ed25519_id,
544
            cc,
545
            flow_ctrl.clone(),
546
        ))
547
    }
548
}
549

            
550
/// An [`IncomingStreamRequestFilter`] factory for building [`IncomingStreamRequestFilter`]s.
551
///
552
/// Each time a new circuit is opened, the [`CreateRequestHandler`] calls
553
/// [`IncomingStreamRequestFilterFactory::current_filter`] to build
554
/// an [`IncomingStreamRequestFilter`] for the circuit.
555
pub trait IncomingStreamRequestFilterFactory {
556
    /// Return the [`IncomingStreamRequestFilter`] to apply to the incoming stream requests
557
    /// arriving on a circuit.
558
    fn current_filter(&self) -> Box<dyn IncomingStreamRequestFilter>;
559
}
560

            
561
impl<F> IncomingStreamRequestFilterFactory for F
562
where
563
    F: Fn() -> Box<dyn IncomingStreamRequestFilter>,
564
{
565
    fn current_filter(&self) -> Box<dyn IncomingStreamRequestFilter> {
566
        (self)()
567
    }
568
}