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