1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Transmission Control Protocol (TCP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "tx_thread.h"
29 #include "tx_timer.h"
30 #include "nx_ip.h"
31 #include "nx_tcp.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nx_tcp_connect_cleanup PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* Yuxin Zhou, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function processes TCP connect timeout and thread terminate */
47 /* actions that require the TCP socket data structures to be cleaned */
48 /* up. */
49 /* */
50 /* INPUT */
51 /* */
52 /* thread_ptr Pointer to suspended thread's */
53 /* control block */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* None */
58 /* */
59 /* CALLS */
60 /* */
61 /* tx_event_flags_set Set event flag */
62 /* _tx_thread_system_resume Resume thread service */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* _nx_tcp_deferred_cleanup_check Deferred cleanup processing */
67 /* _nx_tcp_socket_connection_reset Socket reset processing */
68 /* _nx_tcp_socket_disconnect Socket disconnect processing */
69 /* _tx_thread_timeout Thread timeout processing */
70 /* _tx_thread_terminate Thread terminate processing */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
77 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
78 /* resulting in version 6.1 */
79 /* */
80 /**************************************************************************/
_nx_tcp_connect_cleanup(TX_THREAD * thread_ptr NX_CLEANUP_PARAMETER)81 VOID _nx_tcp_connect_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER)
82 {
83
84 TX_INTERRUPT_SAVE_AREA
85
86 NX_IP *ip_ptr;
87 NX_TCP_SOCKET *socket_ptr; /* Working socket pointer */
88
89 NX_CLEANUP_EXTENSION
90
91 /* Disable interrupts. */
92 TX_DISABLE
93
94 /* Setup pointer to TCP socket control block. */
95 socket_ptr = (NX_TCP_SOCKET *)thread_ptr -> tx_thread_suspend_control_block;
96
97 /* Determine if the socket pointer is valid. */
98 if ((!socket_ptr) || (socket_ptr -> nx_tcp_socket_id != NX_TCP_ID))
99 {
100
101 /* Restore interrupts. */
102 TX_RESTORE
103
104 return;
105 }
106
107 /* Determine if the cleanup is still required. */
108 if (!(thread_ptr -> tx_thread_suspend_cleanup))
109 {
110
111 /* Restore interrupts. */
112 TX_RESTORE
113
114 return;
115 }
116
117 /* Pickup the IP pointer. */
118 ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
119
120 /* Determine if the caller is an ISR or the system timer thread. */
121 #ifndef TX_TIMER_PROCESS_IN_ISR
122 if ((TX_THREAD_GET_SYSTEM_STATE()) || (_tx_thread_current_ptr == &_tx_timer_thread))
123 #else
124 if (TX_THREAD_GET_SYSTEM_STATE())
125 #endif
126 {
127
128 /* Yes, defer the processing to the NetX IP thread. */
129
130 /* Yes, change the suspend cleanup routine to indicate the cleanup is deferred. */
131 thread_ptr -> tx_thread_suspend_cleanup = _nx_tcp_cleanup_deferred;
132
133 /* Restore interrupts. */
134 TX_RESTORE
135
136 /* Set the deferred cleanup flag for the IP thread. */
137 tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_TCP_CLEANUP_DEFERRED, TX_OR);
138
139 /* Return to caller. */
140 return;
141 }
142 else
143 {
144
145 /* Yes, we still have thread suspension! */
146
147 /* Clear the suspension cleanup flag. */
148 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
149
150 /* Clear the suspension pointer. */
151 socket_ptr -> nx_tcp_socket_connect_suspended_thread = NX_NULL;
152
153 /* Clear the timeout. */
154 socket_ptr -> nx_tcp_socket_timeout = 0;
155
156 /* Return to the proper socket state. */
157 if (socket_ptr -> nx_tcp_socket_client_type)
158 {
159
160 /* If trace is enabled, insert this event into the trace buffer. */
161 NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_TCP_STATE_CHANGE, ip_ptr, socket_ptr, socket_ptr -> nx_tcp_socket_state, NX_TCP_CLOSED, NX_TRACE_INTERNAL_EVENTS, 0, 0);
162
163 /* Client socket, return to a CLOSED state. */
164 socket_ptr -> nx_tcp_socket_state = NX_TCP_CLOSED;
165 }
166 else
167 {
168
169 /* If trace is enabled, insert this event into the trace buffer. */
170 NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_TCP_STATE_CHANGE, ip_ptr, socket_ptr, socket_ptr -> nx_tcp_socket_state, NX_TCP_LISTEN_STATE, NX_TRACE_INTERNAL_EVENTS, 0, 0);
171
172 /* Server socket, return to LISTEN state. */
173 socket_ptr -> nx_tcp_socket_state = NX_TCP_LISTEN_STATE;
174
175 /* Move back the acknowledgment number just in case there is a retry. */
176 socket_ptr -> nx_tcp_socket_rx_sequence--;
177 }
178
179 /* Now we need to determine if this cleanup is from a terminate, timeout,
180 or from a wait abort. */
181 if (thread_ptr -> tx_thread_state == TX_TCP_IP)
182 {
183
184 /* Thread still suspended on the TCP socket. Setup return error status and
185 resume the thread. */
186
187 /* Setup return status. */
188 thread_ptr -> tx_thread_suspend_status = NX_NOT_CONNECTED;
189
190 /* Temporarily disable preemption. */
191 _tx_thread_preempt_disable++;
192
193 /* Restore interrupts. */
194 TX_RESTORE
195
196 /* Resume the thread! Check for preemption even though we are executing
197 from the system timer thread right now which normally executes at the
198 highest priority. */
199 _tx_thread_system_resume(thread_ptr);
200
201 /* Finished, just return. */
202 return;
203 }
204 }
205
206 /* Restore interrupts. */
207 TX_RESTORE
208 }
209
210