FreeRTOS_TCP_WIN.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * FreeRTOS+TCP V2.3.2 LTS Patch 1
  3. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. * this software and associated documentation files (the "Software"), to deal in
  7. * the Software without restriction, including without limitation the rights to
  8. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. * the Software, and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * http://aws.amazon.com/freertos
  23. * http://www.FreeRTOS.org
  24. */
  25. /*
  26. * FreeRTOS_TCP_WIN.c
  27. * Module which handles the TCP windowing schemes for FreeRTOS-PLUS-TCP
  28. */
  29. #ifndef FREERTOS_TCP_WIN_H
  30. #define FREERTOS_TCP_WIN_H
  31. #ifdef __cplusplus
  32. extern "C" {
  33. #endif
  34. /**
  35. * The name xTCPTimer was already use as the name of an IP-timer.
  36. */
  37. typedef struct xTCPTimerStruct
  38. {
  39. uint32_t ulBorn; /**< The time when this timer is created. */
  40. } TCPTimer_t;
  41. /**
  42. * Structure to hold the information about a TCP segment.
  43. */
  44. typedef struct xTCP_SEGMENT
  45. {
  46. uint32_t ulSequenceNumber; /**< The sequence number of the first byte in this packet */
  47. int32_t lMaxLength; /**< Maximum space, number of bytes which can be stored in this segment */
  48. int32_t lDataLength; /**< Actual number of bytes */
  49. int32_t lStreamPos; /**< reference to the [t|r]xStream of the socket */
  50. TCPTimer_t xTransmitTimer; /**< saves a timestamp at the moment this segment gets transmitted (TX only) */
  51. union
  52. {
  53. struct
  54. {
  55. uint32_t
  56. ucTransmitCount : 8, /**< Number of times the segment has been transmitted, used to calculate the RTT */
  57. ucDupAckCount : 8, /**< Counts the number of times that a higher segment was ACK'd. After 3 times a Fast Retransmission takes place */
  58. bOutstanding : 1, /**< It the peer's turn, we're just waiting for an ACK */
  59. bAcked : 1, /**< This segment has been acknowledged */
  60. bIsForRx : 1; /**< pdTRUE if segment is used for reception */
  61. } bits;
  62. uint32_t ulFlags;
  63. } u; /**< Use a union to store the 32-bit flag field and the breakdown in the same location. */
  64. #if ( ipconfigUSE_TCP_WIN != 0 )
  65. struct xLIST_ITEM xQueueItem; /**< TX only: segments can be linked in one of three queues: xPriorityQueue, xTxQueue, and xWaitQueue */
  66. struct xLIST_ITEM xSegmentItem; /**< With this item the segment can be connected to a list, depending on who is owning it */
  67. #endif
  68. } TCPSegment_t;
  69. /**
  70. * Structure to store the Rx/Tx window length.
  71. */
  72. typedef struct xTCP_WINSIZE
  73. {
  74. uint32_t ulRxWindowLength; /**< The size of the receive window. */
  75. uint32_t ulTxWindowLength; /**< The size of the send window. */
  76. } TCPWinSize_t;
  77. /*
  78. * If TCP time-stamps are being used, they will occupy 12 bytes in
  79. * each packet, and thus the message space will become smaller
  80. */
  81. /* Keep this as a multiple of 4 */
  82. #if ( ipconfigUSE_TCP_WIN == 1 )
  83. #define ipSIZE_TCP_OPTIONS 16U
  84. #else
  85. #define ipSIZE_TCP_OPTIONS 12U
  86. #endif
  87. /**
  88. * Every TCP connection owns a TCP window for the administration of all packets
  89. * It owns two sets of segment descriptors, incoming and outgoing
  90. */
  91. typedef struct xTCP_WINDOW
  92. {
  93. union
  94. {
  95. struct
  96. {
  97. uint32_t
  98. bHasInit : 1, /**< The window structure has been initialised */
  99. bSendFullSize : 1, /**< May only send packets with a size equal to MSS (for optimisation) */
  100. bTimeStamps : 1; /**< Socket is supposed to use TCP time-stamps. This depends on the */
  101. } bits; /**< party which opens the connection */
  102. uint32_t ulFlags;
  103. } u; /**< Use a union to store the 32-bit flag field and the breakdown at the same place. */
  104. TCPWinSize_t xSize; /**< Size of the TCP window. */
  105. struct
  106. {
  107. uint32_t ulFirstSequenceNumber; /**< Logging & debug: the first segment received/sent in this connection
  108. * for Tx: initial send sequence number (ISS)
  109. * for Rx: initial receive sequence number (IRS) */
  110. uint32_t ulCurrentSequenceNumber; /**< Tx/Rx: the oldest sequence number not yet confirmed, also SND.UNA / RCV.NXT
  111. * In other words: the sequence number of the left side of the sliding window */
  112. uint32_t ulFINSequenceNumber; /**< The sequence number which carried the FIN flag */
  113. uint32_t ulHighestSequenceNumber; /**< Sequence number of the right-most byte + 1 */
  114. } rx, /**< Structure for the receiver for TCP. */
  115. tx; /**< Structure for the transmitter for TCP. */
  116. uint32_t ulOurSequenceNumber; /**< The SEQ number we're sending out */
  117. uint32_t ulUserDataLength; /**< Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
  118. uint32_t ulNextTxSequenceNumber; /**< The sequence number given to the next byte to be added for transmission */
  119. int32_t lSRTT; /**< Smoothed Round Trip Time, it may increment quickly and it decrements slower */
  120. uint8_t ucOptionLength; /**< Number of valid bytes in ulOptionsData[] */
  121. #if ( ipconfigUSE_TCP_WIN == 1 )
  122. List_t xPriorityQueue; /**< Priority queue: segments which must be sent immediately */
  123. List_t xTxQueue; /**< Transmit queue: segments queued for transmission */
  124. List_t xWaitQueue; /**< Waiting queue: outstanding segments */
  125. TCPSegment_t * pxHeadSegment; /**< points to a segment which has not been transmitted and it's size is still growing (user data being added) */
  126. uint32_t ulOptionsData[ ipSIZE_TCP_OPTIONS / sizeof( uint32_t ) ]; /**< Contains the options we send out */
  127. List_t xTxSegments; /**< A linked list of all transmission segments, sorted on sequence number */
  128. List_t xRxSegments; /**< A linked list of reception segments, order depends on sequence of arrival */
  129. #else
  130. /* For tiny TCP, there is only 1 outstanding TX segment */
  131. TCPSegment_t xTxSegment; /**< Priority queue */
  132. #endif
  133. uint16_t usOurPortNumber; /**< Mostly for debugging/logging: our TCP port number */
  134. uint16_t usPeerPortNumber; /**< debugging/logging: the peer's TCP port number */
  135. uint16_t usMSS; /**< Current accepted MSS */
  136. uint16_t usMSSInit; /**< MSS as configured by the socket owner */
  137. } TCPWindow_t;
  138. /*=============================================================================
  139. *
  140. * Creation and destruction
  141. *
  142. *=============================================================================*/
  143. /* Create and initialize a window */
  144. void vTCPWindowCreate( TCPWindow_t * pxWindow,
  145. uint32_t ulRxWindowLength,
  146. uint32_t ulTxWindowLength,
  147. uint32_t ulAckNumber,
  148. uint32_t ulSequenceNumber,
  149. uint32_t ulMSS );
  150. /* Destroy a window (always returns NULL)
  151. * It will free some resources: a collection of segments */
  152. void vTCPWindowDestroy( TCPWindow_t const * pxWindow );
  153. /* Initialize a window */
  154. void vTCPWindowInit( TCPWindow_t * pxWindow,
  155. uint32_t ulAckNumber,
  156. uint32_t ulSequenceNumber,
  157. uint32_t ulMSS );
  158. /* Clean up allocated segments. Should only be called when FreeRTOS+TCP will no longer be used. */
  159. void vTCPSegmentCleanup( void );
  160. /*=============================================================================
  161. *
  162. * Rx functions
  163. *
  164. *=============================================================================*/
  165. /* if true may be passed directly to user (segment expected and window is empty)
  166. * But pxWindow->ackno should always be used to set "BUF->ackno" */
  167. int32_t lTCPWindowRxCheck( TCPWindow_t * pxWindow,
  168. uint32_t ulSequenceNumber,
  169. uint32_t ulLength,
  170. uint32_t ulSpace );
  171. /* This function will be called as soon as a FIN is received. It will return true
  172. * if there are no 'open' reception segments */
  173. BaseType_t xTCPWindowRxEmpty( const TCPWindow_t * pxWindow );
  174. /*=============================================================================
  175. *
  176. * Tx functions
  177. *
  178. *=============================================================================*/
  179. /* Adds data to the Tx-window */
  180. int32_t lTCPWindowTxAdd( TCPWindow_t * pxWindow,
  181. uint32_t ulLength,
  182. int32_t lPosition,
  183. int32_t lMax );
  184. /* Check data to be sent and calculate the time period we may sleep */
  185. BaseType_t xTCPWindowTxHasData( TCPWindow_t const * pxWindow,
  186. uint32_t ulWindowSize,
  187. TickType_t * pulDelay );
  188. /* See if anything is left to be sent
  189. * Function will be called when a FIN has been received. Only when the TX window is clean,
  190. * it will return pdTRUE */
  191. BaseType_t xTCPWindowTxDone( const TCPWindow_t * pxWindow );
  192. /* Fetches data to be sent.
  193. * plPosition will point to a location with the circular data buffer: txStream */
  194. uint32_t ulTCPWindowTxGet( TCPWindow_t * pxWindow,
  195. uint32_t ulWindowSize,
  196. int32_t * plPosition );
  197. /* Receive a normal ACK */
  198. uint32_t ulTCPWindowTxAck( TCPWindow_t * pxWindow,
  199. uint32_t ulSequenceNumber );
  200. /* Receive a SACK option */
  201. uint32_t ulTCPWindowTxSack( TCPWindow_t * pxWindow,
  202. uint32_t ulFirst,
  203. uint32_t ulLast );
  204. #ifdef __cplusplus
  205. } /* extern "C" */
  206. #endif
  207. #endif /* FREERTOS_TCP_WIN_H */