pub struct ClientCirc { /* private fields */ }
Expand description
A circuit that we have constructed over the Tor network.
§Circuit life cycle
ClientCirc
s are created in an initially unusable state using Channel::new_tunnel
,
which returns a PendingClientTunnel
. To get a real (one-hop) tunnel from
one of these, you invoke one of its create_firsthop
methods (typically
create_firsthop_fast()
or
create_firsthop()
).
Then, to add more hops to the circuit, you can call
extend()
on it.
For higher-level APIs, see the tor-circmgr
crate: the ones here in
tor-proto
are probably not what you need.
After a circuit is created, it will persist until it is closed in one of five ways:
- A remote error occurs.
- Some hop on the circuit sends a
DESTROY
message to tear down the circuit. - The circuit’s channel is closed.
- Someone calls
ClientTunnel::terminate
on the tunnel owning the circuit. - The last reference to the
ClientCirc
is dropped. (Note that every stream on aClientCirc
keeps a reference to it, which will in turn keep the circuit from closing until all those streams have gone away.)
Note that in cases 1-4 the ClientCirc
object itself will still exist: it
will just be unusable for most purposes. Most operations on it will fail
with an error.
Implementations§
Source§impl ClientCirc
impl ClientCirc
Sourcepub fn into_tunnel(self) -> Result<ClientTunnel>
pub fn into_tunnel(self) -> Result<ClientTunnel>
Convert this ClientCirc
into a single circuit ClientTunnel
.
Sourcepub fn first_hop(&self) -> Result<OwnedChanTarget>
pub fn first_hop(&self) -> Result<OwnedChanTarget>
Return a description of the first hop of this circuit.
§Panics
Panics if there is no first 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.)
Sourcepub fn last_hop_info(&self) -> Result<Option<OwnedChanTarget>>
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.
§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.)
Sourcepub fn last_hop_num(&self) -> Result<HopNum>
pub fn last_hop_num(&self) -> Result<HopNum>
Return the HopNum
of the last hop of this circuit.
Returns an error 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.)
NOTE: This function will return the HopNum
of the hop
that is currently the last. If there is an extend operation in progress,
the currently pending hop may or may not be counted, depending on whether
the extend operation finishes before this call is done.
Sourcepub fn last_hop(&self) -> Result<TargetHop>
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.
Sourcepub fn all_paths(&self) -> Vec<Arc<Path>>
pub fn all_paths(&self) -> Vec<Arc<Path>>
Return a list of Path
objects describing all the circuits in this tunnel.
Note that these Path
s are not automatically updated if the underlying
circuits are extended.
Sourcepub fn single_path(&self) -> Result<Arc<Path>>
pub fn single_path(&self) -> Result<Arc<Path>>
Return a list of Path
objects describing the only circuit in this tunnel.
Returns an error if the tunnel has more than one tunnel.
Sourcepub async fn first_hop_clock_skew(&self) -> Result<ClockSkew>
pub async fn first_hop_clock_skew(&self) -> Result<ClockSkew>
Get the clock skew claimed by the first hop of the circuit.
Sourcepub fn mq_account(&self) -> &CircuitAccount
pub fn mq_account(&self) -> &CircuitAccount
Return a reference to this circuit’s memory quota account
Sourcepub async fn binding_key(
&self,
hop: TargetHop,
) -> Result<Option<CircuitBinding>>
Available on crate feature hs-service
only.
pub async fn binding_key( &self, hop: TargetHop, ) -> Result<Option<CircuitBinding>>
hs-service
only.Return the cryptographic material used to prove knowledge of a shared
secret with with hop
.
See CircuitBinding
for more information on how this is used.
Return None if we have no circuit binding information for the hop, or if the hop does not exist.
Sourcepub async fn extend<Tg>(
&self,
target: &Tg,
params: CircParameters,
) -> Result<()>where
Tg: CircTarget,
pub async fn extend<Tg>(
&self,
target: &Tg,
params: CircParameters,
) -> Result<()>where
Tg: CircTarget,
Extend the circuit, via the most appropriate circuit extension handshake,
to the chosen target
hop.
Sourcepub async fn extend_ntor<Tg>(
&self,
target: &Tg,
params: CircParameters,
) -> Result<()>where
Tg: CircTarget,
pub async fn extend_ntor<Tg>(
&self,
target: &Tg,
params: CircParameters,
) -> Result<()>where
Tg: CircTarget,
Extend the circuit via the ntor handshake to a new target last hop.
Sourcepub async fn extend_ntor_v3<Tg>(
&self,
target: &Tg,
params: CircParameters,
) -> Result<()>where
Tg: CircTarget,
pub async fn extend_ntor_v3<Tg>(
&self,
target: &Tg,
params: CircParameters,
) -> Result<()>where
Tg: CircTarget,
Extend the circuit via the ntor handshake to a new target last hop.
Sourcepub async fn extend_virtual(
&self,
protocol: RelayProtocol,
role: HandshakeRole,
seed: impl KeyGenerator,
params: &CircParameters,
capabilities: &Protocols,
) -> Result<()>
Available on crate feature hs-common
only.
pub async fn extend_virtual( &self, protocol: RelayProtocol, role: HandshakeRole, seed: impl KeyGenerator, params: &CircParameters, capabilities: &Protocols, ) -> Result<()>
hs-common
only.Extend this circuit by a single, “virtual” hop.
A virtual hop is one for which we do not add an actual network connection between separate hosts (such as Relays). We only add a layer of cryptography.
This is used to implement onion services: the client and the service
both build a circuit to a single rendezvous point, and tell the
rendezvous point to relay traffic between their two circuits. Having
completed a handshake
out of band1, the parties each extend their
circuits by a single “virtual” encryption hop that represents their
shared cryptographic context.
Once a circuit has been extended in this way, it is an error to try to extend it in any other way.
Technically, the handshake is only mostly out of band: the client sends their half of the handshake in an
message, and the service's response is inline in its
RENDEZVOUS2` message. ↩
Sourcepub fn is_closing(&self) -> bool
pub fn is_closing(&self) -> bool
Return true if this circuit is closed and therefore unusable.
Sourcepub fn n_hops(&self) -> Result<usize>
pub fn n_hops(&self) -> Result<usize>
Return the number of hops in this circuit.
NOTE: This function will currently return only the number of hops currently in the circuit. If there is an extend operation in progress, the currently pending hop may or may not be counted, depending on whether the extend operation finishes before this call is done.
Sourcepub fn wait_for_close(
&self,
) -> impl Future<Output = ()> + Send + Sync + 'static + use<>
pub fn wait_for_close( &self, ) -> impl Future<Output = ()> + Send + Sync + 'static + use<>
Return a future that will resolve once this circuit has closed.
Note that this method does not itself cause the circuit to shut down.
TODO: Perhaps this should return some kind of status indication instead of just ()
Trait Implementations§
Source§impl Debug for ClientCirc
impl Debug for ClientCirc
Source§impl TryFrom<ClientCirc> for ClientTunnel
impl TryFrom<ClientCirc> for ClientTunnel
Auto Trait Implementations§
impl Freeze for ClientCirc
impl !RefUnwindSafe for ClientCirc
impl Send for ClientCirc
impl Sync for ClientCirc
impl Unpin for ClientCirc
impl !UnwindSafe for ClientCirc
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
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) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
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
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.