ClientTunnel

Struct ClientTunnel 

Source
pub struct ClientTunnel {
    circ: ClientCirc,
}
Expand description

A low-level client tunnel API.

This is a communication channel to the tunnel reactor, which manages 1 or more circuits.

Note: the tor-circmgr crates wrap this type in specialized *Tunnel types exposing only the desired subset of functionality depending on purpose and path size.

Some API calls are for single path and some for multi path. A check with the underlying reactor is done preventing for instance multi path calls to be used on a single path. Top level types should prevent this and thus this object should never be used directly.

Fields§

§circ: ClientCirc

The underlying handle to the reactor.

Implementations§

Source§

impl ClientTunnel

Source

pub fn as_single_circ(&self) -> Result<&ClientCirc>

Return a handle to the ClientCirc of this ClientTunnel, if the tunnel is a single circuit tunnel.

Returns an error if the tunnel has more than one circuit.

Source

pub fn first_hop(&self) -> Result<OwnedChanTarget>

Return the channel target of the first hop.

Can only be used for single path tunnel.

Source

pub fn is_closed(&self) -> bool

Return true if the circuit reactor is closed meaning the circuit is unusable for both receiving or sending.

Source

pub fn last_hop(&self) -> Result<TargetHop>

Return a TargetHop representing precisely the last hop of the circuit as in set as a HopLocation with its id and hop number.

Return an error if there is no last hop.

Source

pub fn last_hop_info(&self) -> Result<Option<OwnedChanTarget>>

Return a description of the last hop of the tunnel.

Return None if the last hop is virtual; return an error if the tunnel has no circuits, or all of its circuits are zero length.

§Panics

Panics if there is no last hop. (This should be impossible outside of the tor-proto crate, but within the crate it’s possible to have a circuit with no hops.)

Source

pub fn n_hops(&self) -> Result<usize>

Return the number of hops this tunnel as. Fail for a multi path.

Source

pub fn all_paths(&self) -> Vec<Arc<Path>>

Return the Path objects describing all the hops of all the circuits in this tunnel.

Source

pub fn unique_id(&self) -> UniqId

Return a process-unique identifier for this tunnel.

Returns the reactor unique ID of the main reactor.

Source

pub async fn disused_since(&self) -> Result<Option<Instant>>

Return the time at which this tunnel last had any open streams.

Returns None if this tunnel has never had any open streams, or if it currently has open streams.

NOTE that the Instant returned by this method is not affected by any runtime mocking; it is the output of an ordinary call to Instant::now().

Source

pub fn wait_for_close( self: &Arc<Self>, ) -> impl Future<Output = ()> + Send + Sync + 'static + use<>

Return a future that will resolve once the underlying circuit reactor has closed.

Note that this method does not itself cause the tunnel to shut down.

Source

pub async fn allow_stream_requests<'a, FILT>( self: &Arc<Self>, allow_commands: &'a [RelayCmd], hop: TargetHop, filter: FILT, ) -> Result<impl Stream<Item = IncomingStream> + use<'a, FILT>>
where FILT: IncomingStreamRequestFilter + 'a,

Available on crate feature hs-service only.

Single-path tunnel only. Multi path onion service is not supported yet.

Tell this tunnel to begin allowing the final hop of the tunnel to try to create new Tor streams, and to return those pending requests in an asynchronous stream.

Ordinarily, these requests are rejected.

There can only be one Stream of this type created on a given tunnel. If a such a Stream already exists, this method will return an error.

After this method has been called on a tunnel, the tunnel is expected to receive requests of this type indefinitely, until it is finally closed. If the Stream is dropped, the next request on this tunnel will cause it to close.

Only onion services (and eventually) exit relays should call this method.

Source

