|
|
@ -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<Self, ValueDecodeError> {
|
|
|
|
|
|
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)]
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
pub struct PeerInit {
|
|
|
pub struct PeerInit {
|
|
|
pub user_name: String,
|
|
|
pub user_name: String,
|
|
|
pub connection_type: String,
|
|
|
|
|
|
|
|
|
pub connection_type: PeerConnectionType,
|
|
|
pub token: u32,
|
|
|
pub token: u32,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -76,7 +120,7 @@ impl ValueEncode for PeerInit { |
|
|
encoder: &mut ValueEncoder,
|
|
|
encoder: &mut ValueEncoder,
|
|
|
) -> Result<(), ValueEncodeError> {
|
|
|
) -> Result<(), ValueEncodeError> {
|
|
|
encoder.encode_string(&self.user_name)?;
|
|
|
encoder.encode_string(&self.user_name)?;
|
|
|
encoder.encode_string(&self.connection_type)?;
|
|
|
|
|
|
|
|
|
encoder.encode(&self.connection_type)?;
|
|
|
encoder.encode_u32(self.token)?;
|
|
|
encoder.encode_u32(self.token)?;
|
|
|
Ok(())
|
|
|
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::<PeerConnectionType>();
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
|
|
result,
|
|
|
|
|
|
Err(ValueDecodeError::InvalidData {
|
|
|
|
|
|
value_name: "peer connection type".to_string(),
|
|
|
|
|
|
cause: "unknown value \"bleep\"".to_string(),
|
|
|
|
|
|
position: 0,
|
|
|
|
|
|
})
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
#[test]
|
|
|
fn roundtrip_pierce_firewall() {
|
|
|
fn roundtrip_pierce_firewall() {
|
|
|
roundtrip(Message::PierceFirewall(1337))
|
|
|
roundtrip(Message::PierceFirewall(1337))
|
|
|
@ -130,7 +191,7 @@ mod tests { |
|
|
fn roundtrip_peer_init() {
|
|
|
fn roundtrip_peer_init() {
|
|
|
roundtrip(Message::PeerInit(PeerInit {
|
|
|
roundtrip(Message::PeerInit(PeerInit {
|
|
|
user_name: "alice".to_string(),
|
|
|
user_name: "alice".to_string(),
|
|
|
connection_type: "P".to_string(),
|
|
|
|
|
|
|
|
|
connection_type: PeerConnectionType::Peer,
|
|
|
token: 1337,
|
|
|
token: 1337,
|
|
|
}));
|
|
|
}));
|
|
|
}
|
|
|
}
|
|
|
|