RE: Sending empty segment upon receiving partial ACK

From: Scheffenegger, Richard <Richard.Scheffenegger_at_netapp.com>
Date: Sun, 16 Mar 2025 07:06:10 UTC
Yes - it may be possible to remove the ACKNOW flag;  The FreeBSD stack has that behavior (sending empty ACKs) in various cases during loss recovery, retransmissions though, so it is not limited to PRR. 

When initially implementing PRR I used other loss recovery codepaths as scaffolding, and that's probably why the ACKNOW is still in there.


Richard Scheffenegger
Senior Solution Architect
NAS & Networking

NetApp
+43 1 3676 811 3157 Direct Phone
+43 664 8866 1857 Mobile Phone
Richard.Scheffenegger@netapp.com


-----Original Message-----
From: owner-freebsd-net@FreeBSD.org <owner-freebsd-net@FreeBSD.org> On Behalf Of jaeyong yoo
Sent: Mittwoch, 19. Februar 2025 00:12
To: freebsd-net@freebsd.org
Subject: Sending empty segment upon receiving partial ACK

[Sie erhalten nicht häufig E-Mails von y.jaeyong@gmail.com. Weitere Informationen, warum dies wichtig ist, finden Sie unter https://aka.ms/LearnAboutSenderIdentification ]

EXTERNAL EMAIL - USE CAUTION when clicking links or attachments




Hi freebsd-net,

I am observing somewhat strange pcap behavior.
Scenario:
   A --> B
A is the only sender of the data and B is the only receiver. Note that we use PRR.
When B is sending partial ACKs to A, there are cases when A sends out just an empty segment with the same sequence number to B. Which seems to be pure overhead.

After digging through the code, I think this could be triggered by the following sequence:

1. https://urldefense.com/v3/__https://github.com/freebsd/freebsd-src/blob/main/sys/netinet/tcp_input.c*L2892__;Iw!!Nhn8V6BzJA!WM32oNanemi8Gf4F5Tc0D4GS8cYXuQEbRH9qrKnSgt2VnUMbwkPJJ0N-p0RuifaZryRFAVXjavn-tkAYEVnLMGWdc1s$
during prr-partial ack processing, it calls tcp_output with ACKNOW flag.

2.https://urldefense.com/v3/__https://github.com/freebsd/freebsd-src/blob/main/sys/netinet/tcp_output.c*L415__;Iw!!Nhn8V6BzJA!WM32oNanemi8Gf4F5Tc0D4GS8cYXuQEbRH9qrKnSgt2VnUMbwkPJJ0N-p0RuifaZryRFAVXjavn-tkAYEVnLuyuyDvs$
in tcp_output, it determines "len" how much to send and when ACKed bytes in partial ack is small enough, this "len" becomes zero.

3. https://urldefense.com/v3/__https://github.com/freebsd/freebsd-src/blob/main/sys/netinet/tcp_output.c*L702__;Iw!!Nhn8V6BzJA!WM32oNanemi8Gf4F5Tc0D4GS8cYXuQEbRH9qrKnSgt2VnUMbwkPJJ0N-p0RuifaZryRFAVXjavn-tkAYEVnL6dNE6CQ$
As the flag is set to "ACKNOW", with zero length, it anyway sends out a segment with 0 length.

My question is, is there some check before sending out like checking if the length is zero?


Thanks,
Jaeyong