net/tcp(buffered): retransmit only one the earliest not acknowledged segment
Summary
The existing tcp_send_buffered implementation does a full rewind from the most recent sent segment back to the earliest not acknowledged one, thus many TCP segments are re-sent every time when TCP retrasmission timeout occurs.
According to RFC 6298 (5.4) only one the earliest not acknowledged segment should be retransmitted instead.
This PR implements TCP retrasmission according to RFC 6298 (5.4). It is the same issue as it was in tcp_send_unbuffered.c (PR https://github.com/apache/incubator-nuttx/pull/4659) and tcp_sendfile.c (PR https://github.com/apache/incubator-nuttx/pull/5272).
Impact
TCP
Testing
Activate emulating packet loss on Linux host:
$ sudo iptables -A INPUT -p tcp --dport 31337 -m statistic --mode random --probability 0.01 -j DROP
Build NuttX:
$ ./tools/configure.sh -l sim:tcpblaster
$ make menuconfig
(disable CONFIG_NETUTILS_NETCAT_SENDFILE,
enable CONFIG_NET_TCP_WRITE_BUFFERS)
$ make
Enable TUN/TAP on Linux host:
$ sudo setcap cap_net_admin+ep ./nuttx
$ sudo ./tools/simhostroute.sh wlan0 on
Run netcat server on Linux host:
$ netcat -l -p 31337
Run NuttX on Linux host:
$ ./nuttx
NuttShell (NSH) NuttX-10.2.0
nsh> ifconfig eth0 10.0.1.2
nsh> ifup eth0
ifup eth0...OK
Start Wireshark (or tcpdump) and capture appeared tap0 interface.
Run in NuttX:
nsh> dd if=/dev/zero of=/tmp/test.bin count=1000
nsh> netcat LINUX_HOST_IP_ADDRESS 31337 /tmp/test.bin
Observe packet loss -> TCP retransmissions in TCP dump.
Shutdown NuttX:
nsh> poweroff
Disable TUN/TAP on Linux host:
$ sudo ./tools/simhostroute.sh wlan0 off
Deactivate emulating packet loss on Linux host:
$ sudo iptables -D INPUT -p tcp --dport 31337 -m statistic --mode random --probability 0.01 -j DROP