From 1114981cd6654aa5545728fc782a98b3b7e1c564 Mon Sep 17 00:00:00 2001 From: Huge_Black <60165378+hugeBlack@users.noreply.github.com> Date: Sun, 6 Jul 2025 00:44:05 +0800 Subject: [PATCH] Fix retransmission and debug_proxy not swallowing 2 digit checksum issue (#14) * Fix retransmission and debug_proxy not swallowing 2 digit checksum issue * cargo fmt * Fix wrong ACK number when connection is establish but empty packet arrives --- idevice/src/services/debug_proxy.rs | 3 ++ idevice/src/tcp/adapter.rs | 71 +++++++++++++++++------------ 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/idevice/src/services/debug_proxy.rs b/idevice/src/services/debug_proxy.rs index aaa5f25..ee9c7a7 100644 --- a/idevice/src/services/debug_proxy.rs +++ b/idevice/src/services/debug_proxy.rs @@ -156,6 +156,9 @@ impl DebugProxyClient { } buffer.push(received_char[0]); } + // swallow checksum + let mut checksum_chars = [0u8; 2]; + self.socket.read_exact(&mut checksum_chars).await?; if !self.noack_mode { self.send_ack().await?; diff --git a/idevice/src/tcp/adapter.rs b/idevice/src/tcp/adapter.rs index f1a59ef..0724fd0 100644 --- a/idevice/src/tcp/adapter.rs +++ b/idevice/src/tcp/adapter.rs @@ -78,6 +78,7 @@ struct ConnectionState { read_buffer: Vec, write_buffer: Vec, status: ConnectionStatus, + peer_seq: u32, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -97,6 +98,7 @@ impl ConnectionState { read_buffer: Vec::new(), write_buffer: Vec::new(), status: ConnectionStatus::WaitingForSyn, + peer_seq: 0, } } } @@ -516,37 +518,46 @@ impl Adapter { } async fn process_tcp_packet(&mut self) -> Result<(), std::io::Error> { - let ip_packet = self.read_ip_packet().await?; - let res = TcpPacket::parse(&ip_packet)?; - let mut ack_me = None; - if let Some(state) = self.states.get_mut(&res.destination_port) { - state.ack = res.sequence_number - + if res.payload.is_empty() { - 1 - } else { - res.payload.len() as u32 - }; - if res.flags.psh || !res.payload.is_empty() { - ack_me = Some(res.destination_port); - state.read_buffer.extend(res.payload) - } - if res.flags.rst { - state.status = ConnectionStatus::Error(ErrorKind::ConnectionReset); - } - if res.flags.fin { - ack_me = Some(res.destination_port); - state.status = ConnectionStatus::Error(ErrorKind::ConnectionReset); - } - if res.flags.syn && res.flags.ack { - ack_me = Some(res.destination_port); - state.seq = state.seq.wrapping_add(1); - state.status = ConnectionStatus::Connected; - } - } + loop { + let ip_packet = self.read_ip_packet().await?; + let res = TcpPacket::parse(&ip_packet)?; + let mut ack_me = None; + if let Some(state) = self.states.get_mut(&res.destination_port) { + if state.peer_seq > res.sequence_number { + // ignore retransmission + continue; + } - // we have to ack outside of the mutable state borrow - if let Some(a) = ack_me { - self.ack(a).await?; + state.peer_seq = res.sequence_number + res.payload.len() as u32; + state.ack = res.sequence_number + + if res.payload.is_empty() && state.status != ConnectionStatus::Connected { + 1 + } else { + res.payload.len() as u32 + }; + if res.flags.psh || !res.payload.is_empty() { + ack_me = Some(res.destination_port); + state.read_buffer.extend(res.payload); + } + if res.flags.rst { + state.status = ConnectionStatus::Error(ErrorKind::ConnectionReset); + } + if res.flags.fin { + ack_me = Some(res.destination_port); + state.status = ConnectionStatus::Error(ErrorKind::ConnectionReset); + } + if res.flags.syn && res.flags.ack { + ack_me = Some(res.destination_port); + state.seq = state.seq.wrapping_add(1); + state.status = ConnectionStatus::Connected; + } + } + + // we have to ack outside of the mutable state borrow + if let Some(a) = ack_me { + self.ack(a).await?; + } + break; } Ok(()) }