FreeRTOS TCP loop of RST, ACK, RST, ACK when remote connection is closed without FreeRTOS+TCP knowing about it

We captured a problem with our FreeRTOS TCP connection in Wireshark and are hoping you can help us in finding a solution.

The problem starts when the remote connection is closed without FreeRTOS+TCP knowing about it (for example there are network issues/link down event).

  1. FreeRTOS will send a normal TCP message because it thinks the connection is still active.
  2. The remote side has already closed the connection and will respond with a TCP RST message that has a sequence number one higher then what FreeRTOS is expecting.
  3. Because the sequence number is within the TCP window, FreeRTOS responds with an ACK message, to inform the remote side of its current expected sequence number.
  4. The remote side can’t process this ACK because there is no connection and will again send a TCK RST message.

This loop of RST, ACK, RST, ACK, etc. will continue until the FreeRTOS TCP connection goes in to timeout.

We have temporarily fixed the problem by always closing the TCP connection when a RST is received within our TCP window. But we are unsure if this is the correct fix.

We also captured traffic, see attached Wireshark pcap.
FreeRTOS_TCP_RST_loop.zip (15.7 KB)

Is that a similar issue to this here?

FreeRTOS+TCP socket: Long delay before successful reconnect - Libraries - FreeRTOS Community Forums

Hello,

I think correct way to handle this behavior is to use TCP keep alive packets. If keep alive ACK is not received, the stack will resend it 3 times before changing socket TCP state to eCLOSE_WAIT. I think the server will still send RST in response to keep alive packet.

Then you can get current state using FreeRTOS_issocketconnected() and eventually close the socket. Keep alive interval can be modified in FreeRTOSIPConfig.h:

/* Include support for TCP keep-alive messages. */
#define ipconfigTCP_KEEP_ALIVE              ( 1 )
#define ipconfigTCP_KEEP_ALIVE_INTERVAL     ( 30 ) /* in seconds */

Adam

I suppose that you have done the same test while using the latest source code from github?

@nlangenb, were you using the latest release of FreeRTOS+TCP?

Have you found anything new in a meanwhile?

I tried to simulate the problem:

  • Unit 1 connects with unit 2 and exchange data
  • Unit 2 just closes the socket without shutting it down
  • Unit 1 continues to send but receives a RST packet

My result was good: Unit 1 accepted the RST packet and also closed the connection.
Now both units were running FreeRTOS+TCP, I will replace “Unit 2” with my laptop and see how that works. One difficulty: Windows will probably try to gracefully close TCP connections.

Here is the PCAP that I made: tcp_test_hein.zip (2.2 KB)

EDIT
When the TCP server is running on Windows, there is no problem neither: tcp_test_hein_windows.zip (11.6 KB)
This is done between an STM32F7 and a Windows 10 laptop.