tcp: Disabling sack does not disable sack completely

When setting ns3::TcpSocketBase::Sack to false, not all sack features seem to be disabled.

For example when using the tcp-variants-comparison with

  • sack=false
  • transport_prot=TcpCubic or transport_prot=TcpNewReno

some packets get (internally) sacked anyways. This causes some problems:

  • almost every second packet is a TCP Spurious Retransmission

Screenshot_from_2024-06-27_23-08-57

  • the congestion control algorithm enters and exits recovery in fast succession, causing the cwnd to drop and stay minimal.

The cc algorithm entering end exiting recovery seems to be caused by sack information:

the tcp-tx-buffer method DiscardUpTotcp-tx-buffer.cc?#L750, checks the new head if it is sacked, finds it sacked, and marks the head as lost. This later causes the tcp congestion control to go into recovery state after a first dup ack tcp-socket-base.cc#L1780. Which in this case leads to TcpCubic entering and exiting recovery in fast succession, causing the cwnd to drop:

tcp-variants-cwnd

plotted are the trace values cwnd, ssthresh, rtt, and CongState. The congestion State is visualised as vertical lines as follows:

  • green: TcpCongState_t:CA_OPEN
  • yellow: TcpCongState_t:CA_DISORDER
  • purple: TcpCongState_t:CA_RECOVERY
  • cyan: TcpCongState_t:CA_LOSS

TcpVariantsComparison-0-1.pcap