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