1
//! Client channel code.
2
//!
3
//! This contains client specific channel code. In other words, everyting that a client needs to
4
//! establish a channel according to the Tor protocol.
5

            
6
pub(crate) mod handshake;
7

            
8
pub use handshake::ClientInitiatorHandshake;
9

            
10
use futures::{AsyncRead, AsyncWrite};
11

            
12
use tor_rtcompat::{CoarseTimeProvider, SleepProvider, StreamOps};
13

            
14
use crate::memquota::ChannelAccount;
15

            
16
/// Structure for building and launching a client Tor channel.
17
#[derive(Default)]
18
#[non_exhaustive]
19
pub struct ClientChannelBuilder {
20
    /// If present, a description of the address we're trying to connect to,
21
    /// and the way in which we are trying to connect to it.
22
    ///
23
    /// TODO: at some point, check this against the addresses in the netinfo
24
    /// cell too.
25
    target: Option<tor_linkspec::ChannelMethod>,
26
}
27

            
28
impl ClientChannelBuilder {
29
    /// Construct a new ChannelBuilder.
30
48
    pub fn new() -> Self {
31
48
        ClientChannelBuilder::default()
32
48
    }
33

            
34
    /// Set the declared target method of this channel.
35
    ///
36
    /// Note that nothing enforces the correctness of this method: it
37
    /// doesn't have to match the real method used to create the TLS
38
    /// stream.
39
48
    pub fn set_declared_method(&mut self, target: tor_linkspec::ChannelMethod) {
40
48
        self.target = Some(target);
41
48
    }
42

            
43
    /// Launch a new client handshake over a TLS stream.
44
    ///
45
    /// After calling this function, you'll need to call `connect()` on
46
    /// the result to start the handshake.  If that succeeds, you'll have
47
    /// authentication info from the relay: call `check()` on the result
48
    /// to check that.  Finally, to finish the handshake, call `finish()`
49
    /// on the result of _that_.
50
2
    pub fn launch<T, S>(
51
2
        self,
52
2
        tls: T,
53
2
        sleep_prov: S,
54
2
        memquota: ChannelAccount,
55
2
    ) -> ClientInitiatorHandshake<T, S>
56
2
    where
57
2
        T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static,
58
2
        S: CoarseTimeProvider + SleepProvider,
59
    {
60
2
        handshake::ClientInitiatorHandshake::new(tls, self.target, sleep_prov, memquota)
61
2
    }
62
}