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 "nx_ip.h"
29 #include "nx_tcp.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _nx_tcp_deferred_cleanup_check                      PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Yuxin Zhou, Microsoft Corporation                                   */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function checks for deferred cleanup processing, which is the  */
45 /*    case for all TCP socket timeout processing. This is done so that    */
46 /*    mutex protection can be obtained prior to processing the timeout.   */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    ip_ptr                                Pointer to IP control block   */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    None                                                                */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _nx_tcp_client_bind_cleanup           Bind cleanup                  */
59 /*    _nx_tcp_connect_cleanup               Connect cleanup               */
60 /*    _nx_tcp_disconnect_cleanup            Disconnect cleanup            */
61 /*    _nx_tcp_receive_cleanup               Receive cleanup               */
62 /*    _nx_tcp_transmit_cleanup              Transmit cleanup              */
63 /*                                                                        */
64 /*  CALLED BY                                                             */
65 /*                                                                        */
66 /*    _nx_ip_thread_entry                   IP helper thread              */
67 /*                                                                        */
68 /*  RELEASE HISTORY                                                       */
69 /*                                                                        */
70 /*    DATE              NAME                      DESCRIPTION             */
71 /*                                                                        */
72 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
73 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
74 /*                                            resulting in version 6.1    */
75 /*                                                                        */
76 /**************************************************************************/
_nx_tcp_deferred_cleanup_check(NX_IP * ip_ptr)77 VOID  _nx_tcp_deferred_cleanup_check(NX_IP *ip_ptr)
78 {
79 
80 ULONG          created_sockets;
81 ULONG          suspended_threads;
82 NX_TCP_SOCKET *socket_ptr;
83 TX_THREAD     *thread_ptr;
84 
85 
86     /* Pickup the first socket and the created count.  */
87     socket_ptr =       ip_ptr -> nx_ip_tcp_created_sockets_ptr;
88     created_sockets =  ip_ptr -> nx_ip_tcp_created_sockets_count;
89 
90     /* Loop through all created TCP sockets on the IP instance.  */
91     while (created_sockets--)
92     {
93 
94         /* Check the socket for deferred bind cleanup.  */
95         suspended_threads =  socket_ptr -> nx_tcp_socket_bind_suspended_count;
96         if (suspended_threads)
97         {
98 
99             /* Pickup the socket pointer.  */
100             thread_ptr =  socket_ptr -> nx_tcp_socket_bind_suspension_list;
101 
102             /* Loop through the suspended threads for the bind operation to determine if there
103                is a timeout.  */
104             do
105             {
106 
107                 /* Determine if this thread has deferred the timeout processing.  */
108                 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred)
109                 {
110 
111                     /* Yes, call the cleanup routine again!  */
112                     _nx_tcp_client_bind_cleanup(thread_ptr NX_CLEANUP_ARGUMENT);
113                 }
114 
115                 /* Move to next suspended thread.  */
116                 thread_ptr =  thread_ptr -> tx_thread_suspended_next;
117             } while (--suspended_threads);
118         }
119 
120         /* Check the socket for deferred connect cleanup.  */
121         thread_ptr =  socket_ptr -> nx_tcp_socket_connect_suspended_thread;
122         if (thread_ptr)
123         {
124 
125             /* Determine if this thread has deferred the timeout processing.  */
126             if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred)
127             {
128 
129                 /* Yes, call the cleanup routine again!  */
130                 _nx_tcp_connect_cleanup(thread_ptr NX_CLEANUP_ARGUMENT);
131             }
132         }
133 
134         /* Check the socket for deferred disconnect cleanup.  */
135         thread_ptr =  socket_ptr -> nx_tcp_socket_disconnect_suspended_thread;
136         if (thread_ptr)
137         {
138 
139             /* Determine if this thread has deferred the timeout processing.  */
140             if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred)
141             {
142 
143                 /* Yes, call the cleanup routine again!  */
144                 _nx_tcp_disconnect_cleanup(thread_ptr NX_CLEANUP_ARGUMENT);
145             }
146         }
147 
148         /* Check the socket for deferred receive cleanup.  */
149         suspended_threads =  socket_ptr -> nx_tcp_socket_receive_suspended_count;
150         if (suspended_threads)
151         {
152 
153             /* Pickup the socket pointer.  */
154             thread_ptr =  socket_ptr -> nx_tcp_socket_receive_suspension_list;
155 
156             /* Loop through the suspended threads for the receive operation to determine if there
157                is a timeout.  */
158             do
159             {
160 
161                 /* Determine if this thread has deferred the timeout processing.  */
162                 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred)
163                 {
164 
165                     /* Yes, call the cleanup routine again!  */
166                     _nx_tcp_receive_cleanup(thread_ptr NX_CLEANUP_ARGUMENT);
167                 }
168 
169                 /* Move to next suspended thread.  */
170                 thread_ptr =  thread_ptr -> tx_thread_suspended_next;
171             } while (--suspended_threads);
172         }
173 
174         /* Check the socket for deferred transmit cleanup.  */
175         suspended_threads =  socket_ptr -> nx_tcp_socket_transmit_suspended_count;
176         if (suspended_threads)
177         {
178 
179             /* Pickup the socket pointer.  */
180             thread_ptr =  socket_ptr -> nx_tcp_socket_transmit_suspension_list;
181 
182             /* Loop through the suspended threads for the transmit operation to determine if there
183                is a timeout.  */
184             do
185             {
186 
187                 /* Determine if this thread has deferred the timeout processing.  */
188                 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred)
189                 {
190 
191                     /* Yes, call the cleanup routine again!  */
192                     _nx_tcp_transmit_cleanup(thread_ptr NX_CLEANUP_ARGUMENT);
193                 }
194 
195                 /* Move to next suspended thread.  */
196                 thread_ptr =  thread_ptr -> tx_thread_suspended_next;
197             } while (--suspended_threads);
198         }
199 
200         /* Move to next created TCP socket.  */
201         socket_ptr =  socket_ptr -> nx_tcp_socket_created_next;
202     }
203 }
204 
205