1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Component                                                        */
17 /**                                                                       */
18 /**   Transmission Control Protocol (TCP)                                 */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "nx_api.h"
29 #include "nx_ip.h"
30 #include "nx_tcp.h"
31 #ifdef NX_ENABLE_HTTP_PROXY
32 #include "nx_http_proxy_client.h"
33 #endif /* NX_ENABLE_HTTP_PROXY */
34 
35 
36 /**************************************************************************/
37 /*                                                                        */
38 /*  FUNCTION                                               RELEASE        */
39 /*                                                                        */
40 /*    _nx_tcp_socket_state_established                    PORTABLE C      */
41 /*                                                           6.2.0        */
42 /*  AUTHOR                                                                */
43 /*                                                                        */
44 /*    Yuxin Zhou, Microsoft Corporation                                   */
45 /*                                                                        */
46 /*  DESCRIPTION                                                           */
47 /*                                                                        */
48 /*    This function processes packets during the ESTABLISHED state,       */
49 /*    the state of the socket during typical TCP data sending and         */
50 /*    receiving.  The expected packet that changes state once in the      */
51 /*    established state is the FIN packet.  Reception of this will move   */
52 /*    the state for this socket to the CLOSE WAIT state.                  */
53 /*                                                                        */
54 /*  INPUT                                                                 */
55 /*                                                                        */
56 /*    socket_ptr                            Pointer to owning socket      */
57 /*                                                                        */
58 /*  OUTPUT                                                                */
59 /*                                                                        */
60 /*    None                                                                */
61 /*                                                                        */
62 /*  CALLS                                                                 */
63 /*                                                                        */
64 /*    _nx_tcp_packet_send_ack               Send ACK message              */
65 /*    (nx_tcp_disconnect_callback)          Application's callback        */
66 /*                                            function when disconnect    */
67 /*                                            FIN is received             */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    _nx_tcp_socket_packet_process         Process TCP packet for socket */
72 /*                                                                        */
73 /*  RELEASE HISTORY                                                       */
74 /*                                                                        */
75 /*    DATE              NAME                      DESCRIPTION             */
76 /*                                                                        */
77 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
78 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
79 /*                                            resulting in version 6.1    */
80 /*  10-31-2022     Wenhui Xie               Modified comment(s), and      */
81 /*                                            supported HTTP Proxy,       */
82 /*                                            resulting in version 6.2.0  */
83 /*                                                                        */
84 /**************************************************************************/
_nx_tcp_socket_state_established(NX_TCP_SOCKET * socket_ptr)85 VOID  _nx_tcp_socket_state_established(NX_TCP_SOCKET *socket_ptr)
86 {
87 #if !defined(NX_DISABLE_TCP_INFO) || defined(TX_ENABLE_EVENT_TRACE)
88 NX_IP *ip_ptr;
89 
90 
91     /* Setup the IP pointer.  */
92     ip_ptr =  socket_ptr -> nx_tcp_socket_ip_ptr;
93 #endif
94     /* Determine if a FIN has been previously detected in the _nx_tcp_socket_state_data_check
95        routine and if the socket's sequence number matches the expected FIN sequence number.  */
96     if ((socket_ptr -> nx_tcp_socket_fin_received) &&
97         (socket_ptr -> nx_tcp_socket_fin_sequence == socket_ptr -> nx_tcp_socket_rx_sequence))
98     {
99 
100 #ifndef NX_DISABLE_TCP_INFO
101         /* Increment the TCP disconnections count.  */
102         ip_ptr -> nx_ip_tcp_disconnections++;
103 #endif
104 
105 #ifdef NX_ENABLE_TCP_KEEPALIVE
106         /* Is the keepalive feature enabled on this socket? */
107         if (socket_ptr -> nx_tcp_socket_keepalive_enabled)
108         {
109             /* Clear the TCP Keepalive timer to disable it for this socket (only needed when
110                the socket is connected.  */
111             socket_ptr -> nx_tcp_socket_keepalive_timeout =  0;
112             socket_ptr -> nx_tcp_socket_keepalive_retries =  0;
113         }
114 #endif
115 
116         /* If trace is enabled, insert this event into the trace buffer.  */
117         NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_TCP_STATE_CHANGE, ip_ptr, socket_ptr, socket_ptr -> nx_tcp_socket_state, NX_TCP_CLOSE_WAIT, NX_TRACE_INTERNAL_EVENTS, 0, 0);
118 
119         /* The FIN bit is set, we need to go into the finished state.  */
120         socket_ptr -> nx_tcp_socket_state =  NX_TCP_CLOSE_WAIT;
121 
122         /* Increment the received sequence.  */
123         socket_ptr -> nx_tcp_socket_rx_sequence++;
124 
125         /* Loop to release all threads suspended while trying to receive on the socket.  */
126         while (socket_ptr -> nx_tcp_socket_receive_suspension_list)
127         {
128 
129             /* Release the head of the receive suspension list. */
130             _nx_tcp_receive_cleanup(socket_ptr -> nx_tcp_socket_receive_suspension_list NX_CLEANUP_ARGUMENT);
131         }
132 
133         /* Send ACK message.  */
134         _nx_tcp_packet_send_ack(socket_ptr, socket_ptr -> nx_tcp_socket_tx_sequence);
135 
136 #ifdef NX_ENABLE_HTTP_PROXY
137         if ((ip_ptr -> nx_ip_http_proxy_enable) &&
138             (socket_ptr -> nx_tcp_socket_http_proxy_state == NX_HTTP_PROXY_STATE_CONNECTING))
139         {
140 
141             /* If received FIN before HTTP Proxy connection established, disconnect the TCP connection
142                and don't notify the application.  */
143             _nx_tcp_socket_disconnect(socket_ptr, NX_NO_WAIT);
144         }
145         else
146 #endif /* NX_ENABLE_HTTP_PROXY */
147         {
148 
149             /* If given, call the application's disconnect callback function
150                for disconnect.  */
151             if (socket_ptr -> nx_tcp_disconnect_callback)
152             {
153 
154                 /* Call the application's disconnect handling function.  It is
155                    responsible for calling the socket disconnect function.  */
156                 (socket_ptr -> nx_tcp_disconnect_callback)(socket_ptr);
157             }
158         }
159     }
160 }
161 
162