Loading tor-chanmgr/src/builder.rs +5 −64 Original line number Diff line number Diff line Loading @@ -2,13 +2,12 @@ use crate::Error; use tor_linkspec::ChanTarget; use tor_linkspec::{ChanTarget, OwnedChanTarget}; use tor_llcrypto::pk; use tor_rtcompat::{tls::TlsConnector, Runtime, TlsProvider}; use async_trait::async_trait; use futures::task::SpawnExt; use std::net::SocketAddr; use std::sync::Arc; /// TLS-based channel builder. Loading Loading @@ -36,7 +35,7 @@ impl<R: Runtime> ChanBuilder<R> { #[async_trait] impl<R: Runtime> crate::mgr::ChannelFactory for ChanBuilder<R> { type Channel = tor_proto::channel::Channel; type BuildSpec = TargetInfo; type BuildSpec = OwnedChanTarget; async fn build_channel(&self, target: &Self::BuildSpec) -> crate::Result<Arc<Self::Channel>> { use tor_rtcompat::SleepProviderExt; Loading @@ -54,7 +53,7 @@ impl<R: Runtime> ChanBuilder<R> { /// As build_channel, but don't include a timeout. async fn build_channel_notimeout( &self, target: &TargetInfo, target: &OwnedChanTarget, ) -> crate::Result<Arc<tor_proto::channel::Channel>> { use tor_proto::channel::ChannelBuilder; use tor_rtcompat::tls::CertifiedConn; Loading Loading @@ -107,47 +106,6 @@ impl crate::mgr::AbstractChannel for tor_proto::channel::Channel { } } /// TargetInfo is a summary of a [`ChanTarget`] that we can pass to /// [`ChanBuilder`]. /// /// This is a separate type since we can't declare ChanBuilder as having /// a parameterized method in today's Rust. #[derive(Debug, Clone)] pub(crate) struct TargetInfo { /// Copy of the addresses from the underlying ChanTarget. addrs: Vec<SocketAddr>, /// Copy of the ed25519 id from the underlying ChanTarget. ed_identity: pk::ed25519::Ed25519Identity, /// Copy of the rsa id from the underlying ChanTarget. rsa_identity: pk::rsa::RsaIdentity, } impl ChanTarget for TargetInfo { fn addrs(&self) -> &[SocketAddr] { &self.addrs[..] } fn ed_identity(&self) -> &pk::ed25519::Ed25519Identity { &self.ed_identity } fn rsa_identity(&self) -> &pk::rsa::RsaIdentity { &self.rsa_identity } } impl TargetInfo { /// Construct a TargetInfo from a given ChanTarget. pub(crate) fn from_chan_target<C>(target: &C) -> Self where C: ChanTarget + ?Sized, { TargetInfo { addrs: target.addrs().to_vec(), ed_identity: *target.ed_identity(), rsa_identity: *target.rsa_identity(), } } } #[cfg(test)] mod test { use super::*; Loading @@ -157,25 +115,12 @@ mod test { }; use pk::ed25519::Ed25519Identity; use pk::rsa::RsaIdentity; use std::net::SocketAddr; use std::time::{Duration, SystemTime}; use tor_proto::channel::Channel; use tor_rtcompat::{test_with_runtime, TcpListener}; use tor_rtmock::{io::LocalStream, net::MockNetwork, MockSleepRuntime}; #[test] fn targetinfo() { let ti = TargetInfo { addrs: vec!["127.0.0.1:11".parse().unwrap()], ed_identity: [42; 32].into(), rsa_identity: [45; 20].into(), }; let ti2 = TargetInfo::from_chan_target(&ti); assert_eq!(ti.addrs, ti2.addrs); assert_eq!(ti.ed_identity, ti2.ed_identity); assert_eq!(ti.rsa_identity, ti2.rsa_identity); } // Make sure that the builder can build a real channel. To test // this out, we set up a listener that pretends to have the right // IP, fake the current time, and use a canned response from Loading @@ -188,11 +133,7 @@ mod test { let rsa: RsaIdentity = msgs::RSA_ID.into(); let client_addr = "192.0.2.17".parse().unwrap(); let tls_cert = msgs::X509_CERT.into(); let target = TargetInfo { addrs: vec![orport], ed_identity: ed, rsa_identity: rsa, }; let target = OwnedChanTarget::new(vec![orport], ed, rsa); let now = SystemTime::UNIX_EPOCH + Duration::new(msgs::NOW, 0); test_with_runtime(|rt| async move { Loading tor-chanmgr/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,7 @@ impl<R: Runtime> ChanMgr<R> { /// or fail depending on its outcome. pub async fn get_or_launch<T: ChanTarget + ?Sized>(&self, target: &T) -> Result<Arc<Channel>> { let ed_identity = target.ed_identity(); let targetinfo = builder::TargetInfo::from_chan_target(target); let targetinfo = target.to_owned(); let chan = self.mgr.get_or_launch(*ed_identity, targetinfo).await?; // Double-check the match to make sure that the RSA identity is Loading tor-linkspec/src/lib.rs +2 −0 Original line number Diff line number Diff line Loading @@ -58,7 +58,9 @@ #![warn(clippy::unseparated_literal_suffix)] mod ls; mod owned; mod traits; pub use ls::LinkSpec; pub use owned::{OwnedChanTarget, OwnedCircTarget}; pub use traits::{ChanTarget, CircTarget}; tor-linkspec/src/owned.rs 0 → 100644 +125 −0 Original line number Diff line number Diff line //! Owned variants of [`ChanTarget`] and [`CircTarget`]. use std::net::SocketAddr; use tor_llcrypto::pk; use crate::{ChanTarget, CircTarget}; /// OwnedChanTarget is a summary of a [`ChanTarget`] that owns all of its /// members. #[derive(Debug, Clone)] pub struct OwnedChanTarget { /// Copy of the addresses from the underlying ChanTarget. addrs: Vec<SocketAddr>, /// Copy of the ed25519 id from the underlying ChanTarget. ed_identity: pk::ed25519::Ed25519Identity, /// Copy of the rsa id from the underlying ChanTarget. rsa_identity: pk::rsa::RsaIdentity, } impl ChanTarget for OwnedChanTarget { fn addrs(&self) -> &[SocketAddr] { &self.addrs[..] } fn ed_identity(&self) -> &pk::ed25519::Ed25519Identity { &self.ed_identity } fn rsa_identity(&self) -> &pk::rsa::RsaIdentity { &self.rsa_identity } } impl OwnedChanTarget { /// Construct a new OwnedChanTarget from its parts. // TODO: Put this function behind a feature. pub fn new( addrs: Vec<SocketAddr>, ed_identity: pk::ed25519::Ed25519Identity, rsa_identity: pk::rsa::RsaIdentity, ) -> Self { Self { addrs, ed_identity, rsa_identity, } } /// Construct a OwnedChanTarget from a given ChanTarget. pub fn from_chan_target<C>(target: &C) -> Self where C: ChanTarget + ?Sized, { OwnedChanTarget { addrs: target.addrs().to_vec(), ed_identity: *target.ed_identity(), rsa_identity: *target.rsa_identity(), } } } /// OwnedCircTarget is a summary of a [`CircTarget`] that owns all its /// members. #[derive(Debug, Clone)] pub struct OwnedCircTarget { /// The fields from this object when considered as a ChanTarget. chan_target: OwnedChanTarget, /// The ntor key to use when extending to this CircTarget ntor_onion_key: pk::curve25519::PublicKey, /// The subprotocol versions that this CircTarget supports. protovers: tor_protover::Protocols, } impl OwnedCircTarget { /// Construct an OwnedCircTarget from a given CircTarget. pub fn from_circ_target<C>(target: &C) -> Self where C: CircTarget + ?Sized, { OwnedCircTarget { chan_target: OwnedChanTarget::from_chan_target(target), ntor_onion_key: *target.ntor_onion_key(), // TODO: I don't like having to clone here. Our underlying // protovers parsing uses an Arc, IIRC. Can we expose that here? protovers: target.protovers().clone(), } } } impl ChanTarget for OwnedCircTarget { fn addrs(&self) -> &[SocketAddr] { self.chan_target.addrs() } fn ed_identity(&self) -> &pk::ed25519::Ed25519Identity { self.chan_target.ed_identity() } fn rsa_identity(&self) -> &pk::rsa::RsaIdentity { self.chan_target.rsa_identity() } } impl CircTarget for OwnedCircTarget { fn ntor_onion_key(&self) -> &pk::curve25519::PublicKey { &self.ntor_onion_key } fn protovers(&self) -> &tor_protover::Protocols { &self.protovers } } #[cfg(test)] mod test { use super::*; #[test] fn targetinfo() { let ti = OwnedChanTarget::new( vec!["127.0.0.1:11".parse().unwrap()], [42; 32].into(), [45; 20].into(), ); let ti2 = OwnedChanTarget::from_chan_target(&ti); assert_eq!(ti.addrs(), ti2.addrs()); assert_eq!(ti.ed_identity(), ti2.ed_identity()); assert_eq!(ti.rsa_identity(), ti2.rsa_identity()); } } tor-linkspec/src/traits.rs +6 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,12 @@ pub trait ChanTarget { } /// Return the RSA identity for this relay. fn rsa_identity(&self) -> &pk::rsa::RsaIdentity; /// Return a new [`crate::OwnedChanTarget`] containing a copy /// of the information in this `ChanTarget`. fn to_owned(&self) -> crate::OwnedChanTarget { crate::OwnedChanTarget::from_chan_target(self) } } /// Information about a Tor relay used to extend a circuit to it. Loading Loading
tor-chanmgr/src/builder.rs +5 −64 Original line number Diff line number Diff line Loading @@ -2,13 +2,12 @@ use crate::Error; use tor_linkspec::ChanTarget; use tor_linkspec::{ChanTarget, OwnedChanTarget}; use tor_llcrypto::pk; use tor_rtcompat::{tls::TlsConnector, Runtime, TlsProvider}; use async_trait::async_trait; use futures::task::SpawnExt; use std::net::SocketAddr; use std::sync::Arc; /// TLS-based channel builder. Loading Loading @@ -36,7 +35,7 @@ impl<R: Runtime> ChanBuilder<R> { #[async_trait] impl<R: Runtime> crate::mgr::ChannelFactory for ChanBuilder<R> { type Channel = tor_proto::channel::Channel; type BuildSpec = TargetInfo; type BuildSpec = OwnedChanTarget; async fn build_channel(&self, target: &Self::BuildSpec) -> crate::Result<Arc<Self::Channel>> { use tor_rtcompat::SleepProviderExt; Loading @@ -54,7 +53,7 @@ impl<R: Runtime> ChanBuilder<R> { /// As build_channel, but don't include a timeout. async fn build_channel_notimeout( &self, target: &TargetInfo, target: &OwnedChanTarget, ) -> crate::Result<Arc<tor_proto::channel::Channel>> { use tor_proto::channel::ChannelBuilder; use tor_rtcompat::tls::CertifiedConn; Loading Loading @@ -107,47 +106,6 @@ impl crate::mgr::AbstractChannel for tor_proto::channel::Channel { } } /// TargetInfo is a summary of a [`ChanTarget`] that we can pass to /// [`ChanBuilder`]. /// /// This is a separate type since we can't declare ChanBuilder as having /// a parameterized method in today's Rust. #[derive(Debug, Clone)] pub(crate) struct TargetInfo { /// Copy of the addresses from the underlying ChanTarget. addrs: Vec<SocketAddr>, /// Copy of the ed25519 id from the underlying ChanTarget. ed_identity: pk::ed25519::Ed25519Identity, /// Copy of the rsa id from the underlying ChanTarget. rsa_identity: pk::rsa::RsaIdentity, } impl ChanTarget for TargetInfo { fn addrs(&self) -> &[SocketAddr] { &self.addrs[..] } fn ed_identity(&self) -> &pk::ed25519::Ed25519Identity { &self.ed_identity } fn rsa_identity(&self) -> &pk::rsa::RsaIdentity { &self.rsa_identity } } impl TargetInfo { /// Construct a TargetInfo from a given ChanTarget. pub(crate) fn from_chan_target<C>(target: &C) -> Self where C: ChanTarget + ?Sized, { TargetInfo { addrs: target.addrs().to_vec(), ed_identity: *target.ed_identity(), rsa_identity: *target.rsa_identity(), } } } #[cfg(test)] mod test { use super::*; Loading @@ -157,25 +115,12 @@ mod test { }; use pk::ed25519::Ed25519Identity; use pk::rsa::RsaIdentity; use std::net::SocketAddr; use std::time::{Duration, SystemTime}; use tor_proto::channel::Channel; use tor_rtcompat::{test_with_runtime, TcpListener}; use tor_rtmock::{io::LocalStream, net::MockNetwork, MockSleepRuntime}; #[test] fn targetinfo() { let ti = TargetInfo { addrs: vec!["127.0.0.1:11".parse().unwrap()], ed_identity: [42; 32].into(), rsa_identity: [45; 20].into(), }; let ti2 = TargetInfo::from_chan_target(&ti); assert_eq!(ti.addrs, ti2.addrs); assert_eq!(ti.ed_identity, ti2.ed_identity); assert_eq!(ti.rsa_identity, ti2.rsa_identity); } // Make sure that the builder can build a real channel. To test // this out, we set up a listener that pretends to have the right // IP, fake the current time, and use a canned response from Loading @@ -188,11 +133,7 @@ mod test { let rsa: RsaIdentity = msgs::RSA_ID.into(); let client_addr = "192.0.2.17".parse().unwrap(); let tls_cert = msgs::X509_CERT.into(); let target = TargetInfo { addrs: vec![orport], ed_identity: ed, rsa_identity: rsa, }; let target = OwnedChanTarget::new(vec![orport], ed, rsa); let now = SystemTime::UNIX_EPOCH + Duration::new(msgs::NOW, 0); test_with_runtime(|rt| async move { Loading
tor-chanmgr/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,7 @@ impl<R: Runtime> ChanMgr<R> { /// or fail depending on its outcome. pub async fn get_or_launch<T: ChanTarget + ?Sized>(&self, target: &T) -> Result<Arc<Channel>> { let ed_identity = target.ed_identity(); let targetinfo = builder::TargetInfo::from_chan_target(target); let targetinfo = target.to_owned(); let chan = self.mgr.get_or_launch(*ed_identity, targetinfo).await?; // Double-check the match to make sure that the RSA identity is Loading
tor-linkspec/src/lib.rs +2 −0 Original line number Diff line number Diff line Loading @@ -58,7 +58,9 @@ #![warn(clippy::unseparated_literal_suffix)] mod ls; mod owned; mod traits; pub use ls::LinkSpec; pub use owned::{OwnedChanTarget, OwnedCircTarget}; pub use traits::{ChanTarget, CircTarget};
tor-linkspec/src/owned.rs 0 → 100644 +125 −0 Original line number Diff line number Diff line //! Owned variants of [`ChanTarget`] and [`CircTarget`]. use std::net::SocketAddr; use tor_llcrypto::pk; use crate::{ChanTarget, CircTarget}; /// OwnedChanTarget is a summary of a [`ChanTarget`] that owns all of its /// members. #[derive(Debug, Clone)] pub struct OwnedChanTarget { /// Copy of the addresses from the underlying ChanTarget. addrs: Vec<SocketAddr>, /// Copy of the ed25519 id from the underlying ChanTarget. ed_identity: pk::ed25519::Ed25519Identity, /// Copy of the rsa id from the underlying ChanTarget. rsa_identity: pk::rsa::RsaIdentity, } impl ChanTarget for OwnedChanTarget { fn addrs(&self) -> &[SocketAddr] { &self.addrs[..] } fn ed_identity(&self) -> &pk::ed25519::Ed25519Identity { &self.ed_identity } fn rsa_identity(&self) -> &pk::rsa::RsaIdentity { &self.rsa_identity } } impl OwnedChanTarget { /// Construct a new OwnedChanTarget from its parts. // TODO: Put this function behind a feature. pub fn new( addrs: Vec<SocketAddr>, ed_identity: pk::ed25519::Ed25519Identity, rsa_identity: pk::rsa::RsaIdentity, ) -> Self { Self { addrs, ed_identity, rsa_identity, } } /// Construct a OwnedChanTarget from a given ChanTarget. pub fn from_chan_target<C>(target: &C) -> Self where C: ChanTarget + ?Sized, { OwnedChanTarget { addrs: target.addrs().to_vec(), ed_identity: *target.ed_identity(), rsa_identity: *target.rsa_identity(), } } } /// OwnedCircTarget is a summary of a [`CircTarget`] that owns all its /// members. #[derive(Debug, Clone)] pub struct OwnedCircTarget { /// The fields from this object when considered as a ChanTarget. chan_target: OwnedChanTarget, /// The ntor key to use when extending to this CircTarget ntor_onion_key: pk::curve25519::PublicKey, /// The subprotocol versions that this CircTarget supports. protovers: tor_protover::Protocols, } impl OwnedCircTarget { /// Construct an OwnedCircTarget from a given CircTarget. pub fn from_circ_target<C>(target: &C) -> Self where C: CircTarget + ?Sized, { OwnedCircTarget { chan_target: OwnedChanTarget::from_chan_target(target), ntor_onion_key: *target.ntor_onion_key(), // TODO: I don't like having to clone here. Our underlying // protovers parsing uses an Arc, IIRC. Can we expose that here? protovers: target.protovers().clone(), } } } impl ChanTarget for OwnedCircTarget { fn addrs(&self) -> &[SocketAddr] { self.chan_target.addrs() } fn ed_identity(&self) -> &pk::ed25519::Ed25519Identity { self.chan_target.ed_identity() } fn rsa_identity(&self) -> &pk::rsa::RsaIdentity { self.chan_target.rsa_identity() } } impl CircTarget for OwnedCircTarget { fn ntor_onion_key(&self) -> &pk::curve25519::PublicKey { &self.ntor_onion_key } fn protovers(&self) -> &tor_protover::Protocols { &self.protovers } } #[cfg(test)] mod test { use super::*; #[test] fn targetinfo() { let ti = OwnedChanTarget::new( vec!["127.0.0.1:11".parse().unwrap()], [42; 32].into(), [45; 20].into(), ); let ti2 = OwnedChanTarget::from_chan_target(&ti); assert_eq!(ti.addrs(), ti2.addrs()); assert_eq!(ti.ed_identity(), ti2.ed_identity()); assert_eq!(ti.rsa_identity(), ti2.rsa_identity()); } }
tor-linkspec/src/traits.rs +6 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,12 @@ pub trait ChanTarget { } /// Return the RSA identity for this relay. fn rsa_identity(&self) -> &pk::rsa::RsaIdentity; /// Return a new [`crate::OwnedChanTarget`] containing a copy /// of the information in this `ChanTarget`. fn to_owned(&self) -> crate::OwnedChanTarget { crate::OwnedChanTarget::from_chan_target(self) } } /// Information about a Tor relay used to extend a circuit to it. Loading