Menu

#183 FreeRTOS+TCP freezes in bad state if connection is reset during send

v1.0 (example)
open
nobody
None
5
2018-12-10
2018-12-10
No

I first observed this bug during the beta days in 9.0.0, but I've checked the current codebase and the relevant code has not changed.

FreeRTOS_send transmits large amounts of data by means of this core loop:

/* While there are still bytes to be sent. */
while( xBytesLeft > 0 )
{

Before entering this loop, prvTCPSendCheck is called to ensure that the socket is not closed, but this check is not repeated within the body of the loop. This means that if the connection is reset by the peer while in the middle of sending, the loop will never terminate. This in turn causes control not to be returned to the user, potentially frustrating attempts to accept any more connections in the future.

You can test this by loading a simple FreeRTOS application on a device of your choice which accepts incoming connections and then, in the same process, sends some large amount of data to the client. If the client process is terminated before all the data has been received, the application will refuse to accept any more connections until the device is reset.

Ironically, the existing code does already half-solve this problem. Observe the following statement, near the end of the loop body:

xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED,
pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );

It's listening for close notifications so it doesn't get stuck in the wait call, it just fails to act on them!

I suggest fixing this bug by modifying the code to include the following statement after the one above:

if( ( BaseType_t ) prvTCPSendCheck( pxSocket, uxDataLength ) <= 0 )
{
    break;
}

Discussion


Log in to post a comment.

MongoDB Logo MongoDB