Commit 199a6e07 authored by Ian Jackson's avatar Ian Jackson
Browse files

Separate BridgeAddr and PtTargetAddr

As per
  tpo/core/arti#668 (comment 2858220)

This commit is difficult to split up.

The innards of BridgeAddr and PtTargetAddr are still a bit entangled.
parent 45529545
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ use crate::{event::ChanMgrEventSender, Error};

use std::time::Duration;
use tor_error::internal;
use tor_linkspec::{HasChanMethod, IntoOwnedChanTarget, OwnedChanTarget};
use tor_linkspec::{BridgeAddr, HasChanMethod, IntoOwnedChanTarget, OwnedChanTarget};
use tor_proto::channel::params::ChannelPaddingInstructionsUpdates;
use tor_rtcompat::{tls::TlsConnector, Runtime, TlsProvider};

@@ -110,9 +110,13 @@ where
        let peer_ref = &peer;

        let map_ioe = |action: &'static str| {
            let peer: Option<BridgeAddr> = peer_ref.as_ref().and_then(|peer| {
                let peer: Option<BridgeAddr> = peer.clone().into();
                peer
            });
            move |ioe: io::Error| Error::Io {
                action,
                peer: peer_ref.clone().map(Into::into),
                peer: peer.map(Into::into),
                source: ioe.into(),
            }
        };
