1//! Wrappers for using a CircTarget with a verbatim list of
2//! [link specifiers](EncodedLinkSpec).
34use crate::{ChanTarget, CircTarget, EncodedLinkSpec, HasAddrs, HasChanMethod, HasRelayIds};
56/// A wrapper around an underlying [`CircTarget`] that provides a user-specified
7/// list of [link specifiers](EncodedLinkSpec).
8///
9/// Onion services and their clients use this type of target when telling a
10/// relay to extend a circuit to a target relay (an introduction point or
11/// rendezvous point) chosen by some other party.
12#[derive(Clone, Debug)]
13pub struct VerbatimLinkSpecCircTarget<T> {
14/// The underlying CircTarget
15target: T,
16/// The link specifiers to provide.
17linkspecs: Vec<EncodedLinkSpec>,
18}
1920impl<T> VerbatimLinkSpecCircTarget<T> {
21/// Construct a new `VerbatimLinkSpecCircTarget` to wrap an underlying
22 /// `CircTarget` object, and provide it with a new set of encoded link
23 /// specifiers that will be used when telling a relay to extend to this
24 /// node.
25 ///
26 /// Note that nothing here will check that `linkspecs` is sufficient to
27 /// actually connect to the chosen target, or to any target at all. It is
28 /// the caller's responsibility to choose a valid set of link specifiers.
29pub fn new(target: T, linkspecs: Vec<EncodedLinkSpec>) -> Self {
30Self { target, linkspecs }
31 }
32}
3334// Now, the delegation functions. All of these are simple delegations to
35// self.target, except for `CircTarget::linkspecs` with returns self.linkspecs.
3637impl<T: HasRelayIds> HasRelayIds for VerbatimLinkSpecCircTarget<T> {
38fn identity(&self, key_type: crate::RelayIdType) -> Option<crate::RelayIdRef<'_>> {
39self.target.identity(key_type)
40 }
41}
42impl<T: HasAddrs> HasAddrs for VerbatimLinkSpecCircTarget<T> {
43fn addrs(&self) -> impl Iterator<Item = std::net::SocketAddr> {
44self.target.addrs()
45 }
46}
47impl<T: HasChanMethod> HasChanMethod for VerbatimLinkSpecCircTarget<T> {
48fn chan_method(&self) -> crate::ChannelMethod {
49self.target.chan_method()
50 }
51}
52impl<T: ChanTarget> ChanTarget for VerbatimLinkSpecCircTarget<T> {}
53impl<T: CircTarget> CircTarget for VerbatimLinkSpecCircTarget<T> {
54fn linkspecs(&self) -> tor_bytes::EncodeResult<Vec<EncodedLinkSpec>> {
55Ok(self.linkspecs.clone())
56 }
5758fn ntor_onion_key(&self) -> &tor_llcrypto::pk::curve25519::PublicKey {
59self.target.ntor_onion_key()
60 }
6162fn protovers(&self) -> &tor_protover::Protocols {
63self.target.protovers()
64 }
65}
6667#[cfg(test)]
68mod test {
69// @@ begin test lint list maintained by maint/add_warning @@
70#![allow(clippy::bool_assert_comparison)]
71 #![allow(clippy::clone_on_copy)]
72 #![allow(clippy::dbg_macro)]
73 #![allow(clippy::mixed_attributes_style)]
74 #![allow(clippy::print_stderr)]
75 #![allow(clippy::print_stdout)]
76 #![allow(clippy::single_char_pattern)]
77 #![allow(clippy::unwrap_used)]
78 #![allow(clippy::unchecked_duration_subtraction)]
79 #![allow(clippy::useless_vec)]
80 #![allow(clippy::needless_pass_by_value)]
81//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
8283use super::*;
84use crate::OwnedCircTarget;
85use itertools::Itertools;
8687#[test]
88fn verbatim_linkspecs() {
89let mut builder = OwnedCircTarget::builder();
90 builder
91 .chan_target()
92 .addrs(vec!["127.0.0.1:11".parse().unwrap()])
93 .ed_identity([42; 32].into())
94 .rsa_identity([45; 20].into());
95let inner = builder
96 .ntor_onion_key([99; 32].into())
97 .protocols("FlowCtrl=7".parse().unwrap())
98 .build()
99 .unwrap();
100let weird_linkspecs = vec![EncodedLinkSpec::new(
10177.into(),
102b"mysterious whisper".to_vec(),
103 )];
104let wrapped = VerbatimLinkSpecCircTarget::new(inner.clone(), weird_linkspecs.clone());
105106assert_eq!(wrapped.addrs().collect_vec(), inner.addrs().collect_vec());
107assert!(wrapped.same_relay_ids(&inner));
108assert_eq!(wrapped.ntor_onion_key(), inner.ntor_onion_key());
109assert_eq!(wrapped.protovers(), inner.protovers());
110111assert_ne!(inner.linkspecs().unwrap(), weird_linkspecs);
112assert_eq!(wrapped.linkspecs().unwrap(), weird_linkspecs);
113 }
114}