]> The Tcpdump Group git mirrors - libpcap/blob - rpcapd/rpcapd.c
d1f158230ab04e16f94cbf5274993971cb0f09cf
[libpcap] / rpcapd / rpcapd.c
1 /*
2 * Copyright (c) 2002 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Politecnico di Torino nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include "ftmacros.h"
38
39 #include <errno.h> // for the errno variable
40 #include <string.h> // for strtok, etc
41 #include <stdlib.h> // for malloc(), free(), ...
42 #include <pcap.h> // for PCAP_ERRBUF_SIZE
43 #include <signal.h> // for signal()
44
45 #include "fmtutils.h"
46 #include "sockutils.h" // for socket calls
47 #include "varattrs.h" // for _U_
48 #include "portability.h"
49 #include "rpcapd.h"
50 #include "config_params.h" // configuration file parameters
51 #include "fileconf.h" // for the configuration file management
52 #include "rpcap-protocol.h"
53 #include "daemon.h" // the true main() method of this daemon
54 #include "log.h"
55
56 #ifdef HAVE_OPENSSL
57 #include "sslutils.h"
58 #endif
59
60 #ifdef _WIN32
61 #include <process.h> // for thread stuff
62 #include "win32-svc.h" // for Win32 service stuff
63 #include "getopt.h" // for getopt()-for-Windows
64 #else
65 #include <fcntl.h> // for open()
66 #include <unistd.h> // for exit()
67 #include <sys/wait.h> // waitpid()
68 #endif
69
70 //
71 // Element in list of sockets on which we're listening for connections.
72 //
73 struct listen_sock {
74 struct listen_sock *next;
75 SOCKET sock;
76 };
77
78 // Global variables
79 char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
80 struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
81 int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
82 static struct listen_sock *listen_socks; //!< sockets on which we listen
83 char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration
84 static int passivemode = 1; //!< '1' if we want to run in passive mode as well
85 static struct addrinfo mainhints; //!< temporary struct to keep settings needed to open the new socket
86 static char address[MAX_LINE + 1]; //!< keeps the network address (either numeric or literal) to bind to
87 static char port[MAX_LINE + 1]; //!< keeps the network port to bind to
88 #ifdef _WIN32
89 static HANDLE state_change_event; //!< event to signal that a state change should take place
90 #endif
91 static volatile sig_atomic_t shutdown_server; //!< '1' if the server is to shut down
92 static volatile sig_atomic_t reread_config; //!< '1' if the server is to re-read its configuration
93 static int uses_ssl; //!< '1' to use TLS over the data socket
94
95 extern char *optarg; // for getopt()
96
97 // Function definition
98 #ifdef _WIN32
99 static unsigned __stdcall main_active(void *ptr);
100 static BOOL WINAPI main_ctrl_event(DWORD);
101 #else
102 static void *main_active(void *ptr);
103 static void main_terminate(int sign);
104 static void main_reread_config(int sign);
105 #endif
106 static void accept_connections(void);
107 static void accept_connection(SOCKET listen_sock);
108 #ifndef _WIN32
109 static void main_reap_children(int sign);
110 #endif
111 #ifdef _WIN32
112 static unsigned __stdcall main_passive_serviceloop_thread(void *ptr);
113 #endif
114
115 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
116
117 /*!
118 \brief Prints the usage screen if it is launched in console mode.
119 */
120 static void printusage(void)
121 {
122 const char *usagetext =
123 "USAGE:"
124 " " PROGRAM_NAME " [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
125 " [-n] [-v] [-d] "
126 #ifndef _WIN32
127 "[-i] "
128 #endif
129 "[-s <config_file>] [-f <config_file>]\n\n"
130 " -b <address> the address to bind to (either numeric or literal).\n"
131 " Default: binds to all local IPv4 and IPv6 addresses\n\n"
132 " -p <port> the port to bind to.\n"
133 " Default: binds to port " RPCAP_DEFAULT_NETPORT "\n\n"
134 " -4 use only IPv4.\n"
135 " Default: use both IPv4 and IPv6 waiting sockets\n\n"
136 " -l <host_list> a file that contains a list of hosts that are allowed\n"
137 " to connect to this server (if more than one, list them one\n"
138 " per line).\n"
139 " We suggest to use literal names (instead of numeric ones)\n"
140 " in order to avoid problems with different address families.\n\n"
141 " -n permit NULL authentication (usually used with '-l')\n\n"
142 " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
143 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n\n"
144 " -v run in active mode only (default: if '-a' is specified, it\n"
145 " accepts passive connections as well)\n\n"
146 " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
147 " Warning (Win32): this switch is provided automatically when\n"
148 " the service is started from the control panel\n\n"
149 #ifndef _WIN32
150 " -i run in inetd mode (UNIX only)\n\n"
151 #endif
152 #ifdef HAVE_OPENSSL
153 " -S encrypt all communication with SSL (implements rpcaps://)\n"
154 " -C enable compression\n"
155 " -K <pem_file> uses the SSL private key in this file (default: key.pem)\n"
156 " -X <pem_file> uses the certificate from this file (default: cert.pem)\n"
157 #endif
158 " -s <config_file> save the current configuration to file\n\n"
159 " -f <config_file> load the current configuration from file; all switches\n"
160 " specified from the command line are ignored\n\n"
161 " -h print this help screen\n\n";
162
163 (void)fprintf(stderr, "RPCAPD, a remote packet capture daemon.\n"
164 "Compiled with %s\n\n", pcap_lib_version());
165 printf("%s", usagetext);
166 }
167
168
169
170 //! Program main
171 int main(int argc, char *argv[])
172 {
173 char savefile[MAX_LINE + 1]; // name of the file on which we have to save the configuration
174 int log_to_systemlog = 1; // Non-zero if we should log to the "system log" rather than the standard error
175 int isdaemon = 0; // Non-zero if the user wants to run this program as a daemon
176 #ifndef _WIN32
177 int isrunbyinetd = 0; // Non-zero if this is being run by inetd or something inetd-like
178 #endif
179 int log_debug_messages = 0; // Non-zero if the user wants debug messages logged
180 int retval; // keeps the returning value from several functions
181 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
182 #ifndef _WIN32
183 struct sigaction action;
184 #endif
185 #ifdef HAVE_OPENSSL
186 int enable_compression = 0;
187 #endif
188
189 savefile[0] = 0;
190 loadfile[0] = 0;
191 hostlist[0] = 0;
192
193 // Initialize errbuf
194 memset(errbuf, 0, sizeof(errbuf));
195
196 strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE);
197 strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE);
198
199 // Prepare to open a new server socket
200 memset(&mainhints, 0, sizeof(struct addrinfo));
201
202 mainhints.ai_family = PF_UNSPEC;
203 mainhints.ai_flags = AI_PASSIVE; // Ready to a bind() socket
204 mainhints.ai_socktype = SOCK_STREAM;
205
206 // Getting the proper command line options
207 # ifdef HAVE_OPENSSL
208 # define SSL_CLOPTS "SK:X:C"
209 # else
210 # define SSL_CLOPTS ""
211 # endif
212
213 # define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS
214
215 while ((retval = getopt(argc, argv, CLOPTS)) != -1)
216 {
217 switch (retval)
218 {
219 case 'D':
220 log_debug_messages = 1;
221 rpcapd_log_set(log_to_systemlog, log_debug_messages);
222 break;
223 case 'b':
224 strncpy(address, optarg, MAX_LINE);
225 break;
226 case 'p':
227 strncpy(port, optarg, MAX_LINE);
228 break;
229 case '4':
230 mainhints.ai_family = PF_INET; // IPv4 server only
231 break;
232 case 'd':
233 isdaemon = 1;
234 log_to_systemlog = 1;
235 rpcapd_log_set(log_to_systemlog, log_debug_messages);
236 break;
237 case 'i':
238 #ifdef _WIN32
239 printusage();
240 exit(1);
241 #else
242 isrunbyinetd = 1;
243 log_to_systemlog = 1;
244 rpcapd_log_set(log_to_systemlog, log_debug_messages);
245 #endif
246 break;
247 case 'n':
248 nullAuthAllowed = 1;
249 break;
250 case 'v':
251 passivemode = 0;
252 break;
253 case 'l':
254 {
255 strncpy(hostlist, optarg, sizeof(hostlist));
256 break;
257 }
258 case 'a':
259 {
260 char *tmpaddress, *tmpport;
261 char *lasts;
262 int i = 0;
263
264 tmpaddress = pcap_strtok_r(optarg, RPCAP_HOSTLIST_SEP, &lasts);
265
266 while ((tmpaddress != NULL) && (i < MAX_ACTIVE_LIST))
267 {
268 tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
269
270 pcap_strlcpy(activelist[i].address, tmpaddress, MAX_LINE);
271
272 if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port
273 pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, MAX_LINE);
274 else
275 pcap_strlcpy(activelist[i].port, tmpport, MAX_LINE);
276
277 tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
278
279 i++;
280 }
281
282 if (i > MAX_ACTIVE_LIST)
283 rpcapd_log(LOGPRIO_ERROR, "Only MAX_ACTIVE_LIST active connections are currently supported.");
284
285 // I don't initialize the remaining part of the structure, since
286 // it is already zeroed (it is a global var)
287 break;
288 }
289 case 'f':
290 pcap_strlcpy(loadfile, optarg, MAX_LINE);
291 break;
292 case 's':
293 pcap_strlcpy(savefile, optarg, MAX_LINE);
294 break;
295 #ifdef HAVE_OPENSSL
296 case 'S':
297 uses_ssl = 1;
298 break;
299 case 'C':
300 enable_compression = 1;
301 break;
302 case 'K':
303 snprintf(ssl_keyfile, sizeof ssl_keyfile, "%s", optarg);
304 break;
305 case 'X':
306 snprintf(ssl_certfile, sizeof ssl_certfile, "%s", optarg);
307 break;
308 #endif
309 case 'h':
310 printusage();
311 exit(0);
312 /*NOTREACHED*/
313 default:
314 exit(1);
315 /*NOTREACHED*/
316 }
317 }
318
319 #ifndef _WIN32
320 if (isdaemon && isrunbyinetd)
321 {
322 rpcapd_log(LOGPRIO_ERROR, "rpcapd: -d and -i can't be used together");
323 exit(1);
324 }
325 #endif
326
327 if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
328 {
329 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
330 exit(-1);
331 }
332
333 if (savefile[0] && fileconf_save(savefile))
334 rpcapd_log(LOGPRIO_DEBUG, "Error when saving the configuration to file");
335
336 // If the file does not exist, it keeps the settings provided by the command line
337 if (loadfile[0])
338 fileconf_read();
339
340 #ifdef WIN32
341 //
342 // Create a handle to signal the main loop to tell it to do
343 // something.
344 //
345 state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL);
346 if (state_change_event == NULL)
347 {
348 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
349 rpcapd_log(LOGPRIO_ERROR, "Can't create state change event: %s",
350 errbuf);
351 exit(2);
352 }
353
354 //
355 // Catch control signals.
356 //
357 if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
358 {
359 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
360 rpcapd_log(LOGPRIO_ERROR, "Can't set control handler: %s",
361 errbuf);
362 exit(2);
363 }
364 #else
365 memset(&action, 0, sizeof (action));
366 action.sa_handler = main_terminate;
367 action.sa_flags = 0;
368 sigemptyset(&action.sa_mask);
369 sigaction(SIGTERM, &action, NULL);
370 memset(&action, 0, sizeof (action));
371 action.sa_handler = main_reap_children;
372 action.sa_flags = 0;
373 sigemptyset(&action.sa_mask);
374 sigaction(SIGCHLD, &action, NULL);
375 // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
376 // connection, we don't want to get killed by a signal in that case
377 signal(SIGPIPE, SIG_IGN);
378 #endif
379
380 # ifdef HAVE_OPENSSL
381 if (uses_ssl) {
382 if (ssl_init_once(1, enable_compression, errbuf, PCAP_ERRBUF_SIZE) < 0)
383 {
384 rpcapd_log(LOGPRIO_ERROR, "Can't initialize SSL: %s",
385 errbuf);
386 exit(2);
387 }
388 }
389 # endif
390
391 #ifndef _WIN32
392 if (isrunbyinetd)
393 {
394 //
395 // -i was specified, indicating that this is being run
396 // by inetd or something that can run network daemons
397 // as if it were inetd (xinetd, launchd, systemd, etc.).
398 //
399 // Our standard input is the input side of a connection,
400 // and our standard output is the output side of a
401 // connection.
402 //
403 int sockctrl_in, sockctrl_out;
404 int devnull_fd;
405
406 //
407 // Duplicate the standard input and output, making them
408 // the input and output side of the control connection.
409 //
410 sockctrl_in = dup(0);
411 if (sockctrl_in == -1)
412 {
413 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
414 rpcapd_log(LOGPRIO_ERROR, "Can't dup standard input: %s",
415 errbuf);
416 exit(2);
417 }
418 sockctrl_out = dup(1);
419 if (sockctrl_out == -1)
420 {
421 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
422 rpcapd_log(LOGPRIO_ERROR, "Can't dup standard output: %s",
423 errbuf);
424 exit(2);
425 }
426
427 //
428 // Try to set the standard input and output to /dev/null.
429 //
430 devnull_fd = open("/dev/null", O_RDWR);
431 if (devnull_fd != -1)
432 {
433 //
434 // If this fails, just drive on.
435 //
436 (void)dup2(devnull_fd, 0);
437 (void)dup2(devnull_fd, 1);
438 close(devnull_fd);
439 }
440
441 SSL *ssl = NULL;
442 #ifdef HAVE_OPENSSL
443 if (uses_ssl)
444 {
445 ssl = ssl_promotion_rw(1, sockctrl_in, sockctrl_out, errbuf, PCAP_ERRBUF_SIZE);
446 if (! ssl)
447 {
448 rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
449 errbuf);
450 exit(2);
451 }
452 }
453 #endif
454 //
455 // Handle this client.
456 // This is passive mode, so we don't care whether we were
457 // told by the client to close.
458 //
459 (void)daemon_serviceloop(sockctrl_in, sockctrl_out, ssl, 0,
460 nullAuthAllowed, uses_ssl);
461
462 //
463 // Nothing more to do.
464 //
465 exit(0);
466 }
467 #endif
468
469 if (isdaemon)
470 {
471 //
472 // This is being run as a daemon.
473 // On UN*X, it might be manually run, or run from an
474 // rc file.
475 //
476 #ifndef _WIN32
477 int pid;
478
479 //
480 // Daemonize ourselves.
481 //
482 // Unix Network Programming, pg 336
483 //
484 if ((pid = fork()) != 0)
485 exit(0); // Parent terminates
486
487 // First child continues
488 // Set daemon mode
489 setsid();
490
491 // generated under unix with 'kill -HUP', needed to reload the configuration
492 memset(&action, 0, sizeof (action));
493 action.sa_handler = main_reread_config;
494 action.sa_flags = 0;
495 sigemptyset(&action.sa_mask);
496 sigaction(SIGHUP, &action, NULL);
497
498 if ((pid = fork()) != 0)
499 exit(0); // First child terminates
500
501 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
502 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
503 // created. Fom this point on, the number of threads active are always one more compared
504 // to the number you're expecting
505
506 // Second child continues
507 // umask(0);
508 // chdir("/");
509 #else
510 //
511 // This is being run as a service on Windows.
512 //
513 // If this call succeeds, it is blocking on Win32
514 //
515 if (svc_start() != 1)
516 rpcapd_log(LOGPRIO_DEBUG, "Unable to start the service");
517
518 // When the previous call returns, the entire application has to be stopped.
519 exit(0);
520 #endif
521 }
522 else // Console mode
523 {
524 #ifndef _WIN32
525 // Enable the catching of Ctrl+C
526 memset(&action, 0, sizeof (action));
527 action.sa_handler = main_terminate;
528 action.sa_flags = 0;
529 sigemptyset(&action.sa_mask);
530 sigaction(SIGINT, &action, NULL);
531
532 // generated under unix with 'kill -HUP', needed to reload the configuration
533 // We do not have this kind of signal in Win32
534 memset(&action, 0, sizeof (action));
535 action.sa_handler = main_reread_config;
536 action.sa_flags = 0;
537 sigemptyset(&action.sa_mask);
538 sigaction(SIGHUP, &action, NULL);
539 #endif
540
541 printf("Press CTRL + C to stop the server...\n");
542 }
543
544 // If we're a Win32 service, we have already called this function in the service_main
545 main_startup();
546
547 // The code should never arrive here (since the main_startup is blocking)
548 // however this avoids a compiler warning
549 exit(0);
550 }
551
552 void main_startup(void)
553 {
554 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
555 struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
556 int i;
557 #ifdef _WIN32
558 HANDLE threadId; // handle for the subthread
559 #else
560 pid_t pid;
561 #endif
562
563 i = 0;
564 addrinfo = NULL;
565 memset(errbuf, 0, sizeof(errbuf));
566
567 // Starts all the active threads
568 while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
569 {
570 activelist[i].ai_family = mainhints.ai_family;
571
572 #ifdef _WIN32
573 threadId = (HANDLE)_beginthreadex(NULL, 0, main_active,
574 (void *)&activelist[i], 0, NULL);
575 if (threadId == 0)
576 {
577 rpcapd_log(LOGPRIO_DEBUG, "Error creating the active child threads");
578 continue;
579 }
580 CloseHandle(threadId);
581 #else
582 if ((pid = fork()) == 0) // I am the child
583 {
584 main_active((void *) &activelist[i]);
585 exit(0);
586 }
587 #endif
588 i++;
589 }
590
591 /*
592 * The code that manages the active connections is not blocking;
593 * the code that manages the passive connection is blocking.
594 * So, if the user does not want to run in passive mode, we have
595 * to block the main thread here, otherwise the program ends and
596 * all threads are stopped.
597 *
598 * WARNING: this means that in case we have only active mode,
599 * the program does not terminate even if all the child thread
600 * terminates. The user has always to press Ctrl+C (or send a
601 * SIGTERM) to terminate the program.
602 */
603 if (passivemode)
604 {
605 struct addrinfo *tempaddrinfo;
606
607 //
608 // Get a list of sockets on which to listen.
609 //
610 if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
611 {
612 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
613 return;
614 }
615
616 for (tempaddrinfo = addrinfo; tempaddrinfo;
617 tempaddrinfo = tempaddrinfo->ai_next)
618 {
619 SOCKET sock;
620 struct listen_sock *sock_info;
621
622 if ((sock = sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
623 {
624 switch (tempaddrinfo->ai_family)
625 {
626 case AF_INET:
627 {
628 struct sockaddr_in *in;
629 char addrbuf[INET_ADDRSTRLEN];
630
631 in = (struct sockaddr_in *)tempaddrinfo->ai_addr;
632 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
633 inet_ntop(AF_INET, &in->sin_addr,
634 addrbuf, sizeof (addrbuf)),
635 ntohs(in->sin_port),
636 errbuf);
637 break;
638 }
639
640 case AF_INET6:
641 {
642 struct sockaddr_in6 *in6;
643 char addrbuf[INET6_ADDRSTRLEN];
644
645 in6 = (struct sockaddr_in6 *)tempaddrinfo->ai_addr;
646 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
647 inet_ntop(AF_INET6, &in6->sin6_addr,
648 addrbuf, sizeof (addrbuf)),
649 ntohs(in6->sin6_port),
650 errbuf);
651 break;
652 }
653
654 default:
655 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for address family %u: %s",
656 tempaddrinfo->ai_family,
657 errbuf);
658 break;
659 }
660 continue;
661 }
662
663 sock_info = (struct listen_sock *) malloc(sizeof (struct listen_sock));
664 if (sock_info == NULL)
665 {
666 rpcapd_log(LOGPRIO_ERROR, "Can't allocate structure for listen socket");
667 exit(2);
668 }
669 sock_info->sock = sock;
670 sock_info->next = listen_socks;
671 listen_socks = sock_info;
672 }
673
674 freeaddrinfo(addrinfo);
675
676 if (listen_socks == NULL)
677 {
678 rpcapd_log(LOGPRIO_ERROR, "Can't listen on any address");
679 exit(2);
680 }
681
682 //
683 // Now listen on all of them, waiting for connections.
684 //
685 accept_connections();
686 }
687
688 //
689 // We're done; exit.
690 //
691 rpcapd_log(LOGPRIO_DEBUG, PROGRAM_NAME " is closing.\n");
692
693 #ifndef _WIN32
694 //
695 // Sends a KILL signal to all the processes in this process's
696 // process group; i.e., it kills all the child processes
697 // we've created.
698 //
699 // XXX - that also includes us, so we will be killed as well;
700 // that may cause a message to be printed or logged.
701 //
702 kill(0, SIGKILL);
703 #endif
704
705 //
706 // Just leave. We shouldn't need to clean up sockets or
707 // anything else, and if we try to do so, we'll could end
708 // up closing sockets, or shutting Winsock down, out from
709 // under service loops, causing all sorts of noisy error
710 // messages.
711 //
712 // We shouldn't need to worry about cleaning up any resources
713 // such as handles, sockets, threads, etc. - exit() should
714 // terminate the process, causing all those resources to be
715 // cleaned up (including the threads; Microsoft claims in the
716 // ExitProcess() documentation that, if ExitProcess() is called,
717 // "If a thread is waiting on a kernel object, it will not be
718 // terminated until the wait has completed.", but claims in the
719 // _beginthread()/_beginthreadex() documentation that "All threads
720 // are terminated if any thread calls abort, exit, _exit, or
721 // ExitProcess." - the latter appears to be the case, even for
722 // threads waiting on the event for a pcap_t).
723 //
724 exit(0);
725 }
726
727 #ifdef _WIN32
728 static void
729 send_state_change_event(void)
730 {
731 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
732
733 if (!SetEvent(state_change_event))
734 {
735 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
736 rpcapd_log(LOGPRIO_ERROR, "SetEvent on shutdown event failed: %s", errbuf);
737 }
738 }
739
740 void
741 send_shutdown_notification(void)
742 {
743 //
744 // Indicate that the server should shut down.
745 //
746 shutdown_server = 1;
747
748 //
749 // Send a state change event, to wake up WSAWaitForMultipleEvents().
750 //
751 send_state_change_event();
752 }
753
754 void
755 send_reread_configuration_notification(void)
756 {
757 //
758 // Indicate that the server should re-read its configuration file.
759 //
760 reread_config = 1;
761
762 //
763 // Send a state change event, to wake up WSAWaitForMultipleEvents().
764 //
765 send_state_change_event();
766 }
767
768 static BOOL WINAPI main_ctrl_event(DWORD ctrltype)
769 {
770 //
771 // ctrltype is one of:
772 //
773 // CTRL_C_EVENT - we got a ^C; this is like SIGINT
774 // CTRL_BREAK_EVENT - we got Ctrl+Break
775 // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
776 // CTRL_LOGOFF_EVENT - a user is logging off; this is received
777 // only by services
778 // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
779 // received only by services
780 //
781 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
782 // that we should shut down.
783 //
784 switch (ctrltype)
785 {
786 case CTRL_C_EVENT:
787 case CTRL_BREAK_EVENT:
788 case CTRL_CLOSE_EVENT:
789 case CTRL_SHUTDOWN_EVENT:
790 //
791 // Set a shutdown notification.
792 //
793 send_shutdown_notification();
794 break;
795
796 default:
797 break;
798 }
799
800 //
801 // We handled this.
802 //
803 return TRUE;
804 }
805 #else
806 static void main_terminate(int sign _U_)
807 {
808 //
809 // Note that the server should shut down.
810 // select() should get an EINTR error when we return,
811 // so it will wake up and know it needs to check the flag.
812 //
813 shutdown_server = 1;
814 }
815
816 static void main_reread_config(int sign _U_)
817 {
818 //
819 // Note that the server should re-read its configuration file.
820 // select() should get an EINTR error when we return,
821 // so it will wake up and know it needs to check the flag.
822 //
823 reread_config = 1;
824 }
825
826 static void main_reap_children(int sign _U_)
827 {
828 pid_t pid;
829 int exitstat;
830
831 // Reap all child processes that have exited.
832 // For reference, Stevens, pg 128
833
834 while ((pid = waitpid(-1, &exitstat, WNOHANG)) > 0)
835 rpcapd_log(LOGPRIO_DEBUG, "Child terminated");
836
837 return;
838 }
839 #endif
840
841 //
842 // Loop waiting for incoming connections and accepting them.
843 //
844 static void
845 accept_connections(void)
846 {
847 #ifdef _WIN32
848 struct listen_sock *sock_info;
849 DWORD num_events;
850 WSAEVENT *events;
851 int i;
852 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
853
854 //
855 // How big does the set of events need to be?
856 // One for the shutdown event, plus one for every socket on which
857 // we'll be listening.
858 //
859 num_events = 1; // shutdown event
860 for (sock_info = listen_socks; sock_info;
861 sock_info = sock_info->next)
862 {
863 if (num_events == WSA_MAXIMUM_WAIT_EVENTS)
864 {
865 //
866 // WSAWaitForMultipleEvents() doesn't support
867 // more than WSA_MAXIMUM_WAIT_EVENTS events
868 // on which to wait.
869 //
870 rpcapd_log(LOGPRIO_ERROR, "Too many sockets on which to listen");
871 exit(2);
872 }
873 num_events++;
874 }
875
876 //
877 // Allocate the array of events.
878 //
879 events = (WSAEVENT *) malloc(num_events * sizeof (WSAEVENT));
880 if (events == NULL)
881 {
882 rpcapd_log(LOGPRIO_ERROR, "Can't allocate array of events which to listen");
883 exit(2);
884 }
885
886 //
887 // Fill it in.
888 //
889 events[0] = state_change_event; // state change event first
890 for (sock_info = listen_socks, i = 1; sock_info;
891 sock_info = sock_info->next, i++)
892 {
893 WSAEVENT event;
894
895 //
896 // Create an event that is signaled if there's a connection
897 // to accept on the socket in question.
898 //
899 event = WSACreateEvent();
900 if (event == WSA_INVALID_EVENT)
901 {
902 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
903 rpcapd_log(LOGPRIO_ERROR, "Can't create socket event: %s", errbuf);
904 exit(2);
905 }
906 if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
907 {
908 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
909 rpcapd_log(LOGPRIO_ERROR, "Can't setup socket event: %s", errbuf);
910 exit(2);
911 }
912 events[i] = event;
913 }
914
915 for (;;)
916 {
917 //
918 // Wait for incoming connections.
919 //
920 DWORD ret;
921
922 ret = WSAWaitForMultipleEvents(num_events, events, FALSE,
923 WSA_INFINITE, FALSE);
924 if (ret == WSA_WAIT_FAILED)
925 {
926 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
927 rpcapd_log(LOGPRIO_ERROR, "WSAWaitForMultipleEvents failed: %s", errbuf);
928 exit(2);
929 }
930
931 if (ret == WSA_WAIT_EVENT_0)
932 {
933 //
934 // The state change event was set.
935 //
936 if (shutdown_server)
937 {
938 //
939 // Time to quit. Exit the loop.
940 //
941 break;
942 }
943 if (reread_config)
944 {
945 //
946 // We should re-read the configuration
947 // file.
948 //
949 reread_config = 0; // clear the indicator
950 fileconf_read();
951 }
952 }
953
954 //
955 // Check each socket.
956 //
957 for (sock_info = listen_socks, i = 1; sock_info;
958 sock_info = sock_info->next, i++)
959 {
960 WSANETWORKEVENTS network_events;
961
962 if (WSAEnumNetworkEvents(sock_info->sock,
963 events[i], &network_events) == SOCKET_ERROR)
964 {
965 sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
966 rpcapd_log(LOGPRIO_ERROR, "WSAEnumNetworkEvents failed: %s", errbuf);
967 exit(2);
968 }
969 if (network_events.lNetworkEvents & FD_ACCEPT)
970 {
971 //
972 // Did an error occur?
973 //
974 if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0)
975 {
976 //
977 // Yes - report it and keep going.
978 //
979 sock_fmterror(NULL,
980 network_events.iErrorCode[FD_ACCEPT_BIT],
981 errbuf,
982 PCAP_ERRBUF_SIZE);
983 rpcapd_log(LOGPRIO_ERROR, "Socket error: %s", errbuf);
984 continue;
985 }
986
987 //
988 // Accept the connection.
989 //
990 accept_connection(sock_info->sock);
991 }
992 }
993 }
994 #else
995 struct listen_sock *sock_info;
996 int num_sock_fds;
997
998 //
999 // How big does the bitset of sockets on which to select() have
1000 // to be?
1001 //
1002 num_sock_fds = 0;
1003 for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
1004 {
1005 if (sock_info->sock + 1 > num_sock_fds)
1006 {
1007 if ((unsigned int)(sock_info->sock + 1) >
1008 (unsigned int)FD_SETSIZE)
1009 {
1010 rpcapd_log(LOGPRIO_ERROR, "Socket FD is too bit for an fd_set");
1011 exit(2);
1012 }
1013 num_sock_fds = sock_info->sock + 1;
1014 }
1015 }
1016
1017 for (;;)
1018 {
1019 fd_set sock_fds;
1020 int ret;
1021
1022 //
1023 // Set up an fd_set for all the sockets on which we're
1024 // listening.
1025 //
1026 // This set is modified by select(), so we have to
1027 // construct it anew each time.
1028 //
1029 FD_ZERO(&sock_fds);
1030 for (sock_info = listen_socks; sock_info;
1031 sock_info = sock_info->next)
1032 {
1033 FD_SET(sock_info->sock, &sock_fds);
1034 }
1035
1036 //
1037 // Wait for incoming connections.
1038 //
1039 ret = select(num_sock_fds, &sock_fds, NULL, NULL, NULL);
1040 if (ret == -1)
1041 {
1042 if (errno == EINTR)
1043 {
1044 //
1045 // If this is a "terminate the
1046 // server" signal, exit the loop,
1047 // otherwise just keep trying.
1048 //
1049 if (shutdown_server)
1050 {
1051 //
1052 // Time to quit. Exit the loop.
1053 //
1054 break;
1055 }
1056 if (reread_config)
1057 {
1058 //
1059 // We should re-read the configuration
1060 // file.
1061 //
1062 reread_config = 0; // clear the indicator
1063 fileconf_read();
1064 }
1065
1066 //
1067 // Go back and wait again.
1068 //
1069 continue;
1070 }
1071 else
1072 {
1073 rpcapd_log(LOGPRIO_ERROR, "select failed: %s",
1074 strerror(errno));
1075 exit(2);
1076 }
1077 }
1078
1079 //
1080 // Check each socket.
1081 //
1082 for (sock_info = listen_socks; sock_info;
1083 sock_info = sock_info->next)
1084 {
1085 if (FD_ISSET(sock_info->sock, &sock_fds))
1086 {
1087 //
1088 // Accept the connection.
1089 //
1090 accept_connection(sock_info->sock);
1091 }
1092 }
1093 }
1094 #endif
1095
1096 //
1097 // Close all the listen sockets.
1098 //
1099 for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
1100 {
1101 closesocket(sock_info->sock);
1102 }
1103 sock_cleanup();
1104 }
1105
1106 #ifdef _WIN32
1107 //
1108 // A structure to hold the parameter to the windows thread
1109 // (on unix there is no need for this explicit copy since the
1110 // fork "inherits" the parent stack)
1111 //
1112 struct sock_copy {
1113 SOCKET sockctrl;
1114 # ifdef HAVE_OPENSSL
1115 SSL *ssl;
1116 # else
1117 void *ssl;
1118 # endif
1119 };
1120 #endif
1121
1122 //
1123 // Accept a connection and start a worker thread, on Windows, or a
1124 // worker process, on UN*X, to handle the connection.
1125 //
1126 static void
1127 accept_connection(SOCKET listen_sock)
1128 {
1129 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
1130 SOCKET sockctrl; // keeps the socket ID for this control connection
1131 struct sockaddr_storage from; // generic sockaddr_storage variable
1132 socklen_t fromlen; // keeps the length of the sockaddr_storage variable
1133
1134 SSL *ssl = NULL;
1135
1136 #ifdef _WIN32
1137 HANDLE threadId; // handle for the subthread
1138 u_long off = 0;
1139 struct sock_copy *sock_copy = NULL;
1140 #else
1141 pid_t pid;
1142 #endif
1143
1144 // Initialize errbuf
1145 memset(errbuf, 0, sizeof(errbuf));
1146
1147 for (;;)
1148 {
1149 // Accept the connection
1150 fromlen = sizeof(struct sockaddr_storage);
1151
1152 sockctrl = accept(listen_sock, (struct sockaddr *) &from, &fromlen);
1153
1154 if (sockctrl != INVALID_SOCKET)
1155 {
1156 // Success.
1157 break;
1158 }
1159
1160 // The accept() call can return this error when a signal is catched
1161 // In this case, we have simply to ignore this error code
1162 // Stevens, pg 124
1163 #ifdef _WIN32
1164 if (WSAGetLastError() == WSAEINTR)
1165 #else
1166 if (errno == EINTR)
1167 #endif
1168 continue;
1169
1170 // Don't check for errors here, since the error can be due to the fact that the thread
1171 // has been killed
1172 sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
1173 rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
1174 errbuf);
1175 return;
1176 }
1177
1178 #ifdef HAVE_OPENSSL
1179 /* We have to upgrade to TLS as soon as possible so that the whole protocol
1180 * goes through the encrypted tunnel, including early error messages. */
1181 if (uses_ssl)
1182 {
1183 ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
1184 if (! ssl)
1185 {
1186 rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
1187 errbuf);
1188 goto error;
1189 }
1190 }
1191 #endif
1192
1193 //
1194 // We have a connection.
1195 // Check whether the connecting host is among the ones allowed.
1196 //
1197 if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
1198 {
1199 rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
1200 goto error;
1201 }
1202
1203 #ifdef _WIN32
1204 //
1205 // Put the socket back into blocking mode; doing WSAEventSelect()
1206 // on the listen socket makes that socket non-blocking, and it
1207 // appears that sockets returned from an accept() on that socket
1208 // are also non-blocking.
1209 //
1210 // First, we have to un-WSAEventSelect() this socket, and then
1211 // we can turn non-blocking mode off.
1212 //
1213 // If this fails, we aren't guaranteed that, for example, any
1214 // of the error message will be sent - if it can't be put in
1215 // the socket queue, the send will just fail.
1216 //
1217 // So we just log the message and close the connection.
1218 //
1219 if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
1220 {
1221 sock_geterror("WSAEventSelect: ", errbuf, PCAP_ERRBUF_SIZE);
1222 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
1223 sock_close(sockctrl, NULL, 0);
1224 return;
1225 }
1226 if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
1227 {
1228 sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
1229 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
1230 sock_close(sockctrl, NULL, 0);
1231 return;
1232 }
1233
1234 //
1235 // Allocate a location to hold the value of sockctrl.
1236 // It will be freed in the newly-created thread once it's
1237 // finished with it.
1238 // I guess we *could* just cast sockctrl to a void *, but that's
1239 // a bit ugly.
1240 //
1241 sock_copy = malloc(sizeof(*sock_copy));
1242 if (sock_copy == NULL)
1243 {
1244 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1245 errno, "malloc() failed");
1246 rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
1247 goto error;
1248 }
1249 sock_copy->sockctrl = sockctrl;
1250 sock_copy->ssl = NULL;
1251
1252 threadId = (HANDLE)_beginthreadex(NULL, 0,
1253 main_passive_serviceloop_thread, (void *) sock_copy, 0, NULL);
1254 if (threadId == 0)
1255 {
1256 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child thread");
1257 rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
1258 goto error;
1259 }
1260 CloseHandle(threadId);
1261 #else
1262 pid = fork();
1263 if (pid == -1)
1264 {
1265 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child process");
1266 rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
1267 goto error;
1268 }
1269 if (pid == 0)
1270 {
1271 //
1272 // Child process.
1273 //
1274 // Close the socket on which we're listening (must
1275 // be open only in the parent).
1276 //
1277 closesocket(listen_sock);
1278
1279 #if 0
1280 //
1281 // Modify thread params so that it can be killed at any time
1282 // XXX - is this necessary? This is the main and, currently,
1283 // only thread in the child process, and nobody tries to
1284 // cancel us, although *we* may cancel the thread that's
1285 // handling the capture loop.
1286 //
1287 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
1288 goto end;
1289 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
1290 goto end;
1291 #endif
1292
1293 //
1294 // Run the service loop.
1295 // This is passive mode, so we don't care whether we were
1296 // told by the client to close.
1297 //
1298 (void)daemon_serviceloop(sockctrl, sockctrl, ssl, 0,
1299 nullAuthAllowed, uses_ssl);
1300
1301 close(sockctrl);
1302
1303 exit(0);
1304 }
1305
1306 // I am the parent
1307 // Close the socket for this session (must be open only in the child)
1308 #ifdef HAVE_OPENSSL
1309 if (ssl)
1310 {
1311 SSL_free(ssl);
1312 ssl = NULL;
1313 }
1314 #endif
1315 closesocket(sockctrl);
1316 #endif
1317 return;
1318
1319 error:
1320 #ifdef _WIN32
1321 if (sock_copy) free(sock_copy);
1322 #endif
1323 #ifdef HAVE_OPENSSL
1324 if (ssl) SSL_free(ssl); // Have to be done before closing soskctrl
1325 #endif
1326 sock_close(sockctrl, NULL, 0);
1327 }
1328
1329 /*!
1330 \brief 'true' main of the program in case the active mode is turned on.
1331
1332 This function loops forever trying to connect to the remote host, until the
1333 daemon is turned down.
1334
1335 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1336 just because the thread APIs want this format.
1337 */
1338 #ifdef _WIN32
1339 static unsigned __stdcall
1340 #else
1341 static void *
1342 #endif
1343 main_active(void *ptr)
1344 {
1345 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
1346 SOCKET sockctrl; // keeps the socket ID for this control connection
1347 struct addrinfo hints; // temporary struct to keep settings needed to open the new socket
1348 struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
1349 struct active_pars *activepars;
1350 SSL *ssl = NULL;
1351
1352 activepars = (struct active_pars *) ptr;
1353
1354 // Prepare to open a new server socket
1355 memset(&hints, 0, sizeof(struct addrinfo));
1356 // WARNING Currently it supports only ONE socket family among IPv4 and IPv6
1357 hints.ai_family = AF_INET; // PF_UNSPEC to have both IPv4 and IPv6 server
1358 hints.ai_socktype = SOCK_STREAM;
1359 hints.ai_family = activepars->ai_family;
1360
1361 rpcapd_log(LOGPRIO_DEBUG, "Connecting to host %s, port %s, using protocol %s",
1362 activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
1363 (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
1364
1365 // Initialize errbuf
1366 memset(errbuf, 0, sizeof(errbuf));
1367
1368 // Do the work
1369 if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
1370 {
1371 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1372 return 0;
1373 }
1374
1375 for (;;)
1376 {
1377 int activeclose;
1378
1379 if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
1380 {
1381 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1382
1383 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s",
1384 activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
1385 (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
1386
1387 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1388
1389 sleep_secs(RPCAP_ACTIVE_WAIT);
1390
1391 continue;
1392 }
1393
1394 #ifdef HAVE_OPENSSL
1395 /* Even in active mode the other other end has to initiate the TLS handshake
1396 * as we still are the server as far as TLS is concerned: */
1397 if (uses_ssl)
1398 {
1399 ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
1400 if (! ssl)
1401 {
1402 rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
1403 errbuf);
1404 sock_close(sockctrl, NULL, 0);
1405 continue;
1406 }
1407 }
1408 #endif
1409
1410 activeclose = daemon_serviceloop(sockctrl, sockctrl, ssl, 1,
1411 nullAuthAllowed, uses_ssl);
1412
1413 #ifdef HAVE_OPENSSL
1414 if (ssl) SSL_free(ssl);
1415 #endif
1416 sock_close(sockctrl, NULL, 0);
1417
1418 // If the connection is closed by the user explicitely, don't try to connect to it again
1419 // just exit the program
1420 if (activeclose == 1)
1421 break;
1422 }
1423
1424 freeaddrinfo(addrinfo);
1425 return 0;
1426 }
1427
1428 #ifdef _WIN32
1429 //
1430 // Main routine of a passive-mode service thread.
1431 //
1432 unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
1433 {
1434 struct sock_copy sock = *(struct sock_copy *)ptr;
1435 free(ptr);
1436
1437 //
1438 // Handle this client.
1439 // This is passive mode, so we don't care whether we were
1440 // told by the client to close.
1441 //
1442 (void)daemon_serviceloop(sock.sockctrl, sock.sockctrl, sock.ssl, 0,
1443 nullAuthAllowed, uses_ssl);
1444
1445 sock_close(sock.sockctrl, NULL, 0);
1446
1447 return 0;
1448 }
1449 #endif