Socket binding issue

shaanktn wrote on Monday, March 18, 2019:

Hi,
I have set up TCP connection with a particular port number set. A client will be running on host PC and will be contineously taking the data from my device with RTOS.
When I contineously power cycle the client, on some power up the server socket is not able to bind to the port(don’t see any issue in normal). What I observed is it fails with ‘address in use’ state for bind request.
Power cycle makes the port/socket to be closed first and then create and bind. No matter how many times I try to bind, it gives same error until I power cycle the device.
It looks similar to ( https://www.freertos.org/FreeRTOS_Support_Forum_Archive/August_2016/freertos_Race_condition_in_socket_closing_address_binding_DHCP_5850be38j.html ) and I tried the tips given there but it is not helpful. I have a multi threaded system, with separate thread doing these ethernet activities apart from EMAC and IP task.

Thanks,
Shaank.

heinbali01 wrote on Monday, March 18, 2019:

I have set up TCP connection with a particular port number set.
A client will be running on host PC…

Do I understand correctly, that you have a TCP server running under FreeRTOS+TCP, which is bound to a well-known port number?
And is it correct that a client runs from a PC, and it connects to that wel-known port number?
I assume that the client TCP socket binds itself to an anonymous port number (0)?

When I continuously power cycle the client

Here I get lost. Do you continuously reset/reboot your PC here? Then why would it have a problem binding to port 0?

on some power up the server socket is not able to bind to the port

Getting more lost: you talk about a “power up” of the PC. The server socket has already been bound on your FreeRTOS device, or not? So why can it not bind to its server port?

(don’t see any issue in normal). What I observed is it fails with ‘address in use’ state for bind request.

Is the PC complaining here, or is it FreeRTOS+TCP complaining?
The ‘address in use’ response normally has a good and traceable reason :slight_smile:

Power cycle makes the port/socket to be closed first and then create and bind.
No matter how many times I try to bind, it gives same error until I power cycle the device.

Again not clear: “Power cycle” what device?
And what do you mean with “Power cycle”, a cold or warm reboot? Or less than that, maybe just some reset?

I have a multi threaded system, with separate thread doing these
Ethernet activities apart from EMAC and IP task.

Where do you have a “multi threaded system”? On your PC, or within FreeRTOS?

In a PC (Linux/Windows/etc) it can very well happen that you close a socket, and that in fact it continues to exist. That happens when the socket still has a connection with the outside world. When the peer is not responding, this state may last a long time.
So, on a PC, it may happen that you can not bind a socket to a port because an earlier socket is still bound to that port ( invisibly ).

FreeRTOS+TCP is more transparent: once you have called FreeRTOS_closesocket() for a socket, all resources will be freed, and the port number will become available immediately.

shaanktn wrote on Tuesday, March 19, 2019:

Hey Hein,
Sorry for the confusing statements,
FreeRTOS+TCP is on my device and I bind created socket to a particular port say 502 and this will be the server. Client socket(third party application running on windows PC) will connet to this server on RTOS device, once the connection is established there will be contineous data transfer.
PC application is never turned off and I just power cycle the RTOS device. When I do power cycle which means cold reboot, the socket create-bind-listen will happen again on my RTOS device.
Multiple threads are on RTOS platform and the address in use is seen on RTOS side while binding. It is not seen on every power cycle, I do see the issue randomly say in 1/20 power cycles.
I definitely tried closing the socket when the bind is not successful, FreeRTOS_closesocket returns no error but when I try to bind again, it will pop up same error(I will be binding to the same port 502).
Let me know if I am missing some information.
Thanks,

heinbali01 wrote on Tuesday, March 19, 2019:

Thanks you, now it is clear to me.

Can you confirm that this logging statement is triggered in FreeRTOS_Socket.c, around line 1020:

    FreeRTOS_debug_printf( ( "vSocketBind: %sP port %d in use\n",
        pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP ? "TC" : "UD",
        FreeRTOS_ntohs( pxAddress->sin_port ) ) );
    xReturn = -pdFREERTOS_ERRNO_EADDRINUSE;

In your case, it would print ‘vSocketBind: TCP port 502 in use’

When the application gets here, I’d say there must have been an earlier call to FreeRTOS_bind(), binding a TCP socket to port 502. And if not, it looks like xBoundTCPSocketsList is corrupted.
Can you make some logging about all calls to FreeRTOS_bind()?

This is another location where EADDRNOTAVAIL is returned:

    xReturn = -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
    FreeRTOS_debug_printf( ( "vSocketBind: Socket no addr\n" ) );

Sure it doesn’t get there?

Note also that you can define socketAUTO_PORT_ALLOCATION_START_NUMBER in your FreeRTOSIPConfig.h, it defaults to 1024

    #define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0x0400 )

I would recommend choosing your server port numbers under this value, under 1024. Port 502 would be OK.

Another thing is about vApplicationIPNetworkEventHook(): the application hook is called when there is a change in the network status:

void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
    /* If the network has just come up...*/
    if( eNetworkEvent == eNetworkUp )
    {
        /* Create the tasks that use the IP stack if they have not already been
        created. */
        if( xTasksAlreadyCreated == pdFALSE )
        {
			/* Create tasks, and/or set a trigger to create sockets. */
			xCreateSockets = pdTRUE;
			xTasksAlreadyCreated = pdTRUE;
        }
    }
}

