we are using FreeRTOS+TCP V2.4.0 and it’s STM32H7 port.
Our device acts as a TCP server and will answer commands from remote clients with an appropriate response. The client is a terminal program (YAT download | SourceForge.net).
I lately observed, that a shrinking TCP window size caused problems.
Our device uses the default MSS of 1460 bytes. When a command (sent from terminal) triggered a response of 2196 Bytes, the terminal client reduced its window size further and further.
The following wireshark trace shows this, where the FreeRTOS+TCP device is 10.0.32.182 and the terminal is at 10.0.32.142:
The transmission was successful, but sending the same command (see frame #53) to the server (with the same response) permanently bricks the socket. This means, that also smaller responses can’t be sent anymore.
I think there might partly be a problem in the client from the terminal we use, but I also don’t understand the mechanisms in FreeRTOS+TCP. The responses were transmitted with FreeRTOS_send(), which returns values >0, even tho nothing lands on ETH wire.
It seems like the responses can be put into the Tx stream buffers of the socket for some time. I printed the left over space of Tx and Rx buffers of the socket, before calling FreeRTOS_send():
I dug down really deep into the stack, and found that prvTCPSendRepeated() will try send the frames for all these commands. For the mentioned problem, this fails for SEND_REPEATED_COUNT times.
It seems to me like the packets in the Tx queue are never dropped, after all these failed attempts. So subsequent packets, which might fit into the remote TCP window, also can’t get through. Smaller responses are put into the buffer, after the fails:
The workaround I found was either to decrease the MSS from 1460 to a smaller value (800 for example), or to reconnect to the socket.
I’m not too sure if there might be other problems, or if some kind of “clearing” API function call would be required. Is this desired behavior after all?
Thanks and best regards