async fn begin_stream_impl( self: &Arc<Self>, begin_msg: AnyRelayMsg, cmd_checker: Box<dyn CmdChecker + Send + 'static>, ) -> Result<StreamComponents>

Single and Multi path helper, used to begin a stream.

This function allocates a stream ID, and sends the message (like a BEGIN or RESOLVE), but doesn’t wait for a response.

The caller will typically want to see the first cell in response, to see whether it is e.g. an END or a CONNECTED.

Source

pub async fn start_padding_at_hop( self: &Arc<Self>, hop: HopLocation, padder: CircuitPadder, ) -> Result<()>

Available on crate feature circ-padding-manual only.

Install a CircuitPadder at the listed hop.

Replaces any previous padder installed at that hop.

Source

pub async fn stop_padding_at_hop( self: &Arc<Self>, hop: HopLocation, ) -> Result<()>

Available on crate feature circ-padding-manual only.

Remove any CircuitPadder at the listed hop.

Does nothing if there was not a padder installed there.

Source

async fn begin_data_stream( self: &Arc<Self>, msg: AnyRelayMsg, optimistic: bool, ) -> Result<DataStream>

Start a DataStream (anonymized connection) to the given address and port, using a BEGIN cell.

Source

pub async fn begin_stream( self: &Arc<Self>, target: &str, port: u16, parameters: Option<StreamParameters>, ) -> Result<DataStream>

Single and multi path helper.

Start a stream to the given address and port, using a BEGIN cell.

The use of a string for the address is intentional: you should let the remote Tor relay do the hostname lookup for you.

Source

pub async fn begin_dir_stream(self: Arc<Self>) -> Result<DataStream>

Start a new stream to the last relay in the tunnel, using a BEGIN_DIR cell.

Source

pub async fn resolve(self: &Arc<Self>, hostname: &str) -> Result<Vec<IpAddr>>

Perform a DNS lookup, using a RESOLVE cell with the last relay in this tunnel.

Note that this function does not check for timeouts; that’s the caller’s responsibility.

Source

pub async fn resolve_ptr(self: &Arc<Self>, addr: IpAddr) -> Result<Vec<String>>

Perform a reverse DNS lookup, by sending a RESOLVE cell with the last relay on this tunnel.

Note that this function does not check for timeouts; that’s the caller’s responsibility.

Source

pub async fn send_raw_msg(&self, msg: AnyRelayMsg, hop: TargetHop) -> Result<()>

Available on crate feature send-control-msg only.

Send an ad-hoc message to a given hop on the circuit, without expecting a reply.

(If you want to handle one or more possible replies, see ClientTunnel::start_conversation.)

Source

pub async fn start_conversation( &self, msg: Option<AnyRelayMsg>, reply_handler: impl MsgHandler + Send + 'static, hop: TargetHop, ) -> Result<Conversation<'_>>

Available on crate feature send-control-msg only.

Start an ad-hoc protocol exchange to the specified hop on this tunnel.

To use this:

  1. Create an inter-task channel you’ll use to receive the outcome of your conversation, and bundle it into a UserMsgHandler.

  2. Call start_conversation. This will install a your handler, for incoming messages, and send the outgoing message (if you provided one). After that, each message on the circuit that isn’t handled by the core machinery is passed to your provided reply_handler.

  3. Possibly call send_msg on the Conversation, from the call site of start_conversation, possibly multiple times, from time to time, to send further desired messages to the peer.

  4. In your UserMsgHandler, process the incoming messages. You may respond by sending additional messages When the protocol exchange is finished, UserMsgHandler::handle_msg should return ConversationFinished.

If you don’t need the Conversation to send followup messages, you may simply drop it, and rely on the responses you get from your handler, on the channel from step 0 above. Your handler will remain installed and able to process incoming messages until it returns ConversationFinished.

(If you don’t want to accept any replies at all, it may be simpler to use ClientTunnel::send_raw_msg.)

Note that it is quite possible to use this function to violate the tor protocol; most users of this API will not need to call it. It is used to implement most of the onion service handshake.

§Limitations

Only one conversation may be active at any one time, for any one circuit. This generally means that this function should not be called on a tunnel which might be shared with anyone else.

Likewise, it is forbidden to try to extend the tunnel, while the conversation is in progress.

After the conversation has finished, the tunnel may be extended. Or, start_conversation may be called again; but, in that case there will be a gap between the two conversations, during which no UserMsgHandler is installed, and unexpected incoming messages would close the tunnel.

If these restrictions are violated, the tunnel will be closed with an error.

§Precise definition of the lifetime of a conversation

A conversation is in progress from entry to start_conversation, until entry to the body of the UserMsgHandler::handle_msg call which returns ConversationFinished. (Entry since handle_msg is synchronously embedded into the incoming message processing.) So you may start a new conversation as soon as you have the final response via your inter-task channel from (0) above.

The lifetime relationship of the Conversation, vs the handler returning ConversationFinished is not enforced by the type system.

Source

pub fn terminate(&self)

Shut down this tunnel, along with all streams that are using it. Happens asynchronously (i.e. the tunnel won’t necessarily be done shutting down immediately after this function returns!).

Note that other references to this tunnel may exist. If they do, they will stop working after you call this function.

It’s not necessary to call this method if you’re just done with a tunnel: the tunnel should close on its own once nothing is using it any more.

Source

async fn try_resolve(self: &Arc<Self>, msg: Resolve) -> Result<Resolved>

Helper: Send the resolve message, and read resolved message from resolve stream.

Source§

impl ClientTunnel

Source

pub(crate) fn close_pending( &self, stream_id: StreamId, hop: Option<HopLocation>, message: CloseStreamBehavior, ) -> Result<Receiver<Result<()>>>

Available on crate feature hs-service only.

Close the pending stream that owns this StreamTarget, delivering the specified END message (if any)

See StreamTarget::close_pending.

Source

pub(crate) fn send_sendme( &self, stream_id: StreamId, hop: Option<HopLocation>, ) -> Result<()>

Request to send a SENDME cell for this stream.

See StreamTarget::send_sendme.

Source

pub(crate) fn drain_rate_update( &self, stream_id: StreamId, hop: Option<HopLocation>, rate: XonKbpsEwma, ) -> Result<()>

Inform the circuit reactor that there has been a change in the drain rate for this stream.

See StreamTarget::drain_rate_update.

Trait Implementations§

Source§

impl Debug for ClientTunnel

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl TryFrom<ClientCirc> for ClientTunnel

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(circ: ClientCirc) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> PossiblyOption<T> for T

Source§

fn to_option(self) -> Option<T>

Convert this object into an Option<T>
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more