Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

+TCP - How force a close on a TCP connection on a Remote Server

Posted by joehinkle on August 20, 2016

I have a window's based TCP server that communicates with my +TCP embedded application.

My app comes out of reset and attampts to make a connection with the Window's based server.

Upon connection, data is passed back and forth.

ISSUE: If the connection is made and then the app does a reset -- the app attempts to make a connection with the server again. +TCP gives the same port to the app as in the first connection. The server still has an open connection based on that port number but my app is trying to start a new one.

The RED wireshark line below shows the connection mismatch. This issue of not connecting will continue forever.

I suspect it is the use of the same port number that +TCP assigns to the connection that causes the server to think it was the original connection and not a new one being started.

Looking at the Wireshark data, +TCP replies with a RST, ACK to the server's ACK.

+TCP is not using the same SEQ that the server provided in the ACK for the RST reply. Is that why the server is ignoring the RST and keeps the connection open?

pcap file attached

Thanks for any insight.

Joe


+TCP - How force a close on a TCP connection on a Remote Server

Posted by rtel on August 20, 2016

Hi Joe,

If you look in FreeRTOS_Sockets.c, you will find the implementation of prvGetPrivatePortNumber(), and there is a comment in the function "This needs to be randomised" [at least, you will see the comment if you are using the head revision code rather than the last release code].

The function provides port numbers between socketAUTOPORTALLOCATIONSTARTNUMBER and socketAUTOPORTALLOCATIONMAXNUMBER, with the first call always returning port number socketAUTOPORTALLOCATIONSTARTNUMBER.

You can update this function, and we can do here as well, so that on the first call it instead chooses a random number between socketAUTOPORTALLOCATIONSTARTNUMBER and socketAUTOPORTALLOCATIONSTARTNUMBER.

Attachments

Reset_Connect.pcap (1802 bytes)

+TCP - How force a close on a TCP connection on a Remote Server

Posted by joehinkle on August 20, 2016

Thanks, I'll do that.

TCP question.

If +TCP had replied with the Server's SEQ instead of it's connection SEQ -- would THAT have terminated the connection?

If +TCP receives an out of sequence ACK -- why not reply to the same SEQ?

The port number change will fix my issue with not connecting, but the server will still have a connection that has to time out. I just wondering if the RST ACK reply was returned with the server's SEQ if that would fix everything?

Just asking -- Hoping I don't have to dig into the RFC to see.

Thanks.

Attachments

Reset_Connect.pcap (1802 bytes)

+TCP - How force a close on a TCP connection on a Remote Server

Posted by heinbali01 on August 20, 2016

If +TCP had replied with the Server's SEQ instead of it's connection SEQ -- would THAT have terminated the connection?

Tomorrow when I'm not tired I will look at your questions again.

But when a RST is sent, the actual ACK and SEQ numbers do no matter.

A TCP connection is identified by 4 "numbers" : source IP address + port number, and the target IP address and port number. If a sending host receives a RST matching with these 4 numbers, the socket owner must see an error like ECONNRESET

Applications like browsers on any OS will surely behave correctly in this respect.

The correct way to actively shutdown a +TCP connection is as follows:

~~~~ FreeRTOSshutdown( xSocket ); for( ;; ) { xResult = FreeRTOSrecv( xSocket, ucBuffer, sizeof( ucBuffer ), 0 ); if( ( xResult < 0 ) && ( xResult != -pdFREERTOSERRNOEWOULDBLOCK ) ) { FreeRTOS_closesocket( xSocket ); xSocket = NULL; break; } } ~~~~

Regards.

Attachments

Reset_Connect.pcap (1802 bytes)

+TCP - How force a close on a TCP connection on a Remote Server

Posted by rtel on August 21, 2016

Correction! My post here https://sourceforge.net/p/freertos/discussion/382005/thread/794f3d82/#3cf0/39ac was not accurate. The first port number used is already a randomly selected port number between socketAUTOPORTALLOCATIONSTARTNUMBER and socketAUTOPORTALLOCATIONENDNUMBER. This is because FreeRTOS_IPInit() calls vNetworkSocketsInit(), and vNetworkSocketsInit() uses ipconfigRAND32() to randomise the first private port number used. This does however rely on ipconfigRAND32() operating correctly. If you do not define ipconfigRAND32() in FreeRTOSIPConfig.h it will get defaulted to just calling the rand() function provided by your C run time library - but you need to call srand() with appropriate entropy to seed the random number.

Attachments

Reset_Connect.pcap (1802 bytes)

+TCP - How force a close on a TCP connection on a Remote Server

Posted by joehinkle on August 21, 2016

I implemented rand() for ipconfigRAND32() but had not set srand().

I've used an "un-used" ADC channel to acquire a seed for srand() prior to starting the IP thread.

Thanks for your reply

Attachments

Reset_Connect.pcap (1802 bytes)

+TCP - How force a close on a TCP connection on a Remote Server

Posted by kenchang1 on November 10, 2017

I have encountered this issue too. The usage of random ports is a workaround, but the real solution is described in the RFC793 page 34, figure 10. In this case the SEQ number of the RST packet does matter. It has to be equal to the ACK number of the server's reply. If you do that the server will close it's connection and FreeRTOS+TCP can connect (with the same local port) to that remote port again in the next connect attempt.

So, this is my fix in the +TCP stack: In file FreeRTOSTCPIP.c, line 2335, function prvHandleSynReceived(), I have added 1 line of code: pxTCPWindow->ulOurSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );

This seems to work, the server will close it's connection and I can connect to it again. Please let me know whether this is the right way to fix it. Could there be side effects? Because ulOurSequenceNumber has suddenly changed?

Addtional comment: Line 2332: pxTCPHeader->ucTCPFlags |= ipTCP_FLAG_RST; should be pxTCPHeader->ucTCPFlags = ipTCP_FLAG_RST; Correct?

regards, Ken

Attachments

Reset_Connect.pcap (1802 bytes)

+TCP - How force a close on a TCP connection on a Remote Server

Posted by heinbali01 on November 10, 2017

Ken, thank you very much for noticing and reporting this!

Here below is a patch that sets both the Sequence and the ACK number as expected by the host ( other RST packets are being sent with the correct values. In those cases the SEQ and ACK are just swapped ).

In FreeRTOS_TCP_IP.c, in function prvHandleSynReceived(), around line 2331 :

~~~ FreeRTOSdebugprintf( ( "%s: flags %04X expected, not %04Xn", pxSocket->u.xTCP.ucTCPState == eSYNRECEIVED ? "eSYNRECEIVED" : "eCONNECTSYN", usExpect, ucTCPFlags ) ); vTCPStateChange( pxSocket, eCLOSEWAIT ); + + /* Send RST with the expected sequence numbers, otherwise it will be ignored. */ + pxTCPWindow->ulOurSequenceNumber = FreeRTOShtonl( pxTCPHeader->ulAckNr ); + pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber; + - pxTCPHeader->ucTCPFlags |= ipTCPFLAGRST; + pxTCPHeader->ucTCPFlags = ipTCPFLAGRST; xSendLength = ( BaseTypet ) ( ipSIZEOFIPv4HEADER + ipSIZEOFTCPHEADER + uxOptionsLength ); pxTCPHeader->ucTCPOffset = ( uint8t )( ( ipSIZEOFTCPHEADER + uxOptionsLength ) << 2 ); ~~~

Still I would like to urge users to use a random value for srand(), especially while you are testing, experimenting, and doing many reboots.

But with the patch here above, it will be easier to detect the problem: the socket will get the eCLOSE_WAIT status much quicker.

Thanks again.

Attachments

Reset_Connect.pcap (1802 bytes)


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS