arti/rpc/
conntarget.rs

1//! A wrapper around an RPC Object that can be used as a connection target.
2
3use arti_client::{
4    rpc::{ClientConnectionResult, ConnectWithPrefs, ResolvePtrWithPrefs, ResolveWithPrefs},
5    DataStream, StreamPrefs, TorAddr, TorClient,
6};
7use std::{net::IpAddr, sync::Arc};
8use tor_error::into_internal;
9use tor_rpcbase as rpc;
10use tor_rtcompat::Runtime;
11
12/// Wrapper around an RPC object that can be used as a connection target,
13/// or around a TorClient if no RPC object is given.
14///
15/// Provides an API similar to TorClient, for use when opening SOCKS connections.
16pub(crate) enum ConnTarget<R: Runtime> {
17    /// An RPC object with accompanying context.
18    Rpc {
19        /// The RPC object on which to build our connections.
20        object: Arc<dyn rpc::Object>,
21        /// The RPC context in which to invoke methods
22        context: Arc<dyn rpc::Context>,
23    },
24    /// A Tor client, without RPC information
25    Client(Box<TorClient<R>>),
26}
27
28impl<R: Runtime> ConnTarget<R> {
29    /// As [`TorClient::connect_with_prefs`].
30    pub(crate) async fn connect_with_prefs(
31        &self,
32        target: &TorAddr,
33        prefs: &StreamPrefs,
34    ) -> ClientConnectionResult<DataStream> {
35        match self {
36            ConnTarget::Rpc {
37                object: obj,
38                context,
39            } => {
40                let method = ConnectWithPrefs {
41                    target: target.clone(),
42                    prefs: prefs.clone(),
43                };
44                *rpc::invoke_special_method(context.clone(), obj.clone(), Box::new(method) as _)
45                    .await
46                    .map_err(|e| {
47                        Box::new(into_internal!("unable to delegate to RPC object")(e)) as _
48                    })?
49            }
50            ConnTarget::Client(client) => client
51                .connect_with_prefs(target, prefs)
52                .await
53                .map_err(|e| Box::new(e) as _),
54        }
55    }
56
57    /// As [`TorClient::resolve_with_prefs`]
58    pub(crate) async fn resolve_with_prefs(
59        &self,
60        hostname: &str,
61        prefs: &StreamPrefs,
62    ) -> ClientConnectionResult<Vec<IpAddr>> {
63        match self {
64            ConnTarget::Rpc {
65                object: obj,
66                context,
67            } => {
68                let method = ResolveWithPrefs {
69                    hostname: hostname.to_string(),
70                    prefs: prefs.clone(),
71                };
72                *rpc::invoke_special_method(context.clone(), obj.clone(), Box::new(method) as _)
73                    .await
74                    .map_err(|e| {
75                        Box::new(into_internal!("unable to delegate to RPC object")(e)) as _
76                    })?
77            }
78            ConnTarget::Client(client) => client
79                .resolve_with_prefs(hostname, prefs)
80                .await
81                .map_err(|e| Box::new(e) as _),
82        }
83    }
84
85    /// As [`TorClient::resolve_ptr_with_prefs`]
86    pub(crate) async fn resolve_ptr_with_prefs(
87        self,
88        addr: IpAddr,
89        prefs: &StreamPrefs,
90    ) -> ClientConnectionResult<Vec<String>> {
91        match self {
92            ConnTarget::Rpc {
93                object: obj,
94                context,
95            } => {
96                let method = ResolvePtrWithPrefs {
97                    addr,
98                    prefs: prefs.clone(),
99                };
100                *rpc::invoke_special_method(context.clone(), obj.clone(), Box::new(method) as _)
101                    .await
102                    .map_err(|e| {
103                        Box::new(into_internal!("unable to delegate to RPC object")(e)) as _
104                    })?
105            }
106            ConnTarget::Client(client) => client
107                .resolve_ptr_with_prefs(addr, prefs)
108                .await
109                .map_err(|e| Box::new(e) as _),
110        }
111    }
112}