+5 −5
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ use std::{

use futures::{AsyncReadExt, AsyncWriteExt};
use tor_error::internal;
use tor_linkspec::BridgeAddr;
use tor_linkspec::PtTargetAddr;
use tor_rtcompat::TcpProvider;
use tor_socksproto::{
    SocksAddr, SocksAuth, SocksClientHandshake, SocksCmd, SocksRequest, SocksStatus, SocksVersion,
@@ -67,7 +67,7 @@ pub(crate) async fn connect_via_proxy<R: TcpProvider + Send + Sync>(
    runtime: &R,
    proxy: &SocketAddr,
    protocol: &Protocol,
    target: &BridgeAddr,
    target: &PtTargetAddr,
) -> Result<R::TcpStream, ProxyError> {
    let mut stream = runtime
        .connect(proxy)
@@ -77,9 +77,9 @@ pub(crate) async fn connect_via_proxy<R: TcpProvider + Send + Sync>(
    let Protocol::Socks(version, auth) = protocol;

    let (target_addr, target_port): (tor_socksproto::SocksAddr, u16) = match target {
        BridgeAddr::IpPort(a) => (SocksAddr::Ip(a.ip()), a.port()),
        PtTargetAddr::IpPort(a) => (SocksAddr::Ip(a.ip()), a.port()),
        #[cfg(feature = "pt-client")]
        BridgeAddr::HostPort(host, port) => (
        PtTargetAddr::HostPort(host, port) => (
            SocksAddr::Hostname(
                host.clone()
                    .try_into()
@@ -88,7 +88,7 @@ pub(crate) async fn connect_via_proxy<R: TcpProvider + Send + Sync>(
            *port,
        ),
        #[cfg(feature = "pt-client")]
        BridgeAddr::None => (SocksAddr::Ip(NO_ADDR), 1),
        PtTargetAddr::None => (SocksAddr::Ip(NO_ADDR), 1),
        _ => return Err(ProxyError::UnrecognizedAddr),
    };

+30 −22
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ use tor_config::{impl_standard_builder, ConfigBuildError};
use tor_linkspec::RelayId;
use tor_linkspec::TransportId;
use tor_linkspec::{ChanTarget, ChannelMethod, HasChanMethod};
use tor_linkspec::{HasAddrs, HasRelayIds, RelayIdRef, RelayIdType};
use tor_linkspec::{HasAddrs, HasRelayIds, PtTargetAddr, RelayIdRef, RelayIdType};
use tor_llcrypto::pk::{ed25519::Ed25519Identity, rsa::RsaIdentity};

use tor_linkspec::BridgeAddr;
@@ -236,15 +236,18 @@ impl BridgeConfigBuilder {
                        "Specified `settings` for a direct bridge connection",
                    ));
                }
                let addrs = addrs.iter().filter_map(|pta| match pta {
                BridgeAddr::IpPort(sa) => Some(Ok(*sa)),
                BridgeAddr::HostPort(..) => Some(Err(
                let addrs = addrs.iter().filter_map(|ba| {
                    #[allow(clippy::redundant_pattern_matching)] // for consistency
                    if let Some(sa) = ba.addr_as_sockaddr() {
                        Some(Ok(*sa))
                    } else if let Some(_) = ba.named_as_host_port() {
                        Some(Err(
                            "`addrs` contains hostname and port, but only numeric addresses are supported for a direct bridge connection",
                )),
                BridgeAddr::None => None,
                _ => Some(Err(
                    "`addrs` contains unspported target address type, but only numeric addresses are supported for a direct bridge connection"
                )),
                        ))
                    } else {
                        // panic! causes a clippy complaint, so panic like this
                        None.expect("BridgeAddr is neither addr nor named")
                    }
                }).collect::<Result<Vec<SocketAddr>,&str>>().map_err(|problem| inconsist_transp(
                    "addrs",
                    problem,
@@ -263,8 +266,8 @@ impl BridgeConfigBuilder {
                let transport = transp.into_pluggable().expect("became not pluggable!");
                let addr =
                    match addrs {
                        [] => BridgeAddr::None,
                        [addr] => addr.clone(),
                        [] => PtTargetAddr::None,
                        [addr] => Some(addr.clone()).into(),
                        [_, _, ..] => return Err(inconsist_transp(
                            "addrs",
                            "Transport (non-direct bridge) only supports a single nominal address",
@@ -357,13 +360,18 @@ impl FromStr for BridgeConfigBuilder {
        let (transport, addrs, settings) = match bridge.addrs {
            ChannelMethod::Direct(addrs) => (
                "".into(),
                addrs.into_iter().map(BridgeAddr::IpPort).collect(),
                addrs
                    .into_iter()
                    .map(BridgeAddr::new_addr_from_sockaddr)
                    .collect(),
                vec![],
            ),
            #[cfg(feature = "pt-client")]
            ChannelMethod::Pluggable(target) => {
                let (transport, addr, settings) = target.into_parts();
                (transport.to_string(), vec![addr], settings.into_inner())
                let addr: Option<BridgeAddr> = addr.into();
                let addrs = addr.into_iter().collect_vec();
                (transport.to_string(), addrs, settings.into_inner())
            }
            other => {
                return Err(BridgeParseError::UnsupportedChannelMethod {
@@ -455,7 +463,7 @@ impl FromStr for Inner {
                            word: word.to_string(),
                            source,
                        })?
                        .unwrap_or(BridgeAddr::None);
                        .unwrap_or(PtTargetAddr::None);
                    ChannelMethod::Pluggable(PtTarget::new(pt_name, addr))
                }
            }
@@ -605,7 +613,7 @@ mod test {
    use super::*;

    #[cfg(feature = "pt-client")]
    fn mk_pt_target(name: &str, addr: BridgeAddr, params: &[(&str, &str)]) -> ChannelMethod {
    fn mk_pt_target(name: &str, addr: PtTargetAddr, params: &[(&str, &str)]) -> ChannelMethod {
        let mut target = PtTarget::new(name.parse().unwrap(), addr);
        for &(k, v) in params {
            target.push_setting(k, v).unwrap();
@@ -667,7 +675,7 @@ mod test {
        ], Inner {
            addrs: mk_pt_target(
                "obfs4",
                BridgeAddr::IpPort("38.229.33.83:80".parse().unwrap()),
                PtTargetAddr::IpPort("38.229.33.83:80".parse().unwrap()),
                &[
                    ("cert", "VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1Op" ),
                    ("iat-mode", "1"),
@@ -684,7 +692,7 @@ mod test {
        ], Inner {
            addrs: mk_pt_target(
                "obfs4",
                BridgeAddr::HostPort("some-host".into(), 80),
                PtTargetAddr::HostPort("some-host".into(), 80),
                &[
                    ("iat-mode", "1"),
                ],
+3 −1
Original line number Diff line number Diff line
@@ -58,4 +58,6 @@ pub use traits::{
    HasRelayIdsLegacy,
};
pub use transport::{BridgeAddr, BridgeAddrError, ChannelMethod, TransportId, TransportIdError};
pub use transport::{PtTarget, PtTargetInvalidSetting, PtTargetSettings, PtTransportName};
pub use transport::{
    PtTarget, PtTargetAddr, PtTargetInvalidSetting, PtTargetSettings, PtTransportName,
};
+2 −2
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ use std::{fmt, iter::FusedIterator, net::SocketAddr};
use strum::IntoEnumIterator;
use tor_llcrypto::pk;

use crate::{BridgeAddr, ChannelMethod, RelayIdRef, RelayIdType, RelayIdTypeIter};
use crate::{ChannelMethod, PtTargetAddr, RelayIdRef, RelayIdType, RelayIdTypeIter};

/// Legacy implementation helper for HasRelayIds.
///
@@ -257,7 +257,7 @@ impl<'a, T: ChanTarget> DisplayChanTarget<'a, T> {
            #[cfg(feature = "pt-client")]
            ChannelMethod::Pluggable(target) => {
                match target.addr() {
                    BridgeAddr::None => {}
                    PtTargetAddr::None => {}
                    other => write!(f, "{} ", other.maybe_redacted(redact))?,
                }
                write!(f, "via {}", target.transport())?;
Loading