Skip to content

Commit d89a9fa

Browse files
authored
Update RX sequence number after refusing TCP FIN packet. (#1195)
Update RX sequence number after refusing TCP FIN packet.
1 parent dd88502 commit d89a9fa

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
lines changed

source/FreeRTOS_TCP_State_Handling.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,8 @@
584584
{
585585
/* Peer is requesting to stop, see if we're really finished. */
586586
xMayClose = pdTRUE;
587+
ulIntermediateResult = ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber;
588+
lDistance = ( int32_t ) ulIntermediateResult;
587589

588590
/* Checks are only necessary if we haven't sent a FIN yet. */
589591
if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
@@ -601,22 +603,28 @@
601603
( int ) bRxComplete,
602604
( int ) bTxDone ) );
603605
xMayClose = pdFALSE;
604-
}
605-
else
606-
{
607-
ulIntermediateResult = ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber;
608-
lDistance = ( int32_t ) ulIntermediateResult;
609606

610-
if( lDistance > 1 )
607+
/* This action is necessary to ensure proper handling of any subsequent packets that
608+
* may arrive after the refused FIN packet. Note that we only update it when the sequence
609+
* of FIN packet is correct. Otherwise, we wait for re-transmission. */
610+
if( lDistance <= 1 )
611611
{
612-
FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %d (cur %u high %u)\n",
613-
( int ) lDistance,
614-
( unsigned ) ( pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ),
615-
( unsigned ) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) ) );
616-
617-
xMayClose = pdFALSE;
612+
pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulFINSequenceNumber + 1U;
618613
}
619614
}
615+
else if( lDistance > 1 )
616+
{
617+
FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %d (cur %u high %u)\n",
618+
( int ) lDistance,
619+
( unsigned ) ( pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ),
620+
( unsigned ) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) ) );
621+
622+
xMayClose = pdFALSE;
623+
}
624+
else
625+
{
626+
/* Empty else marker. */
627+
}
620628
}
621629

622630
if( xTCPWindowLoggingLevel > 0 )

test/Coverity/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Static code analysis for FreeRTOS-Plus-TCP library
22
This directory is made for the purpose of statically testing the MISRA C:2012 compliance of FreeRTOS+TCP using
3-
[Synopsys Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html) static analysis tool.
3+
[Synopsys Coverity](https://www.blackduck.com/static-analysis-tools-sast/coverity.html) static analysis tool.
44
To that end, this directory provides a [CMake](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/test/Coverity/CMakeLists.txt)
55
file and [configuration files](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/tree/main/test/Coverity/ConfigFiles) required to build
66
an application for the tool to analyze.

test/unit-test/FreeRTOS_TCP_State_Handling/FreeRTOS_TCP_State_Handling_utest.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,47 @@ void test_prvHandleEstablished_FINNotSentRXComplete( void )
821821
TEST_ASSERT_EQUAL( 40, xSendLength );
822822
}
823823

824+
/**
825+
* @brief Data left for receiving when receiving TCP packet with FIN/ACK.
826+
*/
827+
void test_prvHandleEstablished_FINNotSentRXNotCompleteNotExpectedSeq( void )
828+
{
829+
BaseType_t xSendLength = 0;
830+
831+
pxSocket = &xSocket;
832+
833+
pxNetworkBuffer = &xNetworkBuffer;
834+
pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer;
835+
836+
/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */
837+
ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * )
838+
&( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) );
839+
TCPHeader_t * pxTCPHeader = &pxProtocolHeaders->xTCPHeader;
840+
TCPWindow_t * pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
841+
842+
ulCalled = 0;
843+
pxTCPHeader->ucTCPFlags = tcpTCP_FLAG_FIN | tcpTCP_FLAG_ACK;
844+
pxTCPHeader->ulSequenceNumber = FreeRTOS_htonl( 1502 );
845+
pxTCPHeader->usWindow = 1000;
846+
pxSocket->u.xTCP.txStream = ( StreamBuffer_t * ) 0x12345678;
847+
pxSocket->u.xTCP.pxHandleSent = NULL;
848+
pxSocket->u.xTCP.bits.bFinSent = pdFALSE;
849+
pxTCPWindow->rx.ulCurrentSequenceNumber = 1500;
850+
851+
uxIPHeaderSizeSocket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
852+
ulTCPWindowTxAck_ExpectAnyArgsAndReturn( 0 );
853+
prvTCPAddTxData_ExpectAnyArgs();
854+
xTCPWindowRxEmpty_ExpectAnyArgsAndReturn( pdFALSE );
855+
xTCPWindowTxDone_ExpectAnyArgsAndReturn( pdTRUE );
856+
prvTCPPrepareSend_ExpectAnyArgsAndReturn( 0 );
857+
858+
xSendLength = prvHandleEstablished( pxSocket,
859+
&pxNetworkBuffer,
860+
0,
861+
0 );
862+
TEST_ASSERT_EQUAL( 0, xSendLength );
863+
}
864+
824865
/**
825866
* @brief Data left for receiving when receiving TCP packet with FIN/ACK.
826867
*/
@@ -846,7 +887,7 @@ void test_prvHandleEstablished_FINNotSentRXNotComplete( void )
846887
pxSocket->u.xTCP.txStream = ( StreamBuffer_t * ) 0x12345678;
847888
pxSocket->u.xTCP.pxHandleSent = NULL;
848889
pxSocket->u.xTCP.bits.bFinSent = pdFALSE;
849-
pxTCPWindow->rx.ulCurrentSequenceNumber = 2501;
890+
pxTCPWindow->rx.ulCurrentSequenceNumber = 1500;
850891

851892
uxIPHeaderSizeSocket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
852893
ulTCPWindowTxAck_ExpectAnyArgsAndReturn( 0 );

0 commit comments

Comments
 (0)