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 Duo Component                                                    */
17 /**                                                                       */
18 /**   TELNET Protocol (TELNET)                                            */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_TELNET_SOURCE_CODE
24 
25 
26 /* Force error checking to be disabled in this module */
27 
28 #ifndef NX_DISABLE_ERROR_CHECKING
29 #define NX_DISABLE_ERROR_CHECKING
30 #endif
31 
32 /* Include necessary system files.  */
33 
34 #include    "nx_api.h"
35 #include    "nx_ip.h"
36 #include    "nxd_telnet_server.h"
37 #include    "stdio.h"
38 #include    "string.h"
39 
40 
41 /* Bring in externs for caller checking code.  */
42 
43 NX_CALLER_CHECKING_EXTERNS
44 
45 
46 
47 /**************************************************************************/
48 /*                                                                        */
49 /*  FUNCTION                                               RELEASE        */
50 /*                                                                        */
51 /*    _nxe_telnet_server_create                           PORTABLE C      */
52 /*                                                           6.1          */
53 /*  AUTHOR                                                                */
54 /*                                                                        */
55 /*    Yuxin Zhou, Microsoft Corporation                                   */
56 /*                                                                        */
57 /*  DESCRIPTION                                                           */
58 /*                                                                        */
59 /*    This function checks for errors in the TELNET server create call.   */
60 /*                                                                        */
61 /*                                                                        */
62 /*  INPUT                                                                 */
63 /*                                                                        */
64 /*    server_ptr                            Pointer to TELNET server      */
65 /*    server_name                           Name of TELNET server         */
66 /*    ip_ptr                                Pointer to IP instance        */
67 /*    stack_ptr                             Server thread's stack pointer */
68 /*    stack_size                            Server thread's stack size    */
69 /*    new_connection                        Pointer to user's new         */
70 /*                                            connection function         */
71 /*    receive_data                          Pointer to user's receive     */
72 /*                                            data function               */
73 /*    connection_end                        Pointer to user's end of      */
74 /*                                            connection function         */
75 /*                                                                        */
76 /*  OUTPUT                                                                */
77 /*                                                                        */
78 /*    status                                Completion status             */
79 /*                                                                        */
80 /*  CALLS                                                                 */
81 /*                                                                        */
82 /*    _nx_telnet_server_create              Actual server create call     */
83 /*                                                                        */
84 /*  CALLED BY                                                             */
85 /*                                                                        */
86 /*    Application Code                                                    */
87 /*                                                                        */
88 /*  RELEASE HISTORY                                                       */
89 /*                                                                        */
90 /*    DATE              NAME                      DESCRIPTION             */
91 /*                                                                        */
92 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
93 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
94 /*                                            resulting in version 6.1    */
95 /*                                                                        */
96 /**************************************************************************/
_nxe_telnet_server_create(NX_TELNET_SERVER * server_ptr,CHAR * server_name,NX_IP * ip_ptr,VOID * stack_ptr,ULONG stack_size,void (* new_connection)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection),void (* receive_data)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection,NX_PACKET * packet_ptr),void (* connection_end)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection))97 UINT  _nxe_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
98             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
99             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
100             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection))
101 {
102 
103 UINT        status;
104 
105 
106     /* Check for invalid input pointers.  */
107     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
108         (server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id == NX_TELNET_SERVER_ID) ||
109         (stack_ptr == NX_NULL) || (new_connection == NX_NULL) || (receive_data == NX_NULL) || (connection_end == NX_NULL))
110         return(NX_PTR_ERROR);
111 
112     /* Call actual server create function.  */
113     status =  _nx_telnet_server_create(server_ptr, server_name, ip_ptr, stack_ptr, stack_size, new_connection, receive_data, connection_end);
114 
115     /* Return completion status.  */
116     return(status);
117 }
118 
119 
120 /**************************************************************************/
121 /*                                                                        */
122 /*  FUNCTION                                               RELEASE        */
123 /*                                                                        */
124 /*    _nx_telnet_server_create                           PORTABLE C       */
125 /*                                                           6.1          */
126 /*  AUTHOR                                                                */
127 /*                                                                        */
128 /*    Yuxin Zhou, Microsoft Corporation                                   */
129 /*                                                                        */
130 /*  DESCRIPTION                                                           */
131 /*                                                                        */
132 /*    This function creates a TELNET server on the specified IP. In doing */
133 /*    so this function creates a TCP socket for subsequent TELNET         */
134 /*    transfers and a thread for the TELNET server.                       */
135 /*                                                                        */
136 /*                                                                        */
137 /*  INPUT                                                                 */
138 /*                                                                        */
139 /*    server_ptr                            Pointer to TELNET server      */
140 /*    server_name                           Name of TELNET server         */
141 /*    ip_ptr                                Pointer to IP instance        */
142 /*    stack_ptr                             Server thread's stack pointer */
143 /*    stack_size                            Server thread's stack size    */
144 /*    new_connection                        Pointer to user's new         */
145 /*                                            connection function         */
146 /*    receive_data                          Pointer to user's receive     */
147 /*                                            data function               */
148 /*    connection_end                        Pointer to user's end of      */
149 /*                                            connection function         */
150 /*                                                                        */
151 /*  OUTPUT                                                                */
152 /*                                                                        */
153 /*    status                                Completion status             */
154 /*                                                                        */
155 /*  CALLS                                                                 */
156 /*                                                                        */
157 /*    nx_tcp_socket_create                  Create sockets                */
158 /*    nx_tcp_socket_delete                  Delete sockets                */
159 /*    nx_tcp_socket_receive_notify          Register receive notify       */
160 /*                                            callback                    */
161 /*    tx_event_flags_create                 Create event flags            */
162 /*    tx_event_flags_delete                 Delete event flags            */
163 /*    tx_thread_create                      Create TELNET server thread   */
164 /*    tx_thread_delete                      Delete TELNET server thread   */
165 /*    tx_timer_create                       Create TELNET server timer    */
166 /*    tx_timer_delete                       Delete TELNET server timer    */
167 /*                                                                        */
168 /*  CALLED BY                                                             */
169 /*                                                                        */
170 /*    Application Code                                                    */
171 /*                                                                        */
172 /*  RELEASE HISTORY                                                       */
173 /*                                                                        */
174 /*    DATE              NAME                      DESCRIPTION             */
175 /*                                                                        */
176 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
177 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
178 /*                                            resulting in version 6.1    */
179 /*                                                                        */
180 /**************************************************************************/
_nx_telnet_server_create(NX_TELNET_SERVER * server_ptr,CHAR * server_name,NX_IP * ip_ptr,VOID * stack_ptr,ULONG stack_size,void (* new_connection)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection),void (* receive_data)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection,NX_PACKET * packet_ptr),void (* connection_end)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection))181 UINT  _nx_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
182             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
183             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
184             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection))
185 {
186 
187 UINT            i;
188 UINT            status;
189 
190     /* Clear the TELNET server structure.  */
191     memset((void *) server_ptr, 0, sizeof(NX_TELNET_SERVER));
192 
193     /* Create the TELNET Server thread.  */
194     status =  tx_thread_create(&(server_ptr -> nx_telnet_server_thread), "TELNET Server Thread",
195                                _nx_telnet_server_thread_entry, (ULONG) server_ptr, stack_ptr,
196                                stack_size, NX_TELNET_SERVER_PRIORITY, NX_TELNET_SERVER_PRIORITY,
197                                TX_NO_TIME_SLICE, TX_DONT_START);
198 
199     /* Determine if an error occurred creating the thread.  */
200     if (status != TX_SUCCESS)
201     {
202 
203         /* Error creating the server thread.  */
204         return(status);
205     }
206 
207     /* Create the ThreadX event flags.  These will be used to driver the TELNET server thread.  */
208     status =  tx_event_flags_create(&(server_ptr -> nx_telnet_server_event_flags), "TELNET Server Thread Events");
209 
210     /* Determine if an error occurred creating the event flags.  */
211     if (status != TX_SUCCESS)
212     {
213 
214         /* Delete the server thread.  */
215         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
216 
217         /* Error creating the server event flags.  */
218         return(status);
219     }
220 
221     /* Create the ThreadX activity timeout timer.  This will be used to periodically check to see if
222        a client connection has gone silent and needs to be terminated.  */
223     status =  tx_timer_create(&(server_ptr -> nx_telnet_server_timer), "TELNET Server Timer",
224                               _nx_telnet_server_timeout, (ULONG) server_ptr,
225                               (NX_IP_PERIODIC_RATE * NX_TELNET_TIMEOUT_PERIOD),
226                               (NX_IP_PERIODIC_RATE * NX_TELNET_TIMEOUT_PERIOD), TX_NO_ACTIVATE);
227 
228     /* Determine if an error occurred creating the timer.  */
229     if (status != TX_SUCCESS)
230     {
231 
232         /* Delete the server thread.  */
233         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
234 
235         /* Delete the server event flags.  */
236         tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
237 
238         /* Error creating the server timer.  */
239         return(status);
240     }
241 
242     /* Loop to create all the TELNET client sockets.  */
243     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
244     {
245 
246         /* Setup the logical index for this client request structure.  */
247         server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_connection =  i;
248 
249         /* Create an TELNET client socket.  */
250         status +=  nx_tcp_socket_create(ip_ptr, &(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket), "TELNET Server Control Socket",
251                         NX_TELNET_TOS, NX_TELNET_FRAGMENT_OPTION, NX_TELNET_TIME_TO_LIVE, NX_TELNET_SERVER_WINDOW_SIZE, NX_NULL, _nx_telnet_server_disconnect_present);
252 
253         /* If no error is present, register the receive notify function.  */
254         if (status == NX_SUCCESS)
255         {
256 
257             /* Register the receive function.  */
258             nx_tcp_socket_receive_notify(&(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket),
259                                             _nx_telnet_server_data_present);
260         }
261 
262         /* Make sure each socket points to the TELNET server.  */
263         server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket.nx_tcp_socket_reserved_ptr =  server_ptr;
264     }
265 
266     /* Determine if an error has occurred.  */
267     if (status != NX_SUCCESS)
268     {
269 
270         /* Loop to delete any created sockets.  */
271         for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
272         {
273 
274             /* Delete the TELNET socket.  */
275             nx_tcp_socket_delete(&(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket));
276         }
277 
278         /* Delete the server thread.  */
279         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
280 
281         /* Delete the event flag group.  */
282         tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
283 
284         /* Delete the timer.  */
285         tx_timer_delete(&(server_ptr -> nx_telnet_server_timer));
286 
287         /* Return the NetX error.  */
288         return(status);
289     }
290 
291 
292 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
293 
294 #ifndef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
295 
296     /* Create the packet pool for negotiating telnet options, and check the status */
297     status =  nx_packet_pool_create(&(server_ptr -> nx_telnet_server_packet_pool), "Telnet Server Options",
298                                     NX_TELNET_SERVER_PACKET_PAYLOAD, &server_ptr -> nx_telnet_server_pool_area,
299                                     NX_TELNET_SERVER_PACKET_POOL_SIZE);
300 
301     /* Determine if it was successful.  */
302     if (status != NX_SUCCESS)
303     {
304         /* Loop to delete any created sockets.  */
305         for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
306         {
307 
308             /* Delete the TELNET socket.  */
309             nx_tcp_socket_delete(&(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket));
310         }
311 
312         /* Delete the server thread.  */
313         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
314 
315         /* Delete the event flag group.  */
316         tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
317 
318         /* Delete the timer.  */
319         tx_timer_delete(&(server_ptr -> nx_telnet_server_timer));
320 
321         /* No, return error status.  */
322         return(status);
323     }
324 
325     server_ptr -> nx_telnet_server_packet_pool_ptr = &(server_ptr -> nx_telnet_server_packet_pool);
326 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
327 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
328 
329     /* Save the Server name.  */
330     server_ptr -> nx_telnet_server_name =  server_name;
331 
332     /* Save the IP pointer address.  */
333     server_ptr -> nx_telnet_server_ip_ptr =  ip_ptr;
334 
335     /* Save the user-supplied new connection and receive data functions.  */
336     server_ptr -> nx_telnet_new_connection =   new_connection;
337     server_ptr -> nx_telnet_receive_data =     receive_data;
338     server_ptr -> nx_telnet_connection_end =   connection_end;
339 
340     /* Set the server ID to indicate the TELNET server thread is ready.  */
341     server_ptr -> nx_telnet_server_id =  NX_TELNET_SERVER_ID;
342 
343     server_ptr -> nx_telnet_server_open_connections = 0;
344 
345 
346     /* Return successful completion.  */
347     return(NX_SUCCESS);
348 }
349 
350 
351 /**************************************************************************/
352 /*                                                                        */
353 /*  FUNCTION                                               RELEASE        */
354 /*                                                                        */
355 /*    _nxe_telnet_server_delete                           PORTABLE C      */
356 /*                                                           6.1          */
357 /*  AUTHOR                                                                */
358 /*                                                                        */
359 /*    Yuxin Zhou, Microsoft Corporation                                   */
360 /*                                                                        */
361 /*  DESCRIPTION                                                           */
362 /*                                                                        */
363 /*    This function checks for errors in the TELNET server delete call.   */
364 /*                                                                        */
365 /*                                                                        */
366 /*  INPUT                                                                 */
367 /*                                                                        */
368 /*    server_ptr                            Pointer to TELNET server      */
369 /*                                                                        */
370 /*  OUTPUT                                                                */
371 /*                                                                        */
372 /*    status                                Completion status             */
373 /*                                                                        */
374 /*  CALLS                                                                 */
375 /*                                                                        */
376 /*    _nx_telnet_server_delete              Actual server delete call     */
377 /*                                                                        */
378 /*  CALLED BY                                                             */
379 /*                                                                        */
380 /*    Application Code                                                    */
381 /*                                                                        */
382 /*  RELEASE HISTORY                                                       */
383 /*                                                                        */
384 /*    DATE              NAME                      DESCRIPTION             */
385 /*                                                                        */
386 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
387 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
388 /*                                            resulting in version 6.1    */
389 /*                                                                        */
390 /**************************************************************************/
_nxe_telnet_server_delete(NX_TELNET_SERVER * server_ptr)391 UINT  _nxe_telnet_server_delete(NX_TELNET_SERVER *server_ptr)
392 {
393 
394 UINT    status;
395 
396 
397     /* Check for invalid input pointers.  */
398     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
399         return(NX_PTR_ERROR);
400 
401     /* Check for appropriate caller.  */
402     NX_THREADS_ONLY_CALLER_CHECKING
403 
404     /* Call actual server delete function.  */
405     status =  _nx_telnet_server_delete(server_ptr);
406 
407     /* Return completion status.  */
408     return(status);
409 }
410 
411 
412 
413 /**************************************************************************/
414 /*                                                                        */
415 /*  FUNCTION                                               RELEASE        */
416 /*                                                                        */
417 /*    _nx_telnet_server_delete                            PORTABLE C      */
418 /*                                                           6.1          */
419 /*  AUTHOR                                                                */
420 /*                                                                        */
421 /*    Yuxin Zhou, Microsoft Corporation                                   */
422 /*                                                                        */
423 /*  DESCRIPTION                                                           */
424 /*                                                                        */
425 /*    This function deletes a previously created TELNET server on the     */
426 /*    specified IP.                                                       */
427 /*                                                                        */
428 /*                                                                        */
429 /*  INPUT                                                                 */
430 /*                                                                        */
431 /*    server_ptr                            Pointer to TELNET server      */
432 /*                                                                        */
433 /*  OUTPUT                                                                */
434 /*                                                                        */
435 /*    status                                Completion status             */
436 /*                                                                        */
437 /*  CALLS                                                                 */
438 /*                                                                        */
439 /*    nx_tcp_server_socket_unaccept         Unaccept server socket        */
440 /*    nx_tcp_server_socket_unlisten         Unlisten on server            */
441 /*    nx_tcp_socket_delete                  Delete socket                 */
442 /*    nx_tcp_socket_disconnect              Disconnect socket             */
443 /*    tx_event_flags_delete                 Delete event flags            */
444 /*    tx_thread_delete                      Delete thread                 */
445 /*    tx_thread_suspend                     Suspend thread                */
446 /*    tx_thread_terminate                   Terminate thread              */
447 /*    tx_timer_deactivate                   Deactivate timer              */
448 /*    tx_timer_delete                       Delete timer                  */
449 /*                                                                        */
450 /*  CALLED BY                                                             */
451 /*                                                                        */
452 /*    Application Code                                                    */
453 /*                                                                        */
454 /*  RELEASE HISTORY                                                       */
455 /*                                                                        */
456 /*    DATE              NAME                      DESCRIPTION             */
457 /*                                                                        */
458 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
459 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
460 /*                                            resulting in version 6.1    */
461 /*                                                                        */
462 /**************************************************************************/
_nx_telnet_server_delete(NX_TELNET_SERVER * server_ptr)463 UINT  _nx_telnet_server_delete(NX_TELNET_SERVER *server_ptr)
464 {
465 
466 UINT                        i;
467 NX_TELNET_CLIENT_REQUEST   *client_request_ptr;
468 
469 
470     /* Clear the server ID to indicate the TELNET server is no longer ready.  */
471     server_ptr -> nx_telnet_server_id =  0;
472 
473     /* Suspend the TELNET server thread.  */
474     tx_thread_suspend(&(server_ptr -> nx_telnet_server_thread));
475 
476     /* Terminate server thread. */
477     tx_thread_terminate(&(server_ptr -> nx_telnet_server_thread));
478 
479     /* Delete server thread.  */
480     tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
481 
482     /* Delete the event flag group.  */
483     tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
484 
485     /* Deactivate and delete timer.  */
486     tx_timer_deactivate(&(server_ptr -> nx_telnet_server_timer));
487     tx_timer_delete(&(server_ptr -> nx_telnet_server_timer));
488 
489     /* If the Telnet Server is configured to send options and the packet
490        pool is created by  the internally (by the Telnet server task)
491        we need to delete it. */
492 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
493 #ifndef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
494     nx_packet_pool_delete(&server_ptr -> nx_telnet_server_packet_pool);
495 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
496 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
497 
498     /* Walk through the server structure to close and delete any open sockets.  */
499     i =  0;
500     client_request_ptr =  &(server_ptr -> nx_telnet_server_client_list[0]);
501     while (i < NX_TELNET_MAX_CLIENTS)
502     {
503 
504         /* Disconnect the socket.  */
505         nx_tcp_socket_disconnect(&(client_request_ptr -> nx_telnet_client_request_socket), NX_NO_WAIT);
506 
507         /* Unaccept the socket.  */
508         nx_tcp_server_socket_unaccept(&(client_request_ptr -> nx_telnet_client_request_socket));
509 
510         /* Delete the socket.  */
511         nx_tcp_socket_delete(&(client_request_ptr -> nx_telnet_client_request_socket));
512 
513         /* Increment the pointer into the client request list.  */
514         client_request_ptr++;
515         i++;
516     }
517 
518     /* Unlisten on the TELNET port.  */
519     nx_tcp_server_socket_unlisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT);
520 
521     /* Return successful completion.  */
522     return(NX_SUCCESS);
523 }
524 
525 
526 /**************************************************************************/
527 /*                                                                        */
528 /*  FUNCTION                                               RELEASE        */
529 /*                                                                        */
530 /*    _nxe_telnet_server_disconnect                       PORTABLE C      */
531 /*                                                           6.1          */
532 /*  AUTHOR                                                                */
533 /*                                                                        */
534 /*    Yuxin Zhou, Microsoft Corporation                                   */
535 /*                                                                        */
536 /*  DESCRIPTION                                                           */
537 /*                                                                        */
538 /*    This function checks for errors in the TELNET server disconnect     */
539 /*    call.                                                               */
540 /*                                                                        */
541 /*                                                                        */
542 /*  INPUT                                                                 */
543 /*                                                                        */
544 /*    server_ptr                            Pointer to TELNET server      */
545 /*    logical_connection                    Logical connection entry      */
546 /*                                                                        */
547 /*  OUTPUT                                                                */
548 /*                                                                        */
549 /*    status                                Completion status             */
550 /*                                                                        */
551 /*  CALLS                                                                 */
552 /*                                                                        */
553 /*    _nx_telnet_server_disconnect          Actual server disconnect call */
554 /*                                                                        */
555 /*  CALLED BY                                                             */
556 /*                                                                        */
557 /*    Application Code                                                    */
558 /*                                                                        */
559 /*  RELEASE HISTORY                                                       */
560 /*                                                                        */
561 /*    DATE              NAME                      DESCRIPTION             */
562 /*                                                                        */
563 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
564 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
565 /*                                            resulting in version 6.1    */
566 /*                                                                        */
567 /**************************************************************************/
_nxe_telnet_server_disconnect(NX_TELNET_SERVER * server_ptr,UINT logical_connection)568 UINT  _nxe_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection)
569 {
570 
571 UINT    status;
572 
573 
574     /* Check for invalid input pointers.  */
575     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
576         return(NX_PTR_ERROR);
577 
578     /* Check for a valid logical connection.  */
579     if (logical_connection >= NX_TELNET_MAX_CLIENTS)
580         return(NX_OPTION_ERROR);
581 
582     /* Check for appropriate caller.  */
583     NX_THREADS_ONLY_CALLER_CHECKING
584 
585     /* Call actual server disconnect function.  */
586     status =  _nx_telnet_server_disconnect(server_ptr, logical_connection);
587 
588     /* Return completion status.  */
589     return(status);
590 }
591 
592 
593 /**************************************************************************/
594 /*                                                                        */
595 /*  FUNCTION                                               RELEASE        */
596 /*                                                                        */
597 /*    _nx_telnet_server_disconnect                        PORTABLE C      */
598 /*                                                           6.2.1        */
599 /*  AUTHOR                                                                */
600 /*                                                                        */
601 /*    Yuxin Zhou, Microsoft Corporation                                   */
602 /*                                                                        */
603 /*  DESCRIPTION                                                           */
604 /*                                                                        */
605 /*    This function processes server disconnect requests made by the      */
606 /*    application receive data callback function.                         */
607 /*                                                                        */
608 /*  INPUT                                                                 */
609 /*                                                                        */
610 /*    server_ptr                            Pointer to TELNET server      */
611 /*    logical_connection                    Logical connection entry      */
612 /*                                                                        */
613 /*  OUTPUT                                                                */
614 /*                                                                        */
615 /*    status                                Completion status             */
616 /*                                                                        */
617 /*  CALLS                                                                 */
618 /*                                                                        */
619 /*    nx_tcp_server_socket_relisten         Relisten on Telnet port       */
620 /*    nx_tcp_server_socket_unaccept         Socket unaccept               */
621 /*    nx_tcp_socket_disconnect              Socket disconnect             */
622 /*                                                                        */
623 /*  CALLED BY                                                             */
624 /*                                                                        */
625 /*    Application Code                                                    */
626 /*                                                                        */
627 /*  RELEASE HISTORY                                                       */
628 /*                                                                        */
629 /*    DATE              NAME                      DESCRIPTION             */
630 /*                                                                        */
631 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
632 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
633 /*                                            resulting in version 6.1    */
634 /*  03-08-2023     Wenhui Xie               Modified comment(s), and      */
635 /*                                            corrected the processing of */
636 /*                                            disconnection,              */
637 /*                                            resulting in version 6.2.1  */
638 /*                                                                        */
639 /**************************************************************************/
_nx_telnet_server_disconnect(NX_TELNET_SERVER * server_ptr,UINT logical_connection)640 UINT  _nx_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection)
641 {
642 
643 UINT                        i;
644 UINT                        status;
645 NX_TELNET_CLIENT_REQUEST   *client_ptr;
646 
647     /* Set a pointer to the indicated client connection.  */
648     client_ptr =  &(server_ptr -> nx_telnet_server_client_list[logical_connection]);
649 
650     /* Determine if the connection is alive.  */
651     if (client_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state >= NX_TCP_ESTABLISHED)
652     {
653 
654         /* Disconnect the socket.  */
655         nx_tcp_socket_disconnect(&(client_ptr -> nx_telnet_client_request_socket), NX_TELNET_SERVER_TIMEOUT);
656 
657         /* Unaccept this socket.  */
658         nx_tcp_server_socket_unaccept(&(client_ptr -> nx_telnet_client_request_socket));
659 
660         /* Update number of current open connections. */
661         if (server_ptr -> nx_telnet_server_open_connections > 0)
662             server_ptr -> nx_telnet_server_open_connections--;
663 
664         /* Clear the client request activity timeout.  */
665         client_ptr -> nx_telnet_client_request_activity_timeout =  0;
666 
667         /* Call the application's end connection callback routine.  */
668         if (server_ptr -> nx_telnet_connection_end)
669         {
670 
671             /* Yes, there is a connection end callback routine - call it!  */
672             (server_ptr -> nx_telnet_connection_end)(server_ptr, client_ptr -> nx_telnet_client_request_connection);
673         }
674     }
675     else
676     {
677 
678         /* Error, disconnecting an unconnected socket.  */
679         return(NX_TELNET_NOT_CONNECTED);
680     }
681 
682     /* Now look for a socket that is closed to relisten on.  */
683     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
684     {
685 
686         /* Set a pointer to client request structure.  */
687         client_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
688 
689         /* Now see if this socket is closed.  */
690         if (client_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state == NX_TCP_CLOSED)
691         {
692 
693             /* Relisten on this socket.  */
694             status =  nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
695                                                     &(client_ptr -> nx_telnet_client_request_socket));
696             /* Check for bad status.  */
697             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
698             {
699 
700                 /* Increment the error count and keep trying.  */
701                 server_ptr -> nx_telnet_server_relisten_errors++;
702                 continue;
703             }
704 
705             /* Break out of loop.  */
706             break;
707         }
708     }
709 
710     /* Return success.  */
711     return(NX_SUCCESS);
712 }
713 
714 
715 /**************************************************************************/
716 /*                                                                        */
717 /*  FUNCTION                                               RELEASE        */
718 /*                                                                        */
719 /*    _nxe_telnet_server_packet_send                      PORTABLE C      */
720 /*                                                           6.1          */
721 /*  AUTHOR                                                                */
722 /*                                                                        */
723 /*    Yuxin Zhou, Microsoft Corporation                                   */
724 /*                                                                        */
725 /*  DESCRIPTION                                                           */
726 /*                                                                        */
727 /*    This function checks for errors in the TELNET server packet send    */
728 /*    call.                                                               */
729 /*                                                                        */
730 /*                                                                        */
731 /*  INPUT                                                                 */
732 /*                                                                        */
733 /*    server_ptr                            Pointer to TELNET server      */
734 /*    logical_connection                    Logical connection entry      */
735 /*    packet_ptr                            Packet pointer to send        */
736 /*    wait_option                           Suspension option             */
737 /*                                                                        */
738 /*  OUTPUT                                                                */
739 /*                                                                        */
740 /*    status                                Completion status             */
741 /*                                                                        */
742 /*  CALLS                                                                 */
743 /*                                                                        */
744 /*    _nx_telnet_server_packet_send         Actual server packet send call*/
745 /*                                                                        */
746 /*  CALLED BY                                                             */
747 /*                                                                        */
748 /*    Application Code                                                    */
749 /*                                                                        */
750 /*  RELEASE HISTORY                                                       */
751 /*                                                                        */
752 /*    DATE              NAME                      DESCRIPTION             */
753 /*                                                                        */
754 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
755 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
756 /*                                            resulting in version 6.1    */
757 /*                                                                        */
758 /**************************************************************************/
_nxe_telnet_server_packet_send(NX_TELNET_SERVER * server_ptr,UINT logical_connection,NX_PACKET * packet_ptr,ULONG wait_option)759 UINT  _nxe_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option)
760 {
761 
762 UINT    status;
763 
764 
765     /* Check for invalid input pointers.  */
766     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID) || (packet_ptr == NX_NULL))
767         return(NX_PTR_ERROR);
768 
769     /* Check for a valid logical connection.  */
770     if (logical_connection >= NX_TELNET_MAX_CLIENTS)
771         return(NX_OPTION_ERROR);
772 
773     /* Check for appropriate caller.  */
774     NX_THREADS_ONLY_CALLER_CHECKING
775 
776     /* Call actual server packet send function.  */
777     status =  _nx_telnet_server_packet_send(server_ptr, logical_connection, packet_ptr, wait_option);
778 
779     /* Return completion status.  */
780     return(status);
781 }
782 
783 
784 /**************************************************************************/
785 /*                                                                        */
786 /*  FUNCTION                                               RELEASE        */
787 /*                                                                        */
788 /*    _nx_telnet_server_packet_send                       PORTABLE C      */
789 /*                                                           6.1          */
790 /*  AUTHOR                                                                */
791 /*                                                                        */
792 /*    Yuxin Zhou, Microsoft Corporation                                   */
793 /*                                                                        */
794 /*  DESCRIPTION                                                           */
795 /*                                                                        */
796 /*    This function processes packet send requests made from the          */
797 /*    application's receive data callback function.                       */
798 /*                                                                        */
799 /*  INPUT                                                                 */
800 /*                                                                        */
801 /*    server_ptr                            Pointer to TELNET server      */
802 /*    logical_connection                    Logical connection entry      */
803 /*    packet_ptr                            Packet pointer to send        */
804 /*    wait_option                           Suspension option             */
805 /*                                                                        */
806 /*  OUTPUT                                                                */
807 /*                                                                        */
808 /*    status                                Completion status             */
809 /*                                                                        */
810 /*  CALLS                                                                 */
811 /*                                                                        */
812 /*    nx_tcp_socket_send                    Send packet                   */
813 /*                                                                        */
814 /*  CALLED BY                                                             */
815 /*                                                                        */
816 /*    Application Code                                                    */
817 /*                                                                        */
818 /*  RELEASE HISTORY                                                       */
819 /*                                                                        */
820 /*    DATE              NAME                      DESCRIPTION             */
821 /*                                                                        */
822 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
823 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
824 /*                                            resulting in version 6.1    */
825 /*                                                                        */
826 /**************************************************************************/
_nx_telnet_server_packet_send(NX_TELNET_SERVER * server_ptr,UINT logical_connection,NX_PACKET * packet_ptr,ULONG wait_option)827 UINT  _nx_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option)
828 {
829 
830 UINT                        status;
831 NX_TELNET_CLIENT_REQUEST    *client_ptr;
832 
833 
834     /* Derive the pointer to the appropriate client connection.  */
835     client_ptr =  &(server_ptr -> nx_telnet_server_client_list[logical_connection]);
836 
837     /* Send the packet to the client.  */
838     status =  nx_tcp_socket_send(&(client_ptr -> nx_telnet_client_request_socket), packet_ptr, wait_option);
839 
840     /* Determine if the send was successful.  */
841     if (status)
842     {
843 
844         /* Map to a generic error.  */
845         status =  NX_TELNET_FAILED;
846     }
847 
848     /* Return to caller.  */
849     return(status);
850 }
851 
852 
853 /**************************************************************************/
854 /*                                                                        */
855 /*  FUNCTION                                               RELEASE        */
856 /*                                                                        */
857 /*    _nxe_telnet_server_start                            PORTABLE C      */
858 /*                                                           6.1          */
859 /*  AUTHOR                                                                */
860 /*                                                                        */
861 /*    Yuxin Zhou, Microsoft Corporation                                   */
862 /*                                                                        */
863 /*  DESCRIPTION                                                           */
864 /*                                                                        */
865 /*    This function checks for errors in the TELNET server start call.    */
866 /*                                                                        */
867 /*                                                                        */
868 /*  INPUT                                                                 */
869 /*                                                                        */
870 /*    server_ptr                            Pointer to TELNET server      */
871 /*                                                                        */
872 /*  OUTPUT                                                                */
873 /*                                                                        */
874 /*    status                                Completion status             */
875 /*                                                                        */
876 /*  CALLS                                                                 */
877 /*                                                                        */
878 /*    _nx_telnet_server_start               Actual server start call      */
879 /*                                                                        */
880 /*  CALLED BY                                                             */
881 /*                                                                        */
882 /*    Application Code                                                    */
883 /*                                                                        */
884 /*  RELEASE HISTORY                                                       */
885 /*                                                                        */
886 /*    DATE              NAME                      DESCRIPTION             */
887 /*                                                                        */
888 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
889 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
890 /*                                            resulting in version 6.1    */
891 /*                                                                        */
892 /**************************************************************************/
_nxe_telnet_server_start(NX_TELNET_SERVER * server_ptr)893 UINT  _nxe_telnet_server_start(NX_TELNET_SERVER *server_ptr)
894 {
895 
896 UINT    status;
897 
898 
899     /* Check for invalid input pointers.  */
900     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
901         return(NX_PTR_ERROR);
902 
903     /* Call actual server start function.  */
904     status =  _nx_telnet_server_start(server_ptr);
905 
906     /* Return completion status.  */
907     return(status);
908 }
909 
910 
911 /**************************************************************************/
912 /*                                                                        */
913 /*  FUNCTION                                               RELEASE        */
914 /*                                                                        */
915 /*    _nx_telnet_server_start                             PORTABLE C      */
916 /*                                                           6.1          */
917 /*  AUTHOR                                                                */
918 /*                                                                        */
919 /*    Yuxin Zhou, Microsoft Corporation                                   */
920 /*                                                                        */
921 /*  DESCRIPTION                                                           */
922 /*                                                                        */
923 /*    This function starts a previously created TELNET server on the      */
924 /*    specified IP.                                                       */
925 /*                                                                        */
926 /*                                                                        */
927 /*  INPUT                                                                 */
928 /*                                                                        */
929 /*    server_ptr                            Pointer to TELNET server      */
930 /*                                                                        */
931 /*  OUTPUT                                                                */
932 /*                                                                        */
933 /*    status                                Completion status             */
934 /*    NX_TELNET_NO_PACKET_POOL              Telnet server packet pool not */
935 /*                                             set yet                    */
936 /*                                                                        */
937 /*  CALLS                                                                 */
938 /*                                                                        */
939 /*    nx_tcp_server_socket_listen           Listen of TELNET clients      */
940 /*    tx_thread_resume                      Resume TELNET server thread   */
941 /*    tx_timer_activate                     Activate TELNET server timer  */
942 /*                                                                        */
943 /*  CALLED BY                                                             */
944 /*                                                                        */
945 /*    Application Code                                                    */
946 /*                                                                        */
947 /*  RELEASE HISTORY                                                       */
948 /*                                                                        */
949 /*    DATE              NAME                      DESCRIPTION             */
950 /*                                                                        */
951 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
952 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
953 /*                                            resulting in version 6.1    */
954 /*                                                                        */
955 /**************************************************************************/
_nx_telnet_server_start(NX_TELNET_SERVER * server_ptr)956 UINT  _nx_telnet_server_start(NX_TELNET_SERVER *server_ptr)
957 {
958 
959 UINT    status;
960 ULONG   events;
961 
962 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
963 
964     /* Check for Telnet server packet pool we'll need to send options. */
965     if (server_ptr -> nx_telnet_server_packet_pool_ptr == NX_NULL)
966     {
967 
968         /* The Telnet server packet pool is not set. */
969         return NX_TELNET_NO_PACKET_POOL;
970     }
971 #endif
972 
973     /* Start listening on the TELNET socket.  */
974     status =  nx_tcp_server_socket_listen(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
975                         &(server_ptr -> nx_telnet_server_client_list[0].nx_telnet_client_request_socket),
976                                     NX_TELNET_MAX_CLIENTS, _nx_telnet_server_connection_present);
977 
978     /* Determine if an error is present.  */
979     if (status != NX_SUCCESS)
980     {
981 
982         /* Error, return to caller.  */
983         return(status);
984     }
985 
986     /* Activate TELNET server timer.  */
987     tx_timer_activate(&(server_ptr -> nx_telnet_server_timer));
988 
989     /* Clear stop event. */
990     tx_event_flags_get(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_STOP_EVENT, TX_OR_CLEAR, &events, TX_NO_WAIT);
991 
992     /* Start the TELNET server thread.  */
993     tx_thread_resume(&(server_ptr -> nx_telnet_server_thread));
994 
995     /* Return successful completion.  */
996     return(NX_SUCCESS);
997 }
998 
999 
1000 /**************************************************************************/
1001 /*                                                                        */
1002 /*  FUNCTION                                               RELEASE        */
1003 /*                                                                        */
1004 /*    _nxe_telnet_server_stop                             PORTABLE C      */
1005 /*                                                           6.1          */
1006 /*  AUTHOR                                                                */
1007 /*                                                                        */
1008 /*    Yuxin Zhou, Microsoft Corporation                                   */
1009 /*                                                                        */
1010 /*  DESCRIPTION                                                           */
1011 /*                                                                        */
1012 /*    This function checks for errors in the TELNET server stop call.     */
1013 /*                                                                        */
1014 /*                                                                        */
1015 /*  INPUT                                                                 */
1016 /*                                                                        */
1017 /*    server_ptr                            Pointer to TELNET server      */
1018 /*                                                                        */
1019 /*  OUTPUT                                                                */
1020 /*                                                                        */
1021 /*    status                                Completion status             */
1022 /*                                                                        */
1023 /*  CALLS                                                                 */
1024 /*                                                                        */
1025 /*    _nx_telnet_server_stop                Actual server start call      */
1026 /*                                                                        */
1027 /*  CALLED BY                                                             */
1028 /*                                                                        */
1029 /*    Application Code                                                    */
1030 /*                                                                        */
1031 /*  RELEASE HISTORY                                                       */
1032 /*                                                                        */
1033 /*    DATE              NAME                      DESCRIPTION             */
1034 /*                                                                        */
1035 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1036 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1037 /*                                            resulting in version 6.1    */
1038 /*                                                                        */
1039 /**************************************************************************/
_nxe_telnet_server_stop(NX_TELNET_SERVER * server_ptr)1040 UINT  _nxe_telnet_server_stop(NX_TELNET_SERVER *server_ptr)
1041 {
1042 
1043 UINT    status;
1044 
1045 
1046     /* Check for invalid input pointers.  */
1047     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
1048         return(NX_PTR_ERROR);
1049 
1050     /* Check for appropriate caller.  */
1051     NX_THREADS_ONLY_CALLER_CHECKING
1052 
1053     /* Call actual server delete function.  */
1054     status =  _nx_telnet_server_stop(server_ptr);
1055 
1056     /* Return completion status.  */
1057     return(status);
1058 }
1059 
1060 
1061 /**************************************************************************/
1062 /*                                                                        */
1063 /*  FUNCTION                                               RELEASE        */
1064 /*                                                                        */
1065 /*    _nx_telnet_server_stop                              PORTABLE C      */
1066 /*                                                           6.1          */
1067 /*  AUTHOR                                                                */
1068 /*                                                                        */
1069 /*    Yuxin Zhou, Microsoft Corporation                                   */
1070 /*                                                                        */
1071 /*  DESCRIPTION                                                           */
1072 /*                                                                        */
1073 /*    This function stops a previously started TELNET server on the       */
1074 /*    specified IP.                                                       */
1075 /*                                                                        */
1076 /*                                                                        */
1077 /*  INPUT                                                                 */
1078 /*                                                                        */
1079 /*    server_ptr                            Pointer to TELNET server      */
1080 /*                                                                        */
1081 /*  OUTPUT                                                                */
1082 /*                                                                        */
1083 /*    status                                Completion status             */
1084 /*                                                                        */
1085 /*  CALLS                                                                 */
1086 /*                                                                        */
1087 /*    tx_event_flags_set                    Set events for server thread  */
1088 /*    tx_timer_deactivate                   Deactivate TELNET server timer*/
1089 /*    nx_tcp_server_socket_unaccept         Unaccept server socket        */
1090 /*    nx_tcp_server_socket_unlisten         Unlisten on server            */
1091 /*    nx_tcp_socket_disconnect              Disconnect socket             */
1092 /*                                                                        */
1093 /*  CALLED BY                                                             */
1094 /*                                                                        */
1095 /*    Application Code                                                    */
1096 /*                                                                        */
1097 /*  RELEASE HISTORY                                                       */
1098 /*                                                                        */
1099 /*    DATE              NAME                      DESCRIPTION             */
1100 /*                                                                        */
1101 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1102 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1103 /*                                            resulting in version 6.1    */
1104 /*                                                                        */
1105 /**************************************************************************/
_nx_telnet_server_stop(NX_TELNET_SERVER * server_ptr)1106 UINT  _nx_telnet_server_stop(NX_TELNET_SERVER *server_ptr)
1107 {
1108 UINT                        i;
1109 NX_TELNET_CLIENT_REQUEST   *client_request_ptr;
1110 
1111     /* Deactivate TELNET server timer.  */
1112     tx_timer_deactivate(&(server_ptr -> nx_telnet_server_timer));
1113 
1114     /* Suspend the TELNET server thread.  */
1115     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_STOP_EVENT, TX_OR);
1116 
1117     /* Walk through the server structure to close and delete any open sockets.  */
1118     i =  0;
1119     client_request_ptr =  &(server_ptr -> nx_telnet_server_client_list[0]);
1120     while (i < NX_TELNET_MAX_CLIENTS)
1121     {
1122 
1123         /* Disconnect the socket.  */
1124         nx_tcp_socket_disconnect(&(client_request_ptr -> nx_telnet_client_request_socket), NX_NO_WAIT);
1125 
1126         /* Unaccept the socket.  */
1127         nx_tcp_server_socket_unaccept(&(client_request_ptr -> nx_telnet_client_request_socket));
1128 
1129         /* Reset client request. */
1130         client_request_ptr -> nx_telnet_client_request_activity_timeout =  0;
1131 
1132         /* Increment the pointer into the client request list.  */
1133         client_request_ptr++;
1134         i++;
1135     }
1136 
1137     /* Unlisten on the TELNET port.  */
1138     nx_tcp_server_socket_unlisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT);
1139 
1140     /* Return successful completion.  */
1141     return(NX_SUCCESS);
1142 }
1143 
1144 
1145 /**************************************************************************/
1146 /*                                                                        */
1147 /*  FUNCTION                                               RELEASE        */
1148 /*                                                                        */
1149 /*    _nxe_telnet_server_get_open_connection_count        PORTABLE C      */
1150 /*                                                           6.1          */
1151 /*  AUTHOR                                                                */
1152 /*                                                                        */
1153 /*    Yuxin Zhou, Microsoft Corporation                                   */
1154 /*                                                                        */
1155 /*  DESCRIPTION                                                           */
1156 /*                                                                        */
1157 /*    This function checks for errors in the TELNET server get open       */
1158 /*    connection count service.                                           */
1159 /*                                                                        */
1160 /*                                                                        */
1161 /*  INPUT                                                                 */
1162 /*                                                                        */
1163 /*    server_ptr                            Pointer to TELNET server      */
1164 /*    current_connections                   Pointer to # open connections */
1165 /*                                                                        */
1166 /*  OUTPUT                                                                */
1167 /*                                                                        */
1168 /*    status                                Completion status             */
1169 /*                                                                        */
1170 /*  CALLS                                                                 */
1171 /*                                                                        */
1172 /*    _nx_telnet_server_get_open_connection_count                         */
1173 /*                                          Actual server get count call  */
1174 /*                                                                        */
1175 /*  CALLED BY                                                             */
1176 /*                                                                        */
1177 /*    Application Code                                                    */
1178 /*                                                                        */
1179 /*  RELEASE HISTORY                                                       */
1180 /*                                                                        */
1181 /*    DATE              NAME                      DESCRIPTION             */
1182 /*                                                                        */
1183 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1184 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1185 /*                                            resulting in version 6.1    */
1186 /*                                                                        */
1187 /**************************************************************************/
_nxe_telnet_server_get_open_connection_count(NX_TELNET_SERVER * server_ptr,UINT * current_connections)1188 UINT  _nxe_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections)
1189 {
1190 
1191 UINT    status;
1192 
1193 
1194     /* Check for invalid input pointers.  */
1195     if ((server_ptr == NX_NULL) || (current_connections == NX_NULL))
1196         return(NX_PTR_ERROR);
1197 
1198     /* Check for appropriate caller.  */
1199     NX_THREADS_ONLY_CALLER_CHECKING
1200 
1201     /* Call actual server delete function.  */
1202     status =  _nx_telnet_server_get_open_connection_count(server_ptr, current_connections);
1203 
1204     /* Return completion status.  */
1205     return(status);
1206 }
1207 
1208 /**************************************************************************/
1209 /*                                                                        */
1210 /*  FUNCTION                                               RELEASE        */
1211 /*                                                                        */
1212 /*    _nx_telnet_server_get_open_connection_count         PORTABLE C      */
1213 /*                                                           6.1          */
1214 /*  AUTHOR                                                                */
1215 /*                                                                        */
1216 /*    Yuxin Zhou, Microsoft Corporation                                   */
1217 /*                                                                        */
1218 /*  DESCRIPTION                                                           */
1219 /*                                                                        */
1220 /*    This function returns the number of currently open connections.     */
1221 /*                                                                        */
1222 /*                                                                        */
1223 /*  INPUT                                                                 */
1224 /*                                                                        */
1225 /*    server_ptr                            Pointer to TELNET server      */
1226 /*    current_connections                   Pointer to # open connections */
1227 /*                                                                        */
1228 /*  OUTPUT                                                                */
1229 /*                                                                        */
1230 /*    NX_SUCCESS                            Successful completion status  */
1231 /*                                                                        */
1232 /*  CALLS                                                                 */
1233 /*                                                                        */
1234 /*    None                                                                */
1235 /*                                                                        */
1236 /*  CALLED BY                                                             */
1237 /*                                                                        */
1238 /*    Application Code                                                    */
1239 /*                                                                        */
1240 /*  RELEASE HISTORY                                                       */
1241 /*                                                                        */
1242 /*    DATE              NAME                      DESCRIPTION             */
1243 /*                                                                        */
1244 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1245 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1246 /*                                            resulting in version 6.1    */
1247 /*                                                                        */
1248 /**************************************************************************/
_nx_telnet_server_get_open_connection_count(NX_TELNET_SERVER * server_ptr,UINT * current_connections)1249 UINT  _nx_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections)
1250 {
1251 
1252     /* Retrieve server's record of open connections.  */
1253     *current_connections =  server_ptr -> nx_telnet_server_open_connections;
1254 
1255     /* Return completion status.  */
1256     return(NX_SUCCESS);
1257 }
1258 
1259 /**************************************************************************/
1260 /*                                                                        */
1261 /*  FUNCTION                                               RELEASE        */
1262 /*                                                                        */
1263 /*    _nx_telnet_server_thread_entry                      PORTABLE C      */
1264 /*                                                           6.1          */
1265 /*  AUTHOR                                                                */
1266 /*                                                                        */
1267 /*    Yuxin Zhou, Microsoft Corporation                                   */
1268 /*                                                                        */
1269 /*  DESCRIPTION                                                           */
1270 /*                                                                        */
1271 /*    This function is the entry of the TELNET server.  All basic         */
1272 /*    processing is initiated by this function.                           */
1273 /*                                                                        */
1274 /*                                                                        */
1275 /*  INPUT                                                                 */
1276 /*                                                                        */
1277 /*    telnet_server                             Pointer to TELNET server  */
1278 /*                                                                        */
1279 /*  OUTPUT                                                                */
1280 /*                                                                        */
1281 /*    None                                                                */
1282 /*                                                                        */
1283 /*  CALLS                                                                 */
1284 /*                                                                        */
1285 /*   _nx_telnet_server_connect_process          Process connection        */
1286 /*   _nx_telnet_server_data_process             Process received data     */
1287 /*   _nx_telnet_server_disconnect_process       Process disconnection     */
1288 /*   _nx_telnet_server_timeout_processing       Process activity timeout  */
1289 /*   tx_event_flags_get                         Get TELNET event(s)       */
1290 /*   tx_thread_suspend                          Suspend TELNET thread     */
1291 /*                                                                        */
1292 /*  CALLED BY                                                             */
1293 /*                                                                        */
1294 /*    ThreadX                                                             */
1295 /*                                                                        */
1296 /*  RELEASE HISTORY                                                       */
1297 /*                                                                        */
1298 /*    DATE              NAME                      DESCRIPTION             */
1299 /*                                                                        */
1300 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1301 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1302 /*                                            resulting in version 6.1    */
1303 /*                                                                        */
1304 /**************************************************************************/
_nx_telnet_server_thread_entry(ULONG telnet_server)1305 VOID  _nx_telnet_server_thread_entry(ULONG telnet_server)
1306 {
1307 
1308 NX_TELNET_SERVER        *server_ptr;
1309 UINT                    status;
1310 ULONG                   events;
1311 
1312 
1313     /* Setup the server pointer.  */
1314     server_ptr =  (NX_TELNET_SERVER *) telnet_server;
1315 
1316     /* Loop to process TELNET Server requests.  */
1317     while(1)
1318     {
1319 
1320         /* Wait for an TELNET client activity.  */
1321         status =  tx_event_flags_get(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_ANY_EVENT, TX_OR_CLEAR, &events, TX_WAIT_FOREVER);
1322 
1323         /* Check the return status.  */
1324         if (status)
1325         {
1326 
1327             /* If an error occurs, simply continue the loop.  */
1328             continue;
1329         }
1330 
1331         /* Check whether service is started. */
1332         if (events & NX_TELNET_STOP_EVENT)
1333         {
1334 
1335             /* Suspend thread here. */
1336             tx_thread_suspend(&server_ptr -> nx_telnet_server_thread);
1337             continue;
1338         }
1339 
1340         /* Otherwise, an event is present.  Process according to the event.  */
1341 
1342         /* Check for a client connection event.  */
1343         if (events & NX_TELNET_SERVER_CONNECT)
1344         {
1345 
1346             /* Call the connect processing.  */
1347             _nx_telnet_server_connect_process(server_ptr);
1348         }
1349 
1350         /* Check for a TELNET client write data event.  */
1351         if  (events & NX_TELNET_SERVER_DATA)
1352         {
1353 
1354             /* Call processing to handle server data.  */
1355             _nx_telnet_server_data_process(server_ptr);
1356         }
1357 
1358         /* Check for a client disconnect event.  */
1359         if  (events & NX_TELNET_SERVER_DISCONNECT)
1360         {
1361 
1362             /* Call the disconnect processing.  */
1363             _nx_telnet_server_disconnect_process(server_ptr);
1364         }
1365 
1366         /* Check for a client activity timeout event.  */
1367         if  (events & NX_TELNET_SERVER_ACTIVITY_TIMEOUT)
1368         {
1369 
1370             /* Call the activity timeout processing.  */
1371             _nx_telnet_server_timeout_processing(server_ptr);
1372         }
1373     }
1374 }
1375 
1376 
1377 /**************************************************************************/
1378 /*                                                                        */
1379 /*  FUNCTION                                               RELEASE        */
1380 /*                                                                        */
1381 /*    _nx_telnet_server_connect_process                   PORTABLE C      */
1382 /*                                                           6.1          */
1383 /*  AUTHOR                                                                */
1384 /*                                                                        */
1385 /*    Yuxin Zhou, Microsoft Corporation                                   */
1386 /*                                                                        */
1387 /*  DESCRIPTION                                                           */
1388 /*                                                                        */
1389 /*    This function handles all TELNET client connections received.       */
1390 /*                                                                        */
1391 /*                                                                        */
1392 /*  INPUT                                                                 */
1393 /*                                                                        */
1394 /*    server_ptr                            Pointer to TELNET server      */
1395 /*                                                                        */
1396 /*  OUTPUT                                                                */
1397 /*                                                                        */
1398 /*    None                                                                */
1399 /*                                                                        */
1400 /*  CALLS                                                                 */
1401 /*                                                                        */
1402 /*    nx_tcp_server_socket_accept           Accept connection on socket   */
1403 /*    nx_tcp_server_socket_relisten         Relisten for connection       */
1404 /*    nx_tcp_server_socket_unaccept         Unaccept connection           */
1405 /*                                                                        */
1406 /*  CALLED BY                                                             */
1407 /*                                                                        */
1408 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
1409 /*                                                                        */
1410 /*  RELEASE HISTORY                                                       */
1411 /*                                                                        */
1412 /*    DATE              NAME                      DESCRIPTION             */
1413 /*                                                                        */
1414 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1415 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1416 /*                                            resulting in version 6.1    */
1417 /*                                                                        */
1418 /**************************************************************************/
_nx_telnet_server_connect_process(NX_TELNET_SERVER * server_ptr)1419 VOID  _nx_telnet_server_connect_process(NX_TELNET_SERVER *server_ptr)
1420 {
1421 
1422 UINT                        i;
1423 UINT                        status;
1424 NX_TELNET_CLIENT_REQUEST    *client_req_ptr;
1425 
1426 
1427     /* One of the client request sockets is in the process of connection.  */
1428 
1429     /* Search the connections to see which one.  */
1430     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1431     {
1432 
1433         /* Setup pointer to client request structure.  */
1434         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1435 
1436         /* Now see if this socket was the one that is in being connected.  */
1437         if ((client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state > NX_TCP_CLOSED) &&
1438             (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state < NX_TCP_ESTABLISHED) &&
1439             (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_connect_port))
1440         {
1441 
1442             /* Yes, we have found the socket being connected.  */
1443 
1444             /* Increment the number of connection requests.  */
1445             server_ptr -> nx_telnet_server_connection_requests++;
1446 
1447             /* Attempt to accept on this socket.  */
1448             status = nx_tcp_server_socket_accept(&(client_req_ptr -> nx_telnet_client_request_socket), NX_TELNET_SERVER_TIMEOUT);
1449 
1450             /* Determine if it is successful.  */
1451             if (status)
1452             {
1453 
1454                 /* Not successful, simply unaccept on this socket.  */
1455                 nx_tcp_server_socket_unaccept(&(client_req_ptr -> nx_telnet_client_request_socket));
1456             }
1457             else
1458             {
1459 
1460                 /* Reset the client request activity timeout.  */
1461                 client_req_ptr -> nx_telnet_client_request_activity_timeout =  NX_TELNET_ACTIVITY_TIMEOUT;
1462 
1463                 /* Update number of current open connections.  */
1464                 server_ptr -> nx_telnet_server_open_connections++;
1465 
1466                 /* Call the application's new connection callback routine.  */
1467                 if (server_ptr -> nx_telnet_new_connection)
1468                 {
1469                     /* Yes, there is a new connection callback routine - call it!  */
1470                     (server_ptr -> nx_telnet_new_connection)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection);
1471                 }
1472 
1473                 /* Disable remote echo by default. */
1474                 if(server_ptr -> nx_telnet_set_echo)
1475                     server_ptr -> nx_telnet_set_echo(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, NX_FALSE);
1476 
1477 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
1478 
1479                 /* Yes, send out server echo option requests. */
1480                 status = _nx_telnet_server_send_option_requests(server_ptr, client_req_ptr);
1481                 if(status != NX_SUCCESS)
1482                     return;
1483 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
1484 
1485             }
1486         }
1487     }
1488 
1489     /* Now look for a socket that is closed to relisten on.  */
1490     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1491     {
1492 
1493         /* Set a pointer to client request structure.  */
1494         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1495 
1496         /* Now see if this socket is closed.  */
1497         if (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state == NX_TCP_CLOSED)
1498         {
1499 
1500             /* Relisten on this socket.  */
1501             status =  nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
1502                                                     &(client_req_ptr -> nx_telnet_client_request_socket));
1503             /* Check for bad status.  */
1504             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
1505             {
1506 
1507                 /* Increment the error count and keep trying.  */
1508                 server_ptr -> nx_telnet_server_relisten_errors++;
1509                 continue;
1510             }
1511 
1512             /* Break out of loop.  */
1513             break;
1514         }
1515     }
1516 }
1517 
1518 
1519 /**************************************************************************/
1520 /*                                                                        */
1521 /*  FUNCTION                                               RELEASE        */
1522 /*                                                                        */
1523 /*    _nx_telnet_server_connection_present                PORTABLE C      */
1524 /*                                                           6.1          */
1525 /*  AUTHOR                                                                */
1526 /*                                                                        */
1527 /*    Yuxin Zhou, Microsoft Corporation                                   */
1528 /*                                                                        */
1529 /*  DESCRIPTION                                                           */
1530 /*                                                                        */
1531 /*    This function handles all TELNET client connections received on     */
1532 /*    the socket.                                                         */
1533 /*                                                                        */
1534 /*                                                                        */
1535 /*  INPUT                                                                 */
1536 /*                                                                        */
1537 /*    socket_ptr                            Socket event occurred         */
1538 /*    port                                  Port the connection occurred  */
1539 /*                                                                        */
1540 /*  OUTPUT                                                                */
1541 /*                                                                        */
1542 /*    None                                                                */
1543 /*                                                                        */
1544 /*  CALLS                                                                 */
1545 /*                                                                        */
1546 /*    tx_event_flags_set                    Set events for server thread  */
1547 /*                                                                        */
1548 /*  CALLED BY                                                             */
1549 /*                                                                        */
1550 /*    NetX                                  NetX connect callback         */
1551 /*                                                                        */
1552 /*  RELEASE HISTORY                                                       */
1553 /*                                                                        */
1554 /*    DATE              NAME                      DESCRIPTION             */
1555 /*                                                                        */
1556 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1557 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1558 /*                                            resulting in version 6.1    */
1559 /*                                                                        */
1560 /**************************************************************************/
_nx_telnet_server_connection_present(NX_TCP_SOCKET * socket_ptr,UINT port)1561 VOID  _nx_telnet_server_connection_present(NX_TCP_SOCKET *socket_ptr, UINT port)
1562 {
1563 
1564 NX_TELNET_SERVER   *server_ptr;
1565 
1566     NX_PARAMETER_NOT_USED(port);
1567 
1568     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
1569     server_ptr =  socket_ptr -> nx_tcp_socket_reserved_ptr;
1570 
1571     /* Set the connect event flag.  */
1572     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_CONNECT, TX_OR);
1573 }
1574 
1575 
1576 /**************************************************************************/
1577 /*                                                                        */
1578 /*  FUNCTION                                               RELEASE        */
1579 /*                                                                        */
1580 /*    _nx_telnet_server_disconnect_present                PORTABLE C      */
1581 /*                                                           6.1          */
1582 /*  AUTHOR                                                                */
1583 /*                                                                        */
1584 /*    Yuxin Zhou, Microsoft Corporation                                   */
1585 /*                                                                        */
1586 /*  DESCRIPTION                                                           */
1587 /*                                                                        */
1588 /*    This function handles all TELNET client disconnections received on  */
1589 /*    the socket.                                                         */
1590 /*                                                                        */
1591 /*                                                                        */
1592 /*  INPUT                                                                 */
1593 /*                                                                        */
1594 /*    socket_ptr                            Socket event occurred         */
1595 /*                                                                        */
1596 /*  OUTPUT                                                                */
1597 /*                                                                        */
1598 /*    None                                                                */
1599 /*                                                                        */
1600 /*  CALLS                                                                 */
1601 /*                                                                        */
1602 /*    tx_event_flags_set                    Set events for server thread  */
1603 /*                                                                        */
1604 /*  CALLED BY                                                             */
1605 /*                                                                        */
1606 /*    NetX                                  NetX connect callback         */
1607 /*                                                                        */
1608 /*  RELEASE HISTORY                                                       */
1609 /*                                                                        */
1610 /*    DATE              NAME                      DESCRIPTION             */
1611 /*                                                                        */
1612 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1613 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1614 /*                                            resulting in version 6.1    */
1615 /*                                                                        */
1616 /**************************************************************************/
_nx_telnet_server_disconnect_present(NX_TCP_SOCKET * socket_ptr)1617 VOID  _nx_telnet_server_disconnect_present(NX_TCP_SOCKET *socket_ptr)
1618 {
1619 
1620 NX_TELNET_SERVER   *server_ptr;
1621 
1622     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
1623     server_ptr =  socket_ptr -> nx_tcp_socket_reserved_ptr;
1624 
1625     /* Set the disconnect event flag.  */
1626     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_DISCONNECT, TX_OR);
1627 }
1628 
1629 
1630 /**************************************************************************/
1631 /*                                                                        */
1632 /*  FUNCTION                                               RELEASE        */
1633 /*                                                                        */
1634 /*    _nx_telnet_server_disconnect_process                PORTABLE C      */
1635 /*                                                           6.1          */
1636 /*  AUTHOR                                                                */
1637 /*                                                                        */
1638 /*    Yuxin Zhou, Microsoft Corporation                                   */
1639 /*                                                                        */
1640 /*  DESCRIPTION                                                           */
1641 /*                                                                        */
1642 /*    This function processes all TELNET client disconnections received   */
1643 /*    on the socket.                                                      */
1644 /*                                                                        */
1645 /*                                                                        */
1646 /*  INPUT                                                                 */
1647 /*                                                                        */
1648 /*    server_ptr                            Pointer to TELNET server      */
1649 /*                                                                        */
1650 /*  OUTPUT                                                                */
1651 /*                                                                        */
1652 /*    None                                                                */
1653 /*                                                                        */
1654 /*  CALLS                                                                 */
1655 /*                                                                        */
1656 /*    nx_tcp_server_socket_relisten         Relisten on Telnet port       */
1657 /*    nx_tcp_server_socket_unaccept         Unaccept connection           */
1658 /*    nx_tcp_socket_disconnect              Disconnect socket             */
1659 /*                                                                        */
1660 /*  CALLED BY                                                             */
1661 /*                                                                        */
1662 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
1663 /*                                                                        */
1664 /*  RELEASE HISTORY                                                       */
1665 /*                                                                        */
1666 /*    DATE              NAME                      DESCRIPTION             */
1667 /*                                                                        */
1668 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1669 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1670 /*                                            resulting in version 6.1    */
1671 /*                                                                        */
1672 /**************************************************************************/
_nx_telnet_server_disconnect_process(NX_TELNET_SERVER * server_ptr)1673 VOID  _nx_telnet_server_disconnect_process(NX_TELNET_SERVER *server_ptr)
1674 {
1675 
1676 UINT                        i;
1677 UINT                        status;
1678 NX_TELNET_CLIENT_REQUEST   *client_req_ptr;
1679 UINT                        reset_client_request;
1680 
1681 
1682     /* Now look for a socket that has a disconnect state.  */
1683     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1684     {
1685 
1686         reset_client_request = NX_FALSE;
1687 
1688         /* Setup pointer to client request structure.  */
1689         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1690 
1691        /* Has the socket received a RST packet? If so NetX will put it in a CLOSED or LISTEN state
1692           and the socket activity timeout has not been reset yet.  */
1693        if (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state < NX_TCP_SYN_SENT)
1694        {
1695 
1696             if (client_req_ptr -> nx_telnet_client_request_activity_timeout > 0)
1697             {
1698 
1699                 reset_client_request = NX_TRUE;
1700             }
1701        }
1702        else
1703        {
1704 
1705             /* Now see if this socket has entered a disconnect state.  */
1706             while (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state > NX_TCP_ESTABLISHED)
1707             {
1708 
1709                 /* Yes, a disconnect is present, which signals an end of session for TELNET request.  */
1710 
1711                 /* First, cleanup this socket.  */
1712                 nx_tcp_socket_disconnect(&(client_req_ptr -> nx_telnet_client_request_socket), NX_TELNET_SERVER_TIMEOUT);
1713 
1714                 reset_client_request = NX_TRUE;
1715             }
1716        }
1717 
1718        /* If this connection is closed, update the telnet data and notify the application of a disconnect. */
1719        if (reset_client_request == NX_TRUE)
1720        {
1721 
1722            /* Unaccept this socket.  */
1723            nx_tcp_server_socket_unaccept(&(client_req_ptr -> nx_telnet_client_request_socket));
1724 
1725            /* Reset the client request activity timeout.  */
1726            client_req_ptr -> nx_telnet_client_request_activity_timeout =  0;
1727 
1728            /* Update number of current open connections. */
1729            if (server_ptr -> nx_telnet_server_open_connections > 0)
1730                server_ptr -> nx_telnet_server_open_connections--;
1731 
1732            /* Call the application's end connection callback routine.  */
1733            if (server_ptr -> nx_telnet_connection_end)
1734            {
1735 
1736                /* Yes, there is a connection end callback routine - call it!  */
1737                (server_ptr -> nx_telnet_connection_end)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection);
1738            }
1739        }
1740     }
1741 
1742     /* Now look for a socket that is closed to relisten on.  */
1743     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1744     {
1745 
1746         /* Setup pointer to client request structure.  */
1747         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1748 
1749         /* Now see if this socket is closed.  */
1750         if (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state == NX_TCP_CLOSED)
1751         {
1752 
1753             /* Relisten on this socket.  */
1754             status =  nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
1755                                                     &(client_req_ptr -> nx_telnet_client_request_socket));
1756             /* Check for bad status.  */
1757             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
1758             {
1759 
1760                 /* Increment the error count and keep trying.  */
1761                 server_ptr -> nx_telnet_server_relisten_errors++;
1762                 continue;
1763             }
1764 
1765             /* Break out of loop.  */
1766             break;
1767         }
1768     }
1769 }
1770 
1771 
1772 /**************************************************************************/
1773 /*                                                                        */
1774 /*  FUNCTION                                               RELEASE        */
1775 /*                                                                        */
1776 /*    _nx_telnet_server_data_present                      PORTABLE C      */
1777 /*                                                           6.1          */
1778 /*  AUTHOR                                                                */
1779 /*                                                                        */
1780 /*    Yuxin Zhou, Microsoft Corporation                                   */
1781 /*                                                                        */
1782 /*  DESCRIPTION                                                           */
1783 /*                                                                        */
1784 /*    This function notifies the TELNET server thread of data received    */
1785 /*    from a client on the socket.                                        */
1786 /*                                                                        */
1787 /*                                                                        */
1788 /*  INPUT                                                                 */
1789 /*                                                                        */
1790 /*    socket_ptr                            Socket event occurred         */
1791 /*                                                                        */
1792 /*  OUTPUT                                                                */
1793 /*                                                                        */
1794 /*    None                                                                */
1795 /*                                                                        */
1796 /*  CALLS                                                                 */
1797 /*                                                                        */
1798 /*    tx_event_flags_set                    Set events for server thread  */
1799 /*                                                                        */
1800 /*  CALLED BY                                                             */
1801 /*                                                                        */
1802 /*    NetX                                  NetX connect callback         */
1803 /*                                                                        */
1804 /*  RELEASE HISTORY                                                       */
1805 /*                                                                        */
1806 /*    DATE              NAME                      DESCRIPTION             */
1807 /*                                                                        */
1808 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1809 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1810 /*                                            resulting in version 6.1    */
1811 /*                                                                        */
1812 /**************************************************************************/
_nx_telnet_server_data_present(NX_TCP_SOCKET * socket_ptr)1813 VOID  _nx_telnet_server_data_present(NX_TCP_SOCKET *socket_ptr)
1814 {
1815 
1816 NX_TELNET_SERVER   *server_ptr;
1817 
1818     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
1819     server_ptr =  socket_ptr -> nx_tcp_socket_reserved_ptr;
1820 
1821     /* Set the data event flag.  */
1822     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_DATA, TX_OR);
1823 }
1824 
1825 
1826 /**************************************************************************/
1827 /*                                                                        */
1828 /*  FUNCTION                                               RELEASE        */
1829 /*                                                                        */
1830 /*    _nx_telnet_server_data_process                      PORTABLE C      */
1831 /*                                                           6.1          */
1832 /*  AUTHOR                                                                */
1833 /*                                                                        */
1834 /*    Yuxin Zhou, Microsoft Corporation                                   */
1835 /*                                                                        */
1836 /*  DESCRIPTION                                                           */
1837 /*                                                                        */
1838 /*    This function processes all TELNET client data packets received on  */
1839 /*    the request socket.                                                 */
1840 /*                                                                        */
1841 /*                                                                        */
1842 /*  INPUT                                                                 */
1843 /*                                                                        */
1844 /*    server_ptr                            Pointer to TELNET server      */
1845 /*                                                                        */
1846 /*  OUTPUT                                                                */
1847 /*                                                                        */
1848 /*    None                                                                */
1849 /*                                                                        */
1850 /*  CALLS                                                                 */
1851 /*                                                                        */
1852 /*    nx_packet_release                     Release packet                */
1853 /*    nx_tcp_socket_receive                 Receive from socket           */
1854 /*                                                                        */
1855 /*  CALLED BY                                                             */
1856 /*                                                                        */
1857 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
1858 /*                                                                        */
1859 /*  RELEASE HISTORY                                                       */
1860 /*                                                                        */
1861 /*    DATE              NAME                      DESCRIPTION             */
1862 /*                                                                        */
1863 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1864 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1865 /*                                            resulting in version 6.1    */
1866 /*                                                                        */
1867 /**************************************************************************/
_nx_telnet_server_data_process(NX_TELNET_SERVER * server_ptr)1868 VOID  _nx_telnet_server_data_process(NX_TELNET_SERVER *server_ptr)
1869 {
1870 
1871 UINT                        i;
1872 UINT                        status;
1873 NX_PACKET                   *packet_ptr;
1874 NX_TELNET_CLIENT_REQUEST    *client_req_ptr;
1875 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
1876 UCHAR                       data_char;
1877 UINT                        offset;
1878 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
1879 
1880     /* Now look for a socket that has receive data.  */
1881     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1882     {
1883 
1884         /* Setup pointer to client request structure.  */
1885         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1886 
1887         /* Now see if this socket has data.  If so, process all of it now!  */
1888         while (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_receive_queue_count)
1889         {
1890 
1891             /* Reset the client request activity timeout.  */
1892             client_req_ptr -> nx_telnet_client_request_activity_timeout =  NX_TELNET_ACTIVITY_TIMEOUT;
1893 
1894             /* Attempt to read a packet from this socket.  */
1895             status =  nx_tcp_socket_receive(&(client_req_ptr -> nx_telnet_client_request_socket), &packet_ptr, NX_NO_WAIT);
1896 
1897             /* Check for not data present.  */
1898             if (status != NX_SUCCESS)
1899             {
1900 
1901                 /* Break to look at the next socket.  */
1902                 break;
1903             }
1904 
1905 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
1906 
1907             /* If the first byte of the packet data is the telnet "IAC" code,
1908             this is a telnet option packet.  */
1909             if (*packet_ptr -> nx_packet_prepend_ptr == NX_TELNET_IAC)
1910             {
1911 
1912 #ifndef NX_DISABLE_PACKET_CHAIN
1913                 if (packet_ptr -> nx_packet_next)
1914                 {
1915 
1916                     /* Chained packet is not supported. */
1917                     nx_packet_release(packet_ptr);
1918                     break;
1919                 }
1920 #endif /* NX_DISABLE_PACKET_CHAIN */
1921 
1922                 /* We will use an offset to mark the beginning of each telnet option, if there is more
1923                 than one, in the packet payload. */
1924                 offset = 0;
1925 
1926                 /* Validate the packet length.  */
1927                 if (packet_ptr -> nx_packet_length == 1)
1928                 {
1929                     nx_packet_release(packet_ptr);
1930                     break;
1931                 }
1932 
1933                 /* Set the work pointer to just past the telnet IAC tag. */
1934                 data_char = *(packet_ptr -> nx_packet_prepend_ptr + 1);
1935 
1936                 /* Verify the next byte is a valid Telnet option code. */
1937                 if ((data_char >= NX_TELNET_WILL) && (data_char <= NX_TELNET_DONT))
1938                 {
1939 
1940                     /* Process the entire packet for telnet options, ensuring we don't go off the end of the payload. */
1941                     while((offset < packet_ptr -> nx_packet_length) && (*(packet_ptr -> nx_packet_prepend_ptr + offset) == NX_TELNET_IAC))
1942                     {
1943 
1944                         /* Process this telnet option. The offset will be updated to the location
1945                         of the next option (if there is one) on return of this function. */
1946                         _nx_telnet_server_process_option(server_ptr, packet_ptr, &offset, client_req_ptr);
1947                     }
1948                 }
1949 
1950                 /* Are there any data left? */
1951                 if ((offset < packet_ptr -> nx_packet_length) && (server_ptr -> nx_telnet_receive_data))
1952                 {
1953 
1954                     /* Yes. Adjust packet. */
1955                     packet_ptr -> nx_packet_prepend_ptr += offset;
1956                     packet_ptr -> nx_packet_length -= offset;
1957 
1958                     /* Yes, there is a process data callback routine - call it!  */
1959                     (server_ptr -> nx_telnet_receive_data)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr);
1960                 }
1961                 else
1962                 {
1963 
1964                     /* We're done with this packet. */
1965                     nx_packet_release(packet_ptr);
1966                 }
1967 
1968                 /* Check if the echo negotiation is successful.  */
1969                 if((client_req_ptr -> nx_telnet_client_agree_server_will_SGA_success == NX_TRUE) &&
1970                     (client_req_ptr -> nx_telnet_client_agree_server_will_echo_success == NX_TRUE))
1971                 {
1972 
1973                     /* Enable remote echo. */
1974                     if(server_ptr -> nx_telnet_set_echo)
1975                         server_ptr -> nx_telnet_set_echo(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, NX_TRUE);
1976                 }
1977             }
1978 
1979             /* It's not an option packet.  */
1980             else
1981             {
1982 
1983                 /* Check server receive callback.  */
1984                 if (server_ptr -> nx_telnet_receive_data)
1985                 {
1986 
1987                     /* Yes, there is a process data callback routine - call it!  */
1988                     (server_ptr -> nx_telnet_receive_data)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr);
1989                 }
1990                 else
1991                 {
1992 
1993                     /* Error, no application callback routine.  */
1994 
1995                     /* Release the packet and continue the loop.  */
1996                     nx_packet_release(packet_ptr);
1997                 }
1998             }
1999 #else
2000            if (*packet_ptr -> nx_packet_prepend_ptr == NX_TELNET_IAC)
2001            {
2002                 nx_packet_release(packet_ptr);
2003            }
2004            /* Call the server receive callback.  */
2005            else if (server_ptr -> nx_telnet_receive_data)
2006            {
2007 
2008                /* Yes, there is a process data callback routine - call it!  */
2009                (server_ptr -> nx_telnet_receive_data)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr);
2010            }
2011            else
2012            {
2013 
2014                /* Error, no application callback routine.  */
2015 
2016                /* Release the packet and continue the loop.  */
2017                nx_packet_release(packet_ptr);
2018            }
2019 
2020 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
2021         }
2022     }
2023 }
2024 
2025 
2026 /**************************************************************************/
2027 /*                                                                        */
2028 /*  FUNCTION                                               RELEASE        */
2029 /*                                                                        */
2030 /*    _nx_telnet_server_timeout                           PORTABLE C      */
2031 /*                                                           6.1          */
2032 /*  AUTHOR                                                                */
2033 /*                                                                        */
2034 /*    Yuxin Zhou, Microsoft Corporation                                   */
2035 /*                                                                        */
2036 /*  DESCRIPTION                                                           */
2037 /*                                                                        */
2038 /*    This function is the periodic timer for this TELNET server. Its     */
2039 /*    duty is to inform the TELNET server that it is time to check for    */
2040 /*    activity timeouts.                                                  */
2041 /*                                                                        */
2042 /*                                                                        */
2043 /*  INPUT                                                                 */
2044 /*                                                                        */
2045 /*    telnet_server_address                 TELNET server's address       */
2046 /*                                                                        */
2047 /*  OUTPUT                                                                */
2048 /*                                                                        */
2049 /*    None                                                                */
2050 /*                                                                        */
2051 /*  CALLS                                                                 */
2052 /*                                                                        */
2053 /*    tx_event_flags_set                    Set events for server thread  */
2054 /*                                                                        */
2055 /*  CALLED BY                                                             */
2056 /*                                                                        */
2057 /*    ThreadX                               ThreadX timer callback        */
2058 /*                                                                        */
2059 /*  RELEASE HISTORY                                                       */
2060 /*                                                                        */
2061 /*    DATE              NAME                      DESCRIPTION             */
2062 /*                                                                        */
2063 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2064 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2065 /*                                            resulting in version 6.1    */
2066 /*                                                                        */
2067 /**************************************************************************/
_nx_telnet_server_timeout(ULONG telnet_server_address)2068 VOID  _nx_telnet_server_timeout(ULONG telnet_server_address)
2069 {
2070 
2071 NX_TELNET_SERVER   *server_ptr;
2072 
2073     /* Pickup server pointer.  */
2074     server_ptr =  (NX_TELNET_SERVER *) telnet_server_address;
2075 
2076     /* Set the data event flag.  */
2077     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_ACTIVITY_TIMEOUT, TX_OR);
2078 }
2079 
2080 
2081 /**************************************************************************/
2082 /*                                                                        */
2083 /*  FUNCTION                                               RELEASE        */
2084 /*                                                                        */
2085 /*    _nx_telnet_server_timeout_processing                PORTABLE C      */
2086 /*                                                           6.1          */
2087 /*  AUTHOR                                                                */
2088 /*                                                                        */
2089 /*    Yuxin Zhou, Microsoft Corporation                                   */
2090 /*                                                                        */
2091 /*  DESCRIPTION                                                           */
2092 /*                                                                        */
2093 /*    This function reviews all the active TELNET client connections and  */
2094 /*    looks for an activity timeout. If a connection has not had any      */
2095 /*    activity within NX_TELNET_ACTIVITY_TIMEOUT seconds, the connection  */
2096 /*    is deleted and its resources are made available to a new connection.*/
2097 /*                                                                        */
2098 /*                                                                        */
2099 /*  INPUT                                                                 */
2100 /*                                                                        */
2101 /*    server_ptr                            Pointer to TELNET server      */
2102 /*                                                                        */
2103 /*  OUTPUT                                                                */
2104 /*                                                                        */
2105 /*    None                                                                */
2106 /*                                                                        */
2107 /*  CALLS                                                                 */
2108 /*                                                                        */
2109 /*    nx_tcp_server_socket_relisten         Relisten for another connect  */
2110 /*    nx_tcp_server_socket_unaccept         Unaccept server connection    */
2111 /*    nx_tcp_socket_disconnect              Disconnect socket             */
2112 /*                                                                        */
2113 /*  CALLED BY                                                             */
2114 /*                                                                        */
2115 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
2116 /*                                                                        */
2117 /*  RELEASE HISTORY                                                       */
2118 /*                                                                        */
2119 /*    DATE              NAME                      DESCRIPTION             */
2120 /*                                                                        */
2121 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2122 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2123 /*                                            resulting in version 6.1    */
2124 /*                                                                        */
2125 /**************************************************************************/
_nx_telnet_server_timeout_processing(NX_TELNET_SERVER * server_ptr)2126 VOID  _nx_telnet_server_timeout_processing(NX_TELNET_SERVER *server_ptr)
2127 {
2128 
2129 UINT                        i;
2130 NX_TELNET_CLIENT_REQUEST   *client_req_ptr;
2131 
2132 
2133     /* Now look through all the sockets.  */
2134     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
2135     {
2136 
2137         /* Set a pointer to client request structure.  */
2138         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
2139 
2140         /* Now see if this socket has an activity timeout active.  */
2141         if (client_req_ptr -> nx_telnet_client_request_activity_timeout)
2142         {
2143 
2144             /* Decrement the activity timeout for this client request.  */
2145             if (client_req_ptr -> nx_telnet_client_request_activity_timeout > NX_TELNET_TIMEOUT_PERIOD)
2146                 client_req_ptr -> nx_telnet_client_request_activity_timeout =  client_req_ptr -> nx_telnet_client_request_activity_timeout - NX_TELNET_TIMEOUT_PERIOD;
2147             else
2148                 client_req_ptr -> nx_telnet_client_request_activity_timeout =  0;
2149 
2150             /* Determine if this entry has exceeded the activity timeout.  */
2151             if (client_req_ptr -> nx_telnet_client_request_activity_timeout == 0)
2152             {
2153 
2154                 /* Yes, the activity timeout has been exceeded.  Tear down and clean up the
2155                    entire client request structure.  */
2156 
2157                 /* Increment the activity timeout counter.  */
2158                 server_ptr -> nx_telnet_server_activity_timeouts++;
2159 
2160                 /* Now disconnect the command socket.  */
2161                 nx_tcp_socket_disconnect(&(client_req_ptr -> nx_telnet_client_request_socket), NX_NO_WAIT);
2162 
2163                 /* Unaccept the server socket.  */
2164                 nx_tcp_server_socket_unaccept(&(client_req_ptr -> nx_telnet_client_request_socket));
2165 
2166                 /* Relisten on this socket. This will probably fail, but it is needed just in case all available
2167                    clients were in use at the time of the last relisten.  */
2168                 nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
2169                                                     &(client_req_ptr -> nx_telnet_client_request_socket));
2170 
2171                 /* Update number of current open connections. */
2172                 if (server_ptr -> nx_telnet_server_open_connections > 0)
2173                     server_ptr -> nx_telnet_server_open_connections--;
2174 
2175                 /* Call the application's end connection callback routine.  */
2176                 if (server_ptr -> nx_telnet_connection_end)
2177                 {
2178 
2179                     /* Yes, there is a connection end callback routine - call it!  */
2180                     (server_ptr -> nx_telnet_connection_end)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection);
2181                 }
2182             }
2183         }
2184     }
2185 }
2186 
2187 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
2188 
2189 #ifdef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
2190 /**************************************************************************/
2191 /*                                                                        */
2192 /*  FUNCTION                                               RELEASE        */
2193 /*                                                                        */
2194 /*    _nxe_telnet_server_packet_pool_set                  PORTABLE C      */
2195 /*                                                           6.1          */
2196 /*  AUTHOR                                                                */
2197 /*                                                                        */
2198 /*    Yuxin Zhou, Microsoft Corporation                                   */
2199 /*                                                                        */
2200 /*  DESCRIPTION                                                           */
2201 /*                                                                        */
2202 /*    This function checks for errors in the TELNET server create packet  */
2203 /*    pool call.                                                          */
2204 /*                                                                        */
2205 /*                                                                        */
2206 /*  INPUT                                                                 */
2207 /*                                                                        */
2208 /*    server_ptr                            Pointer to TELNET server      */
2209 /*    pool_ptr                              Pointer to telnet packet pool */
2210 /*                                                                        */
2211 /*  OUTPUT                                                                */
2212 /*                                                                        */
2213 /*    status                                Completion status             */
2214 /*    NX_PTR_ERROR                          Invalid pointer input         */
2215 /*                                                                        */
2216 /*  CALLS                                                                 */
2217 /*                                                                        */
2218 /*    _nx_telnet_server_packet_pool_set     Actual set packet pool call   */
2219 /*                                                                        */
2220 /*  CALLED BY                                                             */
2221 /*                                                                        */
2222 /*    Application Code                                                    */
2223 /*                                                                        */
2224 /*  RELEASE HISTORY                                                       */
2225 /*                                                                        */
2226 /*    DATE              NAME                      DESCRIPTION             */
2227 /*                                                                        */
2228 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2229 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2230 /*                                            resulting in version 6.1    */
2231 /*                                                                        */
2232 /**************************************************************************/
2233 
_nxe_telnet_server_packet_pool_set(NX_TELNET_SERVER * server_ptr,NX_PACKET_POOL * pool_ptr)2234 UINT _nxe_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr)
2235 {
2236 
2237 UINT status;
2238 
2239     /* Check for invalid pointer input. */
2240     if ((server_ptr == NX_NULL) || (pool_ptr == NX_NULL))
2241     {
2242         return NX_PTR_ERROR;
2243     }
2244 
2245     /* Actual set packet pool service. */
2246     status = _nx_telnet_server_packet_pool_set(server_ptr, pool_ptr);
2247 
2248     return status;
2249 }
2250 
2251 /**************************************************************************/
2252 /*                                                                        */
2253 /*  FUNCTION                                               RELEASE        */
2254 /*                                                                        */
2255 /*    _nxe_telnet_server_packet_pool_set                  PORTABLE C      */
2256 /*                                                           6.1          */
2257 /*  AUTHOR                                                                */
2258 /*                                                                        */
2259 /*    Yuxin Zhou, Microsoft Corporation                                   */
2260 /*                                                                        */
2261 /*  DESCRIPTION                                                           */
2262 /*                                                                        */
2263 /*    This function sets the Telnet Server packet pool to the packet pool */
2264 /*    created outside the Telnet Server domain. This permits the packet   */
2265 /*    pool memory to be in a different location from the Telnet Server.   */
2266 /*                                                                        */
2267 /*    The Telnet Server only uses this packet pool for sending Telnet     */
2268 /*    options (requires NX_TELNET_SERVER_OPTION_DISABLE not be defined).  */
2269 /*                                                                        */
2270 /*    Note: This will overwrite an existing Telnet Server packet pool if  */
2271 /*    one was previously set.                                             */
2272 /*                                                                        */
2273 /*  INPUT                                                                 */
2274 /*                                                                        */
2275 /*    server_ptr                            Pointer to TELNET server      */
2276 /*    pool_ptr                              Pointer to telnet packet pool */
2277 /*                                                                        */
2278 /*  OUTPUT                                                                */
2279 /*                                                                        */
2280 /*    NX_SUCCESS                            Telnet server packet pool     */
2281 /*                                            successfully set            */
2282 /*                                                                        */
2283 /*  CALLS                                                                 */
2284 /*                                                                        */
2285 /*    None                                                                */
2286 /*                                                                        */
2287 /*  CALLED BY                                                             */
2288 /*                                                                        */
2289 /*    Application Code                                                    */
2290 /*                                                                        */
2291 /*  RELEASE HISTORY                                                       */
2292 /*                                                                        */
2293 /*    DATE              NAME                      DESCRIPTION             */
2294 /*                                                                        */
2295 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2296 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2297 /*                                            resulting in version 6.1    */
2298 /*                                                                        */
2299 /**************************************************************************/
_nx_telnet_server_packet_pool_set(NX_TELNET_SERVER * server_ptr,NX_PACKET_POOL * pool_ptr)2300 UINT _nx_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr)
2301 {
2302 
2303 
2304     server_ptr -> nx_telnet_server_packet_pool_ptr = pool_ptr;
2305 
2306     return NX_SUCCESS;
2307 }
2308 
2309 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
2310 /**************************************************************************/
2311 /*                                                                        */
2312 /*  FUNCTION                                               RELEASE        */
2313 /*                                                                        */
2314 /*    _nx_telnet_server_create_option_packet              PORTABLE C      */
2315 /*                                                           6.1          */
2316 /*  AUTHOR                                                                */
2317 /*                                                                        */
2318 /*    Yuxin Zhou, Microsoft Corporation                                   */
2319 /*                                                                        */
2320 /*  DESCRIPTION                                                           */
2321 /*                                                                        */
2322 /*   This function creates option packet for specified type and id.       */
2323 /*                                                                        */
2324 /*  INPUT                                                                 */
2325 /*                                                                        */
2326 /*    option_message_type                   Option type                   */
2327 /*    option_id                             Option_id                     */
2328 /*    stream                                Output buffer                 */
2329 /*                                                                        */
2330 /*  OUTPUT                                                                */
2331 /*                                                                        */
2332 /*    None                                                                */
2333 /*                                                                        */
2334 /*  CALLS                                                                 */
2335 /*                                                                        */
2336 /*    None                                                                */
2337 /*                                                                        */
2338 /*  CALLED BY                                                             */
2339 /*                                                                        */
2340 /*    _nx_telnet_server_send_option_requests       Send telnet option     */
2341 /*                                                                        */
2342 /*  RELEASE HISTORY                                                       */
2343 /*                                                                        */
2344 /*    DATE              NAME                      DESCRIPTION             */
2345 /*                                                                        */
2346 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2347 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2348 /*                                            resulting in version 6.1    */
2349 /*                                                                        */
2350 /**************************************************************************/
_nx_telnet_server_create_option_packet(UCHAR option_message_type,UCHAR option_id,UCHAR * stream)2351 VOID _nx_telnet_server_create_option_packet(UCHAR option_message_type, UCHAR option_id, UCHAR *stream)
2352 {
2353 
2354     *(stream++) = NX_TELNET_IAC;
2355     *(stream++) = option_message_type;
2356     *stream = option_id;
2357 }
2358 
2359 /**************************************************************************/
2360 /*                                                                        */
2361 /*  FUNCTION                                               RELEASE        */
2362 /*                                                                        */
2363 /*    _nx_telnet_server_send_option_requests              PORTABLE C      */
2364 /*                                                           6.1          */
2365 /*  AUTHOR                                                                */
2366 /*                                                                        */
2367 /*    Yuxin Zhou, Microsoft Corporation                                   */
2368 /*                                                                        */
2369 /*  DESCRIPTION                                                           */
2370 /*                                                                        */
2371 /*   This function is called if 1) the server is configured to send out   */
2372 /*   options without waiting to receive client option requests, or 2)after*/
2373 /*   receiving a client's initial option requests.  This will send out    */
2374 /*   those option requests the server did not receive from the client     */
2375 /*   based on the server session option list.                             */
2376 /*                                                                        */
2377 /*   This function obtains mutex protection on the client session record  */
2378 /*   to update the record with options sent out from the server.          */
2379 /*                                                                        */
2380 /*  INPUT                                                                 */
2381 /*                                                                        */
2382 /*    server_ptr                           Pointer to telnet server       */
2383 /*    client_req_ptr                       Pointer to client record       */
2384 /*                                                                        */
2385 /*  OUTPUT                                                                */
2386 /*                                                                        */
2387 /*    status                               Completion status              */
2388 /*                                                                        */
2389 /*  CALLS                                                                 */
2390 /*                                                                        */
2391 /*    nx_packet_allocate                   Allocate packet from pool      */
2392 /*    nx_packet_release                    Release packet back to pool    */
2393 /*    nx_packet_data_append                Append data to packet payload  */
2394 /*    _nx_telnet_server_create_option_packet                              */
2395 /*                                         Create telnet option message   */
2396 /*   _nx_telnet_server_packet_send         Send telnet option to client   */
2397 /*                                                                        */
2398 /*  CALLED BY                                                             */
2399 /*                                                                        */
2400 /*    _nx_telnet_server_data_process       Top level telnet packet handler*/
2401 /*    _nx_telnet_server_connect_process    Telnet connection handler      */
2402 /*                                                                        */
2403 /*  RELEASE HISTORY                                                       */
2404 /*                                                                        */
2405 /*    DATE              NAME                      DESCRIPTION             */
2406 /*                                                                        */
2407 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2408 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2409 /*                                            resulting in version 6.1    */
2410 /*                                                                        */
2411 /**************************************************************************/
_nx_telnet_server_send_option_requests(NX_TELNET_SERVER * server_ptr,NX_TELNET_CLIENT_REQUEST * client_req_ptr)2412 UINT _nx_telnet_server_send_option_requests(NX_TELNET_SERVER *server_ptr, NX_TELNET_CLIENT_REQUEST *client_req_ptr)
2413 {
2414 UINT        status;
2415 NX_PACKET   *packet_ptr;
2416 UINT        option_length;
2417 UINT        packet_available;
2418 UCHAR       option_stream[9];
2419 
2420     status = NX_SUCCESS;
2421 
2422     /* Indicate packet not available, nor needing to be released. */
2423     packet_available = NX_FALSE;
2424 
2425     /* Allocate a packet for replies to send to this telnet client. */
2426     status =  nx_packet_allocate(server_ptr -> nx_telnet_server_packet_pool_ptr, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
2427 
2428     if (status != NX_SUCCESS)
2429         return status;
2430 
2431     /* Now a packet is available, and if not used should be released. */
2432     packet_available = NX_TRUE;
2433 
2434     /* Initialize option data to zero bytes. */
2435     option_length = 0;
2436 
2437     client_req_ptr -> nx_telnet_client_agree_server_will_echo_success = NX_FALSE;
2438     client_req_ptr -> nx_telnet_client_agree_server_will_SGA_success = NX_FALSE;
2439 
2440     /* Yes, create will echo request (3 bytes). */
2441     _nx_telnet_server_create_option_packet(NX_TELNET_WILL, NX_TELNET_ECHO, &option_stream[0]);
2442 
2443     /* Yes, create dont echo request (3 bytes). */
2444     _nx_telnet_server_create_option_packet(NX_TELNET_DONT, NX_TELNET_ECHO, &option_stream[3]);
2445 
2446     /* Yes, create will SGA request (3 bytes). */
2447     _nx_telnet_server_create_option_packet(NX_TELNET_WILL, NX_TELNET_SGA, &option_stream[6]);
2448 
2449     /* Update the the packet payload for number of bytes for a telnet option request. */
2450     option_length = 9;
2451 
2452     /* Add to the packet payload. */
2453     status = nx_packet_data_append(packet_ptr, option_stream, 9, server_ptr -> nx_telnet_server_packet_pool_ptr, NX_WAIT_FOREVER);
2454 
2455     if (status)
2456     {
2457         nx_packet_release(packet_ptr);
2458         return(status);
2459     }
2460 
2461     /* Check if we have a packet started, but not sent yet.  */
2462     if (option_length > 0)
2463     {
2464 
2465         /* Send the telnet packet out to the client. */
2466         status =  _nx_telnet_server_packet_send(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr, 100);
2467 
2468         /* If errors sending, we need to release the packet. */
2469         if (status != NX_SUCCESS)
2470         {
2471             nx_packet_release(packet_ptr);
2472             return status;
2473         }
2474 
2475         /* Indicate we need another packet, just sent out the last one. */
2476         packet_available = NX_FALSE;
2477     }
2478 
2479     /* Check for unused packet (needs to be released). */
2480     if (packet_available == NX_TRUE)
2481     {
2482 
2483         /* Release the packet we did not use. */
2484         nx_packet_release(packet_ptr);
2485     }
2486     return status;
2487 }
2488 
2489 /**************************************************************************/
2490 /*                                                                        */
2491 /*  FUNCTION                                               RELEASE        */
2492 /*                                                                        */
2493 /*    _nx_telnet_server_process_option                    PORTABLE C      */
2494 /*                                                           6.1          */
2495 /*  AUTHOR                                                                */
2496 /*                                                                        */
2497 /*    Yuxin Zhou, Microsoft Corporation                                   */
2498 /*                                                                        */
2499 /*  DESCRIPTION                                                           */
2500 /*                                                                        */
2501 /*    This function examines the telnet option in the current packet and  */
2502 /*    determines if it is a new client request, an option with            */
2503 /*    subnegotiation data for the server, or a response to a previously   */
2504 /*    sent server telnet option request to the client. It then forwards   */
2505 /*    the telnet option information to the appropriate telnet processor.  */
2506 /*                                                                        */
2507 /*                                                                        */
2508 /*  INPUT                                                                 */
2509 /*                                                                        */
2510 /*    server_ptr                            Pointer to TELNET server      */
2511 /*    packet_ptr                            Packet with telnet option     */
2512 /*    offset                                Option offset in packet       */
2513 /*    client_req_ptr                        Telnet client sending packet  */
2514 /*                                                                        */
2515 /*  OUTPUT                                                                */
2516 /*                                                                        */
2517 /*    NX_TELNET_SESSION_OPTIONS_FULL        Session option list is fill   */
2518 /*    NX_SUCCESS                            Option successfully processed */
2519 /*                                                                        */
2520 /*  CALLS                                                                 */
2521 /*    _nx_telnet_server_update_server_session_attributes                  */
2522 /*                                          Updates server telnet features*/
2523 /*    _nx_telnet_server_update_client_session_attributes                  */
2524 /*                                          Updates client telnet features*/
2525 /*    _nx_telnet_server_process_new_option  Add new option to session list*/
2526 /*    _nx_telnet_server_respond_to_pending_option                         */
2527 /*                                          Send server reply to option   */
2528 /*    _nx_telnet_server_process_subnegotiation_data                       */
2529 /*                                          Process received option specs */
2530 /*    _nx_telnet_server_validate_option_change                            */
2531 /*                                          Determine if option is dupe   */
2532 /*                                          Process received option specs */
2533 /*  CALLED BY                                                             */
2534 /*                                                                        */
2535 /*    _nx_telnet_server_data_process        Top level incoming telnet     */
2536 /*                                             packet handler             */
2537 /*                                                                        */
2538 /*  RELEASE HISTORY                                                       */
2539 /*                                                                        */
2540 /*    DATE              NAME                      DESCRIPTION             */
2541 /*                                                                        */
2542 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2543 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2544 /*                                            resulting in version 6.1    */
2545 /*                                                                        */
2546 /**************************************************************************/
2547 
_nx_telnet_server_process_option(NX_TELNET_SERVER * server_ptr,NX_PACKET * packet_ptr,UINT * offset,NX_TELNET_CLIENT_REQUEST * client_req_ptr)2548 VOID _nx_telnet_server_process_option(NX_TELNET_SERVER *server_ptr, NX_PACKET *packet_ptr, UINT *offset,
2549                                       NX_TELNET_CLIENT_REQUEST *client_req_ptr)
2550 {
2551 UCHAR   data_char;
2552 UCHAR   *work_ptr;
2553 
2554     NX_PARAMETER_NOT_USED(server_ptr);
2555 
2556     /* Set the work pointer to see what option received.  */
2557     work_ptr = (UCHAR *)(packet_ptr -> nx_packet_prepend_ptr + (*offset) + 2);
2558 
2559     /* This option isn't complete, just move to the end of the packet.  */
2560     if (work_ptr >= packet_ptr -> nx_packet_append_ptr)
2561     {
2562         *offset = packet_ptr -> nx_packet_length;
2563         return;
2564     }
2565 
2566     data_char = *work_ptr;
2567 
2568     /* If it is a echo option.  */
2569     if(data_char == NX_TELNET_ECHO)
2570     {
2571 
2572         /* Check whether the client replies with echo negotiation of the local echo disabled.  */
2573         work_ptr--;
2574         data_char = *work_ptr;
2575         if(data_char == NX_TELNET_DO)
2576         {
2577 
2578             /* Server will echo what received from the telnet connection.  */
2579             client_req_ptr -> nx_telnet_client_agree_server_will_echo_success = NX_TRUE;
2580 
2581             /* Move the offset to past the option.  */
2582             (*offset)+=3;
2583         }
2584         else
2585         {
2586 
2587             /* Move the offset to past the option.  */
2588             (*offset)+=3;
2589         }
2590     }
2591 
2592     /* If it is a SGA option.  */
2593     else if(data_char == NX_TELNET_SGA)
2594     {
2595 
2596         /* Check whether the client replies with SGA negotiation.  */
2597         work_ptr--;
2598         data_char = *work_ptr;
2599         if(data_char == NX_TELNET_DO)
2600         {
2601 
2602             /* Server will enable SGA option.  */
2603             client_req_ptr -> nx_telnet_client_agree_server_will_SGA_success = NX_TRUE;
2604 
2605             /* Move the offset to past the option.  */
2606             (*offset)+=3;
2607         }
2608         else
2609         {
2610             /* Move the offset to past the option.  */
2611             (*offset)+=3;
2612             return;
2613         }
2614     }
2615 
2616     /* We have not implemented this option, just return.  */
2617     else
2618     {
2619 
2620         /* See next three bytes.  */
2621         (*offset)+=3;
2622         return;
2623     }
2624 }
2625 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
2626