1mod 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#[derive(Inspect, Default)]
83struct TcpAggregateStats {
84 connections_accepted: Counter,
85 connections_initiated: Counter,
86 connections_closed_normal: Counter,
88 connections_closed_peer_rst: Counter,
90 connections_closed_local_error: Counter,
92 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#[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
183enum TcpBackend {
188 Socket {
191 socket: Option<PolledSocket<Socket>>,
192 static_dns: Option<StaticDnsTcpInspection>,
193 },
194 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 #[inspect(hex)]
283 rx_buffer_max: usize,
284 #[inspect(with = "inspect_seq")]
285 rx_seq: TcpSeqNumber,
286 #[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 #[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 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 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 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 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#[derive(Default, Clone, Copy)]
651enum ConnectionCloseReason {
652 #[default]
653 LocalError,
654 PeerRst,
655 Normal,
656}
657
658#[derive(Copy, Clone, PartialEq, Eq)]
668enum AckPolicy {
669 Defer,
673 Flush,
676}
677
678#[derive(Inspect, Default)]
680struct TcpConnStats {
681 bytes_tx_to_guest: Counter,
683 bytes_rx_from_guest: Counter,
686 pkts_tx_to_guest: Counter,
689 data_segments_rx_from_guest: Counter,
692 standalone_acks_tx: Counter,
696 rsts_tx: Counter,
698 tx_blocked_no_rx_mtu: Counter,
700 tx_blocked_window_full: Counter,
702 out_of_window_pkts: Counter,
704 tx_segment_size: Histogram<14>,
706 rx_segment_size: Histogram<14>,
708 tx_buffer_grows: Counter,
710 rx_buffer_grows: Counter,
712 retransmission_timeouts: Counter,
714 retransmitted_segments: Counter,
716 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 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 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 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 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 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 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 } else if let Some(ack) = tcp.ack_number {
1088 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 let resolved_dst = sender.state.resolve_destination(&sender.ft.dst);
1101 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 }
1143 }
1144 }
1145 Ok(())
1146 }
1147
1148 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 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 match ip {
1212 IpRepr::Ipv4(_) => eth_packet.set_ethertype(EthernetProtocol::Ipv4),
1213 IpRepr::Ipv6(_) => eth_packet.set_ethertype(EthernetProtocol::Ipv6),
1214 }
1215
1216 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 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 let (a, b) = payload.as_slices();
1268 let tcp_header_len = tcp_packet.header_len() as usize;
1269 tcp_packet.set_checksum(0);
1270 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 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 socket.set_tcp_nodelay(true).map_err(DropReason::Io)?;
1406
1407 #[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 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 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 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 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 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 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 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 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 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 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 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 self.send_next(sender, AckPolicy::Flush);
1622 true
1623 }
1624
1625 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 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 self.send_next(sender, AckPolicy::Flush);
1661 return true;
1662 }
1663
1664 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 *opt_socket = None;
1687 }
1688 } else {
1689 '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 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 self.send_next(sender, AckPolicy::Flush);
1764 self.compact_closed_buffers();
1765 true
1766 }
1767
1768 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 if self.should_reopen_window() {
1839 self.needs_ack = true;
1840 }
1841 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 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 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 fn rx_window_avail(&self) -> usize {
1992 self.rx_window_cap - self.rx_buffer.len()
1993 }
1994
1995 fn rx_window_advertised(&self) -> usize {
1999 (self.rx_window_avail() >> self.rx_window_scale) << self.rx_window_scale
2000 }
2001
2002 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 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 let window_scale = self.enable_window_scaling.then_some(self.rx_window_scale);
2038
2039 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 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 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 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 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 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 if payload_len > 0 && tx_next == tx_payload_end && !self.tx_fin.is_pending() {
2164 tcp.control = TcpControl::Psh;
2165 }
2166
2167 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 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 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 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 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 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 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 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 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 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 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 return Err(TcpError::new(*sender.ft, TcpErrorKind::Unacceptable).into());
2677 }
2678
2679 if tcp.seq_number != self.rx_seq {
2681 self.ack(sender);
2683 return Ok(true);
2684 }
2685
2686 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 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 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 self.ack(sender);
2726 return Ok(true);
2727 }
2728
2729 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 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 if ack_number > self.tx_send {
2766 self.ack(sender);
2767 return Err(TcpError::new(*sender.ft, TcpErrorKind::AckPastSequence).into());
2768 }
2769
2770 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 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 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 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 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 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 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 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 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 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 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
3041fn 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
3067mod 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
3147fn 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 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 #[cfg(unix)]
3187 if err.raw_os_error() == Some(libc::EINPROGRESS) {
3188 return true;
3189 }
3190 false
3191}
3192
3193fn 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
3209fn 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;