1 /* 2 * FreeRTOS+TCP V3.1.0 3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * SPDX-License-Identifier: MIT 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 * this software and associated documentation files (the "Software"), to deal in 9 * the Software without restriction, including without limitation the rights to 10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 * the Software, and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * http://aws.amazon.com/freertos 25 * http://www.FreeRTOS.org 26 */ 27 28 /** 29 * @file FreeRTOS_TCP_State_Handling.c 30 * @brief Module which handles the TCP protocol state transition for FreeRTOS+TCP. 31 * 32 * Endianness: in this module all ports and IP addresses are stored in 33 * host byte-order, except fields in the IP-packets 34 */ 35 36 /* Standard includes. */ 37 #include <stdint.h> 38 #include <stdio.h> 39 40 /* FreeRTOS includes. */ 41 #include "FreeRTOS.h" 42 #include "task.h" 43 #include "queue.h" 44 #include "semphr.h" 45 46 /* FreeRTOS+TCP includes. */ 47 #include "FreeRTOS_IP.h" 48 #include "FreeRTOS_Sockets.h" 49 #include "FreeRTOS_IP_Private.h" 50 #include "FreeRTOS_UDP_IP.h" 51 #include "FreeRTOS_DHCP.h" 52 #include "NetworkInterface.h" 53 #include "NetworkBufferManagement.h" 54 #include "FreeRTOS_ARP.h" 55 56 #include "FreeRTOS_TCP_Reception.h" 57 #include "FreeRTOS_TCP_Transmission.h" 58 #include "FreeRTOS_TCP_State_Handling.h" 59 #include "FreeRTOS_TCP_Utils.h" 60 61 /* Just make sure the contents doesn't get compiled if TCP is not enabled. */ 62 #if ipconfigUSE_TCP == 1 63 64 /* 65 * Called to handle the closure of a TCP connection. 66 */ 67 static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t * pxSocket, 68 const NetworkBufferDescriptor_t * pxNetworkBuffer ); 69 70 /* 71 * Called from prvTCPHandleState() as long as the TCP status is eSYN_RECEIVED to 72 * eCONNECT_SYN. 73 */ 74 static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t * pxSocket, 75 const NetworkBufferDescriptor_t * pxNetworkBuffer, 76 uint32_t ulReceiveLength, 77 UBaseType_t uxOptionsLength ); 78 79 /* 80 * Called from prvTCPHandleState() as long as the TCP status is eESTABLISHED. 81 */ 82 static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t * pxSocket, 83 NetworkBufferDescriptor_t ** ppxNetworkBuffer, 84 uint32_t ulReceiveLength, 85 UBaseType_t uxOptionsLength ); 86 87 /* 88 * After a listening socket receives a new connection, it may duplicate itself. 89 * The copying takes place in prvTCPSocketCopy. 90 */ 91 static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t * pxNewSocket, 92 FreeRTOS_Socket_t * pxSocket ); 93 94 /** 95 * @brief Check whether the socket is active or not. 96 * 97 * @param[in] ucStatus: The status of the socket. 98 * 99 * @return pdTRUE if the socket must be checked. Non-active sockets 100 * are waiting for user action, either connect() or close(). 101 */ prvTCPSocketIsActive(eIPTCPState_t eStatus)102 BaseType_t prvTCPSocketIsActive( eIPTCPState_t eStatus ) 103 { 104 BaseType_t xResult; 105 106 switch( eStatus ) 107 { 108 case eCLOSED: 109 case eCLOSE_WAIT: 110 case eFIN_WAIT_2: 111 case eCLOSING: 112 case eTIME_WAIT: 113 xResult = pdFALSE; 114 break; 115 116 case eTCP_LISTEN: 117 case eCONNECT_SYN: 118 case eSYN_FIRST: 119 case eSYN_RECEIVED: 120 case eESTABLISHED: 121 case eFIN_WAIT_1: 122 case eLAST_ACK: 123 default: 124 xResult = pdTRUE; 125 break; 126 } 127 128 return xResult; 129 } 130 /*-----------------------------------------------------------*/ 131 132 133 134 #if ( ipconfigTCP_HANG_PROTECTION == 1 ) 135 136 /** 137 * @brief Some of the TCP states may only last a certain amount of time. 138 * This function checks if the socket is 'hanging', i.e. staying 139 * too long in the same state. 140 * 141 * @param[in] The socket to be checked. 142 * 143 * @return pdFALSE if no checks are needed, pdTRUE if checks were done, or negative 144 * in case the socket has reached a critical time-out. The socket will go to 145 * the eCLOSE_WAIT state. 146 */ prvTCPStatusAgeCheck(FreeRTOS_Socket_t * pxSocket)147 BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t * pxSocket ) 148 { 149 BaseType_t xResult; 150 151 eIPTCPState_t eState = pxSocket->u.xTCP.eTCPState; 152 153 switch( eState ) 154 { 155 case eESTABLISHED: 156 157 /* If the 'ipconfigTCP_KEEP_ALIVE' option is enabled, sockets in 158 * state ESTABLISHED can be protected using keep-alive messages. */ 159 xResult = pdFALSE; 160 break; 161 162 case eCLOSED: 163 case eTCP_LISTEN: 164 case eCLOSE_WAIT: 165 /* These 3 states may last for ever, up to the owner. */ 166 xResult = pdFALSE; 167 break; 168 169 case eCONNECT_SYN: 170 case eSYN_FIRST: 171 case eSYN_RECEIVED: 172 case eFIN_WAIT_1: 173 case eFIN_WAIT_2: 174 case eCLOSING: 175 case eLAST_ACK: 176 case eTIME_WAIT: 177 default: 178 179 /* All other (non-connected) states will get anti-hanging 180 * protection. */ 181 xResult = pdTRUE; 182 break; 183 } 184 185 if( xResult != pdFALSE ) 186 { 187 /* How much time has past since the last active moment which is 188 * defined as A) a state change or B) a packet has arrived. */ 189 TickType_t xAge = xTaskGetTickCount() - pxSocket->u.xTCP.xLastActTime; 190 191 /* ipconfigTCP_HANG_PROTECTION_TIME is in units of seconds. */ 192 if( xAge > ( ( TickType_t ) ipconfigTCP_HANG_PROTECTION_TIME * ( TickType_t ) configTICK_RATE_HZ ) ) 193 { 194 #if ( ipconfigHAS_DEBUG_PRINTF == 1 ) 195 { 196 FreeRTOS_debug_printf( ( "Inactive socket closed: port %u rem %xip:%u status %s\n", 197 pxSocket->usLocalPort, 198 ( unsigned ) pxSocket->u.xTCP.ulRemoteIP, 199 pxSocket->u.xTCP.usRemotePort, 200 FreeRTOS_GetTCPStateName( ( UBaseType_t ) pxSocket->u.xTCP.eTCPState ) ) ); 201 } 202 #endif /* ipconfigHAS_DEBUG_PRINTF */ 203 204 /* Move to eCLOSE_WAIT, user may close the socket. */ 205 vTCPStateChange( pxSocket, eCLOSE_WAIT ); 206 207 /* When 'bPassQueued' true, this socket is an orphan until it 208 * gets connected. */ 209 if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED ) 210 { 211 /* vTCPStateChange() has called vSocketCloseNextTime() 212 * in case the socket is not yet owned by the application. 213 * Return a negative value to inform the caller that 214 * the socket will be closed in the next cycle. */ 215 xResult = -1; 216 } 217 } 218 } 219 220 return xResult; 221 } 222 /*-----------------------------------------------------------*/ 223 224 #endif /* if ( ipconfigTCP_HANG_PROTECTION == 1 ) */ 225 226 /** 227 * @brief prvTCPHandleFin() will be called to handle connection closure. The 228 * closure starts when either a FIN has been received and accepted, 229 * or when the socket has sent a FIN flag to the peer. Before being 230 * called, it has been checked that both reception and transmission 231 * are complete. 232 * 233 * @param[in] pxSocket: Socket owning the the connection. 234 * @param[in] pxNetworkBuffer: The network buffer carrying the TCP packet. 235 * 236 * @return Length of the packet to be sent. 237 */ prvTCPHandleFin(FreeRTOS_Socket_t * pxSocket,const NetworkBufferDescriptor_t * pxNetworkBuffer)238 static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t * pxSocket, 239 const NetworkBufferDescriptor_t * pxNetworkBuffer ) 240 { 241 /* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ 242 243 /* MISRA Ref 11.3.1 [Misaligned access] */ 244 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 245 /* coverity[misra_c_2012_rule_11_3_violation] */ 246 ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) 247 &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); 248 TCPHeader_t * pxTCPHeader = &( pxProtocolHeaders->xTCPHeader ); 249 uint8_t ucIntermediateResult = 0, ucTCPFlags = pxTCPHeader->ucTCPFlags; 250 TCPWindow_t * pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow; 251 BaseType_t xSendLength = 0; 252 uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr ); 253 254 if( ( ucTCPFlags & tcpTCP_FLAG_FIN ) != 0U ) 255 { 256 pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulFINSequenceNumber + 1U; 257 } 258 259 if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) 260 { 261 /* We haven't yet replied with a FIN, do so now. */ 262 pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber; 263 pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED; 264 } 265 else 266 { 267 /* We did send a FIN already, see if it's ACK'd. */ 268 if( ulAckNr == ( pxTCPWindow->tx.ulFINSequenceNumber + 1U ) ) 269 { 270 pxSocket->u.xTCP.bits.bFinAcked = pdTRUE_UNSIGNED; 271 } 272 } 273 274 if( pxSocket->u.xTCP.bits.bFinAcked == pdFALSE_UNSIGNED ) 275 { 276 pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber; 277 pxTCPHeader->ucTCPFlags = ( uint8_t ) tcpTCP_FLAG_ACK | ( uint8_t ) tcpTCP_FLAG_FIN; 278 279 /* And wait for the final ACK. */ 280 vTCPStateChange( pxSocket, eLAST_ACK ); 281 } 282 else 283 { 284 /* Our FIN has been ACK'd, the outgoing sequence number is now fixed. */ 285 pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber + 1U; 286 287 if( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED ) 288 { 289 /* We have sent out a FIN but the peer hasn't replied with a FIN 290 * yet. Do nothing for the moment. */ 291 pxTCPHeader->ucTCPFlags = 0U; 292 } 293 else 294 { 295 if( pxSocket->u.xTCP.bits.bFinLast == pdFALSE_UNSIGNED ) 296 { 297 /* This is the third of the three-way hand shake: the last 298 * ACK. */ 299 pxTCPHeader->ucTCPFlags = tcpTCP_FLAG_ACK; 300 } 301 else 302 { 303 /* The other party started the closure, so we just wait for the 304 * last ACK. */ 305 pxTCPHeader->ucTCPFlags = 0U; 306 } 307 308 /* And wait for the user to close this socket. */ 309 vTCPStateChange( pxSocket, eCLOSE_WAIT ); 310 } 311 } 312 313 pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber; 314 315 if( pxTCPHeader->ucTCPFlags != 0U ) 316 { 317 ucIntermediateResult = uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength; 318 xSendLength = ( BaseType_t ) ucIntermediateResult; 319 } 320 321 pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength ) << 2 ); 322 323 if( xTCPWindowLoggingLevel != 0 ) 324 { 325 FreeRTOS_debug_printf( ( "TCP: send FIN+ACK (ack %u, cur/nxt %u/%u) ourSeqNr %u | Rx %u\n", 326 ( unsigned ) ( ulAckNr - pxTCPWindow->tx.ulFirstSequenceNumber ), 327 ( unsigned ) ( pxTCPWindow->tx.ulCurrentSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber ), 328 ( unsigned ) ( pxTCPWindow->ulNextTxSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber ), 329 ( unsigned ) ( pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber ), 330 ( unsigned ) ( pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) ) ); 331 } 332 333 return xSendLength; 334 } 335 /*-----------------------------------------------------------*/ 336 337 338 /** 339 * @brief prvHandleSynReceived(): called from prvTCPHandleState(). Called 340 * from the states: eSYN_RECEIVED and eCONNECT_SYN. If the flags 341 * received are correct, the socket will move to eESTABLISHED. 342 * 343 * @param[in] pxSocket: The socket handling the connection. 344 * @param[in] pxNetworkBuffer: The pointer to the network buffer carrying 345 * the packet. 346 * @param[in] ulReceiveLength: Length in bytes of the data received. 347 * @param[in] uxOptionsLength: Length of the TCP options in bytes. 348 * 349 * @return Length of the data to be sent. 350 */ prvHandleSynReceived(FreeRTOS_Socket_t * pxSocket,const NetworkBufferDescriptor_t * pxNetworkBuffer,uint32_t ulReceiveLength,UBaseType_t uxOptionsLength)351 static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t * pxSocket, 352 const NetworkBufferDescriptor_t * pxNetworkBuffer, 353 uint32_t ulReceiveLength, 354 UBaseType_t uxOptionsLength ) 355 { 356 /* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ 357 358 /* MISRA Ref 11.3.1 [Misaligned access] */ 359 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 360 /* coverity[misra_c_2012_rule_11_3_violation] */ 361 ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) 362 &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); 363 TCPHeader_t * pxTCPHeader = &pxProtocolHeaders->xTCPHeader; 364 TCPWindow_t * pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow; 365 uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags; 366 uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ); 367 BaseType_t xSendLength = 0; 368 UBaseType_t uxIntermediateResult = 0U; 369 370 /* Either expect a ACK or a SYN+ACK. */ 371 uint8_t ucExpect = tcpTCP_FLAG_ACK; 372 const uint8_t ucFlagsMask = tcpTCP_FLAG_ACK | tcpTCP_FLAG_RST | tcpTCP_FLAG_SYN | tcpTCP_FLAG_FIN; 373 374 if( pxSocket->u.xTCP.eTCPState == eCONNECT_SYN ) 375 { 376 ucExpect |= tcpTCP_FLAG_SYN; 377 } 378 379 if( ( ucTCPFlags & ucFlagsMask ) != ucExpect ) 380 { 381 /* eSYN_RECEIVED: flags 0010 expected, not 0002. */ 382 /* eSYN_RECEIVED: flags ACK expected, not SYN. */ 383 FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n", 384 ( pxSocket->u.xTCP.eTCPState == ( uint8_t ) eSYN_RECEIVED ) ? "eSYN_RECEIVED" : "eCONNECT_SYN", 385 ucExpect, ucTCPFlags ) ); 386 387 /* In case pxSocket is not yet owned by the application, a closure 388 * of the socket will be scheduled for the next cycle. */ 389 vTCPStateChange( pxSocket, eCLOSE_WAIT ); 390 391 /* Send RST with the expected sequence and ACK numbers, 392 * otherwise the packet will be ignored. */ 393 pxTCPWindow->ulOurSequenceNumber = FreeRTOS_htonl( pxTCPHeader->ulAckNr ); 394 pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber; 395 396 pxTCPHeader->ucTCPFlags |= tcpTCP_FLAG_RST; 397 398 uxIntermediateResult = uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength; 399 xSendLength = ( BaseType_t ) uxIntermediateResult; 400 401 pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 ); 402 } 403 else 404 { 405 pxTCPWindow->usPeerPortNumber = pxSocket->u.xTCP.usRemotePort; 406 pxTCPWindow->usOurPortNumber = pxSocket->usLocalPort; 407 408 if( pxSocket->u.xTCP.eTCPState == eCONNECT_SYN ) 409 { 410 /* Map the Last packet onto the ProtocolHeader_t struct for easy access to the fields. */ 411 412 /* MISRA Ref 11.3.1 [Misaligned access] */ 413 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 414 /* coverity[misra_c_2012_rule_11_3_violation] */ 415 ProtocolHeaders_t * pxLastHeaders = ( ( ProtocolHeaders_t * ) 416 &( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); 417 418 /* Clear the SYN flag in lastPacket. */ 419 pxLastHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_ACK; 420 pxProtocolHeaders->xTCPHeader.ucTCPFlags = tcpTCP_FLAG_ACK; 421 422 /* This socket was the one connecting actively so now perform the 423 * synchronisation. */ 424 vTCPWindowInit( &pxSocket->u.xTCP.xTCPWindow, 425 ulSequenceNumber, pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber, ( uint32_t ) pxSocket->u.xTCP.usMSS ); 426 pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1U; 427 pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber + 1U; 428 pxTCPWindow->tx.ulCurrentSequenceNumber++; /* because we send a TCP_SYN [ | TCP_ACK ]; */ 429 pxTCPWindow->ulNextTxSequenceNumber++; 430 } 431 else if( ulReceiveLength == 0U ) 432 { 433 pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber; 434 } 435 else 436 { 437 /* Nothing. */ 438 } 439 440 /* The SYN+ACK has been confirmed, increase the next sequence number by 441 * 1. */ 442 pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1U; 443 444 #if ( ipconfigUSE_TCP_WIN == 1 ) 445 { 446 FreeRTOS_debug_printf( ( "TCP: %s %u => %xip:%u set ESTAB (scaling %u)\n", 447 ( pxSocket->u.xTCP.eTCPState == ( uint8_t ) eCONNECT_SYN ) ? "active" : "passive", 448 pxSocket->usLocalPort, 449 ( unsigned ) pxSocket->u.xTCP.ulRemoteIP, 450 pxSocket->u.xTCP.usRemotePort, 451 ( unsigned ) pxSocket->u.xTCP.bits.bWinScaling ) ); 452 } 453 #endif /* ipconfigUSE_TCP_WIN */ 454 455 if( ( pxSocket->u.xTCP.eTCPState == eCONNECT_SYN ) || ( ulReceiveLength != 0U ) ) 456 { 457 pxTCPHeader->ucTCPFlags = tcpTCP_FLAG_ACK; 458 459 uxIntermediateResult = uxIPHeaderSizeSocket( pxSocket ) + ( size_t ) ipSIZE_OF_TCP_HEADER + uxOptionsLength; 460 xSendLength = ( BaseType_t ) uxIntermediateResult; 461 pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 ); 462 } 463 464 #if ( ipconfigUSE_TCP_WIN != 0 ) 465 { 466 if( pxSocket->u.xTCP.bits.bWinScaling == pdFALSE_UNSIGNED ) 467 { 468 /* The other party did not send a scaling factor. 469 * A shifting factor in this side must be canceled. */ 470 pxSocket->u.xTCP.ucMyWinScaleFactor = 0; 471 pxSocket->u.xTCP.ucPeerWinScaleFactor = 0; 472 } 473 } 474 #endif /* ipconfigUSE_TCP_WIN */ 475 476 /* This was the third step of connecting: SYN, SYN+ACK, ACK so now the 477 * connection is established. */ 478 vTCPStateChange( pxSocket, eESTABLISHED ); 479 } 480 481 return xSendLength; 482 } 483 /*-----------------------------------------------------------*/ 484 485 /** 486 * @brief prvHandleEstablished(): called from prvTCPHandleState() 487 * Called if the status is eESTABLISHED. Data reception has been handled 488 * earlier. Here the ACK's from peer will be checked, and if a FIN is received, 489 * the code will check if it may be accepted, i.e. if all expected data has been 490 * completely received. 491 * 492 * @param[in] pxSocket: The socket owning the connection. 493 * @param[in,out] ppxNetworkBuffer: Pointer to pointer to the network buffer. 494 * @param[in] ulReceiveLength: The length of the received packet. 495 * @param[in] uxOptionsLength: Length of TCP options. 496 * 497 * @return The send length of the packet to be sent. 498 */ prvHandleEstablished(FreeRTOS_Socket_t * pxSocket,NetworkBufferDescriptor_t ** ppxNetworkBuffer,uint32_t ulReceiveLength,UBaseType_t uxOptionsLength)499 static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t * pxSocket, 500 NetworkBufferDescriptor_t ** ppxNetworkBuffer, 501 uint32_t ulReceiveLength, 502 UBaseType_t uxOptionsLength ) 503 { 504 /* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */ 505 506 /* MISRA Ref 11.3.1 [Misaligned access] */ 507 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 508 /* coverity[misra_c_2012_rule_11_3_violation] */ 509 ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) 510 &( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); 511 TCPHeader_t * pxTCPHeader = &pxProtocolHeaders->xTCPHeader; 512 TCPWindow_t * pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow; 513 uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags; 514 uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ), ulCount, ulIntermediateResult = 0; 515 BaseType_t xSendLength = 0, xMayClose = pdFALSE, bRxComplete, bTxDone; 516 int32_t lDistance, lSendResult; 517 uint16_t usWindow; 518 UBaseType_t uxIntermediateResult = 0; 519 520 /* Remember the window size the peer is advertising. */ 521 usWindow = FreeRTOS_ntohs( pxTCPHeader->usWindow ); 522 pxSocket->u.xTCP.ulWindowSize = ( uint32_t ) usWindow; 523 #if ( ipconfigUSE_TCP_WIN != 0 ) 524 { 525 pxSocket->u.xTCP.ulWindowSize = 526 ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor ); 527 } 528 #endif /* ipconfigUSE_TCP_WIN */ 529 530 if( ( ucTCPFlags & ( uint8_t ) tcpTCP_FLAG_ACK ) == 0U ) 531 { 532 /* RFC793: If ACK bit is not set at this state, the segment should 533 * be dropped 534 */ 535 } 536 else 537 { 538 ulCount = ulTCPWindowTxAck( pxTCPWindow, FreeRTOS_ntohl( pxTCPHeader->ulAckNr ) ); 539 540 /* ulTCPWindowTxAck() returns the number of bytes which have been acked, 541 * starting at 'tx.ulCurrentSequenceNumber'. Advance the tail pointer in 542 * txStream. */ 543 if( ( pxSocket->u.xTCP.txStream != NULL ) && ( ulCount > 0U ) ) 544 { 545 /* Just advancing the tail index, 'ulCount' bytes have been 546 * confirmed, and because there is new space in the txStream, the 547 * user/owner should be woken up. */ 548 /* _HT_ : only in case the socket's waiting? */ 549 if( uxStreamBufferGet( pxSocket->u.xTCP.txStream, 0U, NULL, ( size_t ) ulCount, pdFALSE ) != 0U ) 550 { 551 pxSocket->xEventBits |= ( EventBits_t ) eSOCKET_SEND; 552 553 #if ipconfigSUPPORT_SELECT_FUNCTION == 1 554 { 555 if( ( pxSocket->xSelectBits & ( ( EventBits_t ) eSELECT_WRITE ) ) != 0U ) 556 { 557 pxSocket->xEventBits |= ( ( EventBits_t ) eSELECT_WRITE ) << SOCKET_EVENT_BIT_COUNT; 558 } 559 } 560 #endif 561 562 /* In case the socket owner has installed an OnSent handler, 563 * call it now. */ 564 #if ( ipconfigUSE_CALLBACKS == 1 ) 565 { 566 if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleSent ) ) 567 { 568 pxSocket->u.xTCP.pxHandleSent( ( Socket_t ) pxSocket, ulCount ); 569 } 570 } 571 #endif /* ipconfigUSE_CALLBACKS == 1 */ 572 } 573 } 574 575 /* If this socket has a stream for transmission, add the data to the 576 * outgoing segment(s). */ 577 if( pxSocket->u.xTCP.txStream != NULL ) 578 { 579 prvTCPAddTxData( pxSocket ); 580 } 581 582 pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber; 583 584 if( ( pxSocket->u.xTCP.bits.bFinAccepted != pdFALSE_UNSIGNED ) || ( ( ucTCPFlags & ( uint8_t ) tcpTCP_FLAG_FIN ) != 0U ) ) 585 { 586 /* Peer is requesting to stop, see if we're really finished. */ 587 xMayClose = pdTRUE; 588 589 /* Checks are only necessary if we haven't sent a FIN yet. */ 590 if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) 591 { 592 /* xTCPWindowTxDone returns true when all Tx queues are empty. */ 593 bRxComplete = xTCPWindowRxEmpty( pxTCPWindow ); 594 bTxDone = xTCPWindowTxDone( pxTCPWindow ); 595 596 if( ( bRxComplete == 0 ) || ( bTxDone == 0 ) ) 597 { 598 /* Refusing FIN: Rx incomplete 1 optlen 4 tx done 1. */ 599 FreeRTOS_debug_printf( ( "Refusing FIN[%u,%u]: RxCompl %d tx done %d\n", 600 pxSocket->usLocalPort, 601 pxSocket->u.xTCP.usRemotePort, 602 ( int ) bRxComplete, 603 ( int ) bTxDone ) ); 604 xMayClose = pdFALSE; 605 } 606 else 607 { 608 ulIntermediateResult = ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber; 609 lDistance = ( int32_t ) ulIntermediateResult; 610 611 if( lDistance > 1 ) 612 { 613 FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %d (cur %u high %u)\n", 614 ( int ) lDistance, 615 ( unsigned ) ( pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ), 616 ( unsigned ) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) ) ); 617 618 xMayClose = pdFALSE; 619 } 620 } 621 } 622 623 if( xTCPWindowLoggingLevel > 0 ) 624 { 625 FreeRTOS_debug_printf( ( "TCP: FIN received, mayClose = %d (Rx %u Len %d, Tx %u)\n", 626 ( int ) xMayClose, 627 ( unsigned ) ( ulSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber ), 628 ( unsigned ) ulReceiveLength, 629 ( unsigned ) ( pxTCPWindow->tx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber ) ) ); 630 } 631 632 if( xMayClose != pdFALSE ) 633 { 634 pxSocket->u.xTCP.bits.bFinAccepted = pdTRUE_UNSIGNED; 635 xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer ); 636 } 637 } 638 639 if( xMayClose == pdFALSE ) 640 { 641 pxTCPHeader->ucTCPFlags = tcpTCP_FLAG_ACK; 642 643 if( ulReceiveLength != 0U ) 644 { 645 uxIntermediateResult = uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength; 646 xSendLength = ( BaseType_t ) uxIntermediateResult; 647 /* TCP-offset equals '( ( length / 4 ) << 4 )', resulting in a shift-left 2 */ 648 pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 ); 649 650 if( pxSocket->u.xTCP.bits.bFinSent != pdFALSE_UNSIGNED ) 651 { 652 pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber; 653 } 654 } 655 656 /* Now get data to be transmitted. */ 657 658 /* _HT_ patch: since the MTU has be fixed at 1500 in stead of 1526, TCP 659 * can not send-out both TCP options and also a full packet. Sending 660 * options (SACK) is always more urgent than sending data, which can be 661 * sent later. */ 662 if( uxOptionsLength == 0U ) 663 { 664 /* prvTCPPrepareSend might allocate a bigger network buffer, if 665 * necessary. */ 666 lSendResult = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength ); 667 668 if( lSendResult > 0 ) 669 { 670 xSendLength = ( BaseType_t ) lSendResult; 671 } 672 } 673 } 674 } 675 676 return xSendLength; 677 } 678 /*-----------------------------------------------------------*/ 679 680 681 /** 682 * @brief Check incoming packets for valid data and handle the state of the 683 * TCP connection and respond according to the situation. 684 * 685 * @param[in] pxSocket: The socket whose connection state is being handled. 686 * @param[in] ppxNetworkBuffer: The network buffer descriptor holding the 687 * packet received from the peer. 688 * 689 * @return If the data is correct and some packet was sent to the peer, then 690 * the number of bytes sent is returned, or else a negative value is 691 * returned indicating an error. 692 * 693 * @note prvTCPHandleState() is the most important function of this TCP stack 694 * We've tried to keep it (relatively short) by putting a lot of code in 695 * the static functions above: 696 * 697 * prvCheckRxData() 698 * prvStoreRxData() 699 * prvSetOptions() 700 * prvHandleSynReceived() 701 * prvHandleEstablished() 702 * prvSendData() 703 * 704 * As these functions are declared static, and they're called from one location 705 * only, most compilers will inline them, thus avoiding a call and return. 706 */ prvTCPHandleState(FreeRTOS_Socket_t * pxSocket,NetworkBufferDescriptor_t ** ppxNetworkBuffer)707 BaseType_t prvTCPHandleState( FreeRTOS_Socket_t * pxSocket, 708 NetworkBufferDescriptor_t ** ppxNetworkBuffer ) 709 { 710 /* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */ 711 712 /* MISRA Ref 11.3.1 [Misaligned access] */ 713 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 714 /* coverity[misra_c_2012_rule_11_3_violation] */ 715 ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) 716 &( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) ); 717 TCPHeader_t * pxTCPHeader = &( pxProtocolHeaders->xTCPHeader ); 718 BaseType_t xSendLength = 0; 719 uint32_t ulReceiveLength; /* Number of bytes contained in the TCP message. */ 720 uint8_t * pucRecvData; 721 uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ); 722 723 /* uxOptionsLength: the size of the options to be sent (always a multiple of 724 * 4 bytes) 725 * 1. in the SYN phase, we shall communicate the MSS 726 * 2. in case of a SACK, Selective ACK, ack a segment which comes in 727 * out-of-order. */ 728 UBaseType_t uxOptionsLength = 0U; 729 uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags; 730 TCPWindow_t * pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow ); 731 UBaseType_t uxIntermediateResult = 0; 732 uint32_t ulSum; 733 734 /* First get the length and the position of the received data, if any. 735 * pucRecvData will point to the first byte of the TCP payload. */ 736 ulReceiveLength = ( uint32_t ) prvCheckRxData( *ppxNetworkBuffer, &pucRecvData ); 737 738 if( pxSocket->u.xTCP.eTCPState >= eESTABLISHED ) 739 { 740 if( pxTCPWindow->rx.ulCurrentSequenceNumber == ( ulSequenceNumber + 1U ) ) 741 { 742 /* This is most probably a keep-alive message from peer. Setting 743 * 'bWinChange' doesn't cause a window-size-change, the flag is used 744 * here to force sending an immediate ACK. */ 745 pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED; 746 } 747 } 748 749 /* Keep track of the highest sequence number that might be expected within 750 * this connection. */ 751 ulSum = ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulHighestSequenceNumber; 752 753 if( ( ( int32_t ) ulSum ) > 0 ) 754 { 755 pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + ulReceiveLength; 756 } 757 758 /* Storing data may result in a fatal error if malloc() fails. */ 759 if( prvStoreRxData( pxSocket, pucRecvData, *ppxNetworkBuffer, ulReceiveLength ) < 0 ) 760 { 761 xSendLength = -1; 762 } 763 else 764 { 765 eIPTCPState_t eState; 766 767 uxOptionsLength = prvSetOptions( pxSocket, *ppxNetworkBuffer ); 768 769 if( ( pxSocket->u.xTCP.eTCPState == eSYN_RECEIVED ) && ( ( ucTCPFlags & ( uint8_t ) tcpTCP_FLAG_CTRL ) == ( uint8_t ) tcpTCP_FLAG_SYN ) ) 770 { 771 FreeRTOS_debug_printf( ( "eSYN_RECEIVED: ACK expected, not SYN: peer missed our SYN+ACK\n" ) ); 772 773 /* In eSYN_RECEIVED a simple ACK is expected, but apparently the 774 * 'SYN+ACK' didn't arrive. Step back to the previous state in which 775 * a first incoming SYN is handled. The SYN was counted already so 776 * decrease it first. */ 777 vTCPStateChange( pxSocket, eSYN_FIRST ); 778 } 779 780 if( ( ( ucTCPFlags & tcpTCP_FLAG_FIN ) != 0U ) && ( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED ) ) 781 { 782 /* It's the first time a FIN has been received, remember its 783 * sequence number. */ 784 pxTCPWindow->rx.ulFINSequenceNumber = ulSequenceNumber + ulReceiveLength; 785 pxSocket->u.xTCP.bits.bFinRecv = pdTRUE_UNSIGNED; 786 787 /* Was peer the first one to send a FIN? */ 788 if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) 789 { 790 /* If so, don't send the-last-ACK. */ 791 pxSocket->u.xTCP.bits.bFinLast = pdTRUE_UNSIGNED; 792 } 793 } 794 795 eState = ( eIPTCPState_t ) pxSocket->u.xTCP.eTCPState; 796 797 switch( eState ) 798 { 799 case eCLOSED: /* (server + client) no connection state at all. */ 800 801 /* Nothing to do for a closed socket, except waiting for the 802 * owner. */ 803 break; 804 805 case eTCP_LISTEN: /* (server) waiting for a connection request from 806 * any remote TCP and port. */ 807 808 /* The listen state was handled in xProcessReceivedTCPPacket(). 809 * Should not come here. */ 810 break; 811 812 case eSYN_FIRST: /* (server) Just received a SYN request for a server 813 * socket. */ 814 815 /* A new socket has been created, reply with a SYN+ACK. 816 * Acknowledge with seq+1 because the SYN is seen as pseudo data 817 * with len = 1. */ 818 uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPHeader ); 819 pxTCPHeader->ucTCPFlags = ( uint8_t ) tcpTCP_FLAG_SYN | ( uint8_t ) tcpTCP_FLAG_ACK; 820 821 uxIntermediateResult = uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength; 822 xSendLength = ( BaseType_t ) uxIntermediateResult; 823 824 /* Set the TCP offset field: ipSIZE_OF_TCP_HEADER equals 20 and 825 * uxOptionsLength is a multiple of 4. The complete expression is: 826 * ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */ 827 pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 ); 828 vTCPStateChange( pxSocket, eSYN_RECEIVED ); 829 830 pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1U; 831 pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber + 1U; 832 pxTCPWindow->ulNextTxSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1U; 833 pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1U; /* because we send a TCP_SYN. */ 834 break; 835 836 case eCONNECT_SYN: /* (client) also called SYN_SENT: we've just send a 837 * SYN, expect a SYN+ACK and send a ACK now. */ 838 /* Fall through */ 839 case eSYN_RECEIVED: /* (server) we've had a SYN, replied with SYN+SCK 840 * expect a ACK and do nothing. */ 841 xSendLength = prvHandleSynReceived( pxSocket, *( ppxNetworkBuffer ), ulReceiveLength, uxOptionsLength ); 842 break; 843 844 case eESTABLISHED: /* (server + client) an open connection, data 845 * received can be delivered to the user. The normal 846 * state for the data transfer phase of the connection 847 * The closing states are also handled here with the 848 * use of some flags. */ 849 xSendLength = prvHandleEstablished( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength ); 850 break; 851 852 case eLAST_ACK: /* (server + client) waiting for an acknowledgement 853 * of the connection termination request previously 854 * sent to the remote TCP (which includes an 855 * acknowledgement of its connection termination 856 * request). */ 857 /* Fall through */ 858 case eFIN_WAIT_1: /* (server + client) waiting for a connection termination request from the remote TCP, 859 * or an acknowledgement of the connection termination request previously sent. */ 860 /* Fall through */ 861 case eFIN_WAIT_2: /* (server + client) waiting for a connection termination request from the remote TCP. */ 862 xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer ); 863 break; 864 865 case eCLOSE_WAIT: /* (server + client) waiting for a connection 866 * termination request from the local user. Nothing to 867 * do, connection is closed, wait for owner to close 868 * this socket. */ 869 break; 870 871 case eCLOSING: /* (server + client) waiting for a connection 872 * termination request acknowledgement from the remote 873 * TCP. */ 874 break; 875 876 case eTIME_WAIT: /* (either server or client) waiting for enough time 877 * to pass to be sure the remote TCP received the 878 * acknowledgement of its connection termination 879 * request. [According to RFC 793 a connection can stay 880 * in TIME-WAIT for a maximum of four minutes known as 881 * a MSL (maximum segment lifetime).] These states are 882 * implemented implicitly by settings flags like 883 * 'bFinSent', 'bFinRecv', and 'bFinAcked'. */ 884 break; 885 886 default: 887 /* No more known states. */ 888 break; 889 } 890 } 891 892 if( xSendLength > 0 ) 893 { 894 xSendLength = prvSendData( pxSocket, ppxNetworkBuffer, ulReceiveLength, xSendLength ); 895 } 896 897 return xSendLength; 898 } 899 /*-----------------------------------------------------------*/ 900 901 /** 902 * @brief Handle 'listen' event on the given socket. 903 * 904 * @param[in] pxSocket: The socket on which the listen occurred. 905 * @param[in] pxNetworkBuffer: The network buffer carrying the packet. 906 * 907 * @return If a new socket/duplicate socket is created, then the pointer to 908 * that socket is returned or else, a NULL pointer is returned. 909 */ prvHandleListen(FreeRTOS_Socket_t * pxSocket,NetworkBufferDescriptor_t * pxNetworkBuffer)910 FreeRTOS_Socket_t * prvHandleListen( FreeRTOS_Socket_t * pxSocket, 911 NetworkBufferDescriptor_t * pxNetworkBuffer ) 912 { 913 /* Map the ethernet buffer onto a TCPPacket_t struct for easy access to the fields. */ 914 915 /* MISRA Ref 11.3.1 [Misaligned access] */ 916 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 917 /* coverity[misra_c_2012_rule_11_3_violation] */ 918 const TCPPacket_t * pxTCPPacket = ( ( const TCPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer ); 919 FreeRTOS_Socket_t * pxReturn = NULL; 920 uint32_t ulInitialSequenceNumber; 921 922 /* Silently discard a SYN packet which was not specifically sent for this node. */ 923 if( pxTCPPacket->xIPHeader.ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER ) 924 { 925 /* Assume that a new Initial Sequence Number will be required. Request 926 * it now in order to fail out if necessary. */ 927 ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER, 928 pxSocket->usLocalPort, 929 pxTCPPacket->xIPHeader.ulSourceIPAddress, 930 pxTCPPacket->xTCPHeader.usSourcePort ); 931 } 932 else 933 { 934 /* Set the sequence number to 0 to avoid further processing. */ 935 ulInitialSequenceNumber = 0U; 936 } 937 938 /* A pure SYN (without ACK) has come in, create a new socket to answer 939 * it. */ 940 if( ulInitialSequenceNumber != 0U ) 941 { 942 if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED ) 943 { 944 /* The flag bReuseSocket indicates that the same instance of the 945 * listening socket should be used for the connection. */ 946 pxReturn = pxSocket; 947 pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; 948 pxSocket->u.xTCP.pxPeerSocket = pxSocket; 949 } 950 else 951 { 952 /* The socket does not have the bReuseSocket flag set meaning create a 953 * new socket when a connection comes in. */ 954 pxReturn = NULL; 955 956 if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog ) 957 { 958 FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n", 959 pxSocket->usLocalPort, 960 pxSocket->u.xTCP.usChildCount, 961 pxSocket->u.xTCP.usBacklog, 962 ( pxSocket->u.xTCP.usChildCount == 1U ) ? "" : "ren" ) ); 963 ( void ) prvTCPSendReset( pxNetworkBuffer ); 964 } 965 else 966 { 967 FreeRTOS_Socket_t * pxNewSocket = ( FreeRTOS_Socket_t * ) 968 FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); 969 970 /* MISRA Ref 11.4.1 [Socket error and integer to pointer conversion] */ 971 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */ 972 /* coverity[misra_c_2012_rule_11_4_violation] */ 973 if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) ) 974 { 975 FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) ); 976 ( void ) prvTCPSendReset( pxNetworkBuffer ); 977 } 978 else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE ) 979 { 980 /* The socket will be connected immediately, no time for the 981 * owner to setsockopt's, therefore copy properties of the server 982 * socket to the new socket. Only the binding might fail (due to 983 * lack of resources). */ 984 pxReturn = pxNewSocket; 985 } 986 else 987 { 988 /* Copying failed somehow. */ 989 } 990 } 991 } 992 } 993 994 if( ( ulInitialSequenceNumber != 0U ) && ( pxReturn != NULL ) ) 995 { 996 /* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */ 997 998 /* MISRA Ref 11.3.1 [Misaligned access] */ 999 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ 1000 /* coverity[misra_c_2012_rule_11_3_violation] */ 1001 const ProtocolHeaders_t * pxProtocolHeaders = ( ( const ProtocolHeaders_t * ) 1002 &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); 1003 1004 pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort ); 1005 pxReturn->u.xTCP.ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress ); 1006 pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber; 1007 1008 /* Here is the SYN action. */ 1009 pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxProtocolHeaders->xTCPHeader.ulSequenceNumber ); 1010 prvSocketSetMSS( pxReturn ); 1011 1012 prvTCPCreateWindow( pxReturn ); 1013 1014 vTCPStateChange( pxReturn, eSYN_FIRST ); 1015 1016 /* Make a copy of the header up to the TCP header. It is needed later 1017 * on, whenever data must be sent to the peer. */ 1018 ( void ) memcpy( ( void * ) pxReturn->u.xTCP.xPacket.u.ucLastPacket, 1019 ( const void * ) pxNetworkBuffer->pucEthernetBuffer, 1020 sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) ); 1021 } 1022 1023 return pxReturn; 1024 } 1025 /*-----------------------------------------------------------*/ 1026 1027 1028 /** 1029 * @brief Duplicates a socket after a listening socket receives a connection and bind 1030 * the new socket to the same port as the listening socket. 1031 * Also, let the new socket inherit all properties from the listening socket. 1032 * 1033 * @param[in] pxNewSocket: Pointer to the new socket. 1034 * @param[in] pxSocket: Pointer to the socket being duplicated. 1035 * 1036 * @return If all steps all successful, then pdTRUE is returned. Else, pdFALSE. 1037 */ prvTCPSocketCopy(FreeRTOS_Socket_t * pxNewSocket,FreeRTOS_Socket_t * pxSocket)1038 static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t * pxNewSocket, 1039 FreeRTOS_Socket_t * pxSocket ) 1040 { 1041 struct freertos_sockaddr xAddress; 1042 BaseType_t xResult; 1043 1044 pxNewSocket->xReceiveBlockTime = pxSocket->xReceiveBlockTime; 1045 pxNewSocket->xSendBlockTime = pxSocket->xSendBlockTime; 1046 pxNewSocket->ucSocketOptions = pxSocket->ucSocketOptions; 1047 pxNewSocket->u.xTCP.uxRxStreamSize = pxSocket->u.xTCP.uxRxStreamSize; 1048 pxNewSocket->u.xTCP.uxTxStreamSize = pxSocket->u.xTCP.uxTxStreamSize; 1049 pxNewSocket->u.xTCP.uxLittleSpace = pxSocket->u.xTCP.uxLittleSpace; 1050 pxNewSocket->u.xTCP.uxEnoughSpace = pxSocket->u.xTCP.uxEnoughSpace; 1051 pxNewSocket->u.xTCP.uxRxWinSize = pxSocket->u.xTCP.uxRxWinSize; 1052 pxNewSocket->u.xTCP.uxTxWinSize = pxSocket->u.xTCP.uxTxWinSize; 1053 1054 #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 ) 1055 { 1056 pxNewSocket->pxUserSemaphore = pxSocket->pxUserSemaphore; 1057 } 1058 #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */ 1059 1060 #if ( ipconfigUSE_CALLBACKS == 1 ) 1061 { 1062 /* In case call-backs are used, copy them from parent to child. */ 1063 pxNewSocket->u.xTCP.pxHandleConnected = pxSocket->u.xTCP.pxHandleConnected; 1064 pxNewSocket->u.xTCP.pxHandleReceive = pxSocket->u.xTCP.pxHandleReceive; 1065 pxNewSocket->u.xTCP.pxHandleSent = pxSocket->u.xTCP.pxHandleSent; 1066 } 1067 #endif /* ipconfigUSE_CALLBACKS */ 1068 1069 #if ( ipconfigSUPPORT_SELECT_FUNCTION == 1 ) 1070 { 1071 /* Child socket of listening sockets will inherit the Socket Set 1072 * Otherwise the owner has no chance of including it into the set. */ 1073 if( pxSocket->pxSocketSet != NULL ) 1074 { 1075 pxNewSocket->pxSocketSet = pxSocket->pxSocketSet; 1076 pxNewSocket->xSelectBits = pxSocket->xSelectBits | ( ( EventBits_t ) eSELECT_READ ) | ( ( EventBits_t ) eSELECT_EXCEPT ); 1077 } 1078 } 1079 #endif /* ipconfigSUPPORT_SELECT_FUNCTION */ 1080 1081 /* And bind it to the same local port as its parent. */ 1082 xAddress.sin_addr = *ipLOCAL_IP_ADDRESS_POINTER; 1083 xAddress.sin_port = FreeRTOS_htons( pxSocket->usLocalPort ); 1084 1085 #if ( ipconfigTCP_HANG_PROTECTION == 1 ) 1086 { 1087 /* Only when there is anti-hanging protection, a socket may become an 1088 * orphan temporarily. Once this socket is really connected, the owner of 1089 * the server socket will be notified. */ 1090 1091 /* When bPassQueued is true, the socket is an orphan until it gets 1092 * connected. */ 1093 pxNewSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED; 1094 pxNewSocket->u.xTCP.pxPeerSocket = pxSocket; 1095 } 1096 #else 1097 { 1098 /* A reference to the new socket may be stored and the socket is marked 1099 * as 'passable'. */ 1100 1101 /* When bPassAccept is true, this socket may be returned in a call to 1102 * accept(). */ 1103 pxNewSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED; 1104 1105 if( pxSocket->u.xTCP.pxPeerSocket == NULL ) 1106 { 1107 pxSocket->u.xTCP.pxPeerSocket = pxNewSocket; 1108 } 1109 } 1110 #endif /* if ( ipconfigTCP_HANG_PROTECTION == 1 ) */ 1111 1112 pxSocket->u.xTCP.usChildCount++; 1113 1114 FreeRTOS_debug_printf( ( "Gain: Socket %u now has %u / %u child%s\n", 1115 pxSocket->usLocalPort, 1116 pxSocket->u.xTCP.usChildCount, 1117 pxSocket->u.xTCP.usBacklog, 1118 ( pxSocket->u.xTCP.usChildCount == 1U ) ? "" : "ren" ) ); 1119 1120 /* Now bind the child socket to the same port as the listening socket. */ 1121 if( vSocketBind( pxNewSocket, &xAddress, sizeof( xAddress ), pdTRUE ) != 0 ) 1122 { 1123 FreeRTOS_debug_printf( ( "TCP: Listen: new socket bind error\n" ) ); 1124 ( void ) vSocketClose( pxNewSocket ); 1125 xResult = pdFALSE; 1126 } 1127 else 1128 { 1129 xResult = pdTRUE; 1130 } 1131 1132 return xResult; 1133 } 1134 /*-----------------------------------------------------------*/ 1135 1136 #if ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) ) 1137 FreeRTOS_GetTCPStateName(UBaseType_t ulState)1138 const char * FreeRTOS_GetTCPStateName( UBaseType_t ulState ) 1139 { 1140 static const char * const pcStateNames[] = 1141 { 1142 "eCLOSED", 1143 "eTCP_LISTEN", 1144 "eCONNECT_SYN", 1145 "eSYN_FIRST", 1146 "eSYN_RECEIVED", 1147 "eESTABLISHED", 1148 "eFIN_WAIT_1", 1149 "eFIN_WAIT_2", 1150 "eCLOSE_WAIT", 1151 "eCLOSING", 1152 "eLAST_ACK", 1153 "eTIME_WAIT", 1154 "eUNKNOWN", 1155 }; 1156 BaseType_t xIndex = ( BaseType_t ) ulState; 1157 1158 if( ( xIndex < 0 ) || ( xIndex >= ARRAY_SIZE( pcStateNames ) ) ) 1159 { 1160 /* The last item is called 'eUNKNOWN' */ 1161 xIndex = ARRAY_SIZE( pcStateNames ); 1162 xIndex--; 1163 } 1164 1165 return pcStateNames[ xIndex ]; 1166 } 1167 1168 #endif /* ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) ) */ 1169 /*-----------------------------------------------------------*/ 1170 1171 #endif /* ipconfigUSE_TCP == 1 */ 1172