Skip to content

Commit

Permalink
Update RX sequence number after refusing TCP FIN packet. (#1195)
Browse files Browse the repository at this point in the history
Update RX sequence number after refusing TCP FIN packet.
  • Loading branch information
ActoryOu authored Oct 7, 2024
1 parent dd88502 commit d89a9fa
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
32 changes: 20 additions & 12 deletions source/FreeRTOS_TCP_State_Handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@
{
/* Peer is requesting to stop, see if we're really finished. */
xMayClose = pdTRUE;
ulIntermediateResult = ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber;
lDistance = ( int32_t ) ulIntermediateResult;

/* Checks are only necessary if we haven't sent a FIN yet. */
if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
Expand All @@ -601,22 +603,28 @@
( int ) bRxComplete,
( int ) bTxDone ) );
xMayClose = pdFALSE;
}
else
{
ulIntermediateResult = ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber;
lDistance = ( int32_t ) ulIntermediateResult;

if( lDistance > 1 )
/* This action is necessary to ensure proper handling of any subsequent packets that
* may arrive after the refused FIN packet. Note that we only update it when the sequence
* of FIN packet is correct. Otherwise, we wait for re-transmission. */
if( lDistance <= 1 )
{
FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %d (cur %u high %u)\n",
( int ) lDistance,
( unsigned ) ( pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ),
( unsigned ) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) ) );

xMayClose = pdFALSE;
pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulFINSequenceNumber + 1U;
}
}
else if( lDistance > 1 )
{
FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %d (cur %u high %u)\n",
( int ) lDistance,
( unsigned ) ( pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ),
( unsigned ) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) ) );

xMayClose = pdFALSE;
}
else
{
/* Empty else marker. */
}
}

if( xTCPWindowLoggingLevel > 0 )
Expand Down
2 changes: 1 addition & 1 deletion test/Coverity/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Static code analysis for FreeRTOS-Plus-TCP library
This directory is made for the purpose of statically testing the MISRA C:2012 compliance of FreeRTOS+TCP using
[Synopsys Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html) static analysis tool.
[Synopsys Coverity](https://www.blackduck.com/static-analysis-tools-sast/coverity.html) static analysis tool.
To that end, this directory provides a [CMake](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/test/Coverity/CMakeLists.txt)
file and [configuration files](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/tree/main/test/Coverity/ConfigFiles) required to build
an application for the tool to analyze.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,47 @@ void test_prvHandleEstablished_FINNotSentRXComplete( void )
TEST_ASSERT_EQUAL( 40, xSendLength );
}

/**
* @brief Data left for receiving when receiving TCP packet with FIN/ACK.
*/
void test_prvHandleEstablished_FINNotSentRXNotCompleteNotExpectedSeq( void )
{
BaseType_t xSendLength = 0;

pxSocket = &xSocket;

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer;

/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */
ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * )
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) );
TCPHeader_t * pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
TCPWindow_t * pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;

ulCalled = 0;
pxTCPHeader->ucTCPFlags = tcpTCP_FLAG_FIN | tcpTCP_FLAG_ACK;
pxTCPHeader->ulSequenceNumber = FreeRTOS_htonl( 1502 );
pxTCPHeader->usWindow = 1000;
pxSocket->u.xTCP.txStream = ( StreamBuffer_t * ) 0x12345678;
pxSocket->u.xTCP.pxHandleSent = NULL;
pxSocket->u.xTCP.bits.bFinSent = pdFALSE;
pxTCPWindow->rx.ulCurrentSequenceNumber = 1500;

uxIPHeaderSizeSocket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
ulTCPWindowTxAck_ExpectAnyArgsAndReturn( 0 );
prvTCPAddTxData_ExpectAnyArgs();
xTCPWindowRxEmpty_ExpectAnyArgsAndReturn( pdFALSE );
xTCPWindowTxDone_ExpectAnyArgsAndReturn( pdTRUE );
prvTCPPrepareSend_ExpectAnyArgsAndReturn( 0 );

xSendLength = prvHandleEstablished( pxSocket,
&pxNetworkBuffer,
0,
0 );
TEST_ASSERT_EQUAL( 0, xSendLength );
}

/**
* @brief Data left for receiving when receiving TCP packet with FIN/ACK.
*/
Expand All @@ -846,7 +887,7 @@ void test_prvHandleEstablished_FINNotSentRXNotComplete( void )
pxSocket->u.xTCP.txStream = ( StreamBuffer_t * ) 0x12345678;
pxSocket->u.xTCP.pxHandleSent = NULL;
pxSocket->u.xTCP.bits.bFinSent = pdFALSE;
pxTCPWindow->rx.ulCurrentSequenceNumber = 2501;
pxTCPWindow->rx.ulCurrentSequenceNumber = 1500;

uxIPHeaderSizeSocket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
ulTCPWindowTxAck_ExpectAnyArgsAndReturn( 0 );
Expand Down

0 comments on commit d89a9fa

Please sign in to comment.