//! Client channel code. //! //! This contains client specific channel code. In other words, everything that a client needs to //! establish a channel according to the Tor protocol. pub(crate) mod handshake; pub use handshake::ClientInitiatorHandshake; use futures::{AsyncRead, AsyncWrite}; use tor_rtcompat::{CoarseTimeProvider, SleepProvider, StreamOps}; use crate::memquota::ChannelAccount; /// Structure for building and launching a client Tor channel. #[derive(Default)] #[non_exhaustive] pub struct ClientChannelBuilder { /// If present, a description of the address we're trying to connect to, /// and the way in which we are trying to connect to it. /// /// TODO: at some point, check this against the addresses in the netinfo /// cell too. target: Option, } impl ClientChannelBuilder { /// Construct a new ChannelBuilder. pub fn new() -> Self { ClientChannelBuilder::default() } /// Set the declared target method of this channel. /// /// Note that nothing enforces the correctness of this method: it /// doesn't have to match the real method used to create the TLS /// stream. pub fn set_declared_method(&mut self, target: tor_linkspec::ChannelMethod) { self.target = Some(target); } /// Launch a new client handshake over a TLS stream. /// /// After calling this function, you'll need to call `connect()` on /// the result to start the handshake. If that succeeds, you'll have /// authentication info from the relay: call `check()` on the result /// to check that. Finally, to finish the handshake, call `finish()` /// on the result of _that_. pub fn launch( self, tls: T, sleep_prov: S, memquota: ChannelAccount, ) -> ClientInitiatorHandshake where T: AsyncRead + AsyncWrite + StreamOps + Send + Unpin + 'static, S: CoarseTimeProvider + SleepProvider, { handshake::ClientInitiatorHandshake::new(tls, self.target, sleep_prov, memquota) } }