summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c')
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c398
1 files changed, 216 insertions, 182 deletions
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
index 5eee18917..d26756589 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.0.11
+ * FreeRTOS+TCP V2.2.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@@ -228,6 +228,19 @@ static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket );
static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
/*
+ * Identify and deal with a single TCP header option, advancing the pointer to
+ * the header. This function returns pdTRUE or pdFALSE depending on whether the
+ * caller should continue to parse more header options or break the loop.
+ */
+static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow);
+
+/*
+ * Skip past TCP header options when doing Selective ACK, until there are no
+ * more options left.
+ */
+static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const ppucLen );
+
+/*
* Set the initial properties in the options fields, like the preferred
* value of MSS and whether SACK allowed. Will be transmitted in the state
* 'eCONNECT_SYN'.
@@ -312,7 +325,7 @@ static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferD
* payload, just flags).
*/
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
- uint8_t ucTCPFlags );
+ uint8_t ucTCPFlags );
/*
* A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
@@ -1151,7 +1164,7 @@ TCPHeader_t * pxTCPHeader;
const unsigned char *pucPtr;
const unsigned char *pucLast;
TCPWindow_t *pxTCPWindow;
-UBaseType_t uxNewMSS;
+BaseType_t xShouldContinueLoop;
pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
pxTCPHeader = &pxTCPPacket->xTCPHeader;
@@ -1169,162 +1182,184 @@ UBaseType_t uxNewMSS;
/* The comparison with pucLast is only necessary in case the option data are
corrupted, we don't like to run into invalid memory and crash. */
- while( pucPtr < pucLast )
+ xShouldContinueLoop = pdTRUE;
+ while( ( pucPtr < pucLast ) && ( xShouldContinueLoop == pdTRUE ) )
{
- UBaseType_t xRemainingOptionsBytes = pucLast - pucPtr;
+ xShouldContinueLoop = prvSingleStepTCPHeaderOptions( &pucPtr, &pucLast, &pxSocket, &pxTCPWindow );
+ }
+}
- if( pucPtr[ 0 ] == TCP_OPT_END )
- {
- /* End of options. */
- break;
- }
- if( pucPtr[ 0 ] == TCP_OPT_NOOP)
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow)
+{
+ UBaseType_t uxNewMSS;
+ UBaseType_t xRemainingOptionsBytes = ( *ppucLast ) - ( *ppucPtr );
+ unsigned char ucLen;
+
+ if( ( *ppucPtr )[ 0 ] == TCP_OPT_END )
+ {
+ /* End of options. */
+ return pdFALSE;
+ }
+ if( ( *ppucPtr )[ 0 ] == TCP_OPT_NOOP)
+ {
+ /* NOP option, inserted to make the length a multiple of 4. */
+ ( *ppucPtr )++;
+ return pdTRUE;
+ }
+
+ /* Any other well-formed option must be at least two bytes: the option
+ type byte followed by a length byte. */
+ if( xRemainingOptionsBytes < 2 )
+ {
+ return pdFALSE;
+ }
+#if( ipconfigUSE_TCP_WIN != 0 )
+ else if( ( *ppucPtr )[ 0 ] == TCP_OPT_WSOPT )
+ {
+ /* Confirm that the option fits in the remaining buffer space. */
+ if( ( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ) || ( ( *ppucPtr )[ 1 ] != TCP_OPT_WSOPT_LEN ) )
{
- /* NOP option, inserted to make the length a multiple of 4. */
- pucPtr++;
- continue;
+ return pdFALSE;
}
- /* Any other well-formed option must be at least two bytes: the option
- type byte followed by a length byte. */
- if( xRemainingOptionsBytes < 2 )
+ ( *ppxSocket )->u.xTCP.ucPeerWinScaleFactor = ( *ppucPtr )[ 2 ];
+ ( *ppxSocket )->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
+ ( *ppucPtr ) += TCP_OPT_WSOPT_LEN;
+ }
+#endif /* ipconfigUSE_TCP_WIN */
+ else if( ( *ppucPtr )[ 0 ] == TCP_OPT_MSS )
+ {
+ /* Confirm that the option fits in the remaining buffer space. */
+ if( ( xRemainingOptionsBytes < TCP_OPT_MSS_LEN )|| ( ( *ppucPtr )[ 1 ] != TCP_OPT_MSS_LEN ) )
{
- break;
+ return pdFALSE;
}
-#if( ipconfigUSE_TCP_WIN != 0 )
- else if( pucPtr[ 0 ] == TCP_OPT_WSOPT )
+
+ /* An MSS option with the correct option length. FreeRTOS_htons()
+ is not needed here because usChar2u16() already returns a host
+ endian number. */
+ uxNewMSS = usChar2u16( ( *ppucPtr ) + 2 );
+
+ if( ( *ppxSocket )->u.xTCP.usInitMSS != uxNewMSS )
{
- /* Confirm that the option fits in the remaining buffer space. */
- if( ( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ) || ( pucPtr[ 1 ] != TCP_OPT_WSOPT_LEN ) )
+ /* Perform a basic check on the the new MSS. */
+ if( uxNewMSS == 0 )
{
- break;
+ return pdFALSE;
}
- pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ];
- pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
- pucPtr += TCP_OPT_WSOPT_LEN;
+ FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", ( *ppxSocket )->u.xTCP.usInitMSS, uxNewMSS ) );
}
-#endif /* ipconfigUSE_TCP_WIN */
- else if( pucPtr[ 0 ] == TCP_OPT_MSS )
+
+ if( ( *ppxSocket )->u.xTCP.usInitMSS > uxNewMSS )
{
- /* Confirm that the option fits in the remaining buffer space. */
- if( ( xRemainingOptionsBytes < TCP_OPT_MSS_LEN )|| ( pucPtr[ 1 ] != TCP_OPT_MSS_LEN ) )
+ /* our MSS was bigger than the MSS of the other party: adapt it. */
+ ( *ppxSocket )->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED;
+ if( ( ( *ppxTCPWindow ) != NULL ) && ( ( *ppxSocket )->u.xTCP.usCurMSS > uxNewMSS ) )
{
- break;
+ /* The peer advertises a smaller MSS than this socket was
+ using. Use that as well. */
+ FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", ( *ppxSocket )->u.xTCP.usCurMSS, uxNewMSS ) );
+ ( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
}
+ ( *ppxTCPWindow )->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( ( *ppxTCPWindow )->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) );
+ ( *ppxTCPWindow )->usMSSInit = ( uint16_t ) uxNewMSS;
+ ( *ppxTCPWindow )->usMSS = ( uint16_t ) uxNewMSS;
+ ( *ppxSocket )->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS;
+ ( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
+ }
- /* An MSS option with the correct option length. FreeRTOS_htons()
- is not needed here because usChar2u16() already returns a host
- endian number. */
- uxNewMSS = usChar2u16( pucPtr + 2 );
+ #if( ipconfigUSE_TCP_WIN != 1 )
+ /* Without scaled windows, MSS is the only interesting option. */
+ return pdFALSE;
+ #else
+ /* Or else we continue to check another option: selective ACK. */
+ ( *ppucPtr ) += TCP_OPT_MSS_LEN;
+ #endif /* ipconfigUSE_TCP_WIN != 1 */
+ }
+ else
+ {
+ /* All other options have a length field, so that we easily
+ can skip past them. */
+ ucLen = ( *ppucPtr )[ 1 ];
+ if( ( ucLen < 2 ) || ( ucLen > xRemainingOptionsBytes ) )
+ {
+ /* If the length field is too small or too big, the options are
+ * malformed, don't process them further.
+ */
+ return pdFALSE;
+ }
- if( pxSocket->u.xTCP.usInitMSS != uxNewMSS )
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ /* Selective ACK: the peer has received a packet but it is missing
+ * earlier packets. At least this packet does not need retransmission
+ * anymore. ulTCPWindowTxSack( ) takes care of this administration.
+ */
+ if( ( *ppucPtr )[0] == TCP_OPT_SACK_A )
{
- /* Perform a basic check on the the new MSS. */
- if( uxNewMSS == 0 )
- {
- break;
- }
-
- FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) );
- }
+ ucLen -= 2;
+ ( *ppucPtr ) += 2;
- if( pxSocket->u.xTCP.usInitMSS > uxNewMSS )
- {
- /* our MSS was bigger than the MSS of the other party: adapt it. */
- pxSocket->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED;
- if( ( pxTCPWindow != NULL ) && ( pxSocket->u.xTCP.usCurMSS > uxNewMSS ) )
+ while( ucLen >= 8 )
{
- /* The peer advertises a smaller MSS than this socket was
- using. Use that as well. */
- FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", pxSocket->u.xTCP.usCurMSS, uxNewMSS ) );
- pxSocket->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
+ prvSkipPastRemainingOptions( ppucPtr, ppxSocket, &ucLen );
}
- pxTCPWindow->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( pxTCPWindow->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) );
- pxTCPWindow->usMSSInit = ( uint16_t ) uxNewMSS;
- pxTCPWindow->usMSS = ( uint16_t ) uxNewMSS;
- pxSocket->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS;
- pxSocket->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
+ /* ucLen should be 0 by now. */
}
-
- #if( ipconfigUSE_TCP_WIN != 1 )
- /* Without scaled windows, MSS is the only interesting option. */
- break;
- #else
- /* Or else we continue to check another option: selective ACK. */
- pucPtr += TCP_OPT_MSS_LEN;
- #endif /* ipconfigUSE_TCP_WIN != 1 */
}
- else
+ #endif /* ipconfigUSE_TCP_WIN == 1 */
+
+ ( *ppucPtr ) += ucLen;
+ }
+ return pdTRUE;
+}
+
+/*-----------------------------------------------------------*/
+
+static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const pucLen )
+{
+uint32_t ulFirst = ulChar2u32( ( *ppucPtr ) );
+uint32_t ulLast = ulChar2u32( ( *ppucPtr ) + 4 );
+uint32_t ulCount = ulTCPWindowTxSack( &( *ppxSocket )->u.xTCP.xTCPWindow, ulFirst, ulLast );
+ /* ulTCPWindowTxSack( ) returns the number of bytes which have been acked
+ * starting from the head position. Advance the tail pointer in txStream.
+ */
+ if( ( ( *ppxSocket )->u.xTCP.txStream != NULL ) && ( ulCount > 0 ) )
+ {
+ /* Just advancing the tail index, 'ulCount' bytes have been confirmed. */
+ uxStreamBufferGet( ( *ppxSocket )->u.xTCP.txStream, 0, NULL, ( size_t ) ulCount, pdFALSE );
+ ( *ppxSocket )->xEventBits |= eSOCKET_SEND;
+
+ #if ipconfigSUPPORT_SELECT_FUNCTION == 1
{
- /* All other options have a length field, so that we easily
- can skip past them. */
- unsigned char len = pucPtr[ 1 ];
- if( ( len < 2 ) || ( len > xRemainingOptionsBytes ) )
+ if( ( *ppxSocket )->xSelectBits & eSELECT_WRITE )
{
- /* If the length field is too small or too big, the options are malformed.
- Don't process them further. */
- break;
+ /* The field 'xEventBits' is used to store regular socket events
+ * (at most 8), as well as 'select events', which will be left-shifted.
+ */
+ ( *ppxSocket )->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
}
+ }
+ #endif
- #if( ipconfigUSE_TCP_WIN == 1 )
+ /* In case the socket owner has installed an OnSent handler, call it now.
+ */
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ipconfigIS_VALID_PROG_ADDRESS( ( *ppxSocket )->u.xTCP.pxHandleSent ) )
{
- /* Selective ACK: the peer has received a packet but it is missing earlier
- packets. At least this packet does not need retransmission anymore
- ulTCPWindowTxSack( ) takes care of this administration. */
- if( pucPtr[0] == TCP_OPT_SACK_A )
- {
- len -= 2;
- pucPtr += 2;
-
- while( len >= 8 )
- {
- uint32_t ulFirst = ulChar2u32( pucPtr );
- uint32_t ulLast = ulChar2u32( pucPtr + 4 );
- uint32_t ulCount = ulTCPWindowTxSack( &pxSocket->u.xTCP.xTCPWindow, ulFirst, ulLast );
- /* ulTCPWindowTxSack( ) returns the number of bytes which have been acked
- starting from the head position.
- Advance the tail pointer in txStream. */
- if( ( pxSocket->u.xTCP.txStream != NULL ) && ( ulCount > 0 ) )
- {
- /* Just advancing the tail index, 'ulCount' bytes have been confirmed. */
- uxStreamBufferGet( pxSocket->u.xTCP.txStream, 0, NULL, ( size_t ) ulCount, pdFALSE );
- pxSocket->xEventBits |= eSOCKET_SEND;
-
- #if ipconfigSUPPORT_SELECT_FUNCTION == 1
- {
- if( pxSocket->xSelectBits & eSELECT_WRITE )
- {
- /* The field 'xEventBits' is used to store regular socket events (at most 8),
- as well as 'select events', which will be left-shifted */
- pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
-
- /* In case the socket owner has installed an OnSent handler,
- call it now. */
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleSent ) )
- {
- pxSocket->u.xTCP.pxHandleSent( (Socket_t *)pxSocket, ulCount );
- }
- }
- #endif /* ipconfigUSE_CALLBACKS == 1 */
- }
- pucPtr += 8;
- len -= 8;
- }
- /* len should be 0 by now. */
- }
+ ( *ppxSocket )->u.xTCP.pxHandleSent( (Socket_t )( *ppxSocket ), ulCount );
}
- #endif /* ipconfigUSE_TCP_WIN == 1 */
-
- pucPtr += len;
}
+ #endif /* ipconfigUSE_CALLBACKS == 1 */
}
+ ( *ppucPtr ) += 8;
+ ( *pucLen ) -= 8;
}
+
/*-----------------------------------------------------------*/
#if( ipconfigUSE_TCP_WIN != 0 )
@@ -1599,7 +1634,7 @@ BaseType_t bAfter = ( BaseType_t ) NOW_CONNECTED( eTCPState ); /* Is it co
if( xConnected != NULL )
{
/* The 'connected' state has changed, call the OnConnect handler of the parent. */
- xConnected->u.xTCP.pxHandleConnected( ( Socket_t * ) xConnected, bAfter );
+ xConnected->u.xTCP.pxHandleConnected( ( Socket_t ) xConnected, bAfter );
}
}
#endif
@@ -2416,7 +2451,7 @@ int32_t lDistance, lSendResult;
{
if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleSent ) )
{
- pxSocket->u.xTCP.pxHandleSent( (Socket_t *)pxSocket, ulCount );
+ pxSocket->u.xTCP.pxHandleSent( ( Socket_t )pxSocket, ulCount );
}
}
#endif /* ipconfigUSE_CALLBACKS == 1 */
@@ -2836,41 +2871,41 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
}
/*-----------------------------------------------------------*/
-static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
- uint8_t ucTCPFlags )
+static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
+ uint8_t ucTCPFlags )
{
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
- {
- TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
- const BaseType_t xSendLength = ( BaseType_t )
- ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
+ {
+ TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
+ const BaseType_t xSendLength = ( BaseType_t )
+ ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
- pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
- pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;
+ pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
+ pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;
- prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
- }
+ prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
+ }
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
- /* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
- ( void )pxNetworkBuffer;
- ( void )ucTCPFlags;
+ /* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
+ ( void )pxNetworkBuffer;
+ ( void )ucTCPFlags;
- /* The packet was not consumed. */
- return pdFAIL;
+ /* The packet was not consumed. */
+ return pdFAIL;
}
/*-----------------------------------------------------------*/
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
- return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
+ return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
}
/*-----------------------------------------------------------*/
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
- return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
- ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
+ return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
+ ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
}
/*-----------------------------------------------------------*/
@@ -2914,9 +2949,8 @@ uint16_t xRemotePort;
uint32_t ulSequenceNumber;
uint32_t ulAckNumber;
BaseType_t xResult = pdPASS;
-
- configASSERT( pxNetworkBuffer );
- configASSERT( pxNetworkBuffer->pucEthernetBuffer );
+configASSERT(pxNetworkBuffer);
+configASSERT(pxNetworkBuffer->pucEthernetBuffer);
/* Check for a minimum packet size. */
if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
@@ -2926,8 +2960,8 @@ BaseType_t xResult = pdPASS;
xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
- ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
- ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );
+ ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
+ ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );
/* Find the destination socket, and if not found: return a socket listing to
the destination PORT. */
@@ -3007,36 +3041,36 @@ BaseType_t xResult = pdPASS;
flag. */
if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
{
- FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
-
- /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
- if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
- {
- /* Per the above RFC, "In the SYN-SENT state ... the RST is
- acceptable if the ACK field acknowledges the SYN." */
- if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
- {
- vTCPStateChange( pxSocket, eCLOSED );
- }
- }
- else
- {
- /* Check whether the packet matches the next expected sequence number. */
- if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
- {
- vTCPStateChange( pxSocket, eCLOSED );
- }
- /* Otherwise, check whether the packet is within the receive window. */
- else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
- ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
- pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
- {
- /* Send a challenge ACK. */
- prvTCPSendChallengeAck( pxNetworkBuffer );
- }
- }
-
- /* Otherwise, do nothing. In any case, the packet cannot be handled. */
+ FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
+
+ /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
+ if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
+ {
+ /* Per the above RFC, "In the SYN-SENT state ... the RST is
+ acceptable if the ACK field acknowledges the SYN." */
+ if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
+ {
+ vTCPStateChange( pxSocket, eCLOSED );
+ }
+ }
+ else
+ {
+ /* Check whether the packet matches the next expected sequence number. */
+ if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
+ {
+ vTCPStateChange( pxSocket, eCLOSED );
+ }
+ /* Otherwise, check whether the packet is within the receive window. */
+ else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
+ ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
+ pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
+ {
+ /* Send a challenge ACK. */
+ prvTCPSendChallengeAck( pxNetworkBuffer );
+ }
+ }
+
+ /* Otherwise, do nothing. In any case, the packet cannot be handled. */
xResult = pdFAIL;
}
else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )