Fix messages of size >16384 breaking

master
Liam Conway 2024-01-25 22:22:03 -07:00
parent 5089684c70
commit e08037619b
No known key found for this signature in database
1 changed files with 104 additions and 71 deletions

@ -353,7 +353,7 @@ struct BackendMessage {
} }
impl BackendMessage { impl BackendMessage {
fn from_bytes(bytes: Vec<u8>) -> Option<BackendMessage> { fn from_bytes(bytes: &Vec<u8>) -> Option<BackendMessage> {
if bytes.len() < 5 { if bytes.len() < 5 {
return None; return None;
} }
@ -413,7 +413,7 @@ impl BackendPacket {
}; };
} }
fn from_bytes(bytes: Vec<u8>) -> Option<BackendPacket> { fn from_bytes(bytes: &Vec<u8>) -> Option<BackendPacket> {
if bytes.len() < BACKEND_PACKET_HEADER_SIZE { if bytes.len() < BACKEND_PACKET_HEADER_SIZE {
return None; return None;
} }
@ -476,7 +476,7 @@ impl ConnectMsg {
}; };
} }
fn from_bytes(bytes: Vec<u8>) -> Option<ConnectMsg> { fn from_bytes(bytes: &Vec<u8>) -> Option<ConnectMsg> {
if bytes.len() < CONNECT_MSG_LEN { if bytes.len() < CONNECT_MSG_LEN {
return None; return None;
} }
@ -518,14 +518,14 @@ struct NoticeMsg {
} }
impl NoticeMsg { impl NoticeMsg {
fn from_bytes(bytes: Vec<u8>) -> Option<NoticeMsg> { fn from_bytes(bytes: &Vec<u8>) -> Option<NoticeMsg> {
if bytes.len() < 8 { if bytes.len() < 8 {
return None; return None;
} }
let notice_id = u64::from_le_bytes(bytes[0..8].try_into().unwrap()); let notice_id = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
match BackendMessage::from_bytes(bytes[8..].to_vec()) { match BackendMessage::from_bytes(&(bytes[8..].to_vec())) {
Some(message) => { Some(message) => {
match message.data.notice { match message.data.notice {
Some(notice) => Some(NoticeMsg{ Some(notice) => Some(NoticeMsg{
@ -554,7 +554,6 @@ struct TMClient {
time_offset: f64, time_offset: f64,
} }
const TCP_BUFFER_SIZE: usize = 10000;
impl TMClient { impl TMClient {
fn new(uuid: [u8; 16], client_name: [u8; 32], host: String, password: String, username: [u8; 16]) -> (TMClient, TMConnection) { fn new(uuid: [u8; 16], client_name: [u8; 32], host: String, password: String, username: [u8; 16]) -> (TMClient, TMConnection) {
let (work_tx, work_rx) = mpsc::channel(); let (work_tx, work_rx) = mpsc::channel();
@ -616,11 +615,48 @@ impl TMClient {
} }
} }
let mut incoming = [0; TCP_BUFFER_SIZE]; let mut header = [0; BACKEND_PACKET_HEADER_SIZE];
match self.stream.read(&mut incoming) { let mut read_bytes = 0;
let data_size: usize;
match self.stream.read_exact(&mut header) {
Ok(()) => {
match BackendPacket::from_bytes(&header.to_vec()) {
Some(packet) => {
data_size = packet.size as usize;
log::debug!("Received {} bytes ({}/{})", read_bytes, read_bytes, BACKEND_PACKET_HEADER_SIZE + data_size);
},
None => {
log::error!("Failed to parse BackendPacket header: {:?}", header);
return;
},
}
},
Err(ref error) if error.kind() == std::io::ErrorKind::WouldBlock => {
log::debug!("Resource temporarily unavailable, retrying later.");
return;
},
Err(error) => {
log::error!("Error reading header: {:?}", error);
return;
},
}
let mut data = vec![0; BACKEND_PACKET_HEADER_SIZE + data_size];
data[..header.len()].copy_from_slice(&header);
while read_bytes < BACKEND_PACKET_HEADER_SIZE + data_size {
match self.stream.read(&mut data[read_bytes..]) {
Ok(read) => { Ok(read) => {
let data = incoming[0..read].to_vec(); read_bytes += read;
match BackendPacket::from_bytes(data) { log::debug!("Received {} bytes ({}/{})", read, read_bytes, BACKEND_PACKET_HEADER_SIZE + data_size);
},
Err(error) => {
log::error!("Error reading body data: {:?}", error);
},
}
}
match BackendPacket::from_bytes(&data) {
Some(packet) => { Some(packet) => {
let offset = packet.timestamp - get_float_time(); let offset = packet.timestamp - get_float_time();
self.time_offset = offset.clone(); self.time_offset = offset.clone();
@ -628,7 +664,7 @@ impl TMClient {
match packet.msg_type { match packet.msg_type {
// Notice Message // Notice Message
4 => { 4 => {
match NoticeMsg::from_bytes(packet.data.clone()) { match NoticeMsg::from_bytes(&packet.data) {
Some(notice) => { Some(notice) => {
log::debug!("Received notice: {:#?}", notice); log::debug!("Received notice: {:#?}", notice);
let ack = BackendPacket::new(packet.header, packet.timestamp, 5, self.last_seq_num+1, notice.notice_id.to_le_bytes().to_vec()); let ack = BackendPacket::new(packet.header, packet.timestamp, 5, self.last_seq_num+1, notice.notice_id.to_le_bytes().to_vec());
@ -647,7 +683,7 @@ impl TMClient {
}, },
// Response message // Response message
3 => { 3 => {
match BackendMessage::from_bytes(packet.data.clone()) { match BackendMessage::from_bytes(&packet.data) {
Some(message) => { Some(message) => {
log::debug!("Received response: {:#?}", message); log::debug!("Received response: {:#?}", message);
@ -661,7 +697,7 @@ impl TMClient {
}, },
// Server Message // Server Message
2 => { 2 => {
match ConnectMsg::from_bytes(packet.data) { match ConnectMsg::from_bytes(&packet.data) {
Some(welcome_msg) => { Some(welcome_msg) => {
log::debug!("Received connect message: {:#?}", welcome_msg); log::debug!("Received connect message: {:#?}", welcome_msg);
if welcome_msg.pw_valid == 0 { if welcome_msg.pw_valid == 0 {
@ -685,14 +721,11 @@ impl TMClient {
} }
}, },
None => { None => {
log::error!("Failed to parse BackendPacket({}): {}", read, String::from_utf8_lossy(&incoming)); log::error!("Failed to parse BackendPacket({}): {}", read_bytes, String::from_utf8_lossy(&data));
// Sleep to prevent busy loop when TM is spamming 0 length packets // Sleep to prevent busy loop when TM is spamming 0 length packets
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));
} }
} }
},
Err(_) => {},
}
} }
} }