Skip to main content

consomme/
tcp.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4mod assembler;
5mod ring;
6
7use super::Access;
8use super::BindError;
9use super::Client;
10use super::DropReason;
11use crate::ChecksumState;
12use crate::ConsommeState;
13use crate::FourTuple;
14use crate::IpAddresses;
15use crate::IpVersion;
16use crate::PortForwardKey;
17use crate::dns_resolver::DnsResolver;
18use crate::dns_resolver::dns_tcp::DnsTcpFrameAssembler;
19use crate::dns_resolver::dns_tcp::DnsTcpHandler;
20use futures::AsyncRead;
21use futures::AsyncWrite;
22use inspect::Inspect;
23use inspect::InspectMut;
24use inspect_counters::Counter;
25use inspect_counters::Histogram;
26use pal_async::driver::Driver;
27use pal_async::interest::PollEvents;
28use pal_async::socket::PollReady;
29use pal_async::socket::PolledSocket;
30use pal_async::timer::Instant as TimerInstant;
31use pal_async::timer::PolledTimer as TcpTimer;
32use smoltcp::phy::ChecksumCapabilities;
33use smoltcp::wire::ETHERNET_HEADER_LEN;
34use smoltcp::wire::EthernetFrame;
35use smoltcp::wire::EthernetProtocol;
36use smoltcp::wire::IPV4_HEADER_LEN;
37use smoltcp::wire::IPV6_HEADER_LEN;
38use smoltcp::wire::IpAddress;
39use smoltcp::wire::IpProtocol;
40use smoltcp::wire::IpRepr;
41use smoltcp::wire::Ipv4Packet;
42use smoltcp::wire::Ipv6Packet;
43use smoltcp::wire::TcpControl;
44use smoltcp::wire::TcpPacket;
45use smoltcp::wire::TcpRepr;
46use smoltcp::wire::TcpSeqNumber;
47use socket2::Domain;
48use socket2::Protocol;
49use socket2::SockAddr;
50use socket2::Socket;
51use socket2::Type;
52use std::collections::HashMap;
53use std::collections::hash_map;
54use std::io;
55use std::io::ErrorKind;
56use std::io::IoSlice;
57use std::io::IoSliceMut;
58use std::net::IpAddr;
59use std::net::Shutdown;
60use std::net::SocketAddr;
61use std::net::SocketAddrV4;
62use std::net::SocketAddrV6;
63use std::pin::Pin;
64use std::task::Context;
65use std::task::Poll;
66use std::time::Duration;
67use thiserror::Error;
68
69#[derive(InspectMut)]
70pub(crate) struct Tcp {
71    #[inspect(iter_by_key)]
72    connections: HashMap<FourTuple, TcpConnection>,
73    #[inspect(iter_by_key)]
74    listeners: HashMap<PortForwardKey, TcpListener>,
75    #[inspect(skip)]
76    timer: Option<TcpTimer>,
77    connection_params: ConnectionParams,
78    aggregate_stats: TcpAggregateStats,
79}
80
81/// Aggregate statistics across all TCP connections for inspect/diagnostics.
82#[derive(Inspect, Default)]
83struct TcpAggregateStats {
84    connections_accepted: Counter,
85    connections_initiated: Counter,
86    /// Connections closed normally (LastAck final ACK, TimeWait, FIN exchange).
87    connections_closed_normal: Counter,
88    /// Connections closed by receiving a valid RST from the peer.
89    connections_closed_peer_rst: Counter,
90    /// Connections closed due to local errors (socket failures, invalid handshake).
91    connections_closed_local_error: Counter,
92    /// Connections reaped after the peer did not finish a handshake or shutdown.
93    connections_closed_timeout: Counter,
94}
95
96impl TcpAggregateStats {
97    fn record_close(&mut self, reason: ConnectionCloseReason) {
98        match reason {
99            ConnectionCloseReason::Normal => self.connections_closed_normal.increment(),
100            ConnectionCloseReason::PeerRst => self.connections_closed_peer_rst.increment(),
101            ConnectionCloseReason::LocalError => self.connections_closed_local_error.increment(),
102        }
103    }
104
105    fn record_timeout_close(&mut self) {
106        self.connections_closed_timeout.increment();
107    }
108}
109
110#[derive(Inspect)]
111struct ConnectionParams {
112    rx_buffer: NormalizedBufferBounds,
113    tx_buffer: NormalizedBufferBounds,
114}
115
116/// Normalized version of [`crate::TcpBufferBounds`] with both values clamped
117/// to `[16 KiB, 4 MiB]` and rounded up to a power of two, then `initial`
118/// further clamped to be no greater than `max`.
119#[derive(Inspect, Clone, Copy, Debug)]
120struct NormalizedBufferBounds {
121    initial: usize,
122    max: usize,
123}
124
125impl NormalizedBufferBounds {
126    fn from_bounds(b: crate::TcpBufferBounds) -> Self {
127        let clamp = |v: usize| v.clamp(16 << 10, 4 << 20).next_power_of_two();
128        let max = clamp(b.max);
129        let initial = clamp(b.initial).min(max);
130        Self { initial, max }
131    }
132}
133
134#[derive(Debug, Error)]
135#[error("{kind} for flow {flow}")]
136pub struct TcpError {
137    flow: FourTuple,
138    kind: TcpErrorKind,
139}
140
141#[derive(Debug, Error)]
142enum TcpErrorKind {
143    #[error("still connecting")]
144    StillConnecting,
145    #[error("unacceptable segment number")]
146    Unacceptable,
147    #[error("missing ack bit")]
148    MissingAck,
149    #[error("ack newer than sequence")]
150    AckPastSequence,
151    #[error("invalid window scale")]
152    InvalidWindowScale,
153}
154
155impl TcpError {
156    fn new(flow: FourTuple, kind: TcpErrorKind) -> Self {
157        Self { flow, kind }
158    }
159}
160
161impl Tcp {
162    pub fn new(rx_buffer: crate::TcpBufferBounds, tx_buffer: crate::TcpBufferBounds) -> Self {
163        Self {
164            connections: HashMap::new(),
165            listeners: HashMap::new(),
166            timer: None,
167            connection_params: ConnectionParams {
168                rx_buffer: NormalizedBufferBounds::from_bounds(rx_buffer),
169                tx_buffer: NormalizedBufferBounds::from_bounds(tx_buffer),
170            },
171            aggregate_stats: TcpAggregateStats::default(),
172        }
173    }
174}
175
176#[derive(Inspect)]
177#[inspect(tag = "info")]
178enum LoopbackPortInfo {
179    None,
180    ProxyForGuestPort { sending_port: u16, guest_port: u16 },
181}
182
183/// The I/O backend for a TCP connection.
184///
185/// A connection is either backed by a real host socket or a virtual DNS
186/// handler that resolves DNS queries without a real socket.
187enum TcpBackend {
188    /// A real host socket. The socket may be `None` while the connection is
189    /// being constructed, or after both ends have closed.
190    Socket {
191        socket: Option<PolledSocket<Socket>>,
192        static_dns: Option<StaticDnsTcpInspection>,
193    },
194    /// A virtual DNS TCP handler (no real socket).
195    Dns(DnsTcpHandler),
196}
197
198#[derive(Default)]
199struct StaticDnsTcpInspection {
200    frame_assembler: DnsTcpFrameAssembler,
201    forwarding: Option<ForwardingDnsTcpFrame>,
202    host_response_frames: DnsTcpFrameBoundaryTracker,
203}
204
205struct ForwardingDnsTcpFrame {
206    frame: Vec<u8>,
207    offset: usize,
208}
209
210enum StaticDnsTcpDisposition {
211    Hold,
212    Forward,
213}
214
215#[derive(Default)]
216struct DnsTcpFrameBoundaryTracker {
217    prefix: [u8; 2],
218    prefix_len: usize,
219    payload_remaining: usize,
220}
221
222impl DnsTcpFrameBoundaryTracker {
223    fn ingest(&mut self, mut data: &[u8]) {
224        while !data.is_empty() {
225            if self.payload_remaining != 0 {
226                let consumed = data.len().min(self.payload_remaining);
227                self.payload_remaining -= consumed;
228                data = &data[consumed..];
229                continue;
230            }
231
232            let consumed = data.len().min(self.prefix.len() - self.prefix_len);
233            self.prefix[self.prefix_len..self.prefix_len + consumed]
234                .copy_from_slice(&data[..consumed]);
235            self.prefix_len += consumed;
236            data = &data[consumed..];
237
238            if self.prefix_len == self.prefix.len() {
239                self.payload_remaining = u16::from_be_bytes(self.prefix) as usize;
240                self.prefix_len = 0;
241            }
242        }
243    }
244
245    fn at_frame_boundary(&self) -> bool {
246        self.prefix_len == 0 && self.payload_remaining == 0
247    }
248}
249
250impl StaticDnsTcpInspection {
251    fn is_empty(&self) -> bool {
252        self.frame_assembler.is_empty() && self.forwarding.is_none()
253    }
254}
255
256#[derive(Inspect)]
257struct TcpConnection {
258    #[inspect(skip)]
259    backend: TcpBackend,
260    #[inspect(flatten)]
261    inner: TcpConnectionInner,
262}
263
264#[derive(Inspect)]
265struct TcpConnectionInner {
266    loopback_port: LoopbackPortInfo,
267    state: TcpState,
268
269    lifetime_timer: LifetimeTimer,
270    retransmission: RetransmissionState,
271
272    #[inspect(with = "|x| x.len()")]
273    rx_buffer: ring::Ring,
274    #[inspect(hex)]
275    rx_window_cap: usize,
276    rx_window_scale: u8,
277    /// Autotune ceiling for `rx_window_cap`. Once `rx_window_cap` reaches this
278    /// value, no further grow is attempted. The backing ring is rounded up to a
279    /// power of two, so its allocated capacity can slightly exceed this value
280    /// (e.g. when window scaling is disabled and this is capped to `u16::MAX`,
281    /// the ring is 65536 while this is 65535).
282    #[inspect(hex)]
283    rx_buffer_max: usize,
284    #[inspect(with = "inspect_seq")]
285    rx_seq: TcpSeqNumber,
286    /// Window last advertised to the guest, as it reconstructs it after
287    /// window-scale truncation. Used to detect a zero-window reopen.
288    #[inspect(hex)]
289    rx_window_last_adv: usize,
290    #[inspect(flatten)]
291    rx_assembler: assembler::Assembler,
292    needs_ack: bool,
293    is_shutdown: bool,
294    enable_window_scaling: bool,
295
296    #[inspect(with = "|x| x.len()")]
297    tx_buffer: ring::Ring,
298    /// Autotune ceiling for the tx_buffer ring capacity.
299    #[inspect(hex)]
300    tx_buffer_max: usize,
301    #[inspect(with = "inspect_seq")]
302    tx_acked: TcpSeqNumber,
303    #[inspect(with = "inspect_seq")]
304    tx_send: TcpSeqNumber,
305    tx_syn: TxSynState,
306    tx_fin: TxFinState,
307    #[inspect(hex)]
308    tx_window_len: u16,
309    tx_window_scale: u8,
310    /// Whether the tx_window_scale is active (i.e., we've received the first
311    /// non-SYN ACK). Per RFC 1323 §2.2, the window field in SYN/SYN-ACK
312    /// segments is NOT scaled — only subsequent segments are.
313    tx_window_scale_active: bool,
314    #[inspect(with = "inspect_seq")]
315    tx_window_rx_seq: TcpSeqNumber,
316    #[inspect(with = "inspect_seq")]
317    tx_window_tx_seq: TcpSeqNumber,
318    #[inspect(hex)]
319    tx_mss: usize,
320    #[inspect(skip)]
321    last_close_reason: ConnectionCloseReason,
322    stats: TcpConnStats,
323}
324
325const INITIAL_RTO: Duration = Duration::from_secs(1);
326const MIN_RTO: Duration = Duration::from_secs(1);
327const MAX_RTO: Duration = Duration::from_secs(60);
328const CLOCK_GRANULARITY: Duration = Duration::from_millis(1);
329const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(60);
330
331#[derive(Clone, Copy, Default, Inspect)]
332#[inspect(tag = "kind")]
333enum LifetimeTimer {
334    #[default]
335    None,
336    Handshake(#[inspect(skip)] TimerInstant),
337    Close(#[inspect(skip)] TimerInstant),
338}
339
340impl LifetimeTimer {
341    fn deadline(self) -> Option<TimerInstant> {
342        match self {
343            Self::None => None,
344            Self::Handshake(deadline) | Self::Close(deadline) => Some(deadline),
345        }
346    }
347}
348
349#[derive(Clone, Copy, Debug, Default, Inspect, PartialEq, Eq)]
350enum TxSynState {
351    #[default]
352    None,
353    Syn,
354    SynAck,
355}
356
357#[derive(Clone, Copy, Default, Inspect, PartialEq, Eq)]
358enum TxFinState {
359    #[default]
360    None,
361    Buffered,
362    Sent,
363}
364
365impl TxFinState {
366    fn is_pending(self) -> bool {
367        self != Self::None
368    }
369}
370
371#[derive(Clone, Copy, Default, Inspect)]
372#[inspect(tag = "kind")]
373enum RetransmissionTimer {
374    #[default]
375    None,
376    Rto {
377        #[inspect(skip)]
378        deadline: TimerInstant,
379        #[inspect(skip)]
380        recover: Option<TcpSeqNumber>,
381    },
382    Persist {
383        #[inspect(skip)]
384        deadline: TimerInstant,
385        backoff: u8,
386        #[inspect(skip)]
387        recover: Option<TcpSeqNumber>,
388    },
389    Recovery {
390        #[inspect(skip)]
391        deadline: TimerInstant,
392        #[inspect(skip)]
393        recover: TcpSeqNumber,
394    },
395}
396
397impl RetransmissionTimer {
398    fn deadline(self) -> Option<TimerInstant> {
399        match self {
400            Self::None => None,
401            Self::Rto { deadline, .. }
402            | Self::Persist { deadline, .. }
403            | Self::Recovery { deadline, .. } => Some(deadline),
404        }
405    }
406}
407
408#[derive(Inspect)]
409struct RetransmissionState {
410    rto: Duration,
411    timer: RetransmissionTimer,
412    srtt: Option<Duration>,
413    rttvar: Option<Duration>,
414    #[inspect(skip)]
415    sample: Option<RttSample>,
416    #[inspect(skip)]
417    window_reopen_retransmit: Option<TcpSeqNumber>,
418    syn_retransmitted: bool,
419    duplicate_acks: u8,
420}
421
422struct RttSample {
423    sequence_end: TcpSeqNumber,
424    sent_at: TimerInstant,
425}
426
427impl RetransmissionState {
428    fn new() -> Self {
429        Self {
430            rto: INITIAL_RTO,
431            timer: RetransmissionTimer::None,
432            srtt: None,
433            rttvar: None,
434            sample: None,
435            window_reopen_retransmit: None,
436            syn_retransmitted: false,
437            duplicate_acks: 0,
438        }
439    }
440
441    fn on_send(&mut self, sequence_end: TcpSeqNumber) {
442        match self.timer {
443            RetransmissionTimer::Rto {
444                recover: Some(_), ..
445            }
446            | RetransmissionTimer::Recovery { .. } => return,
447            RetransmissionTimer::Rto { .. } if self.sample.is_some() => return,
448            _ => {}
449        }
450        self.on_send_at(sequence_end, TimerInstant::now());
451    }
452
453    fn on_send_at(&mut self, sequence_end: TcpSeqNumber, now: TimerInstant) {
454        if !matches!(
455            self.timer,
456            RetransmissionTimer::Rto { .. } | RetransmissionTimer::Recovery { .. }
457        ) {
458            self.timer = RetransmissionTimer::Rto {
459                deadline: now + self.rto,
460                recover: None,
461            };
462        }
463        if self.sample.is_none() {
464            self.sample = Some(RttSample {
465                sequence_end,
466                sent_at: now,
467            });
468        }
469    }
470
471    fn on_ack(&mut self, ack_number: TcpSeqNumber, tx_send: TcpSeqNumber, now: TimerInstant) {
472        self.duplicate_acks = 0;
473        self.window_reopen_retransmit = None;
474        let recover = self.recovery_boundary();
475        if let Some(sample) = self
476            .sample
477            .take_if(|sample| ack_number >= sample.sequence_end)
478        {
479            self.update_rto(now.saturating_sub(sample.sent_at));
480        }
481
482        self.timer = if ack_number < tx_send {
483            if let Some(recover) = recover.filter(|recover| ack_number < *recover) {
484                RetransmissionTimer::Recovery {
485                    deadline: now,
486                    recover,
487                }
488            } else {
489                RetransmissionTimer::Rto {
490                    deadline: now + self.rto,
491                    recover: None,
492                }
493            }
494        } else {
495            RetransmissionTimer::None
496        };
497    }
498
499    fn record_duplicate_ack(&mut self, is_duplicate: bool) -> bool {
500        if !is_duplicate {
501            return false;
502        }
503        self.duplicate_acks = self.duplicate_acks.saturating_add(1);
504        self.duplicate_acks == 3
505    }
506
507    fn on_fast_retransmit(&mut self, now: TimerInstant, recover: TcpSeqNumber) {
508        self.sample = None;
509        self.timer = RetransmissionTimer::Rto {
510            deadline: now + self.rto,
511            recover: Some(recover),
512        };
513    }
514
515    fn retry_fast_retransmit(&mut self) {
516        self.duplicate_acks = 2;
517    }
518
519    fn on_retransmit(&mut self, now: TimerInstant, recover: TcpSeqNumber) {
520        // Karn's algorithm: an ACK after a retransmission is ambiguous and
521        // cannot be used as an RTT sample.
522        self.duplicate_acks = 0;
523        self.sample = None;
524        self.rto = self.rto.saturating_mul(2).min(MAX_RTO);
525        self.timer = RetransmissionTimer::Rto {
526            deadline: now + self.rto,
527            recover: Some(recover),
528        };
529    }
530
531    fn on_recovery_retransmit(&mut self, now: TimerInstant, recover: TcpSeqNumber) {
532        self.sample = None;
533        self.timer = RetransmissionTimer::Rto {
534            deadline: now + self.rto,
535            recover: Some(recover),
536        };
537    }
538
539    fn update_persist(&mut self, blocked: bool, outstanding: bool) {
540        if blocked {
541            if !matches!(self.timer, RetransmissionTimer::Persist { .. }) {
542                let recover = self.recovery_boundary();
543                self.sample = None;
544                self.timer = RetransmissionTimer::Persist {
545                    deadline: TimerInstant::now() + self.rto,
546                    backoff: 0,
547                    recover,
548                };
549            }
550        } else if matches!(self.timer, RetransmissionTimer::Persist { .. }) {
551            let recover = self.recovery_boundary();
552            self.timer = if outstanding {
553                RetransmissionTimer::Rto {
554                    deadline: TimerInstant::now() + self.rto,
555                    recover,
556                }
557            } else {
558                RetransmissionTimer::None
559            };
560        }
561    }
562
563    fn rearm_persist(&mut self, now: TimerInstant, backoff: u8, recover: Option<TcpSeqNumber>) {
564        let backoff = backoff.saturating_add(1).min(u32::BITS as u8 - 1);
565        let multiplier = 1_u32 << backoff;
566        let interval = self.rto.saturating_mul(multiplier).min(MAX_RTO);
567        self.timer = RetransmissionTimer::Persist {
568            deadline: now + interval,
569            backoff,
570            recover,
571        };
572    }
573
574    fn retry_persist(&mut self, now: TimerInstant, backoff: u8, recover: Option<TcpSeqNumber>) {
575        self.timer = RetransmissionTimer::Persist {
576            deadline: now + self.rto,
577            backoff,
578            recover,
579        };
580    }
581
582    fn can_retransmit_on_window_reopen(&self, ack_number: TcpSeqNumber) -> bool {
583        self.window_reopen_retransmit != Some(ack_number)
584    }
585
586    fn on_early_retransmit(&mut self, now: TimerInstant, ack_number: TcpSeqNumber) {
587        // Karn's algorithm still applies, but RFC 6298 only backs off the RTO
588        // after its timer expires.
589        self.duplicate_acks = 0;
590        self.sample = None;
591        self.window_reopen_retransmit = Some(ack_number);
592        self.timer = RetransmissionTimer::Rto {
593            deadline: now + self.rto,
594            recover: self.recovery_boundary(),
595        };
596    }
597
598    fn recovery_boundary(&self) -> Option<TcpSeqNumber> {
599        match self.timer {
600            RetransmissionTimer::Rto { recover, .. }
601            | RetransmissionTimer::Persist { recover, .. } => recover,
602            RetransmissionTimer::Recovery { recover, .. } => Some(recover),
603            RetransmissionTimer::None => None,
604        }
605    }
606
607    fn on_syn_retransmit(&mut self) {
608        self.syn_retransmitted = true;
609    }
610
611    fn on_handshake_complete(&mut self) {
612        // RFC 6298 section 5.7 requires at least a 3-second RTO for data
613        // after a SYN retransmission when the backed-off RTO is smaller.
614        if self.syn_retransmitted {
615            self.rto = self.rto.max(Duration::from_secs(3));
616            self.syn_retransmitted = false;
617        }
618    }
619
620    fn update_rto(&mut self, sample: Duration) {
621        let (srtt, rttvar) = if let (Some(srtt), Some(rttvar)) = (self.srtt, self.rttvar) {
622            let error = srtt.abs_diff(sample);
623            let rttvar = duration_weighted_average(rttvar, 3, error, 1, 4);
624            let srtt = duration_weighted_average(srtt, 7, sample, 1, 8);
625            (srtt, rttvar)
626        } else {
627            (sample, sample / 2)
628        };
629        self.srtt = Some(srtt);
630        self.rttvar = Some(rttvar);
631
632        let variance = rttvar.saturating_mul(4).max(CLOCK_GRANULARITY);
633        self.rto = (srtt + variance).clamp(MIN_RTO, MAX_RTO);
634    }
635}
636
637fn duration_weighted_average(
638    a: Duration,
639    a_weight: u32,
640    b: Duration,
641    b_weight: u32,
642    divisor: u32,
643) -> Duration {
644    a.saturating_mul(a_weight)
645        .saturating_add(b.saturating_mul(b_weight))
646        / divisor
647}
648
649/// Why a connection was closed, for aggregate stats categorization.
650#[derive(Default, Clone, Copy)]
651enum ConnectionCloseReason {
652    #[default]
653    LocalError,
654    PeerRst,
655    Normal,
656}
657
658/// Policy for whether `send_data` should emit a standalone (pure) ACK when
659/// there is nothing else to put in the segment.
660///
661/// Pure ACKs are deferred from the per-packet `handle_tcp` hot path so that
662/// bursts of inbound guest packets coalesce into a single ACK emitted by the
663/// trailing `poll_tcp` cycle. Without this, every inbound data segment
664/// triggers a zero-payload ACK back, doubling the packet rate and adding
665/// per-packet overhead on the virtual link (RFC 1122 §4.2.3.2 explicitly
666/// permits delaying ACKs to coalesce them).
667#[derive(Copy, Clone, PartialEq, Eq)]
668enum AckPolicy {
669    /// Don't emit a standalone ACK in this call. Data segments and FINs
670    /// still go out; `needs_ack` remains set so a later `Flush` call (or
671    /// a piggybacked ACK on outbound data) will satisfy it.
672    Defer,
673    /// Emit a standalone ACK if one is pending. Used from poll-cycle paths
674    /// that run once per batch (`poll_socket_backend`, `poll_dns_backend`).
675    Flush,
676}
677
678/// Per-connection TCP statistics for performance analysis.
679#[derive(Inspect, Default)]
680struct TcpConnStats {
681    /// Bytes sent from host to guest.
682    bytes_tx_to_guest: Counter,
683    /// Payload bytes received from guest to host (excludes pure ACKs and
684    /// FIN-only segments).
685    bytes_rx_from_guest: Counter,
686    /// Data segments sent from host to guest via `send_data` (every such
687    /// segment carries an ACK; this does not include standalone ACKs).
688    pkts_tx_to_guest: Counter,
689    /// Data segments received from guest to host (payload-bearing only;
690    /// excludes pure ACKs and FIN-only segments).
691    data_segments_rx_from_guest: Counter,
692    /// Standalone ACKs sent via `ack()` in response to unacceptable
693    /// segments (duplicate, out-of-order, out-of-window). Data segments
694    /// sent via `send_data` are counted in `pkts_tx_to_guest` instead.
695    standalone_acks_tx: Counter,
696    /// RSTs sent.
697    rsts_tx: Counter,
698    /// Times send_data broke out because rx_mtu was 0 (no guest rx buffers).
699    tx_blocked_no_rx_mtu: Counter,
700    /// Times send_data was limited by the peer's advertised window being full.
701    tx_blocked_window_full: Counter,
702    /// Out-of-window packets received.
703    out_of_window_pkts: Counter,
704    /// Segment size distribution for packets sent to guest.
705    tx_segment_size: Histogram<14>,
706    /// Segment size distribution for packets received from guest.
707    rx_segment_size: Histogram<14>,
708    /// Number of times the tx_buffer ring capacity was grown by autotune.
709    tx_buffer_grows: Counter,
710    /// Number of times the rx_buffer ring capacity was grown by autotune.
711    rx_buffer_grows: Counter,
712    /// Retransmission timeouts.
713    retransmission_timeouts: Counter,
714    /// Retransmitted segments.
715    retransmitted_segments: Counter,
716    /// Retransmitted payload bytes.
717    retransmitted_bytes: Counter,
718}
719
720fn inspect_seq(seq: &TcpSeqNumber) -> inspect::AsHex<u32> {
721    inspect::AsHex(seq.0 as u32)
722}
723
724#[derive(Inspect)]
725struct TcpListener {
726    #[inspect(skip)]
727    socket: PolledSocket<Socket>,
728    host_port: u16,
729}
730
731#[derive(Debug, PartialEq, Eq, Inspect)]
732enum TcpState {
733    Connecting,
734    SynSent,
735    SynReceived,
736    Established,
737    FinWait1,
738    FinWait2,
739    CloseWait,
740    Closing,
741    LastAck,
742    TimeWait,
743}
744
745impl TcpState {
746    fn tx_fin(&self) -> bool {
747        match self {
748            TcpState::Connecting
749            | TcpState::SynSent
750            | TcpState::SynReceived
751            | TcpState::Established
752            | TcpState::CloseWait => false,
753
754            TcpState::FinWait1
755            | TcpState::FinWait2
756            | TcpState::Closing
757            | TcpState::TimeWait
758            | TcpState::LastAck => true,
759        }
760    }
761
762    fn rx_fin(&self) -> bool {
763        match self {
764            TcpState::Connecting
765            | TcpState::SynSent
766            | TcpState::SynReceived
767            | TcpState::Established
768            | TcpState::FinWait1
769            | TcpState::FinWait2 => false,
770
771            TcpState::CloseWait | TcpState::Closing | TcpState::LastAck | TcpState::TimeWait => {
772                true
773            }
774        }
775    }
776}
777
778impl<T: Client> Access<'_, T> {
779    pub(crate) fn poll_tcp(&mut self, cx: &mut Context<'_>) {
780        // Check for any new incoming connections
781        self.inner
782            .tcp
783            .listeners
784            .retain(|key, listener| match listener.poll_listener(cx) {
785                Ok(result) => {
786                    if let Some((socket, mut other_addr)) = result {
787                        // If this packet was originally from the guest, update the port to match
788                        // the original guest port. This allows loopback to work as expected.
789                        if self.inner.state.params.is_local_address(&other_addr) {
790                            for (other_ft, connection) in self.inner.tcp.connections.iter() {
791                                if matches!(connection.inner.state, TcpState::Connecting | TcpState::SynReceived)
792                                    && PortForwardKey::from_socket_addr(other_ft.dst, other_ft.dst.port()) == *key
793                                {
794                                    if let LoopbackPortInfo::ProxyForGuestPort {
795                                        sending_port,
796                                        guest_port,
797                                    } = connection.inner.loopback_port
798                                    {
799                                        if sending_port == other_addr.port() {
800                                            other_addr.set_port(guest_port);
801                                            break;
802                                        }
803                                    }
804                                }
805                            }
806                        }
807                        let Some(ft) = self.inner.state.try_ft_from_remote_address(&other_addr, key.guest_port) else {
808                            return true;
809                        };
810
811                        // TCP connections are stored with the source always as the guest. Switch the order.
812                        let ft = FourTuple {
813                            src: ft.dst,
814                            dst: ft.src,
815                        };
816
817                        match self.inner.tcp.connections.entry(ft) {
818                            hash_map::Entry::Vacant(e) => {
819                                let mut sender = Sender {
820                                    ft: &ft,
821                                    client: self.client,
822                                    state: &mut self.inner.state,
823                                };
824
825                                let conn = match TcpConnection::new_from_accept(
826                                    &mut sender,
827                                    socket,
828                                    &self.inner.tcp.connection_params,
829                                ) {
830                                    Ok(conn) => conn,
831                                    Err(err) => {
832                                        tracing::warn!(
833                                            error = &err as &dyn std::error::Error,
834                                            src = %ft.src,
835                                            dst = %ft.dst,
836                                            "Failed to create connection from newly accepted socket",
837                                        );
838                                        return true;
839                                    }
840                                };
841                                tracing::trace!(
842                                    src = %ft.src,
843                                    dst = %ft.dst,
844                                    "TCP connection established"
845                                );
846                                e.insert(conn);
847                                self.inner.tcp.aggregate_stats.connections_accepted.increment();
848                            }
849                            hash_map::Entry::Occupied(_) => {
850                                tracing::warn!(
851                                    src = %ft.src,
852                                    dst = %ft.dst,
853                                    "New client request ignored because it was already connected"
854                                );
855                            }
856                        }
857                    }
858                    true
859                }
860                Err(_) => false,
861            });
862        // Check for any new incoming data.
863        let mut now = None;
864        let mut next_deadline: Option<TimerInstant> = None;
865        self.inner.tcp.connections.retain(|ft, conn| {
866            let mut sender = Sender {
867                ft,
868                state: &mut self.inner.state,
869                client: self.client,
870            };
871            let timed_out = conn.inner.next_timer_deadline().is_some_and(|deadline| {
872                let now = *now.get_or_insert_with(TimerInstant::now);
873                deadline <= now && conn.inner.process_expired_timers(now, &mut sender)
874            });
875            if timed_out {
876                tracing::debug!(
877                    src = %ft.src,
878                    dst = %ft.dst,
879                    state = ?conn.inner.state,
880                    "TCP connection timer expired, reclaiming connection",
881                );
882                if matches!(
883                    conn.backend,
884                    TcpBackend::Dns(ref handler) if handler.is_in_flight()
885                ) {
886                    self.inner.dns.complete_tcp_query();
887                }
888                match conn.inner.state {
889                    TcpState::TimeWait => self
890                        .inner
891                        .tcp
892                        .aggregate_stats
893                        .record_close(ConnectionCloseReason::Normal),
894                    _ => {
895                        let guest_has_seen_connection = !matches!(
896                            conn.inner.state,
897                            TcpState::Connecting | TcpState::SynSent | TcpState::SynReceived
898                        ) || conn.inner.tx_syn != TxSynState::None;
899                        if guest_has_seen_connection && sender.client.rx_mtu() != 0 {
900                            let ack_number =
901                                (conn.inner.tx_syn != TxSynState::Syn).then_some(conn.inner.rx_seq);
902                            if sender.try_rst(conn.inner.tx_send, ack_number) {
903                                conn.inner.stats.rsts_tx.increment();
904                            }
905                        }
906                        self.inner.tcp.aggregate_stats.record_timeout_close();
907                    }
908                }
909                return false;
910            }
911
912            let keep = match &mut conn.backend {
913                TcpBackend::Dns(dns_handler) => {
914                    if self.inner.dns.can_answer_queries() {
915                        conn.inner.poll_dns_backend(
916                            cx,
917                            &mut sender,
918                            dns_handler,
919                            &mut self.inner.dns,
920                        )
921                    } else {
922                        tracelimit::warn_ratelimited!(
923                            src = %ft.src,
924                            dst = %ft.dst,
925                            "DNS TCP connection without an answer source, dropping"
926                        );
927                        false
928                    }
929                }
930                TcpBackend::Socket { socket, static_dns } => conn.inner.poll_socket_backend(
931                    cx,
932                    &mut sender,
933                    socket,
934                    static_dns,
935                    &self.inner.dns,
936                ),
937            };
938            if !keep {
939                self.inner
940                    .tcp
941                    .aggregate_stats
942                    .record_close(conn.inner.last_close_reason);
943            } else if let Some(deadline) = conn.inner.next_timer_deadline() {
944                next_deadline = Some(
945                    next_deadline.map_or(deadline, |next_deadline| next_deadline.min(deadline)),
946                );
947            }
948            keep
949        });
950
951        if let Some(deadline) = next_deadline {
952            let timer = self
953                .inner
954                .tcp
955                .timer
956                .get_or_insert_with(|| TcpTimer::new(self.client.driver()));
957            if timer.poll_until(cx, deadline).is_ready() {
958                cx.waker().wake_by_ref();
959            }
960        }
961    }
962
963    pub(crate) fn refresh_tcp_driver(&mut self) {
964        self.inner.tcp.timer = Some(TcpTimer::new(self.client.driver()));
965        self.inner.tcp.connections.retain(|ft, conn| {
966            let TcpBackend::Socket {
967                socket: opt_socket, ..
968            } = &mut conn.backend
969            else {
970                // DNS connections have no real socket to refresh.
971                return true;
972            };
973            let Some(socket) = opt_socket.take() else {
974                return true;
975            };
976            let socket = socket.into_inner();
977            match PolledSocket::new(self.client.driver(), socket) {
978                Ok(socket) => {
979                    *opt_socket = Some(socket);
980                    true
981                }
982                Err(err) => {
983                    tracing::warn!(
984                        error = &err as &dyn std::error::Error,
985                        src = %ft.src,
986                        dst = %ft.dst,
987                        "failed to update driver for tcp connection"
988                    );
989                    false
990                }
991            }
992        });
993    }
994
995    pub(crate) fn handle_tcp(
996        &mut self,
997        addresses: &IpAddresses,
998        payload: &[u8],
999        checksum: &ChecksumState,
1000    ) -> Result<(), DropReason> {
1001        let tcp_packet = TcpPacket::new_checked(payload)?;
1002        let tcp = TcpRepr::parse(
1003            &tcp_packet,
1004            &addresses.src_addr(),
1005            &addresses.dst_addr(),
1006            &checksum.caps(),
1007        )?;
1008
1009        let ft = match addresses {
1010            IpAddresses::V4(addresses) => FourTuple {
1011                dst: SocketAddr::V4(SocketAddrV4::new(addresses.dst_addr, tcp.dst_port)),
1012                src: SocketAddr::V4(SocketAddrV4::new(addresses.src_addr, tcp.src_port)),
1013            },
1014            IpAddresses::V6(addresses) => FourTuple {
1015                dst: SocketAddr::V6(SocketAddrV6::new(addresses.dst_addr, tcp.dst_port, 0, 0)),
1016                src: SocketAddr::V6(SocketAddrV6::new(addresses.src_addr, tcp.src_port, 0, 0)),
1017            },
1018        };
1019        trace_tcp_packet(&ft, &tcp, tcp.payload.len(), "recv");
1020
1021        let is_dns_tcp = is_gateway_dns_tcp(
1022            &ft,
1023            &self.inner.state.params,
1024            self.inner.dns.can_answer_queries(),
1025        );
1026        let inspect_static_dns =
1027            ft.dst.port() == crate::DNS_PORT && self.inner.dns.should_intercept_static_queries();
1028
1029        let replace_time_wait = tcp.control == TcpControl::Syn
1030            && tcp.ack_number.is_none()
1031            && self.inner.tcp.connections.get(&ft).is_some_and(|conn| {
1032                conn.inner.state == TcpState::TimeWait && tcp.seq_number > conn.inner.rx_seq
1033            });
1034        if replace_time_wait && let Some(conn) = self.inner.tcp.connections.remove(&ft) {
1035            if matches!(
1036                conn.backend,
1037                TcpBackend::Dns(ref handler) if handler.is_in_flight()
1038            ) {
1039                self.inner.dns.complete_tcp_query();
1040            }
1041            self.inner
1042                .tcp
1043                .aggregate_stats
1044                .record_close(ConnectionCloseReason::Normal);
1045        }
1046
1047        let mut sender = Sender {
1048            ft: &ft,
1049            client: self.client,
1050            state: &mut self.inner.state,
1051        };
1052
1053        match self.inner.tcp.connections.entry(ft) {
1054            hash_map::Entry::Occupied(mut e) => {
1055                let keep = e.get_mut().inner.handle_packet(&mut sender, &tcp)?;
1056                if keep {
1057                    // Push out any newly-unblocked data (e.g., this ACK advanced
1058                    // the peer window) so we don't wait an entire poll cycle.
1059                    //
1060                    // Use `AckPolicy::Defer` so we DON'T emit a standalone ACK
1061                    // here: inbound bursts arrive as many back-to-back
1062                    // `handle_tcp` calls within a single `poll_ready` cycle,
1063                    // and the trailing `poll_tcp` will emit (at most) one
1064                    // consolidated ACK for the whole batch — or piggyback it
1065                    // on outbound data if any becomes available. Without this,
1066                    // every guest packet would trigger a zero-payload ACK back,
1067                    // doubling packet rate and creating an ACK storm.
1068                    e.get_mut().inner.send_next(&mut sender, AckPolicy::Defer);
1069                } else {
1070                    self.inner
1071                        .tcp
1072                        .aggregate_stats
1073                        .record_close(e.get().inner.last_close_reason);
1074                    let dns_in_flight = matches!(
1075                        e.get().backend,
1076                        TcpBackend::Dns(ref h) if h.is_in_flight()
1077                    );
1078                    e.remove();
1079                    if dns_in_flight {
1080                        self.inner.dns.complete_tcp_query();
1081                    }
1082                }
1083            }
1084            hash_map::Entry::Vacant(e) => {
1085                if tcp.control == TcpControl::Rst {
1086                    // This connection is already closed. Ignore the packet.
1087                } else if let Some(ack) = tcp.ack_number {
1088                    // This is for an old connection. Send reset.
1089                    sender.rst(ack, None);
1090                } else if tcp.control == TcpControl::Syn {
1091                    let conn = if is_dns_tcp {
1092                        TcpConnection::new_dns(
1093                            &mut sender,
1094                            &tcp,
1095                            &self.inner.tcp.connection_params,
1096                        )?
1097                    } else {
1098                        // Resolve virtual mapped addresses back to real host
1099                        // addresses before establishing the connection.
1100                        let resolved_dst = sender.state.resolve_destination(&sender.ft.dst);
1101                        // If this is directed to a local port owned by the guest, use the
1102                        // appropriate host port substitution.
1103                        let is_local_address = sender.state.params.is_local_address(&resolved_dst);
1104                        let key =
1105                            PortForwardKey::from_socket_addr(resolved_dst, resolved_dst.port());
1106                        let ft = if is_local_address
1107                            && let Some(listener) = self.inner.tcp.listeners.get(&key)
1108                        {
1109                            FourTuple {
1110                                src: sender.ft.src,
1111                                dst: SocketAddr::new(resolved_dst.ip(), listener.host_port),
1112                            }
1113                        } else if resolved_dst != sender.ft.dst {
1114                            FourTuple {
1115                                src: sender.ft.src,
1116                                dst: resolved_dst,
1117                            }
1118                        } else {
1119                            ft
1120                        };
1121                        let mut sender = Sender {
1122                            ft: &ft,
1123                            client: sender.client,
1124                            state: sender.state,
1125                        };
1126                        TcpConnection::new(
1127                            &mut sender,
1128                            &tcp,
1129                            &self.inner.tcp.connection_params,
1130                            is_local_address,
1131                            inspect_static_dns,
1132                        )?
1133                    };
1134                    e.insert(conn);
1135                    self.inner
1136                        .tcp
1137                        .aggregate_stats
1138                        .connections_initiated
1139                        .increment();
1140                } else {
1141                    // Ignore the packet.
1142                }
1143            }
1144        }
1145        Ok(())
1146    }
1147
1148    /// Binds to the specified host IP and port for listening for incoming
1149    /// connections.
1150    pub fn bind_tcp_port(&mut self, socket: Socket, guest_port: u16) -> Result<(), BindError> {
1151        let host_addr = Self::socket_local_addr(&socket)?;
1152        let key = PortForwardKey::from_socket_addr(host_addr, guest_port);
1153        match self.inner.tcp.listeners.entry(key) {
1154            hash_map::Entry::Occupied(_) => {
1155                return Err(BindError::PortAlreadyBound(guest_port));
1156            }
1157            hash_map::Entry::Vacant(e) => {
1158                let listener = TcpListener::from_socket(self.client.driver(), socket)?;
1159                e.insert(listener);
1160            }
1161        };
1162        Ok(())
1163    }
1164
1165    /// Unbinds from the specified guest port and IP family.
1166    pub fn unbind_tcp_port(&mut self, family: IpVersion, port: u16) -> Result<(), BindError> {
1167        match self
1168            .inner
1169            .tcp
1170            .listeners
1171            .entry(PortForwardKey::new(family, port))
1172        {
1173            hash_map::Entry::Occupied(e) => {
1174                e.remove();
1175                Ok(())
1176            }
1177            hash_map::Entry::Vacant(_) => Err(BindError::PortNotBound),
1178        }
1179    }
1180
1181    fn socket_local_addr(socket: &Socket) -> Result<SocketAddr, BindError> {
1182        socket
1183            .local_addr()
1184            .map_err(BindError::Io)?
1185            .as_socket()
1186            .ok_or_else(|| BindError::Io(io::Error::other("socket local address is invalid")))
1187    }
1188}
1189
1190struct Sender<'a, T> {
1191    ft: &'a FourTuple,
1192    client: &'a mut T,
1193    state: &'a mut ConsommeState,
1194}
1195
1196impl<T: Client> Sender<'_, T> {
1197    fn send_packet(&mut self, tcp: &TcpRepr<'_>, payload: Option<ring::View<'_>>) {
1198        let payload_len = payload.as_ref().map_or(0, |p| p.len());
1199        let buffer = &mut self.state.buffer;
1200        let mut eth_packet = EthernetFrame::new_unchecked(&mut buffer[..]);
1201        eth_packet.set_dst_addr(self.state.params.client_mac);
1202        eth_packet.set_src_addr(self.state.params.gateway_mac);
1203        let ip = IpRepr::new(
1204            self.ft.dst.ip().into(),
1205            self.ft.src.ip().into(),
1206            IpProtocol::Tcp,
1207            tcp.header_len() + payload_len,
1208            64,
1209        );
1210        // Set the ethernet type based on IP version
1211        match ip {
1212            IpRepr::Ipv4(_) => eth_packet.set_ethertype(EthernetProtocol::Ipv4),
1213            IpRepr::Ipv6(_) => eth_packet.set_ethertype(EthernetProtocol::Ipv6),
1214        }
1215
1216        // Emit IP packet and get the TCP payload buffer (works for both IPv4 and IPv6)
1217        let ip_packet_buf = eth_packet.payload_mut();
1218        ip.emit(&mut *ip_packet_buf, &ChecksumCapabilities::default());
1219
1220        let (tcp_payload_buf, ip_total_len) = match self.ft.dst {
1221            SocketAddr::V4(_) => {
1222                let ipv4_packet = Ipv4Packet::new_unchecked(&*ip_packet_buf);
1223                let total_len = ipv4_packet.total_len() as usize;
1224                let payload_offset = ipv4_packet.header_len() as usize;
1225                (&mut ip_packet_buf[payload_offset..total_len], total_len)
1226            }
1227            SocketAddr::V6(_) => {
1228                let ipv6_packet = Ipv6Packet::new_unchecked(&*ip_packet_buf);
1229                let total_len = ipv6_packet.total_len();
1230                let payload_offset = IPV6_HEADER_LEN;
1231                (&mut ip_packet_buf[payload_offset..total_len], total_len)
1232            }
1233        };
1234
1235        let dst_ip_addr: IpAddress = self.ft.dst.ip().into();
1236        let src_ip_addr: IpAddress = self.ft.src.ip().into();
1237        let mut tcp_packet = TcpPacket::new_unchecked(tcp_payload_buf);
1238        // Checksums are computed explicitly below, so skip smoltcp's pass.
1239        tcp.emit(
1240            &mut tcp_packet,
1241            &dst_ip_addr,
1242            &src_ip_addr,
1243            &ChecksumCapabilities::ignored(),
1244        );
1245
1246        let checksum_state = match self.ft.dst {
1247            SocketAddr::V4(_) => ChecksumState::TCP4,
1248            SocketAddr::V6(_) => ChecksumState::TCP6,
1249        };
1250        let n = ETHERNET_HEADER_LEN + ip_total_len;
1251
1252        let payload = match payload {
1253            Some(p) if p.len() != 0 => p,
1254            _ => {
1255                tcp_packet.fill_checksum(&dst_ip_addr, &src_ip_addr);
1256                let buffer = &self.state.buffer;
1257                self.client.recv(&buffer[..n], &checksum_state);
1258                return;
1259            }
1260        };
1261
1262        // Zero-copy payload path: leave the TCP window bytes in place and hand
1263        // the header and (up to two) payload slices to the client as
1264        // discontiguous segments, avoiding a copy of the payload into the
1265        // header buffer. The TCP checksum must be recomputed across those
1266        // segments because the payload was never linearized here.
1267        let (a, b) = payload.as_slices();
1268        let tcp_header_len = tcp_packet.header_len() as usize;
1269        tcp_packet.set_checksum(0);
1270        // The TCP header length is a multiple of 4, so the header and `a` are
1271        // 16-bit aligned; `b` shifts by a byte only when `a` has odd length, in
1272        // which case its partial checksum is byte-swapped.
1273        let checksum = !checksum::combine(&[
1274            checksum::pseudo_header(
1275                &src_ip_addr,
1276                &dst_ip_addr,
1277                IpProtocol::Tcp,
1278                (tcp_header_len + payload_len) as u32,
1279            ),
1280            checksum::data(&tcp_packet.as_ref()[..tcp_header_len]),
1281            checksum::data(a),
1282            if a.len() % 2 == 0 {
1283                checksum::data(b)
1284            } else {
1285                checksum::data(b).swap_bytes()
1286            },
1287        ]);
1288        tcp_packet.set_checksum(checksum);
1289
1290        let header_len = n - payload_len;
1291        let buffer = &self.state.buffer;
1292        let header = &buffer[..header_len];
1293        if b.is_empty() {
1294            self.client.recv_segments(&[header, a], &checksum_state);
1295        } else {
1296            self.client.recv_segments(&[header, a, b], &checksum_state);
1297        }
1298    }
1299
1300    fn rst(&mut self, seq: TcpSeqNumber, ack: Option<TcpSeqNumber>) {
1301        let _ = self.try_rst(seq, ack);
1302    }
1303
1304    fn try_rst(&mut self, seq: TcpSeqNumber, ack: Option<TcpSeqNumber>) -> bool {
1305        if self.client.rx_mtu() == 0 {
1306            return false;
1307        }
1308
1309        let tcp = TcpRepr {
1310            src_port: self.ft.dst.port(),
1311            dst_port: self.ft.src.port(),
1312            control: TcpControl::Rst,
1313            seq_number: seq,
1314            ack_number: ack,
1315            window_len: 0,
1316            window_scale: None,
1317            max_seg_size: None,
1318            sack_permitted: false,
1319            sack_ranges: [None, None, None],
1320            timestamp: None,
1321            payload: &[],
1322        };
1323
1324        trace_tcp_packet(self.ft, &tcp, 0, "rst xmit");
1325
1326        self.send_packet(&tcp, None);
1327        true
1328    }
1329}
1330
1331impl TcpConnection {
1332    fn new_base(params: &ConnectionParams) -> TcpConnectionInner {
1333        let mut rx_tx_seq = [0; 8];
1334        getrandom::fill(&mut rx_tx_seq[..]).expect("prng failure");
1335        let rx_seq = TcpSeqNumber(i32::from_ne_bytes(
1336            rx_tx_seq[0..4].try_into().expect("invalid length"),
1337        ));
1338        let tx_seq = TcpSeqNumber(i32::from_ne_bytes(
1339            rx_tx_seq[4..8].try_into().expect("invalid length"),
1340        ));
1341
1342        let rx_bounds = params.rx_buffer;
1343        let rx_window_scale =
1344            (usize::BITS - rx_bounds.max.leading_zeros()).saturating_sub(16) as u8;
1345
1346        let tx_bounds = params.tx_buffer;
1347
1348        TcpConnectionInner {
1349            loopback_port: LoopbackPortInfo::None,
1350            state: TcpState::Connecting,
1351            lifetime_timer: LifetimeTimer::Handshake(
1352                TimerInstant::now().saturating_add(HANDSHAKE_TIMEOUT),
1353            ),
1354            retransmission: RetransmissionState::new(),
1355            rx_buffer: ring::Ring::new(0),
1356            rx_window_cap: rx_bounds.initial,
1357            rx_window_scale,
1358            rx_buffer_max: rx_bounds.max,
1359            rx_seq,
1360            rx_window_last_adv: rx_bounds.initial,
1361            rx_assembler: assembler::Assembler::new(),
1362            needs_ack: false,
1363            is_shutdown: false,
1364            enable_window_scaling: false,
1365            tx_buffer: ring::Ring::new(tx_bounds.initial),
1366            tx_buffer_max: tx_bounds.max,
1367            tx_acked: tx_seq,
1368            tx_send: tx_seq,
1369            tx_syn: TxSynState::None,
1370            tx_window_len: 1,
1371            tx_window_scale: 0,
1372            tx_window_scale_active: false,
1373            tx_window_rx_seq: rx_seq,
1374            tx_window_tx_seq: tx_seq,
1375            // The TCPv4 default maximum segment size is 536. This can be bigger for
1376            // IPv6.
1377            tx_mss: 536,
1378            tx_fin: TxFinState::None,
1379            last_close_reason: ConnectionCloseReason::LocalError,
1380            stats: TcpConnStats::default(),
1381        }
1382    }
1383
1384    fn new(
1385        sender: &mut Sender<'_, impl Client>,
1386        tcp: &TcpRepr<'_>,
1387        params: &ConnectionParams,
1388        is_local_address: bool,
1389        inspect_static_dns: bool,
1390    ) -> Result<Self, DropReason> {
1391        let mut inner = Self::new_base(params);
1392        inner.initialize_from_first_client_packet(*sender.ft, tcp)?;
1393
1394        let socket = Socket::new(
1395            match sender.ft.dst {
1396                SocketAddr::V4(_) => Domain::IPV4,
1397                SocketAddr::V6(_) => Domain::IPV6,
1398            },
1399            Type::STREAM,
1400            Some(Protocol::TCP),
1401        )
1402        .map_err(DropReason::Io)?;
1403
1404        // Disable Nagle's algorithm to reduce latency for small packets.
1405        socket.set_tcp_nodelay(true).map_err(DropReason::Io)?;
1406
1407        // On Windows the default behavior for non-existent loopback sockets is
1408        // to wait and try again. This is different than the Linux behavior of
1409        // immediately failing. Default to the Linux behavior.
1410        #[cfg(windows)]
1411        if sender.ft.dst.ip().is_loopback() {
1412            if let Err(err) = crate::windows::disable_connection_retries(&socket) {
1413                tracing::trace!(
1414                    err,
1415                    src = %sender.ft.src,
1416                    dst = %sender.ft.dst,
1417                    "Failed to disable loopback retries"
1418                );
1419            }
1420        }
1421
1422        let socket = PolledSocket::new(sender.client.driver(), socket).map_err(DropReason::Io)?;
1423        match socket.get().connect(&SockAddr::from(sender.ft.dst)) {
1424            Ok(_) => unreachable!(),
1425            Err(err) if is_connect_incomplete_error(&err) => (),
1426            Err(err) => {
1427                log_connect_error(sender.ft, &err);
1428                sender.rst(TcpSeqNumber(0), Some(tcp.seq_number + tcp.segment_len()));
1429                return Err(DropReason::Io(err));
1430            }
1431        }
1432        if is_local_address && let Ok(addr) = socket.get().local_addr() {
1433            match addr.as_socket() {
1434                None => {
1435                    tracing::warn!(
1436                        src = %sender.ft.src,
1437                        dst = %sender.ft.dst,
1438                        "unable to get local socket address",
1439                    );
1440                }
1441                Some(addr) => {
1442                    inner.loopback_port = LoopbackPortInfo::ProxyForGuestPort {
1443                        sending_port: addr.port(),
1444                        guest_port: sender.ft.src.port(),
1445                    };
1446                }
1447            }
1448        }
1449        Ok(Self {
1450            backend: TcpBackend::Socket {
1451                socket: Some(socket),
1452                static_dns: inspect_static_dns.then(StaticDnsTcpInspection::default),
1453            },
1454            inner,
1455        })
1456    }
1457
1458    fn new_from_accept(
1459        sender: &mut Sender<'_, impl Client>,
1460        socket: Socket,
1461        params: &ConnectionParams,
1462    ) -> Result<Self, DropReason> {
1463        // Disable Nagle's algorithm to reduce latency for small packets.
1464        socket.set_tcp_nodelay(true).map_err(DropReason::Io)?;
1465
1466        let mut inner = TcpConnectionInner {
1467            state: TcpState::SynSent,
1468            enable_window_scaling: true,
1469            ..Self::new_base(params)
1470        };
1471        inner.send_syn(sender, None);
1472        Ok(Self {
1473            backend: TcpBackend::Socket {
1474                socket: Some(
1475                    PolledSocket::new(sender.client.driver(), socket).map_err(DropReason::Io)?,
1476                ),
1477                static_dns: None,
1478            },
1479            inner,
1480        })
1481    }
1482
1483    /// Create a virtual DNS TCP connection (no real host socket).
1484    /// The connection completes the TCP handshake with the guest and
1485    /// routes DNS queries through the provided resolver backend.
1486    fn new_dns(
1487        sender: &mut Sender<'_, impl Client>,
1488        tcp: &TcpRepr<'_>,
1489        params: &ConnectionParams,
1490    ) -> Result<Self, DropReason> {
1491        let mut inner = Self::new_base(params);
1492        inner.initialize_from_first_client_packet(*sender.ft, tcp)?;
1493
1494        let flow = crate::dns_resolver::DnsFlow {
1495            src: sender.ft.src,
1496            dst: sender.ft.dst,
1497            gateway_mac: sender.state.params.gateway_mac,
1498            client_mac: sender.state.params.client_mac,
1499            transport: crate::dns_resolver::DnsTransport::Tcp,
1500        };
1501
1502        // Immediately transition to SynReceived so the handshake SYN-ACK is sent.
1503        inner.state = TcpState::SynReceived;
1504        inner.send_syn(sender, Some(inner.rx_seq));
1505
1506        Ok(Self {
1507            backend: TcpBackend::Dns(DnsTcpHandler::new(flow)),
1508            inner,
1509        })
1510    }
1511}
1512
1513impl TcpConnectionInner {
1514    fn initialize_from_first_client_packet(
1515        &mut self,
1516        flow: FourTuple,
1517        tcp: &TcpRepr<'_>,
1518    ) -> Result<(), DropReason> {
1519        // The TCPv4 default maximum segment size is 536. This can be bigger for
1520        // IPv6.
1521        let tx_mss = tcp.max_seg_size.map_or(536, |x| x.into());
1522
1523        if let Some(tx_window_scale) = tcp.window_scale {
1524            if tx_window_scale > 14 {
1525                return Err(TcpError::new(flow, TcpErrorKind::InvalidWindowScale).into());
1526            }
1527            self.enable_window_scaling = true;
1528            self.tx_window_scale = tx_window_scale;
1529        } else {
1530            // Disable rx window scale. Cap the buffer and window to u16::MAX
1531            // since without window scaling, the window field is only 16 bits.
1532            self.enable_window_scaling = false;
1533            self.rx_window_cap = self.rx_window_cap.min(u16::MAX as usize);
1534            self.rx_buffer_max = self.rx_buffer_max.min(u16::MAX as usize);
1535            self.rx_window_scale = 0;
1536        }
1537
1538        self.rx_buffer = ring::Ring::new(self.rx_window_cap.next_power_of_two());
1539        self.rx_seq = tcp.seq_number + 1;
1540        self.tx_window_rx_seq = tcp.seq_number + 1;
1541        self.tx_mss = tx_mss;
1542        Ok(())
1543    }
1544
1545    /// Poll the DNS TCP virtual connection backend.
1546    ///
1547    /// There is no real socket; data flows through the [`DnsTcpHandler`].
1548    fn poll_dns_backend(
1549        &mut self,
1550        cx: &mut Context<'_>,
1551        sender: &mut Sender<'_, impl Client>,
1552        dns_handler: &mut DnsTcpHandler,
1553        dns: &mut DnsResolver,
1554    ) -> bool {
1555        // Propagate guest FIN before the tx path so that poll_read can
1556        // detect EOF on the same iteration.
1557        if self.state.rx_fin() && !dns_handler.guest_fin() {
1558            tracing::trace!(
1559                src = %sender.ft.src,
1560                dst = %sender.ft.dst,
1561                tx_buffer_len = self.tx_buffer.len(),
1562                tx_buffer_full = self.tx_buffer.is_full(),
1563                "tcp: guest FIN received, signaling EOF to DNS handler",
1564            );
1565            dns_handler.set_guest_fin();
1566        }
1567
1568        // rx path: feed guest data into the DNS handler for query extraction.
1569        // Done before the tx path so that a query answered locally from static
1570        // records is drained into tx_buffer within the same poll.
1571        let view = self.rx_buffer.view(0..self.rx_buffer.len());
1572        let (a, b) = view.as_slices();
1573        match dns_handler.ingest(&[a, b], dns) {
1574            Ok(consumed) if consumed > 0 => {
1575                self.rx_buffer.consume(consumed);
1576            }
1577            Ok(_) => {}
1578            Err(_) => {
1579                // The DNS TCP query could not be processed; reset the connection.
1580                if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1581                    self.stats.rsts_tx.increment();
1582                }
1583                return false;
1584            }
1585        }
1586
1587        // tx path: drain DNS responses into tx_buffer.
1588        while !self.tx_buffer.is_full() {
1589            let (a, b) = self.tx_buffer.unwritten_slices_mut();
1590            let mut bufs = [IoSliceMut::new(a), IoSliceMut::new(b)];
1591            match dns_handler.poll_read(cx, &mut bufs, dns) {
1592                Poll::Ready(Ok(n)) => {
1593                    if n == 0 {
1594                        // EOF — close the connection.
1595                        if !self.state.tx_fin() {
1596                            self.close(sender.state.params.tcp_close_timeout, sender.ft);
1597                        }
1598                        break;
1599                    }
1600                    self.tx_buffer.extend_by(n);
1601                    tracing::trace!(
1602                        src = %sender.ft.src,
1603                        dst = %sender.ft.dst,
1604                        n,
1605                        tx_buffer_len = self.tx_buffer.len(),
1606                        tx_buffer_full = self.tx_buffer.is_full(),
1607                        "tcp: response from DNS handler into tx_buffer",
1608                    );
1609                }
1610                Poll::Ready(Err(_)) => {
1611                    if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1612                        self.stats.rsts_tx.increment();
1613                    }
1614                    return false;
1615                }
1616                Poll::Pending => break,
1617            }
1618        }
1619
1620        // Flush any deferred pure-ACK from per-packet `handle_tcp` calls.
1621        self.send_next(sender, AckPolicy::Flush);
1622        true
1623    }
1624
1625    /// Poll the real-socket TCP connection backend.
1626    ///
1627    /// Reads data from the host socket into the tx buffer (host -> guest) and
1628    /// writes guest rx data into the host socket (guest -> host).
1629    fn poll_socket_backend(
1630        &mut self,
1631        cx: &mut Context<'_>,
1632        sender: &mut Sender<'_, impl Client>,
1633        opt_socket: &mut Option<PolledSocket<Socket>>,
1634        static_dns: &mut Option<StaticDnsTcpInspection>,
1635        dns: &DnsResolver,
1636    ) -> bool {
1637        // Wait for the outbound connection to complete.
1638        if self.state == TcpState::Connecting {
1639            let Some(socket) = opt_socket.as_mut() else {
1640                return false;
1641            };
1642            match socket.poll_ready(cx, PollEvents::OUT) {
1643                Poll::Ready(r) => {
1644                    if r.has_err() {
1645                        self.handle_connect_error(sender, socket);
1646                        return false;
1647                    }
1648
1649                    tracing::debug!(
1650                        src = %sender.ft.src,
1651                        dst = %sender.ft.dst,
1652                        "connection established",
1653                    );
1654                    self.state = TcpState::SynReceived;
1655                }
1656                Poll::Pending => return true,
1657            }
1658        } else if self.state == TcpState::SynSent {
1659            // Need to establish connection with client before sending data.
1660            self.send_next(sender, AckPolicy::Flush);
1661            return true;
1662        }
1663
1664        // Handle the tx path.
1665        if let Some(socket) = opt_socket.as_mut() {
1666            if self.state.tx_fin() {
1667                if let Poll::Ready(events) = socket.poll_ready(cx, PollEvents::EMPTY) {
1668                    if events.has_err() {
1669                        let err = take_socket_error(socket);
1670                        match err.kind() {
1671                            ErrorKind::BrokenPipe | ErrorKind::ConnectionReset => {}
1672                            _ => tracelimit::warn_ratelimited!(
1673                                error = &err as &dyn std::error::Error,
1674                                src = %sender.ft.src,
1675                                dst = %sender.ft.dst,
1676                                "socket failure after fin"
1677                            ),
1678                        }
1679                        if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1680                            self.stats.rsts_tx.increment();
1681                        }
1682                        return false;
1683                    }
1684
1685                    // Both ends are closed. Close the actual socket.
1686                    *opt_socket = None;
1687                }
1688            } else {
1689                // Drain the host socket into the tx ring until the socket has
1690                // no more data (Pending) or the ring reaches its autotune
1691                // ceiling. When the ring fills with data still pending, grow it
1692                // (doubling, capped at tx_buffer_max) and keep reading so the
1693                // freshly added capacity is used in this same poll rather than
1694                // waiting for a later guest ACK to re-clock the connection.
1695                'read: loop {
1696                    while !self.tx_buffer.is_full() {
1697                        let (a, b) = self.tx_buffer.unwritten_slices_mut();
1698                        let mut bufs = [IoSliceMut::new(a), IoSliceMut::new(b)];
1699                        match Pin::new(&mut *socket).poll_read_vectored(cx, &mut bufs) {
1700                            Poll::Ready(Ok(n)) => {
1701                                if n == 0 {
1702                                    self.close(sender.state.params.tcp_close_timeout, sender.ft);
1703                                    break 'read;
1704                                }
1705                                if let Some(static_dns) = static_dns.as_mut() {
1706                                    let first = n.min(bufs[0].len());
1707                                    static_dns.host_response_frames.ingest(&bufs[0][..first]);
1708                                    static_dns
1709                                        .host_response_frames
1710                                        .ingest(&bufs[1][..n - first]);
1711                                }
1712                                self.tx_buffer.extend_by(n);
1713                            }
1714                            Poll::Ready(Err(err)) => {
1715                                match err.kind() {
1716                                    ErrorKind::ConnectionReset => tracing::trace!(
1717                                        error = &err as &dyn std::error::Error,
1718                                        src = %sender.ft.src,
1719                                        dst = %sender.ft.dst,
1720                                        "socket read error"
1721                                    ),
1722                                    _ => tracelimit::warn_ratelimited!(
1723                                        error = &err as &dyn std::error::Error,
1724                                        src = %sender.ft.src,
1725                                        dst = %sender.ft.dst,
1726                                        "socket read error"
1727                                    ),
1728                                }
1729                                if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1730                                    self.stats.rsts_tx.increment();
1731                                }
1732                                return false;
1733                            }
1734                            Poll::Pending => break 'read,
1735                        }
1736                    }
1737
1738                    // The ring is full. If we can still grow, double it (capped
1739                    // at tx_buffer_max) and keep reading into the new space. At
1740                    // the ceiling we stop without re-arming: the cached socket
1741                    // readiness stays set and the next guest ACK that drains the
1742                    // ring re-clocks the read, which is safe on edge-triggered
1743                    // epoll backends.
1744                    if self.tx_buffer.capacity() >= self.tx_buffer_max {
1745                        break;
1746                    }
1747                    let new_cap = (self.tx_buffer.capacity() * 2).min(self.tx_buffer_max);
1748                    self.tx_buffer.resize(new_cap);
1749                    self.stats.tx_buffer_grows.increment();
1750                }
1751            }
1752        }
1753
1754        if let Some(socket) = opt_socket.as_mut() {
1755            if !self.poll_socket_write(cx, sender, socket, static_dns, dns) {
1756                return false;
1757            }
1758        }
1759
1760        // Send any pending data or ACKs. Always use Flush: if no data was
1761        // read from the socket and no ACK is pending, send_data will find
1762        // nothing to do anyway.
1763        self.send_next(sender, AckPolicy::Flush);
1764        self.compact_closed_buffers();
1765        true
1766    }
1767
1768    /// Writes guest data to the host socket, optionally inspecting DNS frames.
1769    fn poll_socket_write(
1770        &mut self,
1771        cx: &mut Context<'_>,
1772        sender: &mut Sender<'_, impl Client>,
1773        socket: &mut PolledSocket<Socket>,
1774        static_dns: &mut Option<StaticDnsTcpInspection>,
1775        dns: &DnsResolver,
1776    ) -> bool {
1777        let rx_high_water = self.rx_buffer.len();
1778        loop {
1779            let write = if let Some(static_dns) = static_dns.as_mut() {
1780                if matches!(
1781                    self.poll_static_dns(static_dns, dns),
1782                    StaticDnsTcpDisposition::Hold
1783                ) {
1784                    break;
1785                }
1786                let Some(forwarding) = static_dns.forwarding.as_ref() else {
1787                    break;
1788                };
1789                Pin::new(&mut *socket).poll_write(cx, &forwarding.frame[forwarding.offset..])
1790            } else {
1791                if self.rx_buffer.is_empty() {
1792                    break;
1793                }
1794                let view = self.rx_buffer.view(0..self.rx_buffer.len());
1795                let (a, b) = view.as_slices();
1796                let bufs = [IoSlice::new(a), IoSlice::new(b)];
1797                Pin::new(&mut *socket).poll_write_vectored(cx, &bufs)
1798            };
1799
1800            match write {
1801                Poll::Ready(Ok(0)) | Poll::Pending => break,
1802                Poll::Ready(Ok(n)) => {
1803                    if let Some(static_dns) = static_dns {
1804                        let Some(forwarding) = static_dns.forwarding.as_mut() else {
1805                            break;
1806                        };
1807                        forwarding.offset += n;
1808                        let complete = forwarding.offset == forwarding.frame.len();
1809                        if complete && let Some(forwarding) = static_dns.forwarding.take() {
1810                            static_dns.frame_assembler.recycle_buffer(forwarding.frame);
1811                        }
1812                    } else {
1813                        self.rx_buffer.consume(n);
1814                    }
1815                }
1816                Poll::Ready(Err(err)) => {
1817                    match err.kind() {
1818                        ErrorKind::BrokenPipe | ErrorKind::ConnectionReset => {}
1819                        _ => {
1820                            tracelimit::warn_ratelimited!(
1821                                error = &err as &dyn std::error::Error,
1822                                src = %sender.ft.src,
1823                                dst = %sender.ft.dst,
1824                                "socket write error"
1825                            );
1826                        }
1827                    }
1828                    if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1829                        self.stats.rsts_tx.increment();
1830                    }
1831                    return false;
1832                }
1833            }
1834        }
1835
1836        // Draining to the host may have reopened the window; re-advertise it
1837        // so the guest resumes without waiting on its persist timer.
1838        if self.should_reopen_window() {
1839            self.needs_ack = true;
1840        }
1841        // Autotune: if the host kept up (drained to empty) and the buffer
1842        // was at least 75% full this cycle, the guest is rx-bound. Grow
1843        // both the ring and the advertised window ceiling so the next ACK
1844        // tells the guest it can send more. Gated on the assembler being
1845        // empty because `Ring::resize` only preserves contiguous bytes
1846        // in `[head, tail)` — any out-of-order data staged past `tail`
1847        // via `write_at` would be lost.
1848        if !self.state.rx_fin()
1849            && self.rx_buffer.is_empty()
1850            && self.rx_assembler.is_empty()
1851            && self.rx_window_cap < self.rx_buffer_max
1852            && rx_high_water * 4 >= self.rx_window_cap * 3
1853        {
1854            let new_cap = (self.rx_window_cap * 2).min(self.rx_buffer_max);
1855            let new_ring_cap = new_cap.next_power_of_two();
1856            if new_ring_cap > self.rx_buffer.capacity() {
1857                self.rx_buffer.resize(new_ring_cap);
1858            }
1859            self.rx_window_cap = new_cap;
1860            self.needs_ack = true;
1861            self.stats.rx_buffer_grows.increment();
1862        }
1863
1864        let static_dns_empty = static_dns
1865            .as_ref()
1866            .is_none_or(StaticDnsTcpInspection::is_empty);
1867        if self.rx_buffer.is_empty() && static_dns_empty && self.state.rx_fin() && !self.is_shutdown
1868        {
1869            if let Err(err) = socket.get().shutdown(Shutdown::Write) {
1870                tracelimit::warn_ratelimited!(
1871                    error = &err as &dyn std::error::Error,
1872                    src = %sender.ft.src,
1873                    dst = %sender.ft.dst,
1874                    "shutdown error"
1875                );
1876                if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1877                    self.stats.rsts_tx.increment();
1878                }
1879                return false;
1880            }
1881            self.is_shutdown = true;
1882        }
1883
1884        true
1885    }
1886
1887    /// Answers complete DNS-over-TCP messages from static records.
1888    fn poll_static_dns(
1889        &mut self,
1890        static_dns: &mut StaticDnsTcpInspection,
1891        dns: &DnsResolver,
1892    ) -> StaticDnsTcpDisposition {
1893        if static_dns.forwarding.is_some() {
1894            return StaticDnsTcpDisposition::Forward;
1895        }
1896
1897        loop {
1898            if static_dns.frame_assembler.frame().is_none() {
1899                let view = self.rx_buffer.view(0..self.rx_buffer.len());
1900                let (a, b) = view.as_slices();
1901                let consumed = static_dns.frame_assembler.ingest(&[a, b]);
1902                self.rx_buffer.consume(consumed);
1903            }
1904
1905            let Some(frame) = static_dns.frame_assembler.frame() else {
1906                if self.state.rx_fin()
1907                    && self.rx_buffer.is_empty()
1908                    && !static_dns.frame_assembler.is_empty()
1909                {
1910                    static_dns.forwarding = Some(ForwardingDnsTcpFrame {
1911                        frame: static_dns.frame_assembler.take_buffered(),
1912                        offset: 0,
1913                    });
1914                    return StaticDnsTcpDisposition::Forward;
1915                }
1916                return StaticDnsTcpDisposition::Hold;
1917            };
1918
1919            let max_response_len = self.tx_buffer_max.saturating_sub(2).min(u16::MAX as usize);
1920            let Some(response) = dns.build_static_response(&frame[2..], max_response_len) else {
1921                let Some(frame) = static_dns.frame_assembler.take_frame() else {
1922                    return StaticDnsTcpDisposition::Hold;
1923                };
1924                static_dns.forwarding = Some(ForwardingDnsTcpFrame { frame, offset: 0 });
1925                return StaticDnsTcpDisposition::Forward;
1926            };
1927
1928            if !static_dns.host_response_frames.at_frame_boundary() {
1929                return StaticDnsTcpDisposition::Hold;
1930            }
1931
1932            let response_len = response.len() + 2;
1933            if self.tx_buffer.len() + response_len > self.tx_buffer_max {
1934                return StaticDnsTcpDisposition::Hold;
1935            }
1936
1937            let required_capacity = self.tx_buffer.len() + response_len;
1938            if required_capacity > self.tx_buffer.capacity() {
1939                self.tx_buffer.resize(
1940                    required_capacity
1941                        .next_power_of_two()
1942                        .min(self.tx_buffer_max),
1943                );
1944                self.stats.tx_buffer_grows.increment();
1945            }
1946
1947            let (a, b) = self.tx_buffer.unwritten_slices_mut();
1948            let prefix = (response.len() as u16).to_be_bytes();
1949            let mut framed_response = Vec::with_capacity(response_len);
1950            framed_response.extend_from_slice(&prefix);
1951            framed_response.extend_from_slice(&response);
1952            let first = a.len().min(framed_response.len());
1953            a[..first].copy_from_slice(&framed_response[..first]);
1954            b[..framed_response.len() - first].copy_from_slice(&framed_response[first..]);
1955            self.tx_buffer.extend_by(framed_response.len());
1956            if let Some(frame) = static_dns.frame_assembler.take_frame() {
1957                static_dns.frame_assembler.recycle_buffer(frame);
1958            }
1959        }
1960    }
1961
1962    fn handle_connect_error(
1963        &mut self,
1964        sender: &mut Sender<'_, impl Client>,
1965        socket: &mut PolledSocket<Socket>,
1966    ) {
1967        let err = take_socket_error(socket);
1968        if err.kind() == ErrorKind::TimedOut {
1969            // Avoid resetting so that the guest doesn't think there is a
1970            // responding TCP stack at this address. The guest will time out on
1971            // its own.
1972            tracing::debug!(
1973                src = %sender.ft.src,
1974                dst = %sender.ft.dst,
1975                error = &err as &dyn std::error::Error,
1976                "connect timed out",
1977            );
1978        } else {
1979            log_connect_error(sender.ft, &err);
1980            if sender.try_rst(self.tx_send, Some(self.rx_seq)) {
1981                self.stats.rsts_tx.increment();
1982            }
1983        }
1984    }
1985
1986    fn rx_window_len(&self) -> u16 {
1987        (self.rx_window_avail() >> self.rx_window_scale) as u16
1988    }
1989
1990    /// Available receive window in unscaled bytes.
1991    fn rx_window_avail(&self) -> usize {
1992        self.rx_window_cap - self.rx_buffer.len()
1993    }
1994
1995    /// The receive window as the guest reconstructs it: `rx_window_avail`
1996    /// rounded down to the scale quantum, since the low `rx_window_scale` bits
1997    /// are not transmitted. Equals `rx_window_avail` when scaling is off.
1998    fn rx_window_advertised(&self) -> usize {
1999        (self.rx_window_avail() >> self.rx_window_scale) << self.rx_window_scale
2000    }
2001
2002    /// Record the window just advertised to the guest. `window_len` is the
2003    /// scaled value placed on the wire; the guest shifts it back up by the
2004    /// window scale, so track that reconstructed value to keep the reopen
2005    /// check accurate.
2006    fn record_advertised_window(&mut self, window_len: u16) {
2007        self.rx_window_last_adv = (window_len as usize) << self.rx_window_scale;
2008    }
2009
2010    /// Whether draining to the host reopened the receive window enough to
2011    /// re-advertise it (RFC 1122 §4.2.3.3 receiver SWS avoidance). Fires once on
2012    /// the closed-to-open transition, once the guest-visible (post-scale-
2013    /// truncation) window reaches the reopen threshold: a full segment, or half
2014    /// the window cap when the cap is smaller than one segment.
2015    fn should_reopen_window(&self) -> bool {
2016        let reopen_threshold = self.tx_mss.min(self.rx_window_cap / 2);
2017        self.rx_window_last_adv < reopen_threshold
2018            && self.rx_window_advertised() >= reopen_threshold
2019    }
2020
2021    fn send_next(&mut self, sender: &mut Sender<'_, impl Client>, ack_policy: AckPolicy) {
2022        match self.state {
2023            TcpState::Connecting => {}
2024            TcpState::SynSent => self.send_syn(sender, None),
2025            TcpState::SynReceived => self.send_syn(sender, Some(self.rx_seq)),
2026            _ => self.send_data(sender, ack_policy),
2027        }
2028    }
2029
2030    fn send_syn(&mut self, sender: &mut Sender<'_, impl Client>, ack_number: Option<TcpSeqNumber>) {
2031        if self.tx_send != self.tx_acked || sender.client.rx_mtu() == 0 {
2032            return;
2033        }
2034
2035        // If the client side specified a window scale option, then do the same
2036        // (even with no shift) to enable window scale support.
2037        let window_scale = self.enable_window_scaling.then_some(self.rx_window_scale);
2038
2039        // RFC 7323 §2.2: the window in a SYN/SYN-ACK is not scaled even with the
2040        // window_scale option present. Advertise the real window clamped to 16
2041        // bits; the active-open SYN (no ACK) carries a zero window.
2042        let window_len = if ack_number.is_some() {
2043            self.rx_window_avail().min(u16::MAX as usize) as u16
2044        } else {
2045            0
2046        };
2047
2048        // Advertise the maximum possible segment size, allowing the guest
2049        // to truncate this to its own MTU calculation.
2050        let max_seg_size = u16::MAX;
2051        let tcp = TcpRepr {
2052            src_port: sender.ft.dst.port(),
2053            dst_port: sender.ft.src.port(),
2054            control: TcpControl::Syn,
2055            seq_number: self.tx_send,
2056            ack_number,
2057            window_len,
2058            window_scale,
2059            max_seg_size: Some(max_seg_size),
2060            sack_permitted: false,
2061            sack_ranges: [None, None, None],
2062            timestamp: None,
2063            payload: &[],
2064        };
2065
2066        sender.send_packet(&tcp, None);
2067        self.tx_send += 1;
2068        self.tx_syn = if ack_number.is_some() {
2069            TxSynState::SynAck
2070        } else {
2071            TxSynState::Syn
2072        };
2073        self.retransmission.on_send(self.tx_send);
2074        if ack_number.is_some() {
2075            // The guest reads the SYN-ACK window unscaled, so record that value.
2076            self.rx_window_last_adv = window_len as usize;
2077        }
2078    }
2079
2080    fn send_data(&mut self, sender: &mut Sender<'_, impl Client>, ack_policy: AckPolicy) {
2081        // RFC 1323 §2.2: the window field in SYN/SYN-ACK is unscaled. Only
2082        // apply the shift once the handshake is complete (first non-SYN window
2083        // update sets tx_window_scale_active). For the guest-initiated path
2084        // this is set before send_data can run; for host-initiated (port-forward)
2085        // connections it guards against using the unscaled SYN-ACK window.
2086        let scale = if self.tx_window_scale_active {
2087            self.tx_window_scale
2088        } else {
2089            0
2090        };
2091        let tx_payload_end = self.tx_acked + self.tx_buffer.len();
2092        let tx_end = tx_payload_end + self.tx_fin.is_pending() as usize;
2093        let tx_window_end = self.tx_acked + ((self.tx_window_len as usize) << scale);
2094        let tx_done = seq_min([tx_end, tx_window_end]);
2095        let mut send_fin_probe = self.tx_fin == TxFinState::Buffered
2096            && self.tx_buffer.is_empty()
2097            && self.tx_send == self.tx_acked;
2098
2099        if self.tx_send < tx_end && tx_window_end <= self.tx_send {
2100            self.stats.tx_blocked_window_full.increment();
2101        }
2102
2103        while self.needs_ack || self.tx_send < tx_done || send_fin_probe {
2104            let rx_mtu = sender.client.rx_mtu();
2105            if rx_mtu == 0 {
2106                // Out of receive buffers.
2107                self.stats.tx_blocked_no_rx_mtu.increment();
2108                break;
2109            }
2110
2111            let window_len = self.rx_window_len();
2112            let mut tcp = TcpRepr {
2113                src_port: sender.ft.dst.port(),
2114                dst_port: sender.ft.src.port(),
2115                control: TcpControl::None,
2116                seq_number: self.tx_send,
2117                ack_number: Some(self.rx_seq),
2118                window_len,
2119                window_scale: None,
2120                max_seg_size: None,
2121                sack_permitted: false,
2122                sack_ranges: [None, None, None],
2123                timestamp: None,
2124                payload: &[],
2125            };
2126
2127            let mut tx_next = self.tx_send;
2128
2129            // Compute the end of the segment buffer in sequence space to avoid
2130            // exceeding:
2131            // 1. The available buffer length.
2132            // 2. The current window.
2133            // 3. The configured maximum segment size.
2134            // 4. The client MTU.
2135            let tx_segment_end = {
2136                let ip_header_len = match sender.ft.dst {
2137                    SocketAddr::V4(_) => IPV4_HEADER_LEN,
2138                    SocketAddr::V6(_) => IPV6_HEADER_LEN,
2139                };
2140                let header_len = ETHERNET_HEADER_LEN + ip_header_len + tcp.header_len();
2141                let mtu = rx_mtu.min(sender.state.buffer.len());
2142                seq_min([
2143                    tx_payload_end,
2144                    tx_window_end,
2145                    tx_next + self.tx_mss,
2146                    tx_next + (mtu - header_len),
2147                ])
2148            };
2149
2150            let (payload_start, payload_len) = if tx_next < tx_segment_end {
2151                (tx_next - self.tx_acked, tx_segment_end - tx_next)
2152            } else {
2153                (0, 0)
2154            };
2155
2156            tx_next += payload_len;
2157
2158            // Set PSH on the segment that drains all currently-buffered data.
2159            // This tells the guest TCP stack to deliver the data to the
2160            // application immediately rather than waiting for more.
2161            // Note: when a FIN is pending, the FIN block below will
2162            // override tcp.control to Fin, which takes priority over Psh.
2163            if payload_len > 0 && tx_next == tx_payload_end && !self.tx_fin.is_pending() {
2164                tcp.control = TcpControl::Psh;
2165            }
2166
2167            // Include the FIN if it fits in the peer window. A FIN-only close
2168            // is also sent through a zero window as a probe so a lost window
2169            // update cannot stall the close until the lifetime timeout.
2170            if self.tx_fin.is_pending()
2171                && tcp.control != TcpControl::Fin
2172                && tx_next == tx_payload_end
2173                && (tx_next < tx_window_end || send_fin_probe)
2174            {
2175                tcp.control = TcpControl::Fin;
2176                tx_next += 1;
2177            }
2178
2179            // If this iteration would emit a pure ACK (no payload, no FIN)
2180            // and the caller asked us to defer pure ACKs, stop the loop.
2181            // `needs_ack` is left set for the next poll-cycle `Flush` call
2182            // (or a piggybacked ACK on later outbound data).
2183            if ack_policy == AckPolicy::Defer
2184                && tx_next == self.tx_send
2185                && tcp.control == TcpControl::None
2186            {
2187                break;
2188            }
2189
2190            assert!(tx_next <= tx_end);
2191            assert!(self.needs_ack || tx_next > self.tx_send);
2192
2193            trace_tcp_packet(sender.ft, &tcp, payload_len, "xmit");
2194
2195            let payload = self
2196                .tx_buffer
2197                .view(payload_start..payload_start + payload_len);
2198
2199            sender.send_packet(&tcp, Some(payload));
2200            self.stats.pkts_tx_to_guest.increment();
2201            self.stats.bytes_tx_to_guest.add(payload_len as u64);
2202            self.stats.tx_segment_size.add_sample(payload_len as u64);
2203            self.tx_send = tx_next;
2204            if tcp.control == TcpControl::Fin {
2205                self.tx_fin = TxFinState::Sent;
2206                send_fin_probe = false;
2207            }
2208            if tx_next > tcp.seq_number {
2209                self.retransmission.on_send(tx_next);
2210            }
2211            self.needs_ack = false;
2212            self.record_advertised_window(window_len);
2213        }
2214
2215        self.retransmission.update_persist(
2216            !self.tx_buffer.is_empty() && self.tx_window_len == 0,
2217            self.tx_acked < self.tx_send,
2218        );
2219        assert!(self.tx_send <= tx_end);
2220        self.compact_closed_buffers();
2221    }
2222
2223    fn close(&mut self, close_timeout: Duration, flow: &FourTuple) {
2224        if self.tx_fin.is_pending() {
2225            return;
2226        }
2227        tracing::trace!(src = %flow.src, dst = %flow.dst, "fin");
2228        match self.state {
2229            TcpState::SynSent | TcpState::SynReceived => {
2230                self.start_close_deadline(close_timeout);
2231            }
2232            TcpState::Established => {
2233                self.state = TcpState::FinWait1;
2234                self.start_close_deadline(close_timeout);
2235            }
2236            TcpState::CloseWait => {
2237                self.state = TcpState::LastAck;
2238                self.restart_close_deadline(close_timeout);
2239            }
2240            TcpState::Connecting
2241            | TcpState::FinWait1
2242            | TcpState::FinWait2
2243            | TcpState::Closing
2244            | TcpState::TimeWait
2245            | TcpState::LastAck => unreachable!("fin in {:?}", self.state),
2246        }
2247        self.tx_fin = TxFinState::Buffered;
2248    }
2249
2250    /// Start the user timeout for a graceful close. State transitions do not
2251    /// extend it unless the connection makes forward progress.
2252    fn start_close_deadline(&mut self, close_timeout: Duration) {
2253        if !matches!(self.lifetime_timer, LifetimeTimer::Close(_)) {
2254            self.lifetime_timer =
2255                LifetimeTimer::Close(TimerInstant::now().saturating_add(close_timeout));
2256        }
2257    }
2258
2259    fn refresh_close_deadline(&mut self, now: TimerInstant, close_timeout: Duration) {
2260        if matches!(self.lifetime_timer, LifetimeTimer::Close(_)) {
2261            self.lifetime_timer = LifetimeTimer::Close(now.saturating_add(close_timeout));
2262        }
2263    }
2264
2265    fn restart_close_deadline(&mut self, close_timeout: Duration) {
2266        self.lifetime_timer =
2267            LifetimeTimer::Close(TimerInstant::now().saturating_add(close_timeout));
2268    }
2269
2270    /// Start or restart the 2*MSL TIME-WAIT interval.
2271    fn restart_time_wait(&mut self, close_timeout: Duration) {
2272        self.restart_close_deadline(close_timeout);
2273        self.compact_closed_buffers();
2274    }
2275
2276    fn compact_closed_buffers(&mut self) {
2277        if self.state.tx_fin() && self.tx_buffer.is_empty() && self.tx_buffer.capacity() != 0 {
2278            self.tx_buffer = ring::Ring::new(0);
2279        }
2280
2281        if self.state.rx_fin() && self.rx_buffer.is_empty() && self.rx_buffer.capacity() != 0 {
2282            assert!(self.rx_assembler.is_empty());
2283            self.rx_buffer = ring::Ring::new(0);
2284        }
2285    }
2286
2287    fn next_timer_deadline(&self) -> Option<TimerInstant> {
2288        [
2289            self.lifetime_timer.deadline(),
2290            self.retransmission.timer.deadline(),
2291        ]
2292        .into_iter()
2293        .flatten()
2294        .min()
2295    }
2296
2297    /// Process expired retransmission and connection-lifetime timers. Returns
2298    /// `true` when the connection should be reclaimed.
2299    fn process_expired_timers(
2300        &mut self,
2301        now: TimerInstant,
2302        sender: &mut Sender<'_, impl Client>,
2303    ) -> bool {
2304        if self
2305            .lifetime_timer
2306            .deadline()
2307            .is_some_and(|deadline| now >= deadline)
2308        {
2309            return true;
2310        }
2311
2312        match self.retransmission.timer {
2313            RetransmissionTimer::Rto { deadline, recover } if now >= deadline => {
2314                self.stats.retransmission_timeouts.increment();
2315                if self.retransmit_earliest(sender) {
2316                    self.retransmission
2317                        .on_retransmit(now, recover.unwrap_or(self.tx_send));
2318                } else {
2319                    self.retransmission.timer = RetransmissionTimer::Rto {
2320                        deadline: now + self.retransmission.rto,
2321                        recover,
2322                    };
2323                }
2324            }
2325            RetransmissionTimer::Recovery { deadline, .. } if now >= deadline => {
2326                self.process_recovery_retransmit(now, sender);
2327            }
2328            RetransmissionTimer::Persist {
2329                deadline,
2330                backoff,
2331                recover,
2332            } if now >= deadline => {
2333                if self.send_zero_window_probe(sender) {
2334                    self.retransmission.rearm_persist(now, backoff, recover);
2335                } else {
2336                    self.retransmission.retry_persist(now, backoff, recover);
2337                }
2338            }
2339            _ => {}
2340        }
2341        false
2342    }
2343
2344    fn process_recovery_retransmit(
2345        &mut self,
2346        now: TimerInstant,
2347        sender: &mut Sender<'_, impl Client>,
2348    ) {
2349        let RetransmissionTimer::Recovery { recover, .. } = self.retransmission.timer else {
2350            return;
2351        };
2352        if self.retransmit_earliest(sender) {
2353            self.retransmission.on_recovery_retransmit(now, recover);
2354        } else {
2355            self.retransmission.timer = RetransmissionTimer::Rto {
2356                deadline: now + self.retransmission.rto,
2357                recover: Some(recover),
2358            };
2359        }
2360    }
2361
2362    /// Retransmit the earliest unacknowledged segment per RFC 6298 section 5.4.
2363    fn retransmit_earliest(&mut self, sender: &mut Sender<'_, impl Client>) -> bool {
2364        if self.tx_syn != TxSynState::None {
2365            let retransmitted = self.retransmit_syn(sender);
2366            if retransmitted {
2367                self.retransmission.on_syn_retransmit();
2368            }
2369            return retransmitted;
2370        }
2371
2372        if self.tx_acked >= self.tx_send || sender.client.rx_mtu() == 0 {
2373            return false;
2374        }
2375
2376        let window_len = self.rx_window_len();
2377        let tx_payload_end = self.tx_acked + self.tx_buffer.len();
2378        let ip_header_len = match sender.ft.dst {
2379            SocketAddr::V4(_) => IPV4_HEADER_LEN,
2380            SocketAddr::V6(_) => IPV6_HEADER_LEN,
2381        };
2382        let tcp_header_len = 20;
2383        let mtu = sender.client.rx_mtu().min(sender.state.buffer.len());
2384        let max_payload = mtu.saturating_sub(ETHERNET_HEADER_LEN + ip_header_len + tcp_header_len);
2385        let scale = if self.tx_window_scale_active {
2386            self.tx_window_scale
2387        } else {
2388            0
2389        };
2390        let tx_window_end = self.tx_acked + ((self.tx_window_len as usize) << scale);
2391        let payload_len = (tx_payload_end - self.tx_acked)
2392            .min(self.tx_mss)
2393            .min(max_payload)
2394            .min(tx_window_end - self.tx_acked)
2395            .min(self.tx_send - self.tx_acked);
2396
2397        let mut tcp = TcpRepr {
2398            src_port: sender.ft.dst.port(),
2399            dst_port: sender.ft.src.port(),
2400            control: TcpControl::None,
2401            seq_number: self.tx_acked,
2402            ack_number: Some(self.rx_seq),
2403            window_len,
2404            window_scale: None,
2405            max_seg_size: None,
2406            sack_permitted: false,
2407            sack_ranges: [None, None, None],
2408            timestamp: None,
2409            payload: &[],
2410        };
2411        let segment_end = self.tx_acked + payload_len;
2412        if self.tx_fin == TxFinState::Sent && segment_end == tx_payload_end {
2413            tcp.control = TcpControl::Fin;
2414        } else if payload_len > 0 && segment_end == tx_payload_end {
2415            tcp.control = TcpControl::Psh;
2416        }
2417
2418        if payload_len == 0 && tcp.control != TcpControl::Fin {
2419            return false;
2420        }
2421
2422        trace_tcp_packet(sender.ft, &tcp, payload_len, "retransmit");
2423        let payload = self.tx_buffer.view(0..payload_len);
2424        sender.send_packet(&tcp, Some(payload));
2425        self.stats.pkts_tx_to_guest.increment();
2426        self.stats.bytes_tx_to_guest.add(payload_len as u64);
2427        self.stats.tx_segment_size.add_sample(payload_len as u64);
2428        self.stats.retransmitted_segments.increment();
2429        self.stats.retransmitted_bytes.add(payload_len as u64);
2430        self.record_advertised_window(window_len);
2431        true
2432    }
2433
2434    fn retransmit_syn(&mut self, sender: &mut Sender<'_, impl Client>) -> bool {
2435        if self.tx_syn == TxSynState::None || sender.client.rx_mtu() == 0 {
2436            return false;
2437        }
2438
2439        let ack_number = (self.tx_syn == TxSynState::SynAck).then_some(self.rx_seq);
2440        self.emit_syn(sender, self.tx_acked, ack_number);
2441        self.stats.retransmitted_segments.increment();
2442        true
2443    }
2444
2445    #[must_use]
2446    fn send_zero_window_probe(&mut self, sender: &mut Sender<'_, impl Client>) -> bool {
2447        if self.tx_buffer.is_empty() {
2448            return false;
2449        }
2450
2451        let rx_mtu = sender.client.rx_mtu();
2452        let ip_header_len = match sender.ft.dst {
2453            SocketAddr::V4(_) => IPV4_HEADER_LEN,
2454            SocketAddr::V6(_) => IPV6_HEADER_LEN,
2455        };
2456        let header_len = ETHERNET_HEADER_LEN + ip_header_len + 20;
2457        if rx_mtu.min(sender.state.buffer.len()) <= header_len {
2458            return false;
2459        }
2460
2461        let window_len = self.rx_window_len();
2462        let tcp = TcpRepr {
2463            src_port: sender.ft.dst.port(),
2464            dst_port: sender.ft.src.port(),
2465            control: TcpControl::None,
2466            seq_number: self.tx_acked,
2467            ack_number: Some(self.rx_seq),
2468            window_len,
2469            window_scale: None,
2470            max_seg_size: None,
2471            sack_permitted: false,
2472            sack_ranges: [None, None, None],
2473            timestamp: None,
2474            payload: &[],
2475        };
2476        let payload = self.tx_buffer.view(0..1);
2477        trace_tcp_packet(sender.ft, &tcp, payload.len(), "zero window probe");
2478        sender.send_packet(&tcp, Some(payload));
2479        if self.tx_send == self.tx_acked {
2480            self.tx_send += 1;
2481        } else {
2482            self.stats.retransmitted_segments.increment();
2483            self.stats.retransmitted_bytes.increment();
2484        }
2485        self.stats.pkts_tx_to_guest.increment();
2486        self.stats.bytes_tx_to_guest.increment();
2487        self.stats.tx_segment_size.add_sample(1_u64);
2488        self.record_advertised_window(window_len);
2489        true
2490    }
2491
2492    fn emit_syn(
2493        &mut self,
2494        sender: &mut Sender<'_, impl Client>,
2495        sequence_number: TcpSeqNumber,
2496        ack_number: Option<TcpSeqNumber>,
2497    ) {
2498        let window_scale = self.enable_window_scaling.then_some(self.rx_window_scale);
2499        let window_len = if ack_number.is_some() {
2500            self.rx_window_avail().min(u16::MAX as usize) as u16
2501        } else {
2502            0
2503        };
2504        let tcp = TcpRepr {
2505            src_port: sender.ft.dst.port(),
2506            dst_port: sender.ft.src.port(),
2507            control: TcpControl::Syn,
2508            seq_number: sequence_number,
2509            ack_number,
2510            window_len,
2511            window_scale,
2512            max_seg_size: Some(u16::MAX),
2513            sack_permitted: false,
2514            sack_ranges: [None, None, None],
2515            timestamp: None,
2516            payload: &[],
2517        };
2518        trace_tcp_packet(sender.ft, &tcp, 0, "retransmit");
2519        sender.send_packet(&tcp, None);
2520    }
2521
2522    /// Send an ACK using the current state of the connection.
2523    ///
2524    /// This is used when sending an ack to report a the reception of an
2525    /// unacceptable packet (duplicate, out of order, etc.). These acks
2526    /// shouldn't be combined with data so that they are interpreted correctly
2527    /// by the peer.
2528    fn ack(&mut self, sender: &mut Sender<'_, impl Client>) {
2529        let _ = self.try_ack(sender);
2530    }
2531
2532    fn ack_or_defer(&mut self, sender: &mut Sender<'_, impl Client>) {
2533        if !self.try_ack(sender) {
2534            self.needs_ack = true;
2535        }
2536    }
2537
2538    fn try_ack(&mut self, sender: &mut Sender<'_, impl Client>) -> bool {
2539        if sender.client.rx_mtu() == 0 {
2540            return false;
2541        }
2542
2543        let window_len = self.rx_window_len();
2544        let tcp = TcpRepr {
2545            src_port: sender.ft.dst.port(),
2546            dst_port: sender.ft.src.port(),
2547            control: TcpControl::None,
2548            seq_number: self.tx_send,
2549            ack_number: Some(self.rx_seq),
2550            window_len,
2551            window_scale: None,
2552            max_seg_size: None,
2553            sack_permitted: false,
2554            sack_ranges: [None, None, None],
2555            timestamp: None,
2556            payload: &[],
2557        };
2558
2559        trace_tcp_packet(sender.ft, &tcp, 0, "ack");
2560
2561        sender.send_packet(&tcp, None);
2562        self.stats.standalone_acks_tx.increment();
2563        self.record_advertised_window(window_len);
2564        true
2565    }
2566
2567    fn handle_listen_syn(
2568        &mut self,
2569        sender: &mut Sender<'_, impl Client>,
2570        tcp: &TcpRepr<'_>,
2571    ) -> Result<bool, DropReason> {
2572        let ack_acceptable = tcp
2573            .ack_number
2574            .is_some_and(|ack| ack > self.tx_acked && ack <= self.tx_send);
2575
2576        if let Some(ack_number) = tcp.ack_number
2577            && !ack_acceptable
2578        {
2579            if tcp.control != TcpControl::Rst {
2580                if sender.try_rst(ack_number, None) {
2581                    self.stats.rsts_tx.increment();
2582                }
2583            }
2584            return Ok(true);
2585        }
2586
2587        if tcp.control == TcpControl::Rst {
2588            if ack_acceptable {
2589                tracing::debug!(
2590                    src = %sender.ft.src,
2591                    dst = %sender.ft.dst,
2592                    "connection reset while waiting for SYN"
2593                );
2594                self.last_close_reason = ConnectionCloseReason::PeerRst;
2595                return Ok(false);
2596            }
2597            return Ok(true);
2598        }
2599
2600        if tcp.control != TcpControl::Syn || tcp.segment_len() != 1 {
2601            return Ok(true);
2602        }
2603        let ack_number = tcp
2604            .ack_number
2605            .ok_or_else(|| TcpError::new(*sender.ft, TcpErrorKind::MissingAck))?;
2606        self.initialize_from_first_client_packet(*sender.ft, tcp)?;
2607
2608        self.tx_acked = ack_number;
2609        self.tx_syn = TxSynState::None;
2610        self.retransmission
2611            .on_ack(ack_number, self.tx_send, TimerInstant::now());
2612        self.retransmission.on_handshake_complete();
2613
2614        self.tx_window_tx_seq = ack_number;
2615        self.tx_window_len = tcp.window_len;
2616
2617        // Send an ACK to complete the initial SYN handshake.
2618        self.ack_or_defer(sender);
2619
2620        if !self.tx_fin.is_pending() {
2621            self.lifetime_timer = LifetimeTimer::None;
2622        }
2623        self.state = if self.tx_fin.is_pending() {
2624            TcpState::FinWait1
2625        } else {
2626            TcpState::Established
2627        };
2628        Ok(true)
2629    }
2630
2631    fn handle_packet(
2632        &mut self,
2633        sender: &mut Sender<'_, impl Client>,
2634        tcp: &TcpRepr<'_>,
2635    ) -> Result<bool, DropReason> {
2636        if self.state == TcpState::Connecting {
2637            // We have not yet sent a syn (we are still deciding whether we are
2638            // in LISTEN or CLOSED state), so we can't send a reasonable
2639            // response to this. Just drop the packet.
2640            return Err(TcpError::new(*sender.ft, TcpErrorKind::StillConnecting).into());
2641        } else if self.state == TcpState::SynSent {
2642            return self.handle_listen_syn(sender, tcp);
2643        }
2644
2645        let rx_window_len = self.rx_window_cap - self.rx_buffer.len();
2646        let rx_window_end = self.rx_seq + rx_window_len;
2647        let segment_end = tcp.seq_number + tcp.segment_len();
2648
2649        // RFC 9293 section 3.10.7.4: ACK a retransmitted FIN in TIME-WAIT
2650        // and restart the 2*MSL timer. The FIN is one byte to the left of
2651        // RCV.NXT, so handle it before the normal sequence acceptability test.
2652        if self.state == TcpState::TimeWait
2653            && tcp.control == TcpControl::Fin
2654            && tcp.segment_len() == 1
2655            && tcp.seq_number + 1 == self.rx_seq
2656        {
2657            self.ack_or_defer(sender);
2658            self.restart_time_wait(sender.state.params.tcp_close_timeout);
2659            return Ok(true);
2660        }
2661
2662        // Validate the sequence number per RFC 793.
2663        let seq_acceptable = if rx_window_len != 0 {
2664            (tcp.seq_number >= self.rx_seq && tcp.seq_number < rx_window_end)
2665                || (tcp.segment_len() > 0
2666                    && segment_end > self.rx_seq
2667                    && segment_end <= rx_window_end)
2668        } else {
2669            tcp.segment_len() == 0 && tcp.seq_number == self.rx_seq
2670        };
2671
2672        if tcp.control == TcpControl::Rst {
2673            if !seq_acceptable {
2674                // Silently drop--don't send an ACK--since the peer would then
2675                // immediately respond with a valid RST.
2676                return Err(TcpError::new(*sender.ft, TcpErrorKind::Unacceptable).into());
2677            }
2678
2679            // RFC 5961
2680            if tcp.seq_number != self.rx_seq {
2681                // Send a challenge ACK.
2682                self.ack(sender);
2683                return Ok(true);
2684            }
2685
2686            // This is a valid RST. Drop the connection.
2687            tracing::debug!(
2688                src = %sender.ft.src,
2689                dst = %sender.ft.dst,
2690                "connection reset"
2691            );
2692            self.last_close_reason = ConnectionCloseReason::PeerRst;
2693            return Ok(false);
2694        }
2695
2696        // Send ack and drop packets with unacceptable sequence numbers.
2697        if !seq_acceptable {
2698            self.stats.out_of_window_pkts.increment();
2699            let is_zero_window_probe = rx_window_len == 0
2700                && matches!(tcp.control, TcpControl::None | TcpControl::Psh)
2701                && tcp.ack_number.is_some()
2702                && tcp.payload.len() <= 1
2703                && (tcp.seq_number == self.rx_seq || tcp.seq_number + 1 == self.rx_seq);
2704            if is_zero_window_probe {
2705                self.refresh_close_deadline(
2706                    TimerInstant::now(),
2707                    sender.state.params.tcp_close_timeout,
2708                );
2709            }
2710            self.ack(sender);
2711            return Err(TcpError::new(*sender.ft, TcpErrorKind::Unacceptable).into());
2712        }
2713
2714        // SYN should not be set for in-window segments.
2715        if tcp.control == TcpControl::Syn {
2716            if self.state == TcpState::SynReceived {
2717                tracing::debug!(
2718                    src = %sender.ft.src,
2719                    dst = %sender.ft.dst,
2720                    "invalid syn, drop connection"
2721                );
2722                return Ok(false);
2723            }
2724            // RFC 5961, send a challenge ACK.
2725            self.ack(sender);
2726            return Ok(true);
2727        }
2728
2729        // ACK should always be set at this point.
2730        let ack_number = tcp
2731            .ack_number
2732            .ok_or_else(|| TcpError::new(*sender.ft, TcpErrorKind::MissingAck))?;
2733        let previous_tx_acked = self.tx_acked;
2734        let tx_window_was_zero = self.tx_window_len == 0;
2735        let previous_tx_window_len = self.tx_window_len;
2736        let mut packet_now = None;
2737
2738        // FUTURE: validate ack number per RFC 5961.
2739
2740        // Handle ACK of our SYN.
2741        if self.state == TcpState::SynReceived {
2742            if ack_number <= self.tx_acked || ack_number > self.tx_send {
2743                if sender.try_rst(ack_number, None) {
2744                    self.stats.rsts_tx.increment();
2745                }
2746                return Ok(false);
2747            }
2748            self.tx_window_len = tcp.window_len;
2749            self.tx_window_rx_seq = tcp.seq_number;
2750            self.tx_window_tx_seq = ack_number;
2751            self.tx_acked += 1;
2752            self.tx_syn = TxSynState::None;
2753            if !self.tx_fin.is_pending() {
2754                self.lifetime_timer = LifetimeTimer::None;
2755            }
2756            self.state = if self.tx_fin.is_pending() {
2757                TcpState::FinWait1
2758            } else {
2759                TcpState::Established
2760            };
2761            self.retransmission.on_handshake_complete();
2762        }
2763
2764        // Ignore ACKs for segments that have not been sent.
2765        if ack_number > self.tx_send {
2766            self.ack(sender);
2767            return Err(TcpError::new(*sender.ft, TcpErrorKind::AckPastSequence).into());
2768        }
2769
2770        // Retire the ACKed segments.
2771        if ack_number > self.tx_acked {
2772            let mut consumed = ack_number - self.tx_acked;
2773            if self.tx_fin == TxFinState::Sent
2774                && ack_number == self.tx_acked + self.tx_buffer.len() + 1
2775            {
2776                self.tx_fin = TxFinState::None;
2777                consumed -= 1;
2778                match self.state {
2779                    TcpState::FinWait1 => {
2780                        self.state = TcpState::FinWait2;
2781                    }
2782                    TcpState::Closing => {
2783                        self.state = TcpState::TimeWait;
2784                        self.restart_time_wait(sender.state.params.tcp_close_timeout);
2785                    }
2786                    TcpState::LastAck => {
2787                        self.last_close_reason = ConnectionCloseReason::Normal;
2788                        return Ok(false);
2789                    }
2790                    _ => unreachable!(),
2791                }
2792            }
2793            self.tx_buffer.consume(consumed);
2794            self.tx_acked = ack_number;
2795        }
2796        if self.tx_acked > previous_tx_acked {
2797            let now = *packet_now.get_or_insert_with(TimerInstant::now);
2798            self.retransmission.on_ack(self.tx_acked, self.tx_send, now);
2799            self.refresh_close_deadline(now, sender.state.params.tcp_close_timeout);
2800        } else if ack_number == self.tx_acked
2801            && (self.tx_acked < self.tx_send || !self.tx_buffer.is_empty())
2802            && tcp.control == TcpControl::None
2803            && tcp.payload.is_empty()
2804        {
2805            // A pure ACK for pending data confirms that a flow-controlled peer
2806            // is still responsive, even when its zero window prevents the ACK
2807            // number from advancing.
2808            let now = *packet_now.get_or_insert_with(TimerInstant::now);
2809            self.refresh_close_deadline(now, sender.state.params.tcp_close_timeout);
2810        }
2811
2812        let is_duplicate_ack = self.tx_acked == previous_tx_acked
2813            && ack_number == self.tx_acked
2814            && self.tx_acked < self.tx_send
2815            && previous_tx_window_len != 0
2816            && tcp.window_len == previous_tx_window_len
2817            && tcp.control == TcpControl::None
2818            && tcp.payload.is_empty();
2819        let fast_retransmit = self.retransmission.record_duplicate_ack(is_duplicate_ack);
2820
2821        // Update the send window.
2822        if ack_number >= self.tx_acked
2823            && (tcp.seq_number > self.tx_window_rx_seq
2824                || (tcp.seq_number == self.tx_window_rx_seq && ack_number >= self.tx_window_tx_seq))
2825        {
2826            self.tx_window_len = tcp.window_len;
2827            self.tx_window_rx_seq = tcp.seq_number;
2828            self.tx_window_tx_seq = ack_number;
2829            // RFC 1323 §2.2: window scaling becomes active after the
2830            // handshake. The SYN/SYN-ACK window field is unscaled.
2831            self.tx_window_scale_active = true;
2832
2833            if tx_window_was_zero
2834                && tcp.window_len > 0
2835                && self.tx_acked < self.tx_send
2836                && self
2837                    .retransmission
2838                    .can_retransmit_on_window_reopen(self.tx_acked)
2839                && self.retransmit_earliest(sender)
2840            {
2841                let now = *packet_now.get_or_insert_with(TimerInstant::now);
2842                self.retransmission.on_early_retransmit(now, self.tx_acked);
2843            }
2844        }
2845
2846        if fast_retransmit {
2847            if self.retransmit_earliest(sender) {
2848                let now = *packet_now.get_or_insert_with(TimerInstant::now);
2849                self.retransmission.on_fast_retransmit(now, self.tx_send);
2850            } else {
2851                self.retransmission.retry_fast_retransmit();
2852            }
2853        }
2854
2855        // Scope the data payload and FIN to the in-window portion of the segment.
2856        let mut fin = tcp.control == TcpControl::Fin;
2857        let segment_skip = if tcp.seq_number < self.rx_seq {
2858            self.rx_seq - tcp.seq_number
2859        } else {
2860            0
2861        };
2862        let segment_end = if segment_end > rx_window_end {
2863            fin = false;
2864            rx_window_end
2865        } else {
2866            segment_end
2867        };
2868        let payload = &tcp.payload[segment_skip..segment_end - tcp.seq_number - fin as usize];
2869
2870        let mut rx_fin = false;
2871
2872        // Process the payload.
2873        match self.state {
2874            TcpState::Connecting | TcpState::SynReceived | TcpState::SynSent => unreachable!(),
2875            TcpState::Established | TcpState::FinWait1 | TcpState::FinWait2 => {
2876                if !payload.is_empty() || fin {
2877                    if !payload.is_empty() {
2878                        self.stats.data_segments_rx_from_guest.increment();
2879                        self.stats.bytes_rx_from_guest.add(payload.len() as u64);
2880                        self.stats.rx_segment_size.add_sample(payload.len() as u64);
2881                    }
2882                    // Stage 1: Compute the byte offset from the contiguous
2883                    // frontier.
2884                    //
2885                    // Safety of ring_offset: the sequence acceptance check above
2886                    // bounds the segment to rx_window_end = rx_seq + (rx_window_cap
2887                    // - rx_buffer.len()), so seq_offset + payload.len() <=
2888                    // rx_window_cap <= ring capacity.
2889                    let seq_offset = if tcp.seq_number >= self.rx_seq {
2890                        tcp.seq_number - self.rx_seq
2891                    } else {
2892                        0
2893                    };
2894                    let ring_offset = self.rx_buffer.len() + seq_offset;
2895
2896                    // Stage 2: Record the range in the assembler. Do this
2897                    // *before* writing to the ring so that rejected segments
2898                    // don't leave stale bytes in unwritten
2899                    // ring space.
2900                    let made_progress = self.rx_assembler.would_make_progress(
2901                        seq_offset as u32,
2902                        payload.len() as u32,
2903                        fin,
2904                    );
2905                    let (rx_consumed, assembler_fin, accepted) =
2906                        match self
2907                            .rx_assembler
2908                            .add(seq_offset as u32, payload.len() as u32, fin)
2909                        {
2910                            Ok(result) => (result.consumed as usize, result.fin, true),
2911                            Err(err) => {
2912                                tracing::trace!(?err, "assembler rejected segment");
2913                                (0, false, false)
2914                            }
2915                        };
2916
2917                    // Stage 3: Write payload into the ring and advance the
2918                    // contiguous frontier. Only write when the assembler
2919                    // accepted the segment.
2920                    if accepted && !payload.is_empty() {
2921                        self.rx_buffer.write_at(ring_offset, payload);
2922                    }
2923                    if accepted
2924                        && made_progress
2925                        && (!payload.is_empty() || fin)
2926                        && matches!(self.lifetime_timer, LifetimeTimer::Close(_))
2927                    {
2928                        let now = *packet_now.get_or_insert_with(TimerInstant::now);
2929                        self.refresh_close_deadline(now, sender.state.params.tcp_close_timeout);
2930                    }
2931                    self.rx_buffer.extend_by(rx_consumed);
2932                    self.rx_seq += rx_consumed;
2933                    rx_fin = assembler_fin;
2934                    if rx_fin {
2935                        self.rx_seq += 1;
2936                    }
2937                }
2938                if tcp.segment_len() > 0 {
2939                    self.needs_ack = true;
2940                }
2941            }
2942            TcpState::CloseWait | TcpState::Closing | TcpState::LastAck => {}
2943            TcpState::TimeWait => {
2944                self.ack_or_defer(sender);
2945            }
2946        }
2947
2948        // Process FIN.
2949        if rx_fin {
2950            match self.state {
2951                TcpState::Connecting | TcpState::SynReceived | TcpState::SynSent => unreachable!(),
2952                TcpState::Established => {
2953                    self.state = TcpState::CloseWait;
2954                }
2955                TcpState::FinWait1 => {
2956                    self.state = TcpState::Closing;
2957                }
2958                TcpState::FinWait2 => {
2959                    self.state = TcpState::TimeWait;
2960                    self.restart_time_wait(sender.state.params.tcp_close_timeout);
2961                }
2962                TcpState::CloseWait
2963                | TcpState::Closing
2964                | TcpState::LastAck
2965                | TcpState::TimeWait => {}
2966            }
2967        }
2968
2969        if matches!(
2970            self.retransmission.timer,
2971            RetransmissionTimer::Recovery { .. }
2972        ) {
2973            let now = *packet_now.get_or_insert_with(TimerInstant::now);
2974            self.process_recovery_retransmit(now, sender);
2975        }
2976
2977        Ok(true)
2978    }
2979}
2980
2981impl TcpListener {
2982    /// Creates a `TcpListener` from an already-bound `socket2::Socket`.
2983    ///
2984    /// The socket must already be bound to an address. This method will call
2985    /// `listen` on it.
2986    pub fn from_socket(driver: &dyn Driver, socket: Socket) -> Result<Self, BindError> {
2987        let Some(host_port) = socket
2988            .local_addr()
2989            .map_err(BindError::Io)?
2990            .as_socket()
2991            .map(|addr| addr.port())
2992        else {
2993            return Err(BindError::Io(io::Error::other(
2994                "socket local address is invalid",
2995            )));
2996        };
2997        let socket = PolledSocket::new(driver, socket).map_err(BindError::Io)?;
2998        if let Err(err) = socket.listen(10) {
2999            tracing::warn!(
3000                error = &err as &dyn std::error::Error,
3001                host_port,
3002                "socket listen error"
3003            );
3004            return Err(BindError::Io(err));
3005        }
3006        Ok(Self { socket, host_port })
3007    }
3008
3009    fn poll_listener(
3010        &mut self,
3011        cx: &mut Context<'_>,
3012    ) -> Result<Option<(Socket, SocketAddr)>, DropReason> {
3013        match self.socket.poll_accept(cx) {
3014            Poll::Ready(r) => match r {
3015                Ok((socket, address)) => match address.as_socket() {
3016                    Some(addr) => Ok(Some((socket, addr))),
3017                    None => {
3018                        tracing::warn!(
3019                            host_port = self.host_port,
3020                            ?address,
3021                            "Unknown address from accept"
3022                        );
3023                        Ok(None)
3024                    }
3025                },
3026                Err(_) => {
3027                    let err = take_socket_error(&self.socket);
3028                    tracing::warn!(
3029                        error = &err as &dyn std::error::Error,
3030                        host_port = self.host_port,
3031                        "listen failure"
3032                    );
3033                    Err(DropReason::Io(err))
3034                }
3035            },
3036            Poll::Pending => Ok(None),
3037        }
3038    }
3039}
3040
3041/// Trace a TCP packet with structured key/value fields.
3042///
3043/// Logs protocol-relevant fields (flags, seq, ack, window, payload length)
3044/// as individual tracing fields instead of dumping the full `TcpRepr` Debug
3045/// output which includes raw payload bytes.
3046fn trace_tcp_packet(ft: &FourTuple, tcp: &TcpRepr<'_>, payload_len: usize, label: &str) {
3047    tracing::trace!(
3048        label,
3049        src = %ft.src,
3050        dst = %ft.dst,
3051        flags = match tcp.control {
3052            TcpControl::Syn => Some("SYN"),
3053            TcpControl::Fin => Some("FIN"),
3054            TcpControl::Rst => Some("RST"),
3055            TcpControl::Psh => Some("PSH"),
3056            TcpControl::None => None,
3057        },
3058        seq = tcp.seq_number.0 as u32,
3059        next_seq = (tcp.seq_number.0 as u32).wrapping_add((payload_len + tcp.control.len()) as u32),
3060        ack = tcp.ack_number.map(|a| a.0 as u32),
3061        window = tcp.window_len,
3062        payload_len,
3063        "tcp packet",
3064    );
3065}
3066
3067// RFC 1071 primitives vendored from smoltcp (0BSD); replace with a `use` of
3068// smoltcp::wire::checksum once smoltcp-rs/smoltcp#1172 exposes it.
3069mod checksum {
3070    use smoltcp::wire::IpAddress;
3071    use smoltcp::wire::IpProtocol;
3072
3073    const fn propagate_carries(word: u32) -> u16 {
3074        let sum = (word >> 16) + (word & 0xffff);
3075        ((sum >> 16) as u16) + (sum as u16)
3076    }
3077
3078    pub fn data(mut data: &[u8]) -> u16 {
3079        let mut accum: u32 = 0;
3080        const CHUNK_SIZE: usize = 32;
3081        while data.len() >= CHUNK_SIZE {
3082            let mut d = &data[..CHUNK_SIZE];
3083            while d.len() >= 2 {
3084                accum = accum.wrapping_add(u16::from_be_bytes([d[0], d[1]]) as u32);
3085                d = &d[2..];
3086            }
3087            data = &data[CHUNK_SIZE..];
3088        }
3089        while data.len() >= 2 {
3090            accum = accum.wrapping_add(u16::from_be_bytes([data[0], data[1]]) as u32);
3091            data = &data[2..];
3092        }
3093        if let Some(&value) = data.first() {
3094            accum = accum.wrapping_add((value as u32) << 8);
3095        }
3096        propagate_carries(accum)
3097    }
3098
3099    pub fn combine(checksums: &[u16]) -> u16 {
3100        let mut accum: u32 = 0;
3101        for &word in checksums {
3102            accum = accum.wrapping_add(word as u32);
3103        }
3104        propagate_carries(accum)
3105    }
3106
3107    pub fn pseudo_header(
3108        src_addr: &IpAddress,
3109        dst_addr: &IpAddress,
3110        next_header: IpProtocol,
3111        length: u32,
3112    ) -> u16 {
3113        match (src_addr, dst_addr) {
3114            (IpAddress::Ipv4(src_addr), IpAddress::Ipv4(dst_addr)) => {
3115                let mut proto_len = [0u8; 4];
3116                proto_len[1] = next_header.into();
3117                proto_len[2..4].copy_from_slice(&(length as u16).to_be_bytes());
3118                combine(&[
3119                    data(&src_addr.octets()),
3120                    data(&dst_addr.octets()),
3121                    data(&proto_len),
3122                ])
3123            }
3124            (IpAddress::Ipv6(src_addr), IpAddress::Ipv6(dst_addr)) => {
3125                let mut len_proto = [0u8; 8];
3126                len_proto[0..4].copy_from_slice(&length.to_be_bytes());
3127                len_proto[7] = next_header.into();
3128                combine(&[
3129                    data(&src_addr.octets()),
3130                    data(&dst_addr.octets()),
3131                    data(&len_proto),
3132                ])
3133            }
3134            _ => unreachable!("mismatched IP address families"),
3135        }
3136    }
3137}
3138
3139fn take_socket_error(socket: &PolledSocket<Socket>) -> io::Error {
3140    match socket.get().take_error() {
3141        Ok(Some(err)) => err,
3142        Ok(_) => io::Error::other("missing error"),
3143        Err(err) => err,
3144    }
3145}
3146
3147/// Log a TCP connect error at the appropriate level.
3148///
3149/// Connection refused and network/host unreachable are expected failures logged
3150/// at debug level. Everything else is logged at warn.
3151fn log_connect_error(ft: &FourTuple, err: &io::Error) {
3152    match err.kind() {
3153        ErrorKind::ConnectionRefused => {
3154            tracing::debug!(
3155                error = err as &dyn std::error::Error,
3156                src = %ft.src,
3157                dst = %ft.dst,
3158                "connect refused",
3159            );
3160        }
3161        ErrorKind::NetworkUnreachable | ErrorKind::HostUnreachable => {
3162            // FUTURE: send ICMP unreachable to guest
3163            tracing::debug!(
3164                error = err as &dyn std::error::Error,
3165                src = %ft.src,
3166                dst = %ft.dst,
3167                "connect failed, unreachable",
3168            );
3169        }
3170        _ => {
3171            tracelimit::warn_ratelimited!(
3172                error = err as &dyn std::error::Error,
3173                src = %ft.src,
3174                dst = %ft.dst,
3175                "connect failed",
3176            );
3177        }
3178    }
3179}
3180
3181fn is_connect_incomplete_error(err: &io::Error) -> bool {
3182    if err.kind() == ErrorKind::WouldBlock {
3183        return true;
3184    }
3185    // This handles the remaining cases on Linux.
3186    #[cfg(unix)]
3187    if err.raw_os_error() == Some(libc::EINPROGRESS) {
3188        return true;
3189    }
3190    false
3191}
3192
3193/// Finds the smallest sequence number in a set. To get a coherent result, all
3194/// the sequence numbers must be known to be comparable, meaning they are all
3195/// within 2^31 bytes of each other.
3196///
3197/// This isn't just `Ord::min` or `Iterator::min` because `TcpSeqNumber`
3198/// implements `PartialOrd` but not `Ord`.
3199fn seq_min<const N: usize>(seqs: [TcpSeqNumber; N]) -> TcpSeqNumber {
3200    let mut min = seqs[0];
3201    for &seq in &seqs[1..] {
3202        if min > seq {
3203            min = seq;
3204        }
3205    }
3206    min
3207}
3208
3209/// Check if a TCP connection targets the gateway's DNS port.
3210fn is_gateway_dns_tcp(
3211    ft: &FourTuple,
3212    params: &crate::ConsommeParams,
3213    can_answer_queries: bool,
3214) -> bool {
3215    if !can_answer_queries || ft.dst.port() != crate::DNS_PORT {
3216        return false;
3217    }
3218    match ft.dst.ip() {
3219        IpAddr::V4(ip) => params.gateway_ip == ip,
3220        IpAddr::V6(ip) => params.gateway_link_local_ipv6 == ip,
3221    }
3222}
3223
3224#[cfg(test)]
3225mod tests;