Update TCP/IP tack to latest form Git.

This commit is contained in:
Richard Barry
2019-07-14 22:07:41 +00:00
parent a6a0403fd6
commit 2e18203bb7
29 changed files with 4619 additions and 393 deletions

View File

@ -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