From 2d528ae21c1049cd4c34f57c2b0fb7cdfe0645e8 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Fri, 15 Aug 2025 20:12:32 -0600 Subject: [PATCH] Respond to TCP keep-alive probes --- idevice/src/tcp/adapter.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/idevice/src/tcp/adapter.rs b/idevice/src/tcp/adapter.rs index 714f5f3..41d399b 100644 --- a/idevice/src/tcp/adapter.rs +++ b/idevice/src/tcp/adapter.rs @@ -62,7 +62,7 @@ use std::{collections::HashMap, io::ErrorKind, net::IpAddr, path::Path, sync::Arc}; -use log::trace; +use log::{debug, trace, warn}; use tokio::{io::AsyncWriteExt, sync::Mutex}; use crate::ReadWrite; @@ -542,6 +542,22 @@ impl Adapter { 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(&res.destination_port) { + // A keep-alive probe: ACK set, no payload, and seq == RCV.NXT - 1 + let is_keepalive = res.flags.ack + && res.payload.is_empty() + && res.sequence_number.wrapping_add(1) == state.ack; + + if is_keepalive { + // Don't update any seq/ack state; just ACK what we already expect. + debug!("responding to keep-alive probe"); + let port = res.destination_port; + self.ack(port).await?; + break; + } + } + if let Some(state) = self.states.get_mut(&res.destination_port) { if state.peer_seq > res.sequence_number { // ignore retransmission @@ -560,6 +576,7 @@ impl Adapter { state.read_buffer.extend(res.payload); } if res.flags.rst { + warn!("stream rst"); state.status = ConnectionStatus::Error(ErrorKind::ConnectionReset); } if res.flags.fin {