As socket and tasks must be created only once, it is important to use a variable like xTasksAlreadyCreated, which will be set to true.

It is important not to call FreeRTOS+TCP API’s from within the application hook, because the code is running from within the IP-task. The IP-task may not call many of it’s own API’s.

shaanktn wrote on Tuesday, March 19, 2019:

Hi Hein,
Thanks for the feedback.
Yes, I am getting it from “vSocketBind: TCP port 502 in use” which you have mentioned first not the second one. It is not triggering “pdFREERTOS_ERRNO_EADDRNOTAVAIL”. I don’t get the error response like “already bound” either.
Considering multiple calls to bind, yes if the bind is not successful then will try to bind it again. So if the second call to bind says “address is in use” then close that socket and repeating the create-bind sequence should be proper right ? but for me next bind will give the same address in use response.
socketAUTO_PORT_ALLOCATION_START_NUMBER got the default value as 0xC000 so 502 is below that and I got no issue with that right ?
And with vApplicationIPNetworkEventHook(), it is called initially for network up and nothing from my end is done inside that function. I did not see any xCreateSockets flag in my code base(using 160919 code base). Are you suggesting me to create some flag like that ?
Regarding ‘xBoundTCPSocketsList’ corruption, this takes list of only server sockets or even the client sockets? I mean if I create another client socket and connect that socket to some other server from within the same application(some other port) running on RTOS, that works fine even when I see the issue of bind to 502 fails.
Thanks,

heinbali01 wrote on Tuesday, March 19, 2019:

Considering multiple calls to bind, yes if the bind is not successful then will try to bind it again.

In the many years that I use FreeRTOS+TCP my self, I have never see any problem with binding a socket to a port number.
It’s not useful to try binding to the same port number a second time. Something must be wrong in your code.

If you know how to iterate through a List_t, you can list all entries in xBoundTCPSocketsList when you get the error. I would be curious to see that.

Well, here is some code that will go through the list of bound TCP sockets, although not tested yet:

	const ListItem_t *pxIterator;
	const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
	for( pxIterator  = ( const ListItem_t * ) listGET_NEXT( pxEnd );
		 pxIterator != ( const ListItem_t * ) pxEnd;
		 pxIterator  = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
	{
		pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
		/* usLocalPort is in host endian notation. */
		FreeRTOS_printf( ( "Socket bound to %u\n", pxSocket->usLocalPort);
	}

What does this show at the moment you can not bind a socket?

And with vApplicationIPNetworkEventHook(), it is called initially for network
up and nothing from my end is done inside that function.

The purpose of the hook is that it triggers initiating all sockets and network-related tasks.

I did not see any xCreateSockets flag in my code base(using 160919 code base).
Are you suggesting me to create some flag like that ?

Yes I am suggesting that you wait for this hook to be called, and then create and bind all sockets, and start networking.

using 160919 code base

I hope that you did find the latest releases of the kernel and of FreeRTOS+TCP e.g. here.

Regarding xBoundTCPSocketsList corruption, this takes list of only server sockets or even the client sockets?

xBoundTCPSocketsList is a List_t of all TCP bound TCP sockets.

Hi,

Was this ever resolved?

I am having a similar issue where I have a bound socket. Then need to change the IP address and restart my tcp server tasks (based on the tcp echo example code). Couldn’t really find a clean/direct way (APIs to call) for taking down and restarting the network stack.

When I try to restart the tcp stack and listening task (prvConnectionListeningTask), I get the message

vSocketBind: TCP port 55000 in use

in the call to FreeRTOS_bind.

I checked this, but never saw a response
https://forums.freertos.org./t/race-condition-in-socket-closing-address-binding-dhcp/6120

Any help is appreciated.

Thanks

I found out what my issue was, needed to close the listening socket as well as the child socket then restart things.

1 Like