From 5418a16cf9d2eeeadc49605caedc7ed2369f76f7 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Tue, 16 Nov 2021 12:59:04 +0100 Subject: [PATCH] Define PeerConnectionType enum. --- client/src/client.rs | 6 ++-- proto/src/peer/message.rs | 67 ++++++++++++++++++++++++++++++++++-- proto/src/server/request.rs | 10 +++--- proto/src/server/response.rs | 5 +-- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index b1501ed..89ebed6 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -34,7 +34,7 @@ struct Peer { user_name: String, ip: net::Ipv4Addr, port: u16, - connection_type: String, + connection_type: peer::PeerConnectionType, token: u32, state: PeerState, } @@ -302,7 +302,7 @@ impl Client { server::ConnectToPeerRequest { token: peer.token, user_name: peer.user_name.clone(), - connection_type: peer.connection_type.clone(), + connection_type: peer.connection_type, } .into(), )) @@ -376,7 +376,7 @@ impl Client { // Send a PeerInit. peer::Message::PeerInit(peer::PeerInit { user_name: self.config.credentials.user_name().to_string(), - connection_type: peer.connection_type.clone(), + connection_type: peer.connection_type, token: peer.token, }) } diff --git a/proto/src/peer/message.rs b/proto/src/peer/message.rs index 6d4f916..3309422 100644 --- a/proto/src/peer/message.rs +++ b/proto/src/peer/message.rs @@ -63,10 +63,54 @@ impl ValueEncode for Message { } } +/// The type of a connection to a peer. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum PeerConnectionType { + /// File transfer connection. + File, + + /// Any other connection. + Peer, +} + +const CONNECTION_TYPE_FILE: &'static str = "F"; +const CONNECTION_TYPE_PEER: &'static str = "P"; + +impl ValueEncode for PeerConnectionType { + fn encode_to( + &self, + encoder: &mut ValueEncoder, + ) -> Result<(), ValueEncodeError> { + let string = match *self { + Self::File => CONNECTION_TYPE_FILE, + Self::Peer => CONNECTION_TYPE_PEER, + }; + encoder.encode_string(string)?; + Ok(()) + } +} + +impl ValueDecode for PeerConnectionType { + fn decode_from(decoder: &mut ValueDecoder) -> Result { + let position = decoder.position(); + let string: String = decoder.decode()?; + match string.as_ref() { + CONNECTION_TYPE_FILE => Ok(Self::File), + CONNECTION_TYPE_PEER => Ok(Self::Peer), + _ => Err(ValueDecodeError::InvalidData { + value_name: "peer connection type".to_string(), + cause: format!("unknown value {:?}", string), + position: position, + }), + } + } +} + +// TODO: Rename to PeerInitMessage. #[derive(Clone, Debug, Eq, PartialEq)] pub struct PeerInit { pub user_name: String, - pub connection_type: String, + pub connection_type: PeerConnectionType, pub token: u32, } @@ -76,7 +120,7 @@ impl ValueEncode for PeerInit { encoder: &mut ValueEncoder, ) -> Result<(), ValueEncodeError> { encoder.encode_string(&self.user_name)?; - encoder.encode_string(&self.connection_type)?; + encoder.encode(&self.connection_type)?; encoder.encode_u32(self.token)?; Ok(()) } @@ -121,6 +165,23 @@ mod tests { ); } + #[test] + fn invalid_peer_connection_type() { + let mut bytes = BytesMut::new(); + ValueEncoder::new(&mut bytes).encode("bleep").unwrap(); + + let result = ValueDecoder::new(&bytes).decode::(); + + assert_eq!( + result, + Err(ValueDecodeError::InvalidData { + value_name: "peer connection type".to_string(), + cause: "unknown value \"bleep\"".to_string(), + position: 0, + }) + ); + } + #[test] fn roundtrip_pierce_firewall() { roundtrip(Message::PierceFirewall(1337)) @@ -130,7 +191,7 @@ mod tests { fn roundtrip_peer_init() { roundtrip(Message::PeerInit(PeerInit { user_name: "alice".to_string(), - connection_type: "P".to_string(), + connection_type: PeerConnectionType::Peer, token: 1337, })); } diff --git a/proto/src/server/request.rs b/proto/src/server/request.rs index 59c6729..d59c5ff 100644 --- a/proto/src/server/request.rs +++ b/proto/src/server/request.rs @@ -2,6 +2,7 @@ use crate::core::{ ValueDecode, ValueDecodeError, ValueDecoder, ValueEncode, ValueEncodeError, ValueEncoder, }; +use crate::peer::PeerConnectionType; use crate::server::constants::*; /*================* @@ -231,7 +232,7 @@ impl ValueDecode for CannotConnectRequest { pub struct ConnectToPeerRequest { pub token: u32, pub user_name: String, - pub connection_type: String, + pub connection_type: PeerConnectionType, } impl ValueEncode for ConnectToPeerRequest { @@ -241,7 +242,7 @@ impl ValueEncode for ConnectToPeerRequest { ) -> Result<(), ValueEncodeError> { encoder.encode_u32(self.token)?; encoder.encode_string(&self.user_name)?; - encoder.encode_string(&self.connection_type) + encoder.encode(&self.connection_type) } } @@ -498,6 +499,7 @@ mod tests { use crate::core::testing::roundtrip; use crate::core::{ValueDecodeError, ValueDecoder}; + use crate::peer::PeerConnectionType; use super::*; @@ -543,7 +545,7 @@ mod tests { let request = ConnectToPeerRequest { token: 1337, user_name: "alice".to_string(), - connection_type: "P".to_string(), + connection_type: PeerConnectionType::Peer, }; assert_eq!( ServerRequest::from(request.clone()), @@ -556,7 +558,7 @@ mod tests { roundtrip(ServerRequest::ConnectToPeerRequest(ConnectToPeerRequest { token: 1337, user_name: "alice".to_string(), - connection_type: "P".to_string(), + connection_type: PeerConnectionType::Peer, })) } diff --git a/proto/src/server/response.rs b/proto/src/server/response.rs index ccb6a13..2f4a4ea 100644 --- a/proto/src/server/response.rs +++ b/proto/src/server/response.rs @@ -6,6 +6,7 @@ use crate::core::{ ValueDecode, ValueDecodeError, ValueDecoder, ValueEncode, ValueEncodeError, ValueEncoder, }; +use crate::peer::PeerConnectionType; use crate::server::constants::*; use crate::{User, UserStatus}; @@ -212,7 +213,7 @@ impl ValueDecode for ServerResponse { #[derive(Clone, Debug, Eq, PartialEq)] pub struct ConnectToPeerResponse { pub user_name: String, - pub connection_type: String, + pub connection_type: PeerConnectionType, pub ip: net::Ipv4Addr, pub port: u16, pub token: u32, @@ -1145,7 +1146,7 @@ mod tests { roundtrip(ServerResponse::ConnectToPeerResponse( ConnectToPeerResponse { user_name: "alice".to_string(), - connection_type: "P".to_string(), + connection_type: PeerConnectionType::Peer, ip: net::Ipv4Addr::new(192, 168, 254, 1), port: 1337, token: 42,