mirror of
https://github.com/FreeRTOS/FreeRTOS-Plus-TCP
synced 2025-10-23 18:38:33 +08:00

* Update source location for coverity * Add coverage checker * Add build check with default configuration * Fix build combination and DNS error * uncrustified and fixed cmakelists * This commit updates version number in all files to Development-Branch * Update version number macros * This commit fixes a typo in version number macro * Added a 'critical section' to prevent a race condition in stream buffers * Uncrustify: triggered by comment. * Fixed unit-tests by adding mocked functions * Initial commit of file README.md * Update README.md * Fix the title of README file in coverity * Addressed issue comments * Update command * Add details about remaining exception * Move file to original location * Remove use of sudo in commands * Fix links; added coverity version note * Update README.md * Remove CMake installation instructions * Update manifest/history and copyright year * Update kernel version to 10.4.5 * Update remaining copyright year instances * Update the version number macros * Update license header titles * Remove kernel license header and add TCP header Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
259 lines
12 KiB
C
259 lines
12 KiB
C
/*
|
|
* FreeRTOS+TCP <DEVELOPMENT BRANCH>
|
|
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* http://aws.amazon.com/freertos
|
|
* http://www.FreeRTOS.org
|
|
*/
|
|
|
|
/*
|
|
* FreeRTOS_TCP_WIN.c
|
|
* Module which handles the TCP windowing schemes for FreeRTOS-PLUS-TCP
|
|
*/
|
|
|
|
#ifndef FREERTOS_TCP_WIN_H
|
|
#define FREERTOS_TCP_WIN_H
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
/** @brief A very simple timer that registers the time that a packet was sent. It is used to trigger re-sending. */
|
|
typedef struct xTCPTimerStruct
|
|
{
|
|
TickType_t uxBorn; /**< The time at which a packet was sent ( using xTaskGetTickCount() ). */
|
|
} TCPTimer_t;
|
|
|
|
/** @brief This struct collects the properties of a TCP segment. A segment is a chunk of data which
|
|
* is sent in a single TCP packet, at most 1460 bytes. */
|
|
typedef struct xTCP_SEGMENT
|
|
{
|
|
uint32_t ulSequenceNumber; /**< The sequence number of the first byte in this packet */
|
|
int32_t lMaxLength; /**< Maximum space, number of bytes which can be stored in this segment */
|
|
int32_t lDataLength; /**< Actual number of bytes */
|
|
int32_t lStreamPos; /**< reference to the [t|r]xStream of the socket */
|
|
TCPTimer_t xTransmitTimer; /**< saves a timestamp at the moment this segment gets transmitted (TX only) */
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32_t
|
|
ucTransmitCount : 8, /**< Number of times the segment has been transmitted, used to calculate the RTT */
|
|
ucDupAckCount : 8, /**< Counts the number of times that a higher segment was ACK'd. After 3 times a Fast Retransmission takes place */
|
|
bOutstanding : 1, /**< It the peer's turn, we're just waiting for an ACK */
|
|
bAcked : 1, /**< This segment has been acknowledged */
|
|
bIsForRx : 1; /**< pdTRUE if segment is used for reception */
|
|
} bits;
|
|
uint32_t ulFlags;
|
|
} u; /**< A collection of boolean flags. */
|
|
#if ( ipconfigUSE_TCP_WIN != 0 )
|
|
struct xLIST_ITEM xQueueItem; /**< TX only: segments can be linked in one of three queues: xPriorityQueue, xTxQueue, and xWaitQueue */
|
|
struct xLIST_ITEM xSegmentItem; /**< With this item the segment can be connected to a list, depending on who is owning it */
|
|
#endif
|
|
} TCPSegment_t;
|
|
|
|
/** @brief This struct describes the windows sizes, both for incoming and outgoing. */
|
|
typedef struct xTCP_WINSIZE
|
|
{
|
|
uint32_t ulRxWindowLength; /**< The TCP window size of the incoming stream. */
|
|
uint32_t ulTxWindowLength; /**< The TCP window size of the outgoing stream. */
|
|
} TCPWinSize_t;
|
|
|
|
/** @brief If TCP time-stamps are being used, they will occupy 12 bytes in
|
|
* each packet, and thus the message space will become smaller.
|
|
* Keep this as a multiple of 4 */
|
|
#if ( ipconfigUSE_TCP_WIN == 1 )
|
|
#define ipSIZE_TCP_OPTIONS 16U
|
|
#else
|
|
#define ipSIZE_TCP_OPTIONS 12U
|
|
#endif
|
|
|
|
/** @brief Every TCP connection owns a TCP window for the administration of all packets
|
|
* It owns two sets of segment descriptors, incoming and outgoing
|
|
*/
|
|
typedef struct xTCP_WINDOW
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32_t
|
|
bHasInit : 1, /**< The window structure has been initialised */
|
|
bSendFullSize : 1, /**< May only send packets with a size equal to MSS (for optimisation) */
|
|
bTimeStamps : 1; /**< Socket is supposed to use TCP time-stamps. This depends on the */
|
|
} bits; /**< party which opens the connection */
|
|
uint32_t ulFlags;
|
|
} u; /**< A collection of boolean flags. */
|
|
TCPWinSize_t xSize; /**< The TCP window sizes of the incoming and outgoing streams. */
|
|
struct
|
|
{
|
|
uint32_t ulFirstSequenceNumber; /**< Logging & debug: the first segment received/sent in this connection
|
|
* for Tx: initial send sequence number (ISS)
|
|
* for Rx: initial receive sequence number (IRS) */
|
|
uint32_t ulCurrentSequenceNumber; /**< Tx/Rx: the oldest sequence number not yet confirmed, also SND.UNA / RCV.NXT
|
|
* In other words: the sequence number of the left side of the sliding window */
|
|
uint32_t ulFINSequenceNumber; /**< The sequence number which carried the FIN flag */
|
|
uint32_t ulHighestSequenceNumber; /**< Sequence number of the right-most byte + 1 */
|
|
} rx, /**< Sequence number of the incoming data stream. */
|
|
tx; /**< Sequence number of the outgoing data stream. */
|
|
uint32_t ulOurSequenceNumber; /**< The SEQ number we're sending out */
|
|
uint32_t ulUserDataLength; /**< Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
|
|
uint32_t ulNextTxSequenceNumber; /**< The sequence number given to the next byte to be added for transmission */
|
|
int32_t lSRTT; /**< Smoothed Round Trip Time, it may increment quickly and it decrements slower */
|
|
uint8_t ucOptionLength; /**< Number of valid bytes in ulOptionsData[] */
|
|
#if ( ipconfigUSE_TCP_WIN == 1 )
|
|
List_t xPriorityQueue; /**< Priority queue: segments which must be sent immediately */
|
|
List_t xTxQueue; /**< Transmit queue: segments queued for transmission */
|
|
List_t xWaitQueue; /**< Waiting queue: outstanding segments */
|
|
TCPSegment_t * pxHeadSegment; /**< points to a segment which has not been transmitted and it's size is still growing (user data being added) */
|
|
uint32_t ulOptionsData[ ipSIZE_TCP_OPTIONS / sizeof( uint32_t ) ]; /**< Contains the options we send out */
|
|
List_t xTxSegments; /**< A linked list of all transmission segments, sorted on sequence number */
|
|
List_t xRxSegments; /**< A linked list of reception segments, order depends on sequence of arrival */
|
|
#else
|
|
/* For tiny TCP, there is only 1 outstanding TX segment */
|
|
TCPSegment_t xTxSegment; /**< Priority queue */
|
|
#endif
|
|
uint16_t usOurPortNumber; /**< Mostly for debugging/logging: our TCP port number */
|
|
uint16_t usPeerPortNumber; /**< debugging/logging: the peer's TCP port number */
|
|
uint16_t usMSS; /**< Current accepted MSS */
|
|
uint16_t usMSSInit; /**< MSS as configured by the socket owner */
|
|
} TCPWindow_t;
|
|
|
|
|
|
/*=============================================================================
|
|
*
|
|
* Creation and destruction
|
|
*
|
|
*=============================================================================*/
|
|
|
|
/* Create and initialize a window */
|
|
void vTCPWindowCreate( TCPWindow_t * pxWindow,
|
|
uint32_t ulRxWindowLength,
|
|
uint32_t ulTxWindowLength,
|
|
uint32_t ulAckNumber,
|
|
uint32_t ulSequenceNumber,
|
|
uint32_t ulMSS );
|
|
|
|
/* Destroy a window (always returns NULL)
|
|
* It will free some resources: a collection of segments */
|
|
void vTCPWindowDestroy( TCPWindow_t const * pxWindow );
|
|
|
|
/* Initialize a window */
|
|
void vTCPWindowInit( TCPWindow_t * pxWindow,
|
|
uint32_t ulAckNumber,
|
|
uint32_t ulSequenceNumber,
|
|
uint32_t ulMSS );
|
|
|
|
/* Clean up allocated segments. Should only be called when FreeRTOS+TCP will no longer be used. */
|
|
void vTCPSegmentCleanup( void );
|
|
|
|
/*=============================================================================
|
|
*
|
|
* Rx functions
|
|
*
|
|
*=============================================================================*/
|
|
|
|
/* if true may be passed directly to user (segment expected and window is empty)
|
|
* But pxWindow->ackno should always be used to set "BUF->ackno" */
|
|
int32_t lTCPWindowRxCheck( TCPWindow_t * pxWindow,
|
|
uint32_t ulSequenceNumber,
|
|
uint32_t ulLength,
|
|
uint32_t ulSpace,
|
|
uint32_t * pulSkipCount );
|
|
|
|
/* This function will be called as soon as a FIN is received. It will return true
|
|
* if there are no 'open' reception segments */
|
|
BaseType_t xTCPWindowRxEmpty( const TCPWindow_t * pxWindow );
|
|
|
|
/*=============================================================================
|
|
*
|
|
* Tx functions
|
|
*
|
|
*=============================================================================*/
|
|
|
|
/* Adds data to the Tx-window */
|
|
int32_t lTCPWindowTxAdd( TCPWindow_t * pxWindow,
|
|
uint32_t ulLength,
|
|
int32_t lPosition,
|
|
int32_t lMax );
|
|
|
|
/* Check data to be sent and calculate the time period we may sleep */
|
|
BaseType_t xTCPWindowTxHasData( TCPWindow_t const * pxWindow,
|
|
uint32_t ulWindowSize,
|
|
TickType_t * pulDelay );
|
|
|
|
/* See if anything is left to be sent
|
|
* Function will be called when a FIN has been received. Only when the TX window is clean,
|
|
* it will return pdTRUE */
|
|
BaseType_t xTCPWindowTxDone( const TCPWindow_t * pxWindow );
|
|
|
|
/* Fetches data to be sent.
|
|
* 'plPosition' will point to a location with the circular data buffer: txStream */
|
|
uint32_t ulTCPWindowTxGet( TCPWindow_t * pxWindow,
|
|
uint32_t ulWindowSize,
|
|
int32_t * plPosition );
|
|
|
|
/* Receive a normal ACK */
|
|
uint32_t ulTCPWindowTxAck( TCPWindow_t * pxWindow,
|
|
uint32_t ulSequenceNumber );
|
|
|
|
/* Receive a SACK option */
|
|
uint32_t ulTCPWindowTxSack( TCPWindow_t * pxWindow,
|
|
uint32_t ulFirst,
|
|
uint32_t ulLast );
|
|
|
|
/**
|
|
* @brief Check if a > b, where a and b are rolling counters.
|
|
*
|
|
* @param[in] a: The value on the left-hand side.
|
|
* @param[in] b: The value on the right-hand side.
|
|
*
|
|
* @return pdTRUE if a > b, otherwise pdFALSE.
|
|
*
|
|
* @note GreaterThan is calculated as "( a - ( b + 1U ) ) < 0x80000000".
|
|
*/
|
|
BaseType_t xSequenceGreaterThan( uint32_t a,
|
|
uint32_t b );
|
|
|
|
/**
|
|
* @brief Check if a < b, where a and b are rolling counters.
|
|
*
|
|
* @param[in] a: The value on the left-hand side.
|
|
* @param[in] b: The value on the right-hand side.
|
|
*
|
|
* @return pdTRUE if a < b, otherwise pdFALSE.
|
|
*
|
|
* @note LessThan is implemented as "( b - ( a + 1 ) ) < 0x80000000".
|
|
*/
|
|
BaseType_t xSequenceLessThan( uint32_t a,
|
|
uint32_t b );
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
#endif /* FREERTOS_TCP_WIN_H */
|