Lines
0 %
Functions
Branches
100 %
//! A wrapper around an RPC Object that can be used as a connection target.
use arti_client::{
rpc::{ClientConnectionResult, ConnectWithPrefs, ResolvePtrWithPrefs, ResolveWithPrefs},
DataStream, StreamPrefs, TorAddr, TorClient,
};
use std::{net::IpAddr, sync::Arc};
use tor_error::into_internal;
use tor_rpcbase as rpc;
use tor_rtcompat::Runtime;
/// Wrapper around an RPC object that can be used as a connection target,
/// or around a TorClient if no RPC object is given.
///
/// Provides an API similar to TorClient, for use when opening SOCKS connections.
pub(crate) enum ConnTarget<R: Runtime> {
/// An RPC object with accompanying context.
Rpc {
/// The RPC object on which to build our connections.
object: Arc<dyn rpc::Object>,
/// The RPC context in which to invoke methods
context: Arc<dyn rpc::Context>,
},
/// A Tor client, without RPC information
Client(TorClient<R>),
}
impl<R: Runtime> ConnTarget<R> {
/// As [`TorClient::connect_with_prefs`].
pub(crate) async fn connect_with_prefs(
&self,
target: &TorAddr,
prefs: &StreamPrefs,
) -> ClientConnectionResult<DataStream> {
match self {
ConnTarget::Rpc {
object: obj,
context,
} => {
let method = ConnectWithPrefs {
target: target.clone(),
prefs: prefs.clone(),
*rpc::invoke_special_method(context.clone(), obj.clone(), Box::new(method) as _)
.await
.map_err(|e| {
Box::new(into_internal!("unable to delegate to RPC object")(e)) as _
})?
ConnTarget::Client(client) => client
.connect_with_prefs(target, prefs)
.map_err(|e| Box::new(e) as _),
/// As [`TorClient::resolve_with_prefs`]
pub(crate) async fn resolve_with_prefs(
hostname: &str,
) -> ClientConnectionResult<Vec<IpAddr>> {
let method = ResolveWithPrefs {
hostname: hostname.to_string(),
.resolve_with_prefs(hostname, prefs)
/// As [`TorClient::resolve_ptr_with_prefs`]
pub(crate) async fn resolve_ptr_with_prefs(
self,
addr: IpAddr,
) -> ClientConnectionResult<Vec<String>> {
let method = ResolvePtrWithPrefs {
addr,
.resolve_ptr_with_prefs(addr, prefs)