Skip to content

Commit

Permalink
IPv4/Single: Let send() stop blocking after a connection reset (#561)
Browse files Browse the repository at this point in the history
* IPv4/Single: Let send() stop after a protocol error

* Remove token need

* Repaired unit-testing

* Added the cunftion test_FreeRTOS_send_DisconnectionOccursDuringWait()

* Added a comment for unit-test function test_FreeRTOS_send_DisconnectionOccursDuringWait()

* Added an item to lexicon.txt

* Restored original tcp_utilities

* Restored original tcp_utilities, once more

---------

Co-authored-by: Hein Tibosch <hein@htibosch.net>
Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com>
  • Loading branch information
4 people authored May 17, 2023
1 parent f7e07f8 commit d700359
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/lexicon.txt
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ prvtcpprepareconnect
prvtcppreparesend
prvtcpreturnpacket
prvtcpsendchallengeack
prvtcpsendcheck
prvtcpsendpacket
prvtcpsendrepeated
prvtcpsendreset
Expand Down
10 changes: 9 additions & 1 deletion source/FreeRTOS_Sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -3826,8 +3826,16 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t * pxSocket )
( void ) xEventGroupWaitBits( pxSocket->xEventGroup, ( EventBits_t ) eSOCKET_SEND | ( EventBits_t ) eSOCKET_CLOSED,
pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );

xByteCount = ( BaseType_t ) prvTCPSendCheck( pxSocket, uxDataLength );

if( xByteCount < 0 )
{
/* In a meanwhile, the connection has dropped, stop iterating. */
break;
}

xByteCount = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
}
} /* while( ipTRUE_BOOL ) */

/* How much was actually sent? */
xByteCount = ( ( BaseType_t ) uxDataLength ) - xBytesLeft;
Expand Down
44 changes: 44 additions & 0 deletions test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_TCP_API_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ void test_FreeRTOS_send_LessSpaceInStreamBuffer_Timeout( void )
xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
vTaskSetTimeOutState_ExpectAnyArgs();
xEventGroupWaitBits_ExpectAndReturn( xSocket.xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED, pdTRUE, pdFALSE, 100, pdFALSE );
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( &xBoundTCPSocketsList );

/* Second Iteration. No space still. */
uxStreamBufferGetSpace_ExpectAndReturn( xSocket.u.xTCP.txStream, 0 );
Expand Down Expand Up @@ -1026,6 +1027,7 @@ void test_FreeRTOS_send_LessSpaceInStreamBuffer_EventuallySpaceAvailable( void )
xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
vTaskSetTimeOutState_ExpectAnyArgs();
xEventGroupWaitBits_ExpectAndReturn( xSocket.xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED, pdTRUE, pdFALSE, 100, pdFALSE );
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( &xBoundTCPSocketsList );

/* Second Iteration. */
uxStreamBufferGetSpace_ExpectAndReturn( xSocket.u.xTCP.txStream, 20 );
Expand Down Expand Up @@ -1068,6 +1070,7 @@ void test_FreeRTOS_send_MultipleIterationsAndNoSuccess( void )
xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
vTaskSetTimeOutState_ExpectAnyArgs();
xEventGroupWaitBits_ExpectAndReturn( xSocket.xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED, pdTRUE, pdFALSE, 100, pdFALSE );
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( &xBoundTCPSocketsList );

/* Second Iteration. */
uxStreamBufferGetSpace_ExpectAndReturn( xSocket.u.xTCP.txStream, 10 );
Expand All @@ -1078,6 +1081,7 @@ void test_FreeRTOS_send_MultipleIterationsAndNoSuccess( void )
xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdFALSE );

xEventGroupWaitBits_ExpectAndReturn( xSocket.xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED, pdTRUE, pdFALSE, 100, pdFALSE );
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( &xBoundTCPSocketsList );

/* Third iteration. No space still. */
uxStreamBufferGetSpace_ExpectAndReturn( xSocket.u.xTCP.txStream, 0 );
Expand All @@ -1089,6 +1093,46 @@ void test_FreeRTOS_send_MultipleIterationsAndNoSuccess( void )
TEST_ASSERT_EQUAL( uxDataLength - 10, xReturn );
}

/*
* @brief While waiting for space, the socket gets disconnected.
*/
void test_FreeRTOS_send_DisconnectionOccursDuringWait( void )
{
BaseType_t xReturn;
FreeRTOS_Socket_t xSocket;
uint8_t pvBuffer[ ipconfigTCP_MSS ];
size_t uxDataLength;
BaseType_t xFlags = 0;
StreamBuffer_t xLocalStreamBuffer;

memset( &xSocket, 0, sizeof( xSocket ) );
memset( pvBuffer, 0, ipconfigTCP_MSS );

xSocket.ucProtocol = FREERTOS_IPPROTO_TCP;
xSocket.u.xTCP.eTCPState = eESTABLISHED;
xSocket.u.xTCP.bits.bFinSent = pdFALSE_UNSIGNED;
xSocket.u.xTCP.txStream = &xLocalStreamBuffer;
xSocket.xSendBlockTime = 100;

uxDataLength = 100;
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( &xBoundTCPSocketsList );
uxStreamBufferGetSpace_ExpectAndReturn( xSocket.u.xTCP.txStream, uxDataLength - 20 );
uxStreamBufferAdd_ExpectAndReturn( xSocket.u.xTCP.txStream, 0U, pvBuffer, uxDataLength - 20, uxDataLength - 20 );
xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
xSendEventToIPTask_ExpectAndReturn( eTCPTimerEvent, pdFALSE );
xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
vTaskSetTimeOutState_ExpectAnyArgs();
xEventGroupWaitBits_ExpectAndReturn( xSocket.xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED, pdTRUE, pdFALSE, 100, pdFALSE );

/* Let `socketSOCKET_IS_BOUND()` return false, so that prvTCPSendCheck()
* returns en error, so that the loop is stopped. */
listLIST_ITEM_CONTAINER_ExpectAnyArgsAndReturn( NULL );

xReturn = FreeRTOS_send( &xSocket, pvBuffer, uxDataLength, xFlags );

TEST_ASSERT_EQUAL( uxDataLength - 20, xReturn );
}

/*
* @brief IP task is calling send function with a NULL buffer. Also there are 20 bytes worth of space
* less in the stream buffer as the data length.
Expand Down

0 comments on commit d700359

Please sign in to comment.