Make ChannelMethod non-exhaustive

Enums with variants conditional on cargo features must be
non-exhaustive, because cargo features are supposed to be additive,
meaning that enabling a feature (which might happen due to some random
distant thing) ought not to break things using that enum.

There were surprisingly few places to fix this.
This commit is contained in:
Ian Jackson 2022-11-23 17:04:38 +00:00
parent 90a1a10b3c
commit 1a39a0c7e9
5 changed files with 35 additions and 2 deletions

View File

@ -278,6 +278,12 @@ impl<R: TcpProvider + Send + Sync> TransportHelper for ExternalProxyPlugin<R> {
))) )))
} }
ChannelMethod::Pluggable(target) => target, ChannelMethod::Pluggable(target) => target,
other => {
return Err(crate::Error::UnusableTarget(bad_api_usage!(
"Used unknown, unsupported, transport {:?} for a TCP connection.",
other,
)))
}
}; };
let protocol = settings_to_protocol(encode_settings(pt_target.settings()))?; let protocol = settings_to_protocol(encode_settings(pt_target.settings()))?;

View File

@ -76,7 +76,9 @@ struct Inner {
/// Address and transport via which the bridge can be reached, and /// Address and transport via which the bridge can be reached, and
/// the parameters for those transports. /// the parameters for those transports.
/// ///
/// Restriction: This `addrs` may NOT contain more than one address. /// Restriction: This `addrs` may NOT contain more than one address,
/// and it must be a variant supported by the code in this crate:
/// ie, currently, `Direct` or `Pluggable`.
addrs: ChannelMethod, addrs: ChannelMethod,
/// The RSA identity of the bridge. /// The RSA identity of the bridge.
@ -366,6 +368,11 @@ impl FromStr for BridgeConfigBuilder {
let (transport, addr, settings) = target.into_parts(); let (transport, addr, settings) = target.into_parts();
(transport.into_inner(), vec![addr], settings.into_inner()) (transport.into_inner(), vec![addr], settings.into_inner())
} }
other => {
return Err(BridgeParseError::UnsupportedChannelMethod {
method: Box::new(other),
});
}
}; };
let ids = chain!( let ids = chain!(
@ -518,6 +525,7 @@ impl FromStr for Inner {
source, source,
} }
})?, })?,
other => panic!("made ourselves an unsupported ChannelMethod {:?}", other),
} }
} }
@ -556,6 +564,12 @@ impl Display for BridgeConfig {
write!(f, "{} {}", target.transport(), target.addr())?; write!(f, "{} {}", target.transport(), target.addr())?;
Some(target.settings()) Some(target.settings())
} }
_ => {
// This shouldn't happen, but panicking seems worse than outputting this
write!(f, "[unsupported channel method, cannot display properly]")?;
return Ok(());
}
}; };
// * One or more identity key fingerprints, // * One or more identity key fingerprints,

View File

@ -5,6 +5,8 @@
use thiserror::Error; use thiserror::Error;
use tor_linkspec::ChannelMethod;
/// Error when parsing a bridge line from a string /// Error when parsing a bridge line from a string
#[derive(Error, Clone, Debug)] #[derive(Error, Clone, Debug)]
#[non_exhaustive] #[non_exhaustive]
@ -94,6 +96,16 @@ pub enum BridgeParseError {
word: String, word: String,
}, },
/// Channel method specified of unsupported type
///
/// This can only occur with unusual (unsupported) combinations of cargo features,
/// or building an older `tor-guardmgr` against a newer `tor-linkspec`.
#[error("Channel method specified but not of supported type ({method:?})")]
UnsupportedChannelMethod {
/// The not-understood method
method: Box<ChannelMethod>,
},
/// Parameters may only be specified with a pluggable transport /// Parameters may only be specified with a pluggable transport
#[cfg(feature = "bridge-client")] #[cfg(feature = "bridge-client")]
#[error("Parameters supplied but not valid without a pluggable transport")] #[error("Parameters supplied but not valid without a pluggable transport")]

View File

@ -9,3 +9,4 @@ BREAKING: Replaced functions to strip addresses from ChanMethod.
BREAKING: Remove impl Display for OwnedCircTarget. BREAKING: Remove impl Display for OwnedCircTarget.
ADDED: Provide deconstructors for PtTargetSettings and PtTarget ADDED: Provide deconstructors for PtTargetSettings and PtTarget
MODIFIED: Renaming PtTargetAddr to BridgeAddr (in progress, will become BREAKING) MODIFIED: Renaming PtTargetAddr to BridgeAddr (in progress, will become BREAKING)
BREAKING: ChannelMethod is now non-exhaustive

View File

@ -457,7 +457,7 @@ impl PtTarget {
/// pluggable transport, this includes information about the transport, and any /// pluggable transport, this includes information about the transport, and any
/// address and settings information that transport requires. /// address and settings information that transport requires.
#[derive(Clone, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[allow(clippy::exhaustive_enums)] #[non_exhaustive]
pub enum ChannelMethod { pub enum ChannelMethod {
/// Connect to the relay directly at one of several addresses. /// Connect to the relay directly at one of several addresses.
Direct(Vec<std::net::SocketAddr>), Direct(Vec<std::net::SocketAddr>),