vmm/dumbo/tcp/connection.rs
1// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! This module contains a minimalist TCP [`Connection`] implementation, which only supports
5//! passive open scenarios, and some auxiliary logic and data structures.
6//!
7//! [`Connection`]: struct.Connection.html
8
9use std::fmt::Debug;
10use std::num::{NonZeroU16, NonZeroU64, NonZeroUsize, Wrapping};
11
12use bitflags::bitflags;
13use vmm_sys_util::rand::xor_pseudo_rng_u32;
14
15use crate::dumbo::ByteBuffer;
16use crate::dumbo::pdu::Incomplete;
17use crate::dumbo::pdu::bytes::NetworkBytes;
18use crate::dumbo::pdu::tcp::{Flags as TcpFlags, TcpError as TcpSegmentError, TcpSegment};
19use crate::dumbo::tcp::{
20 MAX_WINDOW_SIZE, MSS_DEFAULT, NextSegmentStatus, RstConfig, seq_after, seq_at_or_after,
21};
22
23bitflags! {
24 // We use a set of flags, instead of a state machine, to represent the connection status. Some
25 // parts of the status information are reflected in other fields of the Connection struct, such
26 // as Connection::fin_received.
27 #[derive(Debug, Clone, PartialEq)]
28 struct ConnStatusFlags: u8 {
29 const SYN_RECEIVED = 1;
30 const SYNACK_SENT = 1 << 1;
31 const ESTABLISHED = 1 << 2;
32 // We signal the end of the TX half by setting Connection.send_fin to Some(sequence_number),
33 // and use this flag to record that at least one FIN segment has been sent.
34 const FIN_SENT = 1 << 3;
35 // The other endpoint has ACKed our FIN.
36 const FIN_ACKED = 1 << 4;
37 // The connection is reset, because we either sent, or received a RST segment.
38 const RESET = 1 << 5;
39 }
40}
41
42bitflags! {
43 /// Represents any unusual conditions which may occur when receiving a TCP segment.
44 #[derive(Debug, Clone, Copy, PartialEq)]
45 pub struct RecvStatusFlags: u16 {
46 /// The acknowledgement number is invalid.
47 const INVALID_ACK = 1;
48 /// The connection received a duplicate ACK.
49 const DUP_ACK = 1 << 1;
50 /// The connection received a data segment which does not fall within the limits of the
51 /// current receive window.
52 const SEGMENT_BEYOND_RWND = 1 << 2;
53 /// The connection received a data segment, but the sequence number does not match the
54 /// next expected sequence number.
55 const UNEXPECTED_SEQ = 1 << 3;
56 /// The other endpoint advertised a receive window edge which has been moved to the left.
57 const REMOTE_RWND_EDGE = 1 << 4;
58 /// The other endpoint transmitted additional data after sending a `FIN`.
59 const DATA_BEYOND_FIN = 1 << 5;
60 /// The connection received a valid `RST` segment.
61 const RESET_RECEIVED = 1 << 6;
62 /// The connection received an invalid `RST` segment.
63 const INVALID_RST = 1 << 7;
64 /// The connection received an invalid segment for its current state.
65 const INVALID_SEGMENT = 1 << 8;
66 /// The connection is resetting, and will switch to being reset after getting the
67 /// chance to transmit a `RST` segment.
68 const CONN_RESETTING = 1 << 9;
69 /// The connection received a `FIN` whose sequence number does not match the next
70 /// expected sequence number.
71 const INVALID_FIN = 1 << 10;
72 }
73}
74
75/// Defines a segment payload source.
76///
77/// When not `None`, it contains a [`ByteBuffer`] which holds the actual data, and the sequence
78/// number associated with the first byte from the buffer.
79///
80/// [`ByteBuffer`]: ../../trait.ByteBuffer.html
81// R should have the trait bound R: ByteBuffer, but bounds are ignored on type aliases.
82pub type PayloadSource<'a, R> = Option<(&'a R, Wrapping<u32>)>;
83
84/// Describes errors which may occur during a passive open.
85#[derive(Debug, PartialEq, Eq, thiserror::Error, displaydoc::Display)]
86pub enum PassiveOpenError {
87 /// The incoming segment is not a valid `SYN`.
88 InvalidSyn,
89 /// The `SYN` segment carries an invalid `MSS` option.
90 MssOption,
91}
92
93/// Describes errors which may occur when an existing connection receives a TCP segment.
94#[derive(Debug, PartialEq, Eq, thiserror::Error, displaydoc::Display)]
95pub enum RecvError {
96 /// The payload length is larger than the receive buffer size.
97 BufferTooSmall,
98 /// The connection cannot receive the segment because it has been previously reset.
99 ConnectionReset,
100}
101
102/// Describes errors which may occur when a connection attempts to write a segment.
103/// Needs `rustfmt::skip` to make multiline comments work
104#[rustfmt::skip]
105#[derive(Debug, PartialEq, Eq, thiserror::Error, displaydoc::Display)]
106pub enum WriteNextError {
107 /// The connection cannot write the segment because it has been previously reset.
108 ConnectionReset,
109 /// The write sends additional data after a `FIN` has been transmitted.
110 DataAfterFin,
111 /** The remaining MSS (which can be reduced by IP and/or TCP options) is not large enough to \
112 write the segment. */
113 MssRemaining,
114 // The payload source specifies a buffer larger than [`MAX_WINDOW_SIZE`].
115 //
116 // [`MAX_WINDOW_SIZE`]: ../constant.MAX_WINDOW_SIZE.html
117 /// The payload source is too large.
118 PayloadBufTooLarge,
119 /// The payload source does not contain the first sequence number that should be sent.
120 PayloadMissingSeq,
121 /// An error occurred during the actual write to the buffer: {0}
122 TcpSegment(#[from] TcpSegmentError),
123}
124
125/// Contains the state information and implements the logic for a minimalist TCP connection.
126///
127/// One particular thing is that whenever the connection sends a `RST` segment, it will also stop
128/// working itself. This is just a design decision for our envisioned use cases;
129/// improvements/changes may happen in the future (this also goes for other aspects of the
130/// current implementation).
131///
132/// A `Connection` object can only be created via passive open, and will not recognize/use any TCP
133/// options except `MSS` during the handshake. The associated state machine is similar to how
134/// TCP normally functions, but there are some differences:
135///
136/// * Since only passive opens are supported, a `Connection` can only be instantiated in response to
137/// an incoming `SYN` segment. If the segment is valid, it will start directly in a state called
138/// `SYN_RECEIVED`. The valid events at this point are receiving a retransmission of the previous
139/// `SYN` (which does nothing), and getting the chance to write a `SYNACK`, which also moves the
140/// connection to the `SYNACK_SENT` state. Any incoming segment which is not a copy of the
141/// previous `SYN` will reset the connection.
142/// * In the `SYNACK_SENT` state, the connection awaits an `ACK` for the `SYNACK`. A retransmission
143/// of the original `SYN` moves the state back to `SYN_RECEIVED`. A valid `ACK` advances the state
144/// to `ESTABLISHED`. Any unexpected/invalid segment resets the connection.
145/// * While `ESTABLISHED`, the connection will only reset if it receives a `RST` or a `SYN`. Invalid
146/// segments are simply ignored. `FIN` handling is simplifed: when [`close`] is invoked the
147/// connection records the `FIN` sequence number, and starts setting the `FIN` flag (when
148/// possible) on outgoing segments. A `FIN` from the other endpoint is only taken into
149/// consideration if it has the next expected sequence number. When the connection has both sent
150/// and received a `FIN`, it marks itself as being done. There's no equivalent for the `TIME_WAIT`
151/// TCP state.
152///
153/// The current implementation does not do any kind of congestion control, expects segments to
154/// arrive in order, triggers a retransmission after the first duplicate `ACK`, and relies on the
155/// user to supply an opaque `u64` timestamp value when invoking send or receive functionality. The
156/// timestamps must be non-decreasing, and are mainly used for retransmission timeouts.
157///
158/// See [mmds-design](https://github.com/firecracker-microvm/firecracker/blob/main/docs/mmds/mmds-design.md#dumbo)
159/// for why we are able to make these simplifications. Specifically, we want to stress that no
160/// traffic handled by dumbo ever leaves a microVM.
161///
162/// [`close`]: #method.close
163#[derive(Debug, Clone)]
164pub struct Connection {
165 // The sequence number to ACK at the next opportunity. This is 1 + the highest received
166 // in-order sequence number.
167 ack_to_send: Wrapping<u32>,
168 // The highest ACK we received from the other end of the connection.
169 highest_ack_received: Wrapping<u32>,
170 // The sequence number of the first byte which has NOT yet been sent to the other endpoint.
171 first_not_sent: Wrapping<u32>,
172 // The right edge of the local receive window. We shouldn't receive any data past this point.
173 local_rwnd_edge: Wrapping<u32>,
174 // The right edge of the remote receive window. We shouldn't send any data past this point.
175 remote_rwnd_edge: Wrapping<u32>,
176 // The last time we received an ACK which advanced the receive window. Only makes sense as
177 // long as we seq_after(first_not_sent, highest_ack_received), and if we sent something that
178 // takes up sequence number space.
179 rto_start: u64,
180 // How much time can pass after rto_start, without making progress in the ACK space, before a
181 // retransmission is triggered.
182 rto_period: u64,
183 // How many retransmissions triggered before receiving a valid ACK from the other endpoint.
184 rto_count: u16,
185 // When rto_count reaches this value, the next retransmission will actually reset the
186 // connection.
187 rto_count_max: u16,
188 // Set to the FIN sequence number received from the other endpoint.
189 fin_received: Option<Wrapping<u32>>,
190 // When set, it represents the sequence number of the FIN byte which closes our end of the
191 // connection. No data may be sent past that point.
192 send_fin: Option<Wrapping<u32>>,
193 // If some, send a RST segment with the specified sequence and ACK numbers, and mark the
194 // connection as reset afterwards. The second option determines whether we set the ACK flag
195 // on the RST segment.
196 send_rst: Option<RstConfig>,
197 // The MSS used when sending data segments.
198 mss: u16,
199 // If true, send an ACK segment at the first opportunity. ACKs can piggyback data segments, so
200 // we'll only send an empty ACK segment if we can't transmit any data.
201 pending_ack: bool,
202 // We've got a duplicate ACK, so we'll retransmit the highest ACKed sequence number at the
203 // first opportunity. Unlike regular TCP, we retransmit after the first duplicate ACK.
204 dup_ack: bool,
205 status_flags: ConnStatusFlags,
206}
207
208fn parse_mss_option<T: NetworkBytes + Debug>(
209 segment: &TcpSegment<T>,
210) -> Result<u16, PassiveOpenError> {
211 match segment.parse_mss_option_unchecked(segment.header_len().into()) {
212 Ok(Some(value)) => Ok(value.get()),
213 Ok(None) => Ok(MSS_DEFAULT),
214 Err(_) => Err(PassiveOpenError::MssOption),
215 }
216}
217
218fn is_valid_syn<T: NetworkBytes + Debug>(segment: &TcpSegment<T>) -> bool {
219 segment.flags_after_ns() == TcpFlags::SYN && segment.payload_len() == 0
220}
221
222impl Connection {
223 /// Attempts to create a new `Connection` in response to an incoming `SYN` segment.
224 ///
225 /// # Arguments
226 ///
227 /// * `segment` - The incoming `SYN`.
228 /// * `local_rwnd_size` - Initial size of the local receive window.
229 /// * `rto_period` - How long the connection waits before a retransmission timeout fires for the
230 /// first segment which has not been acknowledged yet. This uses an opaque time unit.
231 /// * `rto_count_max` - How many consecutive timeout-based retransmission may occur before the
232 /// connection resets itself.
233 pub fn passive_open<T: NetworkBytes + Debug>(
234 segment: &TcpSegment<T>,
235 local_rwnd_size: u32,
236 rto_period: NonZeroU64,
237 rto_count_max: NonZeroU16,
238 ) -> Result<Self, PassiveOpenError> {
239 // We don't accepting anything other than a SYN segment here.
240 if !is_valid_syn(segment) {
241 return Err(PassiveOpenError::InvalidSyn);
242 }
243
244 // TODO: If we ever implement window scaling, change the part that computes
245 // remote_rwnd_edge below.
246
247 // We only care about the MSS option for now.
248 let mss = parse_mss_option(segment)?;
249
250 // This is going to get sent on the SYNACK.
251 let ack_to_send = Wrapping(segment.sequence_number()) + Wrapping(1);
252
253 // Let's pick the initial sequence number.
254 let isn = Wrapping(xor_pseudo_rng_u32());
255 let first_not_sent = isn + Wrapping(1);
256 let remote_rwnd_edge = first_not_sent + Wrapping(u32::from(segment.window_size()));
257
258 Ok(Connection {
259 ack_to_send,
260 highest_ack_received: isn,
261 // The ISN is sent over the SYNACK, and this is the next sequence number.
262 first_not_sent,
263 local_rwnd_edge: ack_to_send + Wrapping(local_rwnd_size),
264 // We have no information about this yet. It will get updated as the connection reaches
265 // the ESTABLISHED state.
266 remote_rwnd_edge,
267 rto_start: 0,
268 rto_period: rto_period.get(),
269 rto_count: 0,
270 rto_count_max: rto_count_max.get(),
271 fin_received: None,
272 send_fin: None,
273 send_rst: None,
274 mss,
275 pending_ack: false,
276 dup_ack: false,
277 status_flags: ConnStatusFlags::SYN_RECEIVED,
278 })
279 }
280
281 fn flags_intersect(&self, flags: ConnStatusFlags) -> bool {
282 self.status_flags.intersects(flags)
283 }
284
285 fn set_flags(&mut self, flags: ConnStatusFlags) {
286 self.status_flags.insert(flags);
287 }
288
289 fn clear_flags(&mut self, flags: ConnStatusFlags) {
290 self.status_flags.remove(flags);
291 }
292
293 fn syn_received(&self) -> bool {
294 self.flags_intersect(ConnStatusFlags::SYN_RECEIVED)
295 }
296
297 fn synack_pending(&self) -> bool {
298 self.syn_received() && !self.synack_sent()
299 }
300
301 fn synack_sent(&self) -> bool {
302 self.flags_intersect(ConnStatusFlags::SYNACK_SENT)
303 }
304
305 fn is_reset(&self) -> bool {
306 self.flags_intersect(ConnStatusFlags::RESET)
307 }
308
309 fn fin_sent(&self) -> bool {
310 self.flags_intersect(ConnStatusFlags::FIN_SENT)
311 }
312
313 fn fin_acked(&self) -> bool {
314 self.flags_intersect(ConnStatusFlags::FIN_ACKED)
315 }
316
317 fn is_same_syn<T: NetworkBytes + Debug>(&self, segment: &TcpSegment<T>) -> bool {
318 // This only really makes sense before getting into ESTABLISHED, but that's fine
319 // because we only use it before that point.
320 if !is_valid_syn(segment) || self.ack_to_send.0 != segment.sequence_number().wrapping_add(1)
321 {
322 return false;
323 }
324
325 matches!(parse_mss_option(segment), Ok(mss) if mss == self.mss)
326 }
327
328 fn reset_for_segment<T: NetworkBytes + Debug>(&mut self, s: &TcpSegment<T>) {
329 if !self.rst_pending() {
330 self.send_rst = Some(RstConfig::new(s));
331 }
332 }
333
334 fn rst_pending(&self) -> bool {
335 self.send_rst.is_some()
336 }
337
338 fn rto_expired(&self, now: u64) -> bool {
339 now - self.rto_start >= self.rto_period
340 }
341
342 // We send a FIN control segment if every data byte up to the self.send_fin sequence number
343 // has been ACKed by the other endpoint, and no FIN has been previously sent.
344 fn can_send_first_fin(&self) -> bool {
345 !self.fin_sent()
346 && matches!(self.send_fin, Some(fin_seq) if fin_seq == self.highest_ack_received)
347 }
348
349 // Returns the window size which should be written to an outgoing segment. This is going to be
350 // even more useful when we'll support window scaling.
351 fn local_rwnd(&self) -> u16 {
352 let rwnd = (self.local_rwnd_edge - self.ack_to_send).0;
353
354 u16::try_from(rwnd).unwrap_or(u16::MAX)
355 }
356
357 // Will actually become meaningful when/if we implement window scaling.
358 fn remote_window_size(&self, window_size: u16) -> u32 {
359 u32::from(window_size)
360 }
361
362 // Computes the remote rwnd edge given the ACK number and window size from an incoming segment.
363 fn compute_remote_rwnd_edge(&self, ack: Wrapping<u32>, window_size: u16) -> Wrapping<u32> {
364 ack + Wrapping(self.remote_window_size(window_size))
365 }
366
367 // Has this name just in case the pending_ack status will be more than just some boolean at
368 // some point in the future.
369 fn enqueue_ack(&mut self) {
370 self.pending_ack = true;
371 }
372
373 /// Closes this half of the connection.
374 ///
375 /// Subsequent calls after the first one do not have any effect. The sequence number of the
376 /// `FIN` is the first sequence number not yet sent at this point.
377 #[inline]
378 pub fn close(&mut self) {
379 if self.send_fin.is_none() {
380 self.send_fin = Some(self.first_not_sent);
381 }
382 }
383
384 /// Returns a valid configuration for a `RST` segment, which can be sent to the other
385 /// endpoint to signal the connection should be reset.
386 #[inline]
387 pub fn make_rst_config(&self) -> RstConfig {
388 if self.is_established() {
389 RstConfig::Seq(self.first_not_sent.0)
390 } else {
391 RstConfig::Ack(self.ack_to_send.0)
392 }
393 }
394
395 /// Specifies that a `RST` segment should be sent to the other endpoint, and then the
396 /// connection should be destroyed.
397 #[inline]
398 pub fn reset(&mut self) {
399 if !self.rst_pending() {
400 self.send_rst = Some(self.make_rst_config());
401 }
402 }
403
404 /// Returns `true` if the connection is past the `ESTABLISHED` point.
405 #[inline]
406 pub fn is_established(&self) -> bool {
407 self.flags_intersect(ConnStatusFlags::ESTABLISHED)
408 }
409
410 /// Returns `true` if a `FIN` has been received.
411 #[inline]
412 pub fn fin_received(&self) -> bool {
413 self.fin_received.is_some()
414 }
415
416 // TODO: The description of this method is also a TODO in disguise.
417 /// Returns `true` if the connection is done communicating with the other endpoint.
418 ///
419 /// Maybe it would be a good idea to return true only after our FIN has also been ACKed?
420 /// Otherwise, when using the TCP handler there's pretty much always going to be an ACK for the
421 /// FIN that's going to trigger a gratuitous RST (best case), or can even be considered valid if
422 /// a new connection is created meanwhile using the same tuple and we get very unlucky (worst
423 /// case, extremely unlikely though).
424 #[inline]
425 pub fn is_done(&self) -> bool {
426 self.is_reset() || (self.fin_received() && self.flags_intersect(ConnStatusFlags::FIN_SENT))
427 }
428
429 /// Returns the first sequence number which has not been sent yet for the current window.
430 #[inline]
431 pub fn first_not_sent(&self) -> Wrapping<u32> {
432 self.first_not_sent
433 }
434
435 /// Returns the highest acknowledgement number received for the current window.
436 #[inline]
437 pub fn highest_ack_received(&self) -> Wrapping<u32> {
438 self.highest_ack_received
439 }
440
441 /// Advances the right edge of the local receive window.
442 ///
443 /// This is effectively allowing the other endpoint to send more data, because no byte can be
444 /// sent unless its sequence number falls into the receive window.
445 // TODO: return the actual advance value here
446 #[inline]
447 pub fn advance_local_rwnd_edge(&mut self, value: u32) {
448 let v = Wrapping(value);
449 let max_w = Wrapping(MAX_WINDOW_SIZE);
450 let current_w = self.local_rwnd_edge - self.ack_to_send;
451
452 // Enqueue an ACK if we have to let the other endpoint know the window is opening.
453 if current_w.0 == 0 {
454 self.enqueue_ack();
455 }
456
457 if v + current_w > max_w {
458 self.local_rwnd_edge = self.ack_to_send + max_w;
459 } else {
460 self.local_rwnd_edge += v;
461 }
462 }
463
464 /// Returns the right edge of the receive window advertised by the other endpoint.
465 #[inline]
466 pub fn remote_rwnd_edge(&self) -> Wrapping<u32> {
467 self.remote_rwnd_edge
468 }
469
470 /// Returns `true` if a retransmission caused by the reception of a duplicate `ACK` is pending.
471 #[inline]
472 pub fn dup_ack_pending(&self) -> bool {
473 self.dup_ack
474 }
475
476 /// Describes whether a control segment can be sent immediately, a retransmission is pending,
477 /// or there's nothing to transmit until more segments are received.
478 ///
479 /// This function does not tell whether any data segments can/will be sent, because the
480 /// Connection itself does not control the send buffer. Thus the information returned here
481 /// only pertains to control segments and timeout expiry. Data segment related status will
482 /// be reported by higher level components, which also manage the contents of the send buffer.
483 #[inline]
484 pub fn control_segment_or_timeout_status(&self) -> NextSegmentStatus {
485 if self.synack_pending()
486 || self.rst_pending()
487 || self.can_send_first_fin()
488 || self.pending_ack
489 {
490 NextSegmentStatus::Available
491 } else if self.highest_ack_received != self.first_not_sent {
492 NextSegmentStatus::Timeout(self.rto_start + self.rto_period)
493 } else {
494 NextSegmentStatus::Nothing
495 }
496 }
497
498 // We use this helper method to set up self.send_rst and prepare a return value in one go. It's
499 // only used by the receive_segment() method.
500 fn reset_for_segment_helper<T: NetworkBytes + Debug>(
501 &mut self,
502 s: &TcpSegment<T>,
503 flags: RecvStatusFlags,
504 ) -> Result<(Option<NonZeroUsize>, RecvStatusFlags), RecvError> {
505 self.reset_for_segment(s);
506 Ok((None, RecvStatusFlags::CONN_RESETTING | flags))
507 }
508
509 /// Handles an incoming segment.
510 ///
511 /// When no errors occur, returns a pair consisting of how many
512 /// bytes (if any) were received, and whether any unusual conditions arose while processing the
513 /// segment. Since a `Connection` does not have its own internal buffer, `buf` is required to
514 /// store any data carried by incoming segments.
515 ///
516 /// # Arguments
517 ///
518 /// * `s` - The incoming segment.
519 /// * `buf` - The receive buffer where payload data (if any) from `s` is going to be written.
520 /// * `now` - An opaque timestamp representing the current moment in time.
521 pub fn receive_segment<T: NetworkBytes + Debug>(
522 &mut self,
523 s: &TcpSegment<T>,
524 buf: &mut [u8],
525 now: u64,
526 ) -> Result<(Option<NonZeroUsize>, RecvStatusFlags), RecvError> {
527 if self.rst_pending() || self.is_reset() {
528 return Err(RecvError::ConnectionReset);
529 }
530
531 // TODO: The following logic fully makes sense only for a passive open (which is what we
532 // currently support). Things must change a bit if/when we also implement active opens.
533
534 let segment_flags = s.flags_after_ns();
535
536 if segment_flags.intersects(TcpFlags::RST) {
537 let seq = Wrapping(s.sequence_number());
538 // We accept the RST only if it carries an in-window sequence number.
539 // TODO: If/when we support active opens, we'll also have to accept RST/SYN segments,
540 // which must acknowledge our SYN to be valid.
541 if seq_at_or_after(seq, self.ack_to_send) && seq_after(self.local_rwnd_edge, seq) {
542 self.set_flags(ConnStatusFlags::RESET);
543 return Ok((None, RecvStatusFlags::RESET_RECEIVED));
544 } else {
545 return Ok((None, RecvStatusFlags::INVALID_RST));
546 }
547 }
548
549 let payload_len = s.len() - u16::from(s.header_len());
550 let mut recv_status_flags = RecvStatusFlags::empty();
551
552 if !self.synack_sent() {
553 // We received another segment before getting the chance to send a SYNACK. It's either
554 // a retransmitted SYN, or something that does not make sense.
555 if self.is_same_syn(s) {
556 return Ok((None, recv_status_flags));
557 } else {
558 return self.reset_for_segment_helper(s, RecvStatusFlags::INVALID_SEGMENT);
559 }
560 } else if !self.is_established() {
561 // So at this point we've sent at least one SYNACK, but the connection is not
562 // ESTABLISHED yet. We only accept SYN retransmissions and ACKs. I'm not sure that
563 // it's completely forbidden to sent an ACK + data in response to a SYNACK, so we don't
564 // complain about non-pure ACKs (or even data + ACK + FIN segments).
565 if self.is_same_syn(s) {
566 // Maybe our previous SYNACK got lost or smt, so clear SYN_ACK_SENT to resend it.
567 self.clear_flags(ConnStatusFlags::SYNACK_SENT);
568 return Ok((None, recv_status_flags));
569 } else if segment_flags.intersects(TcpFlags::SYN) {
570 // So we basically freak out over SYN segments which are not valid SYN
571 // retransmission.
572 return self.reset_for_segment_helper(s, RecvStatusFlags::INVALID_SEGMENT);
573 }
574 } else {
575 // Reaching this branch means the connection is ESTABLISHED. The only thing we want to
576 // do right now is reset if we get segments which carry the SYN flag, because they are
577 // obviously invalid, and something must be really wrong.
578 // TODO: Is it an overreaction to reset here?
579 if s.flags_after_ns().intersects(TcpFlags::SYN) {
580 return self.reset_for_segment_helper(s, RecvStatusFlags::INVALID_SEGMENT);
581 }
582 }
583
584 // The ACK number can only be valid when ACK flag is set. The following logic applies to
585 // pretty much all connection states which can reach this point.
586 if segment_flags.intersects(TcpFlags::ACK) {
587 let ack = Wrapping(s.ack_number());
588
589 if seq_at_or_after(ack, self.highest_ack_received)
590 && seq_at_or_after(self.first_not_sent, ack)
591 {
592 // This is a valid ACK. Reset rto_count, since this means the other side is still
593 // alive and kicking (or ACking).
594 self.rto_count = 0;
595
596 if ack == self.highest_ack_received && ack != self.first_not_sent {
597 if !self.is_established() {
598 // Just kidding, a DUPACK is not valid before the connection is ESTABLISHED.
599 return self.reset_for_segment_helper(s, RecvStatusFlags::INVALID_ACK);
600 }
601 // Duplicate ACKs can only increase in sequence number, so there's no need
602 // to check if this one is older than self.dup_ack.
603 self.dup_ack = true;
604 recv_status_flags |= RecvStatusFlags::DUP_ACK;
605 } else {
606 // We're making progress. We should also reset rto_start in this case.
607 self.highest_ack_received = ack;
608 self.rto_start = now;
609 if !self.is_established() && self.synack_sent() {
610 // The connection becomes ESTABLISHED.
611 self.set_flags(ConnStatusFlags::ESTABLISHED);
612 }
613
614 if self.fin_sent() && ack == self.first_not_sent {
615 self.set_flags(ConnStatusFlags::FIN_ACKED);
616 }
617 }
618
619 // Look for remote remote rwnd updates.
620 if self.is_established() {
621 let edge = self.compute_remote_rwnd_edge(ack, s.window_size());
622 if seq_after(edge, self.remote_rwnd_edge) {
623 self.remote_rwnd_edge = edge;
624 } else if edge != self.remote_rwnd_edge {
625 // The right edge of the remote receive window has been moved to the left,
626 // or has been set to an invalid value. Both cases represent erroneous TCP
627 // behaviour.
628 recv_status_flags |= RecvStatusFlags::REMOTE_RWND_EDGE;
629 }
630 }
631 } else {
632 recv_status_flags |= RecvStatusFlags::INVALID_ACK;
633 if !self.is_established() {
634 // Reset the connection if we receive an invalid ACK before reaching the
635 // ESTABLISHED state.
636 return self.reset_for_segment_helper(s, recv_status_flags);
637 }
638 }
639 }
640
641 // We start looking at the payload and/or FIN next. This makes sense only if the
642 // connection is established.
643 if !self.is_established() {
644 return Ok((None, recv_status_flags));
645 }
646
647 let seq = Wrapping(s.sequence_number());
648 let wrapping_payload_len = Wrapping(u32::from(payload_len));
649
650 if usize::from(payload_len) > buf.len() {
651 return Err(RecvError::BufferTooSmall);
652 }
653
654 let mut enqueue_ack = if payload_len > 0 {
655 let data_end_seq = seq + wrapping_payload_len;
656
657 if let Some(fin_seq) = self.fin_received
658 && !seq_at_or_after(fin_seq, data_end_seq)
659 {
660 // TODO: This is a strange situation, because the other endpoint is sending data
661 // after it initially closed its half of the connection. We simply ignore the
662 // segment for now.
663 return Ok((None, recv_status_flags | RecvStatusFlags::DATA_BEYOND_FIN));
664 }
665
666 if !seq_at_or_after(self.local_rwnd_edge, data_end_seq) {
667 // TODO: This is another strange (and potentially dangerous) situation, because
668 // either we or the other endpoint broke receive window semantics. We simply ignore
669 // the segment for now.
670 return Ok((
671 None,
672 recv_status_flags | RecvStatusFlags::SEGMENT_BEYOND_RWND,
673 ));
674 }
675
676 // We currently assume segments are seldom lost or reordered, and only accept those with
677 // the exact next sequence number we're waiting for.
678 if seq != self.ack_to_send {
679 // TODO: Maybe we should enqueue multiple ACKs here (after making such a thing
680 // possible in the first place), just so we're more likely to trigger a
681 // retransmission.
682 self.enqueue_ack();
683 return Ok((None, recv_status_flags | RecvStatusFlags::UNEXPECTED_SEQ));
684 }
685
686 self.ack_to_send = data_end_seq;
687 true
688 } else {
689 false
690 };
691
692 // We assume the sequence number of the FIN does not change via conflicting FIN carrying
693 // segments (as it should be the case during TCP normal operation). It the other endpoint
694 // breaks this convention, it will have to deal with potentially hanging (until timing out)
695 // connections and/or RST segments.
696 if segment_flags.intersects(TcpFlags::FIN) && !self.fin_received() {
697 let fin_seq = seq + wrapping_payload_len;
698
699 // In order to avoid some complexity on our side, we only accept an incoming FIN if its
700 // sequence number matches that of the first byte yet to be received (this is similar to
701 // what we do for data segments right now).
702 if fin_seq == self.ack_to_send {
703 self.fin_received = Some(fin_seq);
704 // Increase this to also ACK the FIN.
705 self.ack_to_send += Wrapping(1);
706 enqueue_ack = true;
707 } else {
708 recv_status_flags |= RecvStatusFlags::INVALID_FIN;
709 }
710 }
711
712 if enqueue_ack {
713 self.enqueue_ack();
714
715 // We check this here because if a valid payload has been received, then we must have
716 // set enqueue_ack = true earlier.
717 if let Some(payload_len) = NonZeroUsize::new(payload_len.into()) {
718 buf[..payload_len.into()].copy_from_slice(s.payload());
719 return Ok((Some(payload_len), recv_status_flags));
720 }
721 }
722
723 Ok((None, recv_status_flags))
724 }
725
726 // The write helper functions return incomplete segments because &self does not have information
727 // regarding the identity of the endpoints, such as source and destination ports, or source and
728 // destination L3 addresses (which are required for checksum computation). We need this stupid
729 // ?Sized trait bound, because otherwise Sized would be implied, and we can have unsized types
730 // which implement ByteBuffer (such as [u8]), since payload expects a reference to some R.
731 fn write_segment<'a, R: ByteBuffer + ?Sized + Debug>(
732 &mut self,
733 buf: &'a mut [u8],
734 mss_reserved: u16,
735 seq: Wrapping<u32>,
736 ack: Wrapping<u32>,
737 flags_after_ns: TcpFlags,
738 payload: Option<(&R, usize)>,
739 ) -> Result<Incomplete<TcpSegment<'a, &'a mut [u8]>>, WriteNextError> {
740 // Write the MSS option on SYNACK segments.
741 let mss_option = if flags_after_ns == TcpFlags::SYN | TcpFlags::ACK {
742 Some(self.mss)
743 } else {
744 None
745 };
746
747 let segment = TcpSegment::write_incomplete_segment(
748 buf,
749 seq.0,
750 ack.0,
751 flags_after_ns,
752 self.local_rwnd(),
753 mss_option,
754 self.mss
755 .checked_sub(mss_reserved)
756 .ok_or(WriteNextError::MssRemaining)?,
757 payload,
758 )?;
759
760 if flags_after_ns.intersects(TcpFlags::ACK) {
761 self.pending_ack = false;
762 }
763
764 Ok(segment)
765 }
766
767 // Control segments are segments with no payload (at least I like to use this name).
768 fn write_control_segment<'a, R: ByteBuffer + ?Sized + Debug>(
769 &mut self,
770 buf: &'a mut [u8],
771 mss_reserved: u16,
772 ) -> Result<Incomplete<TcpSegment<'a, &'a mut [u8]>>, WriteNextError> {
773 let mut seq = self.highest_ack_received;
774 let mut ack = self.ack_to_send;
775 let mut flags_after_ns = TcpFlags::empty();
776
777 if let Some(cfg) = self.send_rst {
778 let t = cfg.seq_ack_tcp_flags();
779 seq = Wrapping(t.0);
780 ack = Wrapping(t.1);
781 flags_after_ns = t.2;
782 } else if !self.is_established() {
783 // We can only send SYNACKs on this branch. The ISN should be right before
784 // self.first_not_sent.
785 flags_after_ns |= TcpFlags::SYN | TcpFlags::ACK;
786 seq = self.first_not_sent - Wrapping(1);
787 } else {
788 // If we got to this point, the connection is ESTABLISHED, and we're not sending a RST.
789 // We always want to enable the ACK flag.
790 flags_after_ns = TcpFlags::ACK;
791
792 if let Some(fin_seq) = self.send_fin {
793 // When all outgoing data segments have been acked, we place the FIN flag and the
794 // appropriate sequence number on outgoing control segments, unless we received an
795 // ACK for the FIN.
796 if !self.fin_acked() && seq_at_or_after(seq, fin_seq) {
797 flags_after_ns |= TcpFlags::FIN;
798 seq = fin_seq;
799 }
800 }
801 }
802
803 self.write_segment::<R>(buf, mss_reserved, seq, ack, flags_after_ns, None)
804 }
805
806 /// Writes a new segment (if available) to the specified buffer.
807 ///
808 /// The `payload_src` argument is required because the `Connection` does not have an internal
809 /// send buffer. If the payload source is present, the data referenced therein must not amount
810 /// to more than [`MAX_WINDOW_SIZE`].
811 ///
812 /// # Arguments
813 ///
814 /// * `buf` - The buffer where the segment is written.
815 /// * `mss_reserved` - How much (if anything) of the MSS value has been already used at the
816 /// lower layers (by IP options, for example). This will be zero most of the time.
817 /// * `payload_src` - References a buffer which contains data to send, and also specifies the
818 /// sequence number associated with the first byte from that buffer.
819 /// * `now` - An opaque timestamp representing the current moment in time.
820 ///
821 /// [`MAX_WINDOW_SIZE`]: ../constant.MAX_WINDOW_SIZE.html
822 pub fn write_next_segment<'a, R: ByteBuffer + ?Sized + Debug>(
823 &mut self,
824 buf: &'a mut [u8],
825 mss_reserved: u16,
826 payload_src: PayloadSource<R>,
827 now: u64,
828 ) -> Result<Option<Incomplete<TcpSegment<'a, &'a mut [u8]>>>, WriteNextError> {
829 // TODO: like receive_segment(), this function is specific in some ways to Connections
830 // created via passive open. When/if we also implement active opens, some things will
831 // have to change.
832
833 if self.is_reset() {
834 return Err(WriteNextError::ConnectionReset);
835 }
836
837 if self.send_rst.is_some() {
838 // A RST is pending. Try to write it, and change the state of the connection to reset
839 // if successfull.
840 let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
841 self.set_flags(ConnStatusFlags::RESET);
842 return Ok(Some(segment));
843 }
844
845 // The first thing we have to do is reply with a SYNACK if needed.
846 if self.synack_pending() {
847 let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
848 self.set_flags(ConnStatusFlags::SYNACK_SENT);
849 self.rto_start = now;
850 return Ok(Some(segment));
851 }
852
853 // Resend a SYNACK if the RTO expired. Otherwise, no reason to continue until the connection
854 // becomes ESTABLISHED.
855 if !self.is_established() {
856 if self.rto_expired(now) {
857 // If we exceeded the maximum retransmission count, reset the connection and call
858 // write_next_segment one more time to generate the RST.
859 self.rto_count += 1;
860 if self.rto_count >= self.rto_count_max {
861 self.reset();
862 return self.write_next_segment(buf, mss_reserved, payload_src, now);
863 }
864 let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
865 self.rto_start = now;
866 return Ok(Some(segment));
867 }
868 return Ok(None);
869 }
870
871 // First, try sending a data segment, because we can piggy back ACKs and FINs on top of it.
872 if let Some((read_buf, payload_seq)) = payload_src {
873 // Limit the size of read_buf so it doesn't mess up later calculations (as usual, I take
874 // the easy way out).
875 let len = match u32::try_from(read_buf.len()) {
876 Ok(len) if len <= MAX_WINDOW_SIZE => len,
877 _ => return Err(WriteNextError::PayloadBufTooLarge),
878 };
879
880 let payload_end = payload_seq + Wrapping(len);
881
882 let mut rto_triggered = false;
883
884 // Decide what sequence number to send next. Check out if a timeout expired first.
885 let seq_to_send =
886 if self.highest_ack_received != self.first_not_sent && self.rto_expired(now) {
887 self.rto_count += 1;
888 if self.rto_count >= self.rto_count_max {
889 self.reset();
890 return self.write_next_segment(buf, mss_reserved, payload_src, now);
891 }
892
893 if let Some(fin_seq) = self.send_fin
894 && self.highest_ack_received == fin_seq
895 {
896 // We're in the relatively unlikely situation where our FIN got lost.
897 // Simply calling write_control_segment() will retransmit it.
898 let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
899 self.rto_start = now;
900 return Ok(Some(segment));
901 }
902
903 // We have to remember this is a retransmission for later.
904 rto_triggered = true;
905 self.highest_ack_received
906 } else if self.dup_ack {
907 // We retransmit an older segment if a DUPACK is recorded. We'll clear
908 // self.dup_ack after we make sure the segment has been successfully written.
909 self.highest_ack_received
910 } else {
911 // Otherwise, we send some data (if possible) starting with the first byte not
912 // yet sent.
913 self.first_not_sent
914 };
915
916 // The payload buffer begins after the first sequence number we are trying to send
917 // (or the payload_seq is totally off).
918 if !seq_at_or_after(seq_to_send, payload_seq) {
919 return Err(WriteNextError::PayloadMissingSeq);
920 }
921
922 // We can only send data if it's within both the send buffer and the remote rwnd, and
923 // before the sequence number of the local FIN (if the connection is closing).
924 let actual_end = if seq_at_or_after(self.remote_rwnd_edge, payload_end) {
925 payload_end
926 } else {
927 self.remote_rwnd_edge
928 };
929
930 // Make sure we're not trying to send data past the FIN sequence we previously
931 // announced.
932 if let Some(fin_seq) = self.send_fin
933 && seq_after(actual_end, fin_seq)
934 {
935 return Err(WriteNextError::DataAfterFin);
936 }
937
938 // We only proceed with writing a data segment if the previously computed bounds
939 // delimit a valid sequence number interval.
940 if seq_after(actual_end, seq_to_send) {
941 let max_payload_len = (actual_end - seq_to_send).0 as usize;
942
943 // We always set the ACK flag for data segments.
944 let tcp_flags = TcpFlags::ACK;
945
946 let ack_to_send = self.ack_to_send;
947 let mut segment = self.write_segment(
948 buf,
949 mss_reserved,
950 seq_to_send,
951 ack_to_send,
952 tcp_flags,
953 Some((read_buf, max_payload_len)),
954 )?;
955
956 // If self.dup_ack was Some(_), we've just written the retransmission segment,
957 // either directly or via the RTO timer expiring.
958 self.dup_ack = false;
959
960 let payload_len = segment.inner().payload_len();
961 let mut first_seq_after = seq_to_send + Wrapping(u32::from(payload_len));
962
963 if let Some(fin_seq) = self.send_fin
964 && first_seq_after == fin_seq
965 {
966 // This segment contains the last bytes of data we're going to send, so
967 // we should also set the FIN flag.
968 segment
969 .inner_mut()
970 .set_flags_after_ns(tcp_flags | TcpFlags::FIN);
971
972 // The FIN takes up 1 sequence number.
973 first_seq_after += Wrapping(1);
974 // The main purpose of knowing we sent at least one FIN is to signal that
975 // we already added 1 to self.first_not_sent, to account for its sequence
976 // number.
977 self.set_flags(ConnStatusFlags::FIN_SENT);
978 }
979
980 if rto_triggered || self.first_not_sent == self.highest_ack_received {
981 // Reset the RTO "timer" after each retransmission, or after sending the first
982 // unacknowledged segment in the current window.
983 self.rto_start = now;
984 }
985
986 if seq_after(first_seq_after, self.first_not_sent) {
987 self.first_not_sent = first_seq_after;
988 }
989
990 return Ok(Some(segment));
991 }
992 }
993
994 // At this point, we only send a control segment if there's a pending ACK, or we didn't send
995 // a FIN segment before and we would be sending the first one.
996
997 // The FIN flag will be automatically added to the segment when necessary by the
998 // write_control_segment() method.
999 let send_first_fin = self.can_send_first_fin();
1000 if self.pending_ack || send_first_fin {
1001 let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
1002
1003 if send_first_fin {
1004 self.first_not_sent += Wrapping(1);
1005 self.set_flags(ConnStatusFlags::FIN_SENT);
1006 }
1007
1008 return Ok(Some(segment));
1009 }
1010
1011 Ok(None)
1012 }
1013}
1014
1015// TODO: I'll be honest: the tests here cover the situations most likely to be encountered, but are
1016// not even close to being exhaustive. Something like that might be worth pursuing after polishing
1017// the rougher edges around the current implementation, and deciding its scope relative to an
1018// actual TCP implementation.
1019#[cfg(test)]
1020pub(crate) mod tests {
1021 use super::*;
1022
1023 // A segment without options or a payload is 20 bytes long.
1024 const BASIC_SEGMENT_SIZE: usize = 20;
1025
1026 #[derive(Debug)]
1027 pub struct ConnectionTester {
1028 buf: [u8; 2000],
1029 src_port: u16,
1030 dst_port: u16,
1031 remote_window_size: u16,
1032 pub mss: u16,
1033 pub mss_reserved: u16,
1034 local_rwnd_size: u32,
1035 remote_isn: u32,
1036 pub rto_period: u64,
1037 rto_count_max: u16,
1038 now: u64,
1039 }
1040
1041 impl ConnectionTester {
1042 pub fn new() -> Self {
1043 ConnectionTester {
1044 buf: [0u8; 2000],
1045 src_port: 1000,
1046 dst_port: 80,
1047 remote_window_size: 11000,
1048 mss: 1100,
1049 mss_reserved: 0,
1050 local_rwnd_size: 10000,
1051 remote_isn: 12_345_678,
1052 rto_period: 100_000,
1053 rto_count_max: 3,
1054 now: 0,
1055 }
1056 }
1057
1058 fn passive_open<T: NetworkBytes + Debug>(
1059 &self,
1060 s: &TcpSegment<T>,
1061 ) -> Result<Connection, PassiveOpenError> {
1062 Connection::passive_open(
1063 s,
1064 self.local_rwnd_size,
1065 NonZeroU64::new(self.rto_period).unwrap(),
1066 NonZeroU16::new(self.rto_count_max).unwrap(),
1067 )
1068 }
1069
1070 // This helps write segments; it uses a lot of default values, and sets the ACK and SEQ
1071 // numbers to 0, and self.remote_isn respectively.
1072 fn write_segment_helper<'a>(
1073 &self,
1074 buf: &'a mut [u8],
1075 add_mss_option: bool,
1076 payload: Option<(&[u8], usize)>,
1077 ) -> TcpSegment<'a, &'a mut [u8]> {
1078 let mss_option = if add_mss_option { Some(self.mss) } else { None };
1079 TcpSegment::write_segment(
1080 buf,
1081 self.src_port,
1082 self.dst_port,
1083 self.remote_isn,
1084 0,
1085 TcpFlags::empty(),
1086 self.remote_window_size,
1087 mss_option,
1088 self.mss.checked_sub(self.mss_reserved).unwrap(),
1089 payload,
1090 None,
1091 )
1092 .unwrap()
1093 }
1094
1095 pub fn write_syn<'a>(&self, buf: &'a mut [u8]) -> TcpSegment<'a, &'a mut [u8]> {
1096 self.write_segment_helper(buf, true, None)
1097 }
1098
1099 pub fn write_ctrl<'a>(&self, buf: &'a mut [u8]) -> TcpSegment<'a, &'a mut [u8]> {
1100 self.write_segment_helper(buf, false, None)
1101 }
1102
1103 pub fn write_data<'a>(
1104 &self,
1105 buf: &'a mut [u8],
1106 data_buf: &[u8],
1107 ) -> TcpSegment<'a, &'a mut [u8]> {
1108 let segment = self.write_segment_helper(buf, false, Some((data_buf, data_buf.len())));
1109 assert_eq!(usize::from(segment.payload_len()), data_buf.len());
1110 segment
1111 }
1112
1113 fn receive_segment<T: NetworkBytes + Debug>(
1114 &mut self,
1115 c: &mut Connection,
1116 s: &TcpSegment<T>,
1117 ) -> Result<(Option<NonZeroUsize>, RecvStatusFlags), RecvError> {
1118 c.receive_segment(s, self.buf.as_mut(), self.now)
1119 }
1120
1121 fn write_next_segment(
1122 &mut self,
1123 c: &mut Connection,
1124 payload_src: Option<(&[u8], Wrapping<u32>)>,
1125 ) -> Result<Option<TcpSegment<'_, &mut [u8]>>, WriteNextError> {
1126 let src_port = self.src_port;
1127 let dst_port = self.dst_port;
1128 c.write_next_segment(self.buf.as_mut(), self.mss_reserved, payload_src, self.now)
1129 .map(|o| o.map(|incomplete| incomplete.finalize(src_port, dst_port, None)))
1130 }
1131
1132 // Checks if the specified connection will reset after receiving the provided segment, and
1133 // that the receive_segment() method also returns the specified RecvStatusFlags. We
1134 // also make sure the outgoing RST segment has additional_segment_flags set besides
1135 // TcpFlags::RST.
1136 fn should_reset_after<T: NetworkBytes + Debug>(
1137 &mut self,
1138 c: &mut Connection,
1139 s: &TcpSegment<T>,
1140 recv_flags: RecvStatusFlags,
1141 additional_segment_flags: TcpFlags,
1142 ) {
1143 assert_eq!(self.receive_segment(c, s).unwrap(), (None, recv_flags));
1144
1145 // We add a payload also, to see that sending a RST has precedence over everything.
1146 let send_buf = [0u8; 2000];
1147 let payload_src = Some((send_buf.as_ref(), c.highest_ack_received));
1148
1149 if !recv_flags.intersects(RecvStatusFlags::RESET_RECEIVED) {
1150 // If the connection initiated the reset, the next segment to write should be a RST.
1151 // The first unwrap is for the Result, and the second for the Option.
1152 check_control_segment(
1153 &self.write_next_segment(c, payload_src).unwrap().unwrap(),
1154 0,
1155 additional_segment_flags | TcpFlags::RST,
1156 );
1157 }
1158
1159 // Calling write_next_segment again should result in a ConnectionReset error.
1160 assert_eq!(
1161 self.write_next_segment(c, payload_src).unwrap_err(),
1162 WriteNextError::ConnectionReset
1163 );
1164
1165 // Receive should also no longer work.
1166 assert_eq!(
1167 self.receive_segment(c, s).unwrap_err(),
1168 RecvError::ConnectionReset
1169 );
1170
1171 assert!(c.is_done());
1172 }
1173
1174 // Checks that the next segment sent by c is a SYNACK.
1175 fn check_synack_is_next(&mut self, c: &mut Connection) {
1176 let send_buf = [0u8; 2000];
1177 let payload_src = Some((send_buf.as_ref(), c.highest_ack_received));
1178 let remote_isn = self.remote_isn;
1179 let conn_isn = c.first_not_sent.0.wrapping_sub(1);
1180 let mss = self.mss;
1181
1182 let s = self.write_next_segment(c, payload_src).unwrap().unwrap();
1183 // The MSS option is 4 bytes long.
1184 check_control_segment(&s, 4, TcpFlags::SYN | TcpFlags::ACK);
1185
1186 assert_eq!(s.sequence_number(), conn_isn);
1187 assert_eq!(s.ack_number(), remote_isn.wrapping_add(1));
1188
1189 // Our implementation mirrors the received value of the MSS option.
1190 assert_eq!(parse_mss_option(&s).unwrap(), mss);
1191
1192 check_synack_sent(c);
1193 }
1194 }
1195
1196 // Verifies whether we are dealing with a control segment with the specified flags.
1197 fn check_control_segment<T: NetworkBytes + Debug>(
1198 s: &TcpSegment<T>,
1199 options_len: usize,
1200 flags_after_ns: TcpFlags,
1201 ) {
1202 assert_eq!(usize::from(s.len()), BASIC_SEGMENT_SIZE + options_len);
1203 assert_eq!(s.flags_after_ns(), flags_after_ns);
1204 }
1205
1206 // Checks if the segment ACKs the specified sequence number, and whether the additional_flags
1207 // are set (besides ACK).
1208 fn check_acks<T: NetworkBytes + Debug>(
1209 s: &TcpSegment<T>,
1210 ack_number: u32,
1211 additional_flags: TcpFlags,
1212 ) {
1213 assert_eq!(s.flags_after_ns(), TcpFlags::ACK | additional_flags);
1214 assert_eq!(s.ack_number(), ack_number);
1215 }
1216
1217 // The following "check_" helper functions ensure a Connection in a certain state does not have
1218 // any unwarranted status flags set. We wouldn't need to look at this if we used a state enum
1219 // instead of a status flags set.
1220 fn check_syn_received(c: &Connection) {
1221 assert_eq!(c.status_flags, ConnStatusFlags::SYN_RECEIVED);
1222 }
1223
1224 fn check_synack_sent(c: &Connection) {
1225 assert_eq!(
1226 c.status_flags,
1227 ConnStatusFlags::SYN_RECEIVED | ConnStatusFlags::SYNACK_SENT
1228 );
1229 }
1230
1231 fn check_established(c: &Connection) {
1232 assert_eq!(
1233 c.status_flags,
1234 ConnStatusFlags::SYN_RECEIVED
1235 | ConnStatusFlags::SYNACK_SENT
1236 | ConnStatusFlags::ESTABLISHED
1237 );
1238 }
1239
1240 fn check_fin_received_but_not_sent(c: &Connection) {
1241 assert_eq!(
1242 c.status_flags,
1243 ConnStatusFlags::SYN_RECEIVED
1244 | ConnStatusFlags::SYNACK_SENT
1245 | ConnStatusFlags::ESTABLISHED
1246 );
1247 assert!(c.fin_received());
1248 }
1249
1250 #[test]
1251 #[allow(clippy::cognitive_complexity)]
1252 fn test_connection() {
1253 // These are used to support some segments we play around with.
1254 let mut buf1 = [0u8; 100];
1255 let mut buf2 = [0u8; 100];
1256 let mut buf3 = [0u8; 1500];
1257 // Buffer containing the payload of the incoming data segment.
1258 let data_buf = [2u8; 1000];
1259 // Buffer containing the data which the connection sends on outgoing segments.
1260 let send_buf = [11u8; 20000];
1261
1262 let mut t = ConnectionTester::new();
1263
1264 let mut syn = t.write_syn(buf1.as_mut());
1265 let mut ctrl = t.write_ctrl(buf2.as_mut());
1266 let mut data = t.write_data(buf3.as_mut(), data_buf.as_ref());
1267
1268 // Test creating a new connection based on invalid SYN segments.
1269
1270 // Invalid flags.
1271 syn.set_flags_after_ns(TcpFlags::SYN | TcpFlags::ACK);
1272 assert_eq!(
1273 t.passive_open(&syn).unwrap_err(),
1274 PassiveOpenError::InvalidSyn
1275 );
1276
1277 // SYN segment with payload.
1278 data.set_flags_after_ns(TcpFlags::SYN);
1279 assert_eq!(
1280 t.passive_open(&data).unwrap_err(),
1281 PassiveOpenError::InvalidSyn
1282 );
1283
1284 // Ok, now let's test with connections created using valid SYN segments.
1285
1286 // Set valid flags.
1287 syn.set_flags_after_ns(TcpFlags::SYN);
1288
1289 let mut c = t.passive_open(&syn).unwrap();
1290
1291 assert_eq!(c.ack_to_send.0, t.remote_isn.wrapping_add(1));
1292 assert_eq!(c.first_not_sent, c.highest_ack_received + Wrapping(1));
1293 assert_eq!(
1294 c.local_rwnd_edge.0,
1295 t.remote_isn.wrapping_add(1 + t.local_rwnd_size)
1296 );
1297 assert_eq!(
1298 c.remote_rwnd_edge,
1299 c.first_not_sent + Wrapping(u32::from(t.remote_window_size))
1300 );
1301 check_syn_received(&c);
1302
1303 // There's a SYNACK to send.
1304 assert_eq!(
1305 c.control_segment_or_timeout_status(),
1306 NextSegmentStatus::Available
1307 );
1308
1309 let mut c_clone = c.clone();
1310
1311 // While the connection is in this state, we send another SYN, with a different ISN.
1312 syn.set_sequence_number(t.remote_isn.wrapping_add(1));
1313 t.should_reset_after(
1314 &mut c,
1315 &syn,
1316 RecvStatusFlags::INVALID_SEGMENT | RecvStatusFlags::CONN_RESETTING,
1317 TcpFlags::ACK,
1318 );
1319
1320 // Let's restore the connection.
1321 c = c_clone;
1322 let mut payload_src = Some((send_buf.as_ref(), c.highest_ack_received));
1323
1324 // Sending the exact same SYN again should be fine.
1325 syn.set_sequence_number(t.remote_isn);
1326 assert_eq!(
1327 t.receive_segment(&mut c, &syn).unwrap(),
1328 (None, RecvStatusFlags::empty())
1329 );
1330
1331 // The connection should send a SYNACK at the next opportunity.
1332 t.check_synack_is_next(&mut c);
1333
1334 // Calling write_next_segment again should not send anything else.
1335 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1336
1337 // Also, we now have a RTO pending.
1338 assert_eq!(
1339 c.control_segment_or_timeout_status(),
1340 NextSegmentStatus::Timeout(t.rto_period)
1341 );
1342
1343 // However, if we advance the time until just after the RTO, a SYNACK is retransmitted.
1344 t.now += t.rto_period;
1345 t.check_synack_is_next(&mut c);
1346
1347 assert_eq!(
1348 c.control_segment_or_timeout_status(),
1349 NextSegmentStatus::Timeout(2 * t.rto_period)
1350 );
1351
1352 // Re-receiving a valid SYN moves the connection back to SYN_RECEIVED.
1353 assert_eq!(
1354 t.receive_segment(&mut c, &syn).unwrap(),
1355 (None, RecvStatusFlags::empty())
1356 );
1357 check_syn_received(&c);
1358
1359 // And thus, a SYNACK will be the next segment to be transmitted once again.
1360 t.check_synack_is_next(&mut c);
1361
1362 // Now is a time as good as any to see what happens if we receive a RST. First, let's try
1363 // with an invalid RST (its sequence number is out of window).
1364 ctrl.set_sequence_number(c.ack_to_send.0.wrapping_sub(1))
1365 .set_flags_after_ns(TcpFlags::RST);
1366 assert_eq!(
1367 t.receive_segment(&mut c, &ctrl).unwrap(),
1368 (None, RecvStatusFlags::INVALID_RST)
1369 );
1370
1371 // Let's back up c, because the next segment will be a valid RST.
1372 c_clone = c.clone();
1373 ctrl.set_sequence_number(c.ack_to_send.0);
1374 t.should_reset_after(
1375 &mut c,
1376 &ctrl,
1377 RecvStatusFlags::RESET_RECEIVED,
1378 TcpFlags::ACK,
1379 );
1380
1381 // Cool, let's restore c and continue.
1382 c = c_clone.clone();
1383 let conn_isn = c.first_not_sent.0.wrapping_sub(1);
1384
1385 // Ok so we're waiting for the SYNACK to be acked. Any incoming segment which is not a
1386 // retransmitted SYN, but has the SYN flag set will cause a reset.
1387 data.set_flags_after_ns(TcpFlags::ACK | TcpFlags::SYN)
1388 .set_ack_number(conn_isn.wrapping_add(1))
1389 .set_sequence_number(t.remote_isn.wrapping_add(1));
1390
1391 t.should_reset_after(
1392 &mut c,
1393 &data,
1394 RecvStatusFlags::INVALID_SEGMENT | RecvStatusFlags::CONN_RESETTING,
1395 // The RST emitted in response won't have the ACK flag set because we can infer a
1396 // sequence number from the ACK carried by the data segment.
1397 TcpFlags::empty(),
1398 );
1399
1400 c = c_clone.clone();
1401 // A valid ACK should move the connection into ESTABLISHED. Also, since we allow more than
1402 // just pure ACKs at this point, any valid data should be received as well.
1403 data.set_flags_after_ns(TcpFlags::ACK);
1404 assert_eq!(
1405 t.receive_segment(&mut c, &data).unwrap(),
1406 (
1407 Some(NonZeroUsize::new(data_buf.len()).unwrap()),
1408 RecvStatusFlags::empty()
1409 )
1410 );
1411 assert!(c.is_established());
1412
1413 c = c_clone.clone();
1414 // In fact, since we're so like whatever about the segments we receive here, let's see what
1415 // happens if data also carries the FIN flag (spoiler: it works).
1416 data.set_flags_after_ns(TcpFlags::ACK | TcpFlags::FIN);
1417
1418 assert_eq!(
1419 t.receive_segment(&mut c, &data).unwrap(),
1420 (
1421 Some(NonZeroUsize::new(data_buf.len()).unwrap()),
1422 RecvStatusFlags::empty()
1423 )
1424 );
1425 assert!(c.is_established());
1426 assert!(c.fin_received());
1427
1428 c = c_clone.clone();
1429 // That being said, let's move into established via a pure ACK.
1430 ctrl.set_flags_after_ns(TcpFlags::ACK)
1431 .set_ack_number(conn_isn.wrapping_add(1));
1432
1433 assert_eq!(
1434 t.receive_segment(&mut c, &ctrl).unwrap(),
1435 (None, RecvStatusFlags::empty())
1436 );
1437 check_established(&c);
1438
1439 // Cool, let's back c up.
1440 c_clone = c.clone();
1441
1442 // We still get spooked if we get something with a SYN.
1443 data.set_flags_after_ns(TcpFlags::SYN | TcpFlags::ACK);
1444 t.should_reset_after(
1445 &mut c,
1446 &data,
1447 RecvStatusFlags::INVALID_SEGMENT | RecvStatusFlags::CONN_RESETTING,
1448 // The RST emitted in response won't have the ACK flag set because we can infer a
1449 // sequence number from the ACK carried by the data segment.
1450 TcpFlags::empty(),
1451 );
1452
1453 c = c_clone.clone();
1454
1455 // Ok so back to ESTABLISHED, let's make sure we only accept the exact sequence
1456 // number we expect (which is t.remote_isn + 1 at this point). The following segment should
1457 // not be accepted.
1458 data.set_flags_after_ns(TcpFlags::ACK)
1459 .set_sequence_number(t.remote_isn);
1460 assert_eq!(
1461 t.receive_segment(&mut c, &data).unwrap(),
1462 (None, RecvStatusFlags::UNEXPECTED_SEQ)
1463 );
1464
1465 // However, if we set the expected sequence everything should be ok.
1466 data.set_sequence_number(t.remote_isn + 1);
1467 assert_eq!(
1468 t.receive_segment(&mut c, &data).unwrap(),
1469 (
1470 Some(NonZeroUsize::new(data.payload_len().into()).unwrap()),
1471 RecvStatusFlags::empty()
1472 )
1473 );
1474
1475 // This is the ack number that should be set/sent.
1476 let expected_ack = t.remote_isn.wrapping_add(u32::from(data.payload_len()) + 1);
1477
1478 // Check that internal state gets updated properly.
1479 assert_eq!(c.ack_to_send.0, expected_ack);
1480
1481 {
1482 // We should get a pure ACK here, because we don't provide a payload source.
1483 let s = t.write_next_segment(&mut c, None).unwrap().unwrap();
1484 check_acks(&s, expected_ack, TcpFlags::empty());
1485 }
1486
1487 // Calling write_next_segment (without a payload source) again should not send
1488 // anything else.
1489 assert!(t.write_next_segment(&mut c, None).unwrap().is_none());
1490
1491 {
1492 let payload_len = u32::from(data.payload_len());
1493
1494 // Assuming no one changed the code, the local window size of the connection was 10000,
1495 // so we should be able to successfully receive 9 more segments with 1000 byte payloads.
1496 let max = 9;
1497 for i in 1u32..=max {
1498 // The 1 we add is because the SYN consumes a sequence number.
1499 data.set_sequence_number(t.remote_isn.wrapping_add(1 + i * payload_len));
1500 assert_eq!(
1501 t.receive_segment(&mut c, &data).unwrap(),
1502 (
1503 Some(NonZeroUsize::new(data.payload_len().into()).unwrap()),
1504 RecvStatusFlags::empty()
1505 )
1506 );
1507 }
1508
1509 let expected_ack = t.remote_isn.wrapping_add(1 + (max + 1) * payload_len);
1510 // The connection should send a single cumulative ACK, and no other segment afterward
1511 // (if we don't also provide a payload source, which we don't).
1512 {
1513 {
1514 let s = t.write_next_segment(&mut c, None).unwrap().unwrap();
1515 check_acks(&s, expected_ack, TcpFlags::empty());
1516 }
1517
1518 assert!(t.write_next_segment(&mut c, None).unwrap().is_none());
1519 }
1520
1521 // Sending any more new data should be outside of the receive window of the connection.
1522 data.set_sequence_number(expected_ack);
1523 assert_eq!(
1524 t.receive_segment(&mut c, &data).unwrap(),
1525 (None, RecvStatusFlags::SEGMENT_BEYOND_RWND)
1526 );
1527 }
1528
1529 // Restore connection state to just after ESTABLISHED, and make it send some data.
1530 c = c_clone.clone();
1531
1532 // This should send anything, as the payload source does not contain the next sequence
1533 // number to be sent.
1534
1535 // Should contain conn_isn + 1 to be fine, but we make it start just after.
1536 payload_src.as_mut().unwrap().1 = Wrapping(conn_isn) + Wrapping(2);
1537
1538 assert_eq!(
1539 t.write_next_segment(&mut c, payload_src).unwrap_err(),
1540 WriteNextError::PayloadMissingSeq
1541 );
1542
1543 // Let's fix it.
1544 payload_src.as_mut().unwrap().1 = Wrapping(conn_isn) + Wrapping(1);
1545
1546 // The mss is 1100, and the remote window is 11000, so we can send 10 data packets.
1547 let max = 10;
1548 let remote_isn = t.remote_isn;
1549 let mss = t.mss;
1550
1551 let (payload_buf, mut response_seq) = payload_src.unwrap();
1552 let mut payload_offset = 0;
1553 for i in 0..max {
1554 // Using the expects to get the value of i if there's an error.
1555 let s = t
1556 .write_next_segment(&mut c, Some((&payload_buf[payload_offset..], response_seq)))
1557 .unwrap_or_else(|_| panic!("{}", i))
1558 .unwrap_or_else(|| panic!("{}", i));
1559
1560 payload_offset += usize::from(s.payload_len());
1561 response_seq += Wrapping(u32::from(s.payload_len()));
1562
1563 // Again, the 1 accounts for the sequence number taken up by the SYN.
1564 assert_eq!(
1565 s.sequence_number(),
1566 conn_isn.wrapping_add(1 + i * u32::from(mss)),
1567 );
1568 assert_eq!(s.ack_number(), remote_isn.wrapping_add(1));
1569 assert_eq!(s.flags_after_ns(), TcpFlags::ACK);
1570 assert_eq!(s.payload_len(), mss);
1571 }
1572
1573 // No more new data can be sent until the window advances, even though data_buf
1574 // contains 20_000 bytes.
1575 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1576
1577 // Let's ACK the first segment previously sent.
1578 ctrl.set_ack_number(conn_isn.wrapping_add(1 + u32::from(mss)))
1579 .set_flags_after_ns(TcpFlags::ACK);
1580 assert_eq!(
1581 t.receive_segment(&mut c, &ctrl).unwrap(),
1582 (None, RecvStatusFlags::empty())
1583 );
1584
1585 // We should be able to send one more segment now.
1586 {
1587 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1588 assert_eq!(
1589 s.sequence_number(),
1590 conn_isn.wrapping_add(1 + max * u32::from(mss)),
1591 );
1592 assert_eq!(s.payload_len(), mss);
1593 }
1594 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1595
1596 // We have to wait for the window to open again in order to send new data, but we can
1597 // have retransmissions. For example, receiving the previous ACK again will cause a
1598 // DUPACK, which will trigger a retransmission.
1599 assert_eq!(
1600 t.receive_segment(&mut c, &ctrl).unwrap(),
1601 (None, RecvStatusFlags::DUP_ACK)
1602 );
1603 assert!(c.dup_ack_pending());
1604
1605 // Let's check that we indeed get a single retransmitted segment.
1606 {
1607 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1608 assert_eq!(s.sequence_number(), ctrl.ack_number());
1609 assert_eq!(s.payload_len(), mss);
1610 }
1611 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1612
1613 // Retransmissions also trigger after time-out.
1614 t.now += t.rto_period;
1615 {
1616 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1617 assert_eq!(s.sequence_number(), ctrl.ack_number());
1618 assert_eq!(s.payload_len(), mss);
1619 }
1620 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1621
1622 // Btw, let's also make sure another retransmission will happen after another time-out,
1623 // but not earlier.
1624 t.now += t.rto_period - 1;
1625 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1626
1627 t.now += 1;
1628 {
1629 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1630 assert_eq!(s.sequence_number(), ctrl.ack_number());
1631 assert_eq!(s.payload_len(), mss);
1632 }
1633 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1634
1635 c_clone = c.clone();
1636
1637 // Triggering another timeout should reset the connection, because t.rto_count_max == 3.
1638 t.now += t.rto_period;
1639 {
1640 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1641 assert!(s.flags_after_ns().intersects(TcpFlags::RST));
1642 assert!(c.is_reset());
1643 }
1644
1645 // Let's undo the reset.
1646 t.now -= t.rto_period;
1647 c = c_clone;
1648
1649 // Also, time-outs should stop happening if we got ACKs for all outgoing segments. This
1650 // ACK also closes the remote receive window so we can't send any new data.
1651 ctrl.set_ack_number(c.first_not_sent.0).set_window_size(0);
1652 assert_eq!(
1653 t.receive_segment(&mut c, &ctrl).unwrap(),
1654 (None, RecvStatusFlags::empty())
1655 );
1656 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1657 t.now += t.rto_period;
1658 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1659
1660 // Let's open the window a bit, to see that the next transmitted segment fits that
1661 // exact size.
1662 ctrl.set_window_size(123);
1663 assert_eq!(
1664 t.receive_segment(&mut c, &ctrl).unwrap(),
1665 (None, RecvStatusFlags::empty())
1666 );
1667 {
1668 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1669 assert_eq!(s.sequence_number(), ctrl.ack_number());
1670 assert_eq!(s.payload_len(), 123);
1671 }
1672 // And let's do one more retransmission timing check.
1673 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1674 t.now += t.rto_period - 1;
1675 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1676 t.now += 1;
1677 {
1678 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1679 assert_eq!(s.sequence_number(), ctrl.ack_number());
1680 assert_eq!(s.payload_len(), 123);
1681 }
1682
1683 // This looks like a good time to check what happens for some invalid ACKs. First, let's
1684 // make sure we properly detect an invalid window_size advertisement (where the remote rwnd
1685 // edge decreases compared to previously received info).
1686 ctrl.set_window_size(100);
1687 assert_eq!(
1688 t.receive_segment(&mut c, &ctrl).unwrap(),
1689 (
1690 None,
1691 RecvStatusFlags::DUP_ACK | RecvStatusFlags::REMOTE_RWND_EDGE
1692 )
1693 );
1694 // Let's clear the DUP_ACK related state.
1695 c.dup_ack = false;
1696
1697 // Now let try some invalid ACKs. This one is an older ACK.
1698 ctrl.set_ack_number(c.highest_ack_received.0.wrapping_sub(1));
1699 assert_eq!(
1700 t.receive_segment(&mut c, &ctrl).unwrap(),
1701 (None, RecvStatusFlags::INVALID_ACK)
1702 );
1703
1704 // Another example of invalid ACK is one that tries to acknowledge a sequence number yet
1705 // to be sent.
1706 ctrl.set_ack_number(c.first_not_sent.0.wrapping_add(1));
1707 assert_eq!(
1708 t.receive_segment(&mut c, &ctrl).unwrap(),
1709 (None, RecvStatusFlags::INVALID_ACK)
1710 );
1711
1712 // FIN time! As usual let's begin with receiving an invalid FIN, one that does not match
1713 // the sequence number we expect.
1714 ctrl.set_flags_after_ns(TcpFlags::FIN)
1715 .set_sequence_number(c.ack_to_send.0.wrapping_sub(1));
1716 assert_eq!(
1717 t.receive_segment(&mut c, &ctrl).unwrap(),
1718 (None, RecvStatusFlags::INVALID_FIN)
1719 );
1720
1721 // Ok now let's use a valid FIN.
1722 ctrl.set_sequence_number(c.ack_to_send.0);
1723 assert_eq!(
1724 t.receive_segment(&mut c, &ctrl).unwrap(),
1725 (None, RecvStatusFlags::empty())
1726 );
1727 check_fin_received_but_not_sent(&c);
1728
1729 // The next segment right now should be a pure ACK for the FIN.
1730 {
1731 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1732 check_control_segment(&s, 0, TcpFlags::ACK);
1733 assert_eq!(s.ack_number(), ctrl.sequence_number().wrapping_add(1),);
1734 }
1735
1736 // Receiving data after the FIN is an error. We increase the rwnd edge for c, because the
1737 // window was full after the earlier reception tests.
1738 c.advance_local_rwnd_edge(10_000);
1739 // We'll also get the INVALID_ACK RecvStausFlag here because the ACK number is old.
1740 data.set_sequence_number(c.ack_to_send.0);
1741 assert_eq!(
1742 t.receive_segment(&mut c, &data).unwrap(),
1743 (
1744 None,
1745 RecvStatusFlags::DATA_BEYOND_FIN | RecvStatusFlags::INVALID_ACK
1746 )
1747 );
1748
1749 assert!(t.write_next_segment(&mut c, payload_src).unwrap().is_none());
1750
1751 // c = c_clone.clone();
1752
1753 // We change payload_src to only include those parts of send_buf that were already sent,
1754 // so it makes sense to close the connection as if we're done transmitting data.
1755 let bytes_sent_by_c = c.first_not_sent.0.wrapping_sub(conn_isn + 1) as usize;
1756 payload_src.as_mut().unwrap().0 = &send_buf[..bytes_sent_by_c];
1757
1758 // We artifically increase the remote rwnd for c, so we can verify we sent everything, and
1759 // we're not just rwnd bound. We also make it so everything is ACKed, so we can sent a FIN
1760 // right after calling close() below (this is needed because we didn't ACK the last
1761 // segment sent by c).
1762 c.remote_rwnd_edge += Wrapping(50_000);
1763 c.highest_ack_received = c.first_not_sent;
1764
1765 // Save the state.
1766 // c_clone = c.clone();
1767
1768 // Close the connection.
1769 c.close();
1770
1771 // We shouldn't be done yet. Even though we got a FIN, we didn't send our own yet.
1772 assert!(!c.is_done());
1773
1774 // If we call write_next at this point, the next outgoing segment should be a pure FIN/ACK.
1775 {
1776 let s = t.write_next_segment(&mut c, payload_src).unwrap().unwrap();
1777 check_control_segment(&s, 0, TcpFlags::FIN | TcpFlags::ACK);
1778 assert_eq!(
1779 s.sequence_number(),
1780 conn_isn.wrapping_add(1 + u32::try_from(bytes_sent_by_c).unwrap())
1781 );
1782 }
1783
1784 // At this point, the connection should be done, because we both sent and received a FIN,
1785 // and we don't wait for our FIN to be ACKed.
1786 assert!(c.is_done());
1787 }
1788}