mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-06-22 00:50:34 +08:00
Update TCP/IP tack to latest form Git.
This commit is contained in:
@ -307,6 +307,20 @@ static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescrip
|
||||
*/
|
||||
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
|
||||
|
||||
/*
|
||||
* Common code for sending a TCP protocol control packet (i.e. no options, no
|
||||
* payload, just flags).
|
||||
*/
|
||||
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
|
||||
uint8_t ucTCPFlags );
|
||||
|
||||
/*
|
||||
* A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
|
||||
* case #3. In summary, an RST was received with a sequence number that is
|
||||
* unexpected but still within the window.
|
||||
*/
|
||||
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||
|
||||
/*
|
||||
* Reply to a peer with the RST flag on, in case a packet can not be handled.
|
||||
*/
|
||||
@ -738,7 +752,7 @@ NetworkBufferDescriptor_t xTempBuffer;
|
||||
}
|
||||
|
||||
/* Take the minimum of the RX buffer space and the RX window size. */
|
||||
ulSpace = FreeRTOS_min_uint32( pxSocket->u.xTCP.ulRxCurWinSize, pxTCPWindow->xSize.ulRxWindowLength );
|
||||
ulSpace = FreeRTOS_min_uint32( pxTCPWindow->xSize.ulRxWindowLength, ulFrontSpace );
|
||||
|
||||
if( ( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED ) || ( pxSocket->u.xTCP.bits.bRxStopped != pdFALSE_UNSIGNED ) )
|
||||
{
|
||||
@ -1092,9 +1106,6 @@ uint32_t ulInitialSequenceNumber = 0;
|
||||
/* Set the values of usInitMSS / usCurMSS for this socket. */
|
||||
prvSocketSetMSS( pxSocket );
|
||||
|
||||
/* For now this is also the advertised window size. */
|
||||
pxSocket->u.xTCP.ulRxCurWinSize = pxSocket->u.xTCP.usInitMSS;
|
||||
|
||||
/* The initial sequence numbers at our side are known. Later
|
||||
vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
|
||||
first wait for a SYN+ACK reply. */
|
||||
@ -2521,7 +2532,6 @@ TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetB
|
||||
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
|
||||
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
|
||||
/* Find out what window size we may advertised. */
|
||||
uint32_t ulFrontSpace;
|
||||
int32_t lRxSpace;
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
#if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
|
||||
@ -2530,20 +2540,6 @@ int32_t lRxSpace;
|
||||
int32_t lMinLength;
|
||||
#endif
|
||||
#endif
|
||||
pxSocket->u.xTCP.ulRxCurWinSize = pxTCPWindow->xSize.ulRxWindowLength -
|
||||
( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulCurrentSequenceNumber );
|
||||
|
||||
/* Free space in rxStream. */
|
||||
if( pxSocket->u.xTCP.rxStream != NULL )
|
||||
{
|
||||
ulFrontSpace = ( uint32_t ) uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
|
||||
}
|
||||
else
|
||||
{
|
||||
ulFrontSpace = ( uint32_t ) pxSocket->u.xTCP.uxRxStreamSize;
|
||||
}
|
||||
|
||||
pxSocket->u.xTCP.ulRxCurWinSize = FreeRTOS_min_uint32( ulFrontSpace, pxSocket->u.xTCP.ulRxCurWinSize );
|
||||
|
||||
/* Set the time-out field, so that we'll be called by the IP-task in case no
|
||||
next message will be received. */
|
||||
@ -2840,28 +2836,44 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
|
||||
uint8_t ucTCPFlags )
|
||||
{
|
||||
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
|
||||
#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 = ipTCP_FLAG_ACK | ipTCP_FLAG_RST;
|
||||
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 */
|
||||
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
|
||||
|
||||
/* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
|
||||
( void ) pxNetworkBuffer;
|
||||
( void )pxNetworkBuffer;
|
||||
( void )ucTCPFlags;
|
||||
|
||||
/* The packet was not consumed. */
|
||||
return pdFAIL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
|
||||
ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
|
||||
{
|
||||
uint32_t ulMSS = ipconfigTCP_MSS;
|
||||
@ -2899,8 +2911,13 @@ uint32_t ulLocalIP;
|
||||
uint16_t xLocalPort;
|
||||
uint32_t ulRemoteIP;
|
||||
uint16_t xRemotePort;
|
||||
uint32_t ulSequenceNumber;
|
||||
uint32_t ulAckNumber;
|
||||
BaseType_t xResult = pdPASS;
|
||||
|
||||
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 ) )
|
||||
{
|
||||
@ -2909,6 +2926,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 );
|
||||
|
||||
/* Find the destination socket, and if not found: return a socket listing to
|
||||
the destination PORT. */
|
||||
@ -2988,13 +3007,36 @@ BaseType_t xResult = pdPASS;
|
||||
flag. */
|
||||
if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
|
||||
{
|
||||
/* The target socket is not in a listening state, any RST packet
|
||||
will cause the socket to be closed. */
|
||||
FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
|
||||
/* _HT_: should indicate that 'ECONNRESET' must be returned to the used during next API. */
|
||||
vTCPStateChange( pxSocket, eCLOSED );
|
||||
|
||||
/* The packet cannot be handled. */
|
||||
/* 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 ) )
|
||||
@ -3304,6 +3346,11 @@ BaseType_t xResult = pdFALSE;
|
||||
|
||||
/* Provide access to private members for testing. */
|
||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
||||
#include "aws_freertos_tcp_test_access_tcp_define.h"
|
||||
#include "iot_freertos_tcp_test_access_tcp_define.h"
|
||||
#endif
|
||||
|
||||
/* Provide access to private members for verification. */
|
||||
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
|
||||
#include "aws_freertos_tcp_verification_access_tcp_define.h"
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user