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