Merge pull request #64 from michel/lib/u32-message-codes
fix(lib): route on the full four-byte message code
This commit is contained in:
@@ -481,7 +481,7 @@ impl SeederState {
|
||||
let Ok(init) = read_framed(&mut p) else {
|
||||
return;
|
||||
};
|
||||
if init.get_message_code() != 1 {
|
||||
if init.get_init_code() != 1 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -735,7 +735,7 @@ fn accept_file_connection(
|
||||
let Ok(mut init) = read_framed(&mut stream) else {
|
||||
continue;
|
||||
};
|
||||
if init.get_message_code() != 1 {
|
||||
if init.get_init_code() != 1 {
|
||||
continue;
|
||||
}
|
||||
init.set_pointer(5);
|
||||
|
||||
@@ -535,7 +535,7 @@ impl PeerActor {
|
||||
message
|
||||
.get_message_name(
|
||||
MessageType::Peer,
|
||||
u32::from(message.get_message_code())
|
||||
message.get_message_code()
|
||||
)
|
||||
.map_err(|e| e.to_string())
|
||||
);
|
||||
|
||||
@@ -803,7 +803,7 @@ impl ServerActor {
|
||||
message
|
||||
.get_message_name(
|
||||
MessageType::Server,
|
||||
u32::from(message.get_message_code())
|
||||
message.get_message_code()
|
||||
)
|
||||
.map_err(|e| e.to_string())
|
||||
);
|
||||
|
||||
@@ -37,3 +37,40 @@ impl<Op> MessageDispatcher<Op> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::message::MessageHandler;
|
||||
use std::sync::mpsc::channel;
|
||||
|
||||
struct Echo(u32);
|
||||
|
||||
impl MessageHandler<u32> for Echo {
|
||||
fn get_code(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
fn handle(&self, _: &mut Message, sender: Sender<u32>) {
|
||||
let _ = sender.send(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn framed(code: u32) -> Message {
|
||||
Message::new_with_data(Message::new().write_int32(code).get_buffer())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_code_above_255_is_not_confused_with_its_low_byte() {
|
||||
let (sender, received) = channel();
|
||||
let mut handlers = Handlers::new();
|
||||
handlers.register_handler(Echo(1));
|
||||
handlers.register_handler(Echo(1001));
|
||||
let dispatcher =
|
||||
MessageDispatcher::new("test".to_string(), sender, handlers);
|
||||
|
||||
dispatcher.dispatch(&mut framed(257));
|
||||
dispatcher.dispatch(&mut framed(1001));
|
||||
|
||||
assert_eq!(received.try_iter().collect::<Vec<_>>(), [1001]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ use crate::message::Message;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
pub trait MessageHandler<Op>: Send {
|
||||
fn get_code(&self) -> u8;
|
||||
fn get_code(&self) -> u32;
|
||||
fn handle(&self, message: &mut Message, sender: Sender<Op>);
|
||||
}
|
||||
pub struct Handlers<Op> {
|
||||
handlers: HashMap<u8, Box<dyn MessageHandler<Op> + Send>>,
|
||||
handlers: HashMap<u32, Box<dyn MessageHandler<Op> + Send>>,
|
||||
}
|
||||
|
||||
impl<Op> Default for Handlers<Op> {
|
||||
@@ -35,7 +35,7 @@ impl<Op> Handlers<Op> {
|
||||
#[must_use]
|
||||
pub fn get_handler(
|
||||
&self,
|
||||
code: u8,
|
||||
code: u32,
|
||||
) -> Option<&(dyn MessageHandler<Op> + Send)> {
|
||||
self.handlers.get(&code).map(|v| &**v)
|
||||
}
|
||||
|
||||
@@ -51,21 +51,19 @@ impl Message {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[must_use]
|
||||
pub fn get_message_code_u32(&self) -> u32 {
|
||||
pub fn get_message_code(&self) -> u32 {
|
||||
if self.data.len() < 8 {
|
||||
return 0;
|
||||
}
|
||||
self.data[4..8].try_into().map_or(0, u32::from_le_bytes)
|
||||
}
|
||||
|
||||
/// The one-byte code of a peer init frame (PierceFirewall 0, PeerInit 1),
|
||||
/// the only messages whose code is not four bytes wide.
|
||||
#[must_use]
|
||||
pub fn get_message_code(&self) -> u8 {
|
||||
if self.data.len() <= 4 {
|
||||
return 0;
|
||||
}
|
||||
self.data[4]
|
||||
pub fn get_init_code(&self) -> u8 {
|
||||
self.data.get(4).copied().unwrap_or(0)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@@ -388,10 +386,19 @@ fn read_string_with_missing_length_prefix_does_not_panic() {
|
||||
#[test]
|
||||
fn get_message_code_on_short_message_does_not_panic() {
|
||||
// A zero-length frame drains to exactly the 4-byte length prefix, leaving
|
||||
// no room for a message code at data[4].
|
||||
// no room for a code after it.
|
||||
let msg = Message::new_with_data(vec![0, 0, 0, 0]);
|
||||
assert_eq!(msg.get_message_code(), 0);
|
||||
assert_eq!(msg.get_message_code_u32(), 0);
|
||||
assert_eq!(msg.get_init_code(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_init_frame_reads_its_one_byte_code() {
|
||||
let init = Message::new_with_data(
|
||||
Message::new().write_int8(1).write_string("ab").get_buffer(),
|
||||
);
|
||||
assert_eq!(init.get_init_code(), 1);
|
||||
assert_ne!(init.get_message_code(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -50,7 +50,7 @@ pub fn build_file_search_response(
|
||||
|
||||
pub struct FileSearchResponse;
|
||||
impl MessageHandler<PeerMessage> for FileSearchResponse {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
9
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<PeerMessage>) {
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::sync::mpsc::Sender;
|
||||
/// owns the shares) builds the real SharedFileListResponse in reply.
|
||||
pub struct GetShareFileList;
|
||||
impl MessageHandler<PeerMessage> for GetShareFileList {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
4
|
||||
}
|
||||
fn handle(&self, _message: &mut Message, sender: Sender<PeerMessage>) {
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
|
||||
pub struct PeerInit;
|
||||
impl MessageHandler<PeerMessage> for PeerInit {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct PlaceInQueueRequest;
|
||||
|
||||
impl MessageHandler<PeerMessage> for PlaceInQueueRequest {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
51
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct PlaceInQueueResponse;
|
||||
|
||||
impl MessageHandler<PeerMessage> for PlaceInQueueResponse {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
44
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct QueueUploadHandler;
|
||||
|
||||
impl MessageHandler<PeerMessage> for QueueUploadHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
43
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ pub struct SharedDirectory {
|
||||
/// Receives a peer's `SharedFileListResponse` (peer code 5) when browsing them.
|
||||
pub struct SharedFileListResponseHandler;
|
||||
impl MessageHandler<PeerMessage> for SharedFileListResponseHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
5
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<PeerMessage>) {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
|
||||
pub struct TransferRequest;
|
||||
impl MessageHandler<PeerMessage> for TransferRequest {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
40
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<PeerMessage>) {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct TransferResponse;
|
||||
|
||||
impl MessageHandler<PeerMessage> for TransferResponse {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
41
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
|
||||
pub struct UploadDeniedHandler;
|
||||
impl MessageHandler<PeerMessage> for UploadDeniedHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
50
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<PeerMessage>) {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
|
||||
pub struct UploadFailedHandler;
|
||||
impl MessageHandler<PeerMessage> for UploadFailedHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
46
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<PeerMessage>) {
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct ConnectToPeerHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for ConnectToPeerHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
18
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<ServerMessage>) {
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct ExcludedSearchPhrasesHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for ExcludedSearchPhrasesHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
160
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
pub struct FileSearchHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for FileSearchHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
26
|
||||
}
|
||||
fn handle(&self, message: &mut Message, sender: Sender<ServerMessage>) {
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct GetPeerAddressHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for GetPeerAddressHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
3
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct JoinRoomHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for JoinRoomHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
14
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct LeaveRoomHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for LeaveRoomHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
15
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::message::MessageHandler;
|
||||
pub struct LoginHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for LoginHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@ fn a_transfer_denial_carries_the_token_and_the_reason() {
|
||||
let message =
|
||||
MessageFactory::build_transfer_denial_message(555, "Cancelled");
|
||||
let mut decoded = Message::new_with_data(message.get_buffer());
|
||||
assert_eq!(decoded.get_message_code_u32(), 41);
|
||||
assert_eq!(decoded.get_message_code(), 41);
|
||||
decoded.set_pointer(8);
|
||||
assert_eq!(decoded.read_int32(), 555);
|
||||
assert!(!decoded.read_bool());
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct MessageUser;
|
||||
|
||||
impl MessageHandler<ServerMessage> for MessageUser {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
22
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
pub struct ParentMinSpeedHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for ParentMinSpeedHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
83
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ pub struct ParentSpeedRatioHandler;
|
||||
|
||||
// The server sends us a speed ratio determining the number of children we can have in the distributed network. The maximum number of children is our upload speed divided by the speed ratio.
|
||||
impl MessageHandler<ServerMessage> for ParentSpeedRatioHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
84
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::{
|
||||
pub struct PrivilegedUsersHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for PrivilegedUsersHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
69
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ impl MessageHandler<ServerMessage> for PrivilegedUsersHandler {
|
||||
pub struct CheckPrivilegesHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for CheckPrivilegesHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
92
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct ReloggedHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for ReloggedHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
41
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct RoomListHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for RoomListHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
64
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct SayChatroomHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for SayChatroomHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
13
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct GetUserStatusHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for GetUserStatusHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
7
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ impl MessageHandler<ServerMessage> for GetUserStatusHandler {
|
||||
pub struct GetUserStatsHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for GetUserStatsHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
36
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct UserJoinedRoomHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for UserJoinedRoomHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
16
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct UserLeftRoomHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for UserLeftRoomHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
17
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::sync::mpsc::Sender;
|
||||
pub struct WatchUserHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for WatchUserHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
5
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
pub struct WishListIntervalHandler;
|
||||
|
||||
impl MessageHandler<ServerMessage> for WishListIntervalHandler {
|
||||
fn get_code(&self) -> u8 {
|
||||
fn get_code(&self) -> u32 {
|
||||
104
|
||||
}
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ fn handle_incoming_connection(
|
||||
|
||||
// A firewalled peer brokered through the server connects back with a
|
||||
// PierceFirewall (code 0) instead of a PeerInit (code 1).
|
||||
if message.get_message_code() == 0 {
|
||||
if message.get_init_code() == 0 {
|
||||
handle_pierce_firewall(
|
||||
message, stream, reader, &context, &peer_ip, peer_port,
|
||||
);
|
||||
|
||||
@@ -191,7 +191,7 @@ fn test_new_from_message2() {
|
||||
let mut message = Message::new_with_data(data);
|
||||
message.set_pointer(8);
|
||||
|
||||
println!("code: {}", message.get_message_code_u32());
|
||||
println!("code: {}", message.get_message_code());
|
||||
|
||||
let peer = Peer::new_from_message(&mut message).unwrap();
|
||||
|
||||
|
||||
@@ -750,7 +750,7 @@ fn login_raw(
|
||||
/// passes. Returns the matching message.
|
||||
fn read_until_code(
|
||||
stream: &mut TcpStream,
|
||||
code: u8,
|
||||
code: u32,
|
||||
timeout: Duration,
|
||||
) -> Option<Message> {
|
||||
let deadline = Instant::now() + timeout;
|
||||
@@ -767,7 +767,7 @@ fn read_until_code(
|
||||
/// Like [`read_until_code`] but turns a miss into an `io::Error` for `?`.
|
||||
fn expect_code(
|
||||
stream: &mut TcpStream,
|
||||
code: u8,
|
||||
code: u32,
|
||||
timeout: Duration,
|
||||
) -> std::io::Result<Message> {
|
||||
read_until_code(stream, code, timeout).ok_or_else(|| {
|
||||
@@ -1379,7 +1379,7 @@ fn run_mock_direct_peer(cfg: &MockDirectUpload) -> std::io::Result<()> {
|
||||
p.set_nonblocking(false)?;
|
||||
p.set_read_timeout(Some(Duration::from_secs(10)))?;
|
||||
let mut init = read_framed(&mut p)?;
|
||||
assert_eq!(init.get_message_code(), 1, "expected inbound PeerInit");
|
||||
assert_eq!(init.get_init_code(), 1, "expected inbound PeerInit");
|
||||
init.set_pointer(5);
|
||||
assert_eq!(init.read_string(), cfg.downloader_username, "PeerInit user");
|
||||
assert_eq!(init.read_string(), "P", "PeerInit connection type");
|
||||
@@ -2079,7 +2079,7 @@ fn a_third_party_client_browses_our_shares_via_the_server_broker() {
|
||||
|
||||
let mut pierce = read_framed(&mut p).expect("a PierceFirewall frame");
|
||||
assert_eq!(
|
||||
pierce.get_message_code(),
|
||||
pierce.get_init_code(),
|
||||
0,
|
||||
"the brokered connect-back must start with a PierceFirewall"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user