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_tcp.h"
30 #include "nx_ipv6.h"
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _nx_tcp_socket_state_closing PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Yuxin Zhou, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function processes packets during the CLOSING state, */
45 /* which is the state at the end of an active, simultaneous */
46 /* disconnect. If a valid ACK is present, set the socket state */
47 /* to TIMED WAIT. */
48 /* */
49 /* INPUT */
50 /* */
51 /* socket_ptr Pointer to owning socket */
52 /* tcp_header_ptr Pointer to packet header */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* None */
57 /* */
58 /* CALLS */
59 /* */
60 /* _nx_tcp_packet_send_ack Send ACK message */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* _nx_tcp_socket_packet_process Process TCP packet for socket */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
71 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_nx_tcp_socket_state_closing(NX_TCP_SOCKET * socket_ptr,NX_TCP_HEADER * tcp_header_ptr)75 VOID _nx_tcp_socket_state_closing(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr)
76 {
77
78
79 /* Determine if the incoming message is an ACK message. */
80 if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)
81 {
82
83 /* If it is proper, finish the disconnect. */
84 if ((tcp_header_ptr -> nx_tcp_acknowledgment_number == socket_ptr -> nx_tcp_socket_tx_sequence) &&
85 (tcp_header_ptr -> nx_tcp_sequence_number == socket_ptr -> nx_tcp_socket_rx_sequence))
86 {
87
88 /* Return to the proper socket state. */
89
90 /* Yes, return the socket to the TIMED WAIT state. */
91
92 /* If trace is enabled, insert this event into the trace buffer. */
93 NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_TCP_STATE_CHANGE, socket_ptr -> nx_tcp_socket_ip_ptr, socket_ptr, socket_ptr -> nx_tcp_socket_state, NX_TCP_TIMED_WAIT, NX_TRACE_INTERNAL_EVENTS, 0, 0);
94
95 /* Set the socket state to TIMED WAIT now. */
96 socket_ptr -> nx_tcp_socket_state = NX_TCP_TIMED_WAIT;
97
98 /* Set the timeout as 2MSL (Maximum Segment Lifetime). */
99 socket_ptr -> nx_tcp_socket_timeout = _nx_tcp_2MSL_timer_rate;
100
101 /* Determine if we need to wake a thread suspended on the connection. */
102 if (socket_ptr -> nx_tcp_socket_disconnect_suspended_thread)
103 {
104
105 /* Resume the thread suspended for the disconnect. */
106 _nx_tcp_socket_thread_resume(&(socket_ptr -> nx_tcp_socket_disconnect_suspended_thread), NX_SUCCESS);
107 }
108
109 /* If given, call the application's disconnect callback function
110 for disconnect. */
111 if (socket_ptr -> nx_tcp_disconnect_callback)
112 {
113
114 /* Call the application's disconnect handling function. It is
115 responsible for calling the socket disconnect function. */
116 (socket_ptr -> nx_tcp_disconnect_callback)(socket_ptr);
117 }
118
119 #ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
120
121 /* Is a timed wait callback registered for this socket? */
122 if (socket_ptr -> nx_tcp_timed_wait_callback)
123 {
124
125 /* Call the timed wait callback for this socket to let the host
126 know the socket can now be put in the timed wait state (if
127 the RE-USE ADDRESS socket option is not enabled). */
128 (socket_ptr -> nx_tcp_timed_wait_callback)(socket_ptr);
129 }
130
131 /* Is a disconnect complete callback registered with the TCP socket? */
132 if (socket_ptr -> nx_tcp_disconnect_complete_notify)
133 {
134
135 /* Call the application's disconnect_complete callback function. */
136 (socket_ptr -> nx_tcp_disconnect_complete_notify)(socket_ptr);
137 }
138 #endif
139 }
140
141 /* Ignore the segment. According to RFC 793, Section 3.9, Page 73. */
142 }
143 }
144
145