TCP stack: same TCP remote host is being used on every power up

shaanktn wrote on Thursday, January 04, 2018:

Hi All,

Could any one please suggest how to remember old TCP bounded tcp local port number list.

Scenario: 1. STM cortex using FreeRTOS stack as a mater established a successfull connection with exchanging data with PC software slave with local host port number setted to 0xC085,

Scenario 2: Power OFF and ON the Master which is a cortex.

Scernario 3 : Now Our Cortex tries to connect with PC with same previous local host number which is again 0xC085 but as far PC concernit had already established connection, then rejects the SYNC, and as a result our stack does not connect again,

Is there is any way to remember in TCP port bounded listed , so that the master can initaite with a new 0xC086 as a local host TCP port?

Do we have any FreeRTOS config , i have tried MACRO , but fails

kenchang1 wrote on Thursday, January 04, 2018:

After scenario 3 your STM cortec can send a RST packet to close the PC connection at port 0xC085. After that the cortex can reconnect to port 0xC085.
Or you can use random local ports, like this: xBindAddress.sin_port = 0; // Use random port number

Are you maybe facing this issue?

Best regards,

heinbali01 wrote on Thursday, January 04, 2018:

I think that Ken gave you the exact answer. In the mentioned post you will find a fix for this, which is not yet included in the public release of FreeRTOS+TCP.
But I will always keep on repeating: please provide a randomise function ipconfigRAND32(), that returns a random number after start-up. Try to find a seed that is random.
It is a bad behaviour if a device reboots and comes up with the same port numbers, and the same initial sequence numbers. This is causing a security issue.

shaanktn wrote on Friday, January 05, 2018:

Thanks for rply,
i have tried the above patch with using
#define ipconfigRAND32() rand()

Still i am seeing the same issue frequently.

i have attached snap shot of wireshark tace, there is a TCP ACKed unseen segment from the slave whose ip is and cortex as a master whose IP is

As we can see to reinitiate a new SYN tcp packet it takes nearly 20 sec, which makes the communication halts for every power up,

kenchang1 wrote on Friday, January 05, 2018:

This is my analysis:
Packet 92: tries to connect
Packet 93: send an ACK because of old half open connection
Packet 94: sends RST to close this old half open connection. SEQ = ACK from packet 93.
Packet 229: tries to connect (this time successful) again after 20 seconds? I don’t see why it would take 20 seconds to reconnect. Your cortex can send SYN directly after packet 94. Is your application blocking everything for 20 seconds?
You have to implement it in your application to connect again after the first failed attempt. In your SW, check the return status of FreeRTOS_connect(). If it is not 0 or -pdFREERTOS_ERRNO_EISCONN, call FreeRTOS_connect() again.


heinbali01 wrote on Friday, January 05, 2018:

I totally agree with Ken’s post.
And beside that, I wrote: “Try to find a seed that is random”. This means that if you are using rand(), you will have to call srand(value) at start-up with a random value.
If not, the rand() function will start with the same value, every time when the device has rebooted.

shaanktn wrote on Tuesday, January 09, 2018:

Hi Hein,
After setting this value still we are seeing disconnect and reusing previous tcp local port with a new SYN with a delay of 20 sec.
with srand (0xc035) i taken an example still it uses same tcp local port on power cycle.

heinbali01 wrote on Tuesday, January 09, 2018:

Hi Shaank, would it be possible that you run WireShark while testing? You can enter a filter like e.g. ip.addr== to keep the number of records small. Could you run WireShark for a couple of minutes and post the resulting .PCAPNG or a .PCAP here?

About the randomiser, you will find these defines in your FreeRTOSIPConfig.h :

extern void vSRand( UBaseType_t ulSeed );
extern UBaseType_t uxRand( void );
#define ipconfigRAND32()    uxRand()

Before starting the IP-stack, you must make sure that vSRand() is called with a random number. This number must be different for every restart.

In STM32F projects, I use the Random Number Generator (RNG) for this:

    /* Enable the clock for the RNG. */
    /* Set the Instance pointer. */
    hrng.Instance = RNG;
    /* Initialise it. */
    HAL_RNG_Init( &hrng );
    /* Get a random number. */
    HAL_RNG_GenerateRandomNumber( &hrng, &ulSeed );
    /* And pass it to the rand() function. */
    vSRand( ulSeed );

Of course it is possible to use the standard rand() function:

#include <stdlib.h>     /* srand, rand */
#define ipconfigRAND32()    rand()

but as rand() probably returns a random value smaller than 32-bits (15-bits I think), I would not use it directly.