From 81b56ea4c6d95f8751d2e52290ea98ce917a52fe Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 3 Oct 2024 10:26:26 -0700 Subject: [PATCH] Add v1 only detection --- protocol/src/lib.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 7b3cb7b..a310c50 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -976,7 +976,11 @@ impl<'a> Handshake<'a> { #[cfg(feature = "std")] #[derive(Debug)] pub enum ProtocolError { + /// Wrap an IO errors. Io(std::io::Error), + /// Remote party likely only supports V1 protocol. + IncompatibleProtocol, + /// Internal protocol specific errors. Internal(Error), } @@ -1001,8 +1005,11 @@ impl std::error::Error for ProtocolError {} impl fmt::Display for ProtocolError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - ProtocolError::Io(e) => write!(f, "IO error: {:?}", e), - ProtocolError::Internal(e) => write!(f, "Internal error: {:?}", e), + ProtocolError::Io(e) => write!(f, "IO error: {:?}.", e), + ProtocolError::Internal(e) => write!(f, "Internal error: {:?}.", e), + ProtocolError::IncompatibleProtocol => { + write!(f, "Remote likely only supports V1 protocol.") + } } } } @@ -1061,7 +1068,16 @@ where // Read remote's initial key. let mut remote_ellswift_buffer = [0u8; 64]; - reader.read_exact(&mut remote_ellswift_buffer).await?; + // Try to detect errors which likely mean the remote doesn't understand + // the V2 protocol and the caller should re-attempt on V1 if they want. + if let Err(e) = reader.read_exact(&mut remote_ellswift_buffer).await { + return match e.kind() { + std::io::ErrorKind::UnexpectedEof + | std::io::ErrorKind::ConnectionReset + | std::io::ErrorKind::TimedOut => Err(ProtocolError::IncompatibleProtocol), + _ => Err(ProtocolError::Io(e)), + }; + } let num_version_packet_bytes = PacketWriter::required_packet_allocation(&VERSION_CONTENT); let num_decoy_packets_bytes: usize = match decoys {