BridgeRelay: Implement more traits.

Also add a BridgeRelayWithDesc type (name tbd) to guarantee that
a bridge relay really does have a known descriptor before you
try to build a circuit with it.
This commit is contained in:
Nick Mathewson 2022-10-04 13:34:23 -04:00
parent acb6288621
commit 23b3b0553f
3 changed files with 59 additions and 2 deletions

1
Cargo.lock generated
View File

@ -3704,6 +3704,7 @@ dependencies = [
"tor-netdoc",
"tor-persist",
"tor-proto",
"tor-protover",
"tor-rtcompat",
"tor-rtmock",
"tor-units",

View File

@ -19,7 +19,7 @@ experimental = ["bridge-client"]
# Support for using bridges as a client. Note that this is not the same as
# the pt-client feature, since here we are not concerned with
# pluggable transports necessarily.
bridge-client = ["tor-netdoc/routerdesc"]
bridge-client = ["tor-netdoc/routerdesc", "tor-protover"]
# Support for pluggable transports.
pt-client = ["bridge-client", "tor-linkspec/pt-client"]
@ -51,6 +51,7 @@ tor-netdir = { path = "../tor-netdir", version = "0.6.0" }
tor-netdoc = { path = "../tor-netdoc", version = "0.5.2" } # for address pattern
tor-persist = { path = "../tor-persist", version = "0.5.1" }
tor-proto = { path = "../tor-proto", version = "0.7.0" }
tor-protover = { path = "../tor-protover", version = "0.3.2", optional = true }
tor-rtcompat = { path = "../tor-rtcompat", version = "0.7.0" }
tor-units = { path = "../tor-units", version = "0.3.1" }
tracing = "0.1.18"

View File

@ -2,7 +2,7 @@
use std::sync::Arc;
use tor_linkspec::{HasRelayIds, RelayIdRef, RelayIdType};
use tor_linkspec::{ChanTarget, CircTarget, HasAddrs, HasRelayIds, RelayIdRef, RelayIdType};
use super::{Bridge, BridgeDesc};
@ -22,11 +22,26 @@ pub struct BridgeRelay {
desc: Option<BridgeDesc>,
}
/// A BridgeRelay that is known to have its full information available, and
/// which is therefore usable for circuits.
#[derive(Clone, Debug)]
pub struct BridgeRelayWithDesc<'a>(
/// This will _always_ be a bridge relay with a non-None desc.
&'a BridgeRelay,
);
impl BridgeRelay {
/// Return true if this BridgeRelay has a known descriptor and can be used for relays.
pub fn has_descriptor(&self) -> bool {
self.desc.is_some()
}
/// If we have enough information about this relay to build a circuit through it,
/// return a BridgeRelayWithDesc for it.
// TODO pt-client rename XXXX
pub fn for_circuit_usage(&self) -> Option<BridgeRelayWithDesc<'_>> {
self.desc.is_some().then(|| BridgeRelayWithDesc(self))
}
}
impl HasRelayIds for BridgeRelay {
@ -36,3 +51,43 @@ impl HasRelayIds for BridgeRelay {
.or_else(|| self.desc.as_ref().and_then(|d| d.identity(key_type)))
}
}
impl HasAddrs for BridgeRelay {
fn addrs(&self) -> &[std::net::SocketAddr] {
todo!()
}
}
impl ChanTarget for BridgeRelay {}
impl<'a> HasRelayIds for BridgeRelayWithDesc<'a> {
fn identity(&self, key_type: RelayIdType) -> Option<RelayIdRef<'_>> {
self.0.identity(key_type)
}
}
impl<'a> HasAddrs for BridgeRelayWithDesc<'a> {
fn addrs(&self) -> &[std::net::SocketAddr] {
self.0.addrs()
}
}
impl<'a> ChanTarget for BridgeRelayWithDesc<'a> {}
impl<'a> BridgeRelayWithDesc<'a> {
/// Return a reference to the BridgeDesc in this reference.
fn desc(&self) -> &BridgeDesc {
self.0
.desc
.as_ref()
.expect("There was supposed to be a descriptor here")
}
}
impl<'a> CircTarget for BridgeRelayWithDesc<'a> {
fn ntor_onion_key(&self) -> &tor_llcrypto::pk::curve25519::PublicKey {
self.desc().as_ref().ntor_onion_key()
}
fn protovers(&self) -> &tor_protover::Protocols {
self.desc().as_ref().protocols()
}
}