2 * Copyright (C) 1997 Angelos D. Keromytis.
3 * Copyright (C) 1998-2002 D. Hugh Redelmeier.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * RCSID $Id: server.c,v 1.9 2005/09/09 14:15:35 as Exp $
25 #include <sys/types.h>
27 #include <sys/socket.h>
30 # include <sys/sockio.h> /* for Solaris 2.6: defines SIOCGIFCONF */
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
39 #include <sys/ioctl.h>
41 #include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
42 #include <sys/queue.h>
46 #include "constants.h"
49 #include "connections.h"
55 #include "demux.h" /* needs packet.h */
56 #include "rcv_whack.h"
58 #include "adns.h" /* needs <resolv.h> */
59 #include "dnskey.h" /* needs keys.h and adns.h */
60 #include "whack.h" /* for RC_LOG_SERIOUS */
64 #include "kameipsec.h"
67 #include "nat_traversal.h"
71 * Server main loop and socket initialization routines.
74 static const int on
= TRUE
; /* by-reference parameter; constant, we hope */
76 /* control (whack) socket */
77 int ctl_fd
= NULL_FD
; /* file descriptor of control (whack) socket */
78 struct sockaddr_un ctl_addr
= { AF_UNIX
, DEFAULT_CTLBASE CTL_SUFFIX
};
80 /* info (showpolicy) socket */
81 int policy_fd
= NULL_FD
;
82 struct sockaddr_un info_addr
= { AF_UNIX
, DEFAULT_CTLBASE INFO_SUFFIX
};
84 /* Initialize the control socket.
85 * Note: this is called very early, so little infrastructure is available.
86 * It is important that the socket is created before the original
87 * Pluto process returns.
94 delete_ctl_socket(); /* preventative medicine */
95 ctl_fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
98 else if (fcntl(ctl_fd
, F_SETFD
, FD_CLOEXEC
) == -1)
99 failed
= "fcntl FD+CLOEXEC";
100 else if (setsockopt(ctl_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const void *)&on
, sizeof(on
)) < 0)
101 failed
= "setsockopt";
104 /* to keep control socket secure, use umask */
105 mode_t ou
= umask(~S_IRWXU
);
107 if (bind(ctl_fd
, (struct sockaddr
*)&ctl_addr
108 , offsetof(struct sockaddr_un
, sun_path
) + strlen(ctl_addr
.sun_path
)) < 0)
113 /* 5 is a haphazardly chosen limit for the backlog.
114 * Rumour has it that this is the max on BSD systems.
116 if (failed
== NULL
&& listen(ctl_fd
, 5) < 0)
117 failed
= "listen() on";
119 return failed
== NULL
? NULL
: builddiag("could not %s control socket: %d %s"
120 , failed
, errno
, strerror(errno
));
124 delete_ctl_socket(void)
126 /* Is noting failure useful? Not when used as preventative medicine. */
127 unlink(ctl_addr
.sun_path
);
131 /* Initialize the info socket.
134 init_info_socket(void)
138 delete_info_socket(); /* preventative medicine */
139 info_fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
142 else if (fcntl(info_fd
, F_SETFD
, FD_CLOEXEC
) == -1)
143 failed
= "fcntl FD+CLOEXEC";
144 else if (setsockopt(info_fd
, SOL_SOCKET
, SO_REUSEADDR
, (const void *)&on
, sizeof(on
)) < 0)
145 failed
= "setsockopt";
148 /* this socket should be openable by all proceses */
149 mode_t ou
= umask(0);
151 if (bind(info_fd
, (struct sockaddr
*)&info_addr
152 , offsetof(struct sockaddr_un
, sun_path
) + strlen(info_addr
.sun_path
)) < 0)
157 /* 64 might be big enough, and the system may limit us anyway.
159 if (failed
== NULL
&& listen(info_fd
, 64) < 0)
160 failed
= "listen() on";
162 return failed
== NULL
? NULL
: builddiag("could not %s info socket: %d %s"
163 , failed
, errno
, strerror(errno
));
167 delete_info_socket(void)
169 unlink(info_addr
.sun_path
);
171 #endif /* IPSECPOLICY */
174 bool listening
= FALSE
; /* should we pay attention to IKE messages? */
176 struct iface
*interfaces
= NULL
; /* public interfaces */
178 /* Initialize the interface sockets. */
181 mark_ifaces_dead(void)
185 for (p
= interfaces
; p
!= NULL
; p
= p
->next
)
186 p
->change
= IFN_DELETE
;
190 free_dead_ifaces(void)
193 bool some_dead
= FALSE
196 for (p
= interfaces
; p
!= NULL
; p
= p
->next
)
198 if (p
->change
== IFN_DELETE
)
200 plog("shutting down interface %s/%s %s"
201 , p
->vname
, p
->rname
, ip_str(&p
->addr
));
204 else if (p
->change
== IFN_ADD
)
214 release_dead_interfaces();
215 for (pp
= &interfaces
; (p
= *pp
) != NULL
; )
217 if (p
->change
== IFN_DELETE
)
219 *pp
= p
->next
; /* advance *pp */
227 pp
= &p
->next
; /* advance pp */
232 /* this must be done after the release_dead_interfaces
233 * in case some to the newly unoriented connections can
234 * become oriented here.
236 if (some_dead
|| some_new
)
237 check_orientations();
249 char name
[IFNAMSIZ
+ 20]; /* what would be a safe size? */
250 struct raw_iface
*next
;
253 /* Called to handle --interface <ifname>
254 * Semantics: if specified, only these (real) interfaces are considered.
256 static const char *pluto_ifn
[10];
257 static int pluto_ifn_roof
= 0;
260 use_interface(const char *rifn
)
262 if (pluto_ifn_roof
>= (int)elemsof(pluto_ifn
))
268 pluto_ifn
[pluto_ifn_roof
++] = rifn
;
273 #ifndef IPSECDEVPREFIX
274 # define IPSECDEVPREFIX "ipsec"
277 static struct raw_iface
*
278 find_raw_ifaces4(void)
280 int j
; /* index into buf */
281 struct ifconf ifconf
;
282 struct ifreq buf
[300]; /* for list of interfaces -- arbitrary limit */
283 struct raw_iface
*rifaces
= NULL
;
284 int master_sock
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
); /* Get a UDP socket */
286 /* get list of interfaces with assigned IPv4 addresses from system */
288 if (master_sock
== -1)
289 exit_log_errno((e
, "socket() failed in find_raw_ifaces4()"));
291 if (setsockopt(master_sock
, SOL_SOCKET
, SO_REUSEADDR
292 , (const void *)&on
, sizeof(on
)) < 0)
293 exit_log_errno((e
, "setsockopt() in find_raw_ifaces4()"));
295 /* bind the socket */
299 happy(anyaddr(AF_INET
, &any
));
300 setportof(htons(pluto_port
), &any
);
301 if (bind(master_sock
, sockaddrof(&any
), sockaddrlenof(&any
)) < 0)
302 exit_log_errno((e
, "bind() failed in find_raw_ifaces4()"));
305 /* Get local interfaces. See netdevice(7). */
306 ifconf
.ifc_len
= sizeof(buf
);
307 ifconf
.ifc_buf
= (void *) buf
;
310 if (ioctl(master_sock
, SIOCGIFCONF
, &ifconf
) == -1)
311 exit_log_errno((e
, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
313 /* Add an entry to rifaces for each interesting interface. */
314 for (j
= 0; (j
+1) * sizeof(*buf
) <= (size_t)ifconf
.ifc_len
; j
++)
317 const struct sockaddr_in
*rs
= (struct sockaddr_in
*) &buf
[j
].ifr_addr
;
318 struct ifreq auxinfo
;
320 /* ignore all but AF_INET interfaces */
321 if (rs
->sin_family
!= AF_INET
)
322 continue; /* not interesting */
324 /* build a NUL-terminated copy of the rname field */
325 memcpy(ri
.name
, buf
[j
].ifr_name
, IFNAMSIZ
);
326 ri
.name
[IFNAMSIZ
] = '\0';
328 /* ignore if our interface names were specified, and this isn't one */
329 if (pluto_ifn_roof
!= 0)
333 for (i
= 0; i
!= pluto_ifn_roof
; i
++)
334 if (streq(ri
.name
, pluto_ifn
[i
]))
336 if (i
== pluto_ifn_roof
)
337 continue; /* not found -- skip */
340 /* Find out stuff about this interface. See netdevice(7). */
341 zero(&auxinfo
); /* paranoia */
342 memcpy(auxinfo
.ifr_name
, buf
[j
].ifr_name
, IFNAMSIZ
);
343 if (ioctl(master_sock
, SIOCGIFFLAGS
, &auxinfo
) == -1)
345 , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
347 if (!(auxinfo
.ifr_flags
& IFF_UP
))
348 continue; /* ignore an interface that isn't UP */
350 /* ignore unconfigured interfaces */
351 if (rs
->sin_addr
.s_addr
== 0)
354 happy(initaddr((const void *)&rs
->sin_addr
, sizeof(struct in_addr
)
355 , AF_INET
, &ri
.addr
));
357 DBG(DBG_CONTROL
, DBG_log("found %s with address %s"
358 , ri
.name
, ip_str(&ri
.addr
)));
360 rifaces
= clone_thing(ri
, "struct raw_iface");
368 static struct raw_iface
*
369 find_raw_ifaces6(void)
372 /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
374 * Documentation of format?
375 * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
376 * linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
378 * Sample from Gerhard's laptop:
379 * 00000000000000000000000000000001 01 80 10 80 lo
380 * 30490009000000000000000000010002 02 40 00 80 ipsec0
381 * 30490009000000000000000000010002 07 40 00 80 eth0
382 * fe80000000000000025004fffefd5484 02 0a 20 80 ipsec0
383 * fe80000000000000025004fffefd5484 07 0a 20 80 eth0
385 * Each line contains:
386 * - IPv6 address: 16 bytes, in hex, no punctuation
387 * - ifindex: 1 byte, in hex
388 * - prefix_len: 1 byte, in hex
389 * - scope (e.g. global, link local): 1 byte, in hex
390 * - flags: 1 byte, in hex
391 * - device name: string, followed by '\n'
393 struct raw_iface
*rifaces
= NULL
;
394 static const char proc_name
[] = "/proc/net/if_inet6";
395 FILE *proc_sock
= fopen(proc_name
, "r");
397 if (proc_sock
== NULL
)
399 DBG(DBG_CONTROL
, DBG_log("could not open %s", proc_name
));
406 unsigned short xb
[8]; /* IPv6 address as 8 16-bit chunks */
407 char sb
[8*5]; /* IPv6 address as string-with-colons */
408 unsigned int if_idx
; /* proc field, not used */
409 unsigned int plen
; /* proc field, not used */
410 unsigned int scope
; /* proc field, used to exclude link-local */
411 unsigned int dad_status
; /* proc field, not used */
412 /* ??? I hate and distrust scanf -- DHR */
413 int r
= fscanf(proc_sock
414 , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
415 " %02x %02x %02x %02x %20s\n"
416 , xb
+0, xb
+1, xb
+2, xb
+3, xb
+4, xb
+5, xb
+6, xb
+7
417 , &if_idx
, &plen
, &scope
, &dad_status
, ri
.name
);
419 /* ??? we should diagnose any problems */
423 /* ignore addresses with link local scope.
424 * From linux-2.4.9-13/include/net/ipv6.h:
425 * IPV6_ADDR_LINKLOCAL 0x0020U
426 * IPV6_ADDR_SCOPE_MASK 0x00f0U
428 if ((scope
& 0x00f0U
) == 0x0020U
)
431 snprintf(sb
, sizeof(sb
)
432 , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
433 , xb
[0], xb
[1], xb
[2], xb
[3], xb
[4], xb
[5], xb
[6], xb
[7]);
435 happy(ttoaddr(sb
, 0, AF_INET6
, &ri
.addr
));
437 if (!isunspecaddr(&ri
.addr
))
440 , DBG_log("found %s with address %s"
443 rifaces
= clone_thing(ri
, "struct raw_iface");
454 create_socket(struct raw_iface
*ifp
, const char *v_name
, int port
)
456 int fd
= socket(addrtypeof(&ifp
->addr
), SOCK_DGRAM
, IPPROTO_UDP
);
461 log_errno((e
, "socket() in process_raw_ifaces()"));
466 /* Set socket Nonblocking */
467 if ((fcntl_flags
=fcntl(fd
, F_GETFL
)) >= 0) {
468 if (!(fcntl_flags
& O_NONBLOCK
)) {
469 fcntl_flags
|= O_NONBLOCK
;
470 fcntl(fd
, F_SETFL
, fcntl_flags
);
475 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
) == -1)
477 log_errno((e
, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
482 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
483 , (const void *)&on
, sizeof(on
)) < 0)
485 log_errno((e
, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
490 /* To improve error reporting. See ip(7). */
491 #if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
492 if (setsockopt(fd
, SOL_IP
, IP_RECVERR
493 , (const void *)&on
, sizeof(on
)) < 0)
495 log_errno((e
, "setsockopt IP_RECVERR in process_raw_ifaces()"));
501 /* With IPv6, there is no fragmentation after
502 * it leaves our interface. PMTU discovery
503 * is mandatory but doesn't work well with IKE (why?).
504 * So we must set the IPV6_USE_MIN_MTU option.
505 * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
507 #ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
508 if (addrtypeof(&ifp
->addr
) == AF_INET6
509 && setsockopt(fd
, SOL_SOCKET
, IPV6_USE_MIN_MTU
510 , (const void *)&on
, sizeof(on
)) < 0)
512 log_errno((e
, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
518 #if defined(linux) && defined(KERNEL26_SUPPORT)
519 if (!no_klips
&& kernel_ops
->type
== KERNEL_TYPE_LINUX
)
521 struct sadb_x_policy policy
;
524 policy
.sadb_x_policy_len
= sizeof(policy
) / IPSEC_PFKEYv2_ALIGN
;
525 policy
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
526 policy
.sadb_x_policy_type
= IPSEC_POLICY_BYPASS
;
527 policy
.sadb_x_policy_dir
= IPSEC_DIR_INBOUND
;
528 policy
.sadb_x_policy_reserved
= 0;
529 policy
.sadb_x_policy_id
= 0;
530 policy
.sadb_x_policy_reserved2
= 0;
532 if (addrtypeof(&ifp
->addr
) == AF_INET6
)
534 level
= IPPROTO_IPV6
;
535 opt
= IPV6_IPSEC_POLICY
;
540 opt
= IP_IPSEC_POLICY
;
543 if (setsockopt(fd
, level
, opt
544 , &policy
, sizeof(policy
)) < 0)
546 log_errno((e
, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
551 policy
.sadb_x_policy_dir
= IPSEC_DIR_OUTBOUND
;
553 if (setsockopt(fd
, level
, opt
554 , &policy
, sizeof(policy
)) < 0)
556 log_errno((e
, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
563 setportof(htons(port
), &ifp
->addr
);
564 if (bind(fd
, sockaddrof(&ifp
->addr
), sockaddrlenof(&ifp
->addr
)) < 0)
566 log_errno((e
, "bind() for %s/%s %s:%u in process_raw_ifaces()"
568 , ip_str(&ifp
->addr
), (unsigned) port
));
572 setportof(htons(pluto_port
), &ifp
->addr
);
578 process_raw_ifaces(struct raw_iface
*rifaces
)
580 struct raw_iface
*ifp
;
582 /* Find all virtual/real interface pairs.
583 * For each real interface...
585 for (ifp
= rifaces
; ifp
!= NULL
; ifp
= ifp
->next
)
587 struct raw_iface
*v
= NULL
; /* matching ipsecX interface */
588 struct raw_iface fake_v
;
589 bool after
= FALSE
; /* has vfp passed ifp on the list? */
591 struct raw_iface
*vfp
;
593 /* ignore if virtual (ipsec*) interface */
594 if (strncmp(ifp
->name
, IPSECDEVPREFIX
, sizeof(IPSECDEVPREFIX
)-1) == 0)
597 for (vfp
= rifaces
; vfp
!= NULL
; vfp
= vfp
->next
)
603 else if (sameaddr(&ifp
->addr
, &vfp
->addr
))
605 /* Different entries with matching IP addresses.
606 * Many interesting cases.
608 if (strncmp(vfp
->name
, IPSECDEVPREFIX
, sizeof(IPSECDEVPREFIX
)-1) == 0)
610 if (v
!= NULL
&& !streq(v
->name
, vfp
->name
))
612 loglog(RC_LOG_SERIOUS
613 , "ipsec interfaces %s and %s share same address %s"
614 , v
->name
, vfp
->name
, ip_str(&ifp
->addr
));
619 v
= vfp
; /* current winner */
624 /* ugh: a second real interface with the same IP address
625 * "after" allows us to avoid double reporting.
627 #if defined(linux) && defined(KERNEL26_SUPPORT)
628 if (!no_klips
&& kernel_ops
->type
== KERNEL_TYPE_LINUX
)
640 loglog(RC_LOG_SERIOUS
641 , "IP interfaces %s and %s share address %s!"
642 , ifp
->name
, vfp
->name
, ip_str(&ifp
->addr
));
652 #if defined(linux) && defined(KERNEL26_SUPPORT)
653 if (!no_klips
&& kernel_ops
->type
== KERNEL_TYPE_LINUX
)
660 /* what if we didn't find a virtual interface? */
665 /* kludge for testing: invent a virtual device */
666 static const char fvp
[] = "virtual";
668 passert(sizeof(fake_v
.name
) > sizeof(fvp
));
669 strcpy(fake_v
.name
, fvp
);
670 addrtot(&ifp
->addr
, 0, fake_v
.name
+ sizeof(fvp
) - 1
671 , sizeof(fake_v
.name
) - (sizeof(fvp
) - 1));
677 DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
678 , ifp
->name
, ip_str(&ifp
->addr
)));
683 /* We've got all we need; see if this is a new thing:
684 * search old interfaces list.
686 #if defined(linux) && defined(KERNEL26_SUPPORT)
690 struct iface
**p
= &interfaces
;
694 struct iface
*q
= *p
;
696 /* search is over if at end of list */
699 /* matches nothing -- create a new entry */
700 int fd
= create_socket(ifp
, v
->name
, pluto_port
);
706 if (nat_traversal_support_non_ike
707 && addrtypeof(&ifp
->addr
) == AF_INET
)
709 nat_traversal_espinudp_socket(fd
, ESPINUDP_WITH_NON_IKE
);
713 q
= alloc_thing(struct iface
, "struct iface");
714 q
->rname
= clone_str(ifp
->name
, "real device name");
715 q
->vname
= clone_str(v
->name
, "virtual device name");
718 q
->next
= interfaces
;
721 plog("adding interface %s/%s %s:%d"
722 , q
->vname
, q
->rname
, ip_str(&q
->addr
), pluto_port
);
724 if (nat_traversal_support_port_floating
725 && addrtypeof(&ifp
->addr
) == AF_INET
)
727 fd
= create_socket(ifp
, v
->name
, NAT_T_IKE_FLOAT_PORT
);
730 nat_traversal_espinudp_socket(fd
,
731 ESPINUDP_WITH_NON_ESP
);
732 q
= alloc_thing(struct iface
, "struct iface");
733 q
->rname
= clone_str(ifp
->name
, "real device name");
734 q
->vname
= clone_str(v
->name
, "virtual device name");
736 setportof(htons(NAT_T_IKE_FLOAT_PORT
), &q
->addr
);
738 q
->next
= interfaces
;
742 plog("adding interface %s/%s %s:%d",
743 q
->vname
, q
->rname
, ip_str(&q
->addr
), NAT_T_IKE_FLOAT_PORT
);
749 /* search over if matching old entry found */
750 if (streq(q
->rname
, ifp
->name
)
751 && streq(q
->vname
, v
->name
)
752 && sameaddr(&q
->addr
, &ifp
->addr
))
754 /* matches -- rejuvinate old entry */
755 q
->change
= IFN_KEEP
;
757 /* look for other interfaces to keep (due to NAT-T) */
758 for (q
= q
->next
; q
; q
= q
->next
) {
759 if (streq(q
->rname
, ifp
->name
)
760 && streq(q
->vname
, v
->name
)
761 && sameaddr(&q
->addr
, &ifp
->addr
)) {
762 q
->change
= IFN_KEEP
;
775 /* delete the raw interfaces list */
776 while (rifaces
!= NULL
)
778 struct raw_iface
*t
= rifaces
;
789 process_raw_ifaces(find_raw_ifaces4());
790 process_raw_ifaces(find_raw_ifaces6());
792 free_dead_ifaces(); /* ditch remaining old entries */
794 if (interfaces
== NULL
)
795 loglog(RC_LOG_SERIOUS
, "no public interfaces found");
799 show_ifaces_status(void)
803 for (p
= interfaces
; p
!= NULL
; p
= p
->next
)
804 whack_log(RC_COMMENT
, "interface %s/%s %s:%d"
805 , p
->vname
, p
->rname
, ip_str(&p
->addr
), ntohs(portof(&p
->addr
)));
809 show_debug_status(void)
812 whack_log(RC_COMMENT
, "debug %s"
813 , bitnamesof(debug_bit_names
, cur_debugging
));
817 static volatile sig_atomic_t sighupflag
= FALSE
;
820 huphandler(int sig UNUSED
)
825 static volatile sig_atomic_t sigtermflag
= FALSE
;
828 termhandler(int sig UNUSED
)
833 /* call_server listens for incoming ISAKMP packets and Whack messages,
834 * and handles timer events.
841 /* catch SIGHUP and SIGTERM */
844 struct sigaction act
;
846 act
.sa_handler
= &huphandler
;
847 sigemptyset(&act
.sa_mask
);
848 act
.sa_flags
= 0; /* no SA_ONESHOT, no SA_RESTART, no nothing */
849 r
= sigaction(SIGHUP
, &act
, NULL
);
852 act
.sa_handler
= &termhandler
;
853 r
= sigaction(SIGTERM
, &act
, NULL
);
863 /* wait for next interesting thing */
867 long next_time
= next_event(); /* time to any pending timer event */
875 /* Ignorant folks think poking any daemon with SIGHUP
876 * is polite. We catch it and tell them otherwise.
877 * There is one use: unsticking a hung recvfrom.
878 * This sticking happens sometimes -- kernel bug?
881 plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
886 FD_SET(ctl_fd
, &readfds
);
888 FD_SET(info_fd
, &readfds
);
893 /* the only write file-descriptor of interest */
894 if (adns_qfd
!= NULL_FD
&& unsent_ADNS_queries
)
896 if (maxfd
< adns_qfd
)
898 FD_SET(adns_qfd
, &writefds
);
901 if (adns_afd
!= NULL_FD
)
903 if (maxfd
< adns_afd
)
905 FD_SET(adns_afd
, &readfds
);
911 int fd
= *kernel_ops
->async_fdp
;
913 if (kernel_ops
->process_queue
)
914 kernel_ops
->process_queue();
917 passert(!FD_ISSET(fd
, &readfds
));
918 FD_SET(fd
, &readfds
);
924 for (ifp
= interfaces
; ifp
!= NULL
; ifp
= ifp
->next
)
928 passert(!FD_ISSET(ifp
->fd
, &readfds
));
929 FD_SET(ifp
->fd
, &readfds
);
935 /* select without timer */
937 ndes
= select(maxfd
+ 1, &readfds
, &writefds
, NULL
, NULL
);
939 else if (next_time
== 0)
941 /* timer without select: there is a timer event pending,
942 * and it should fire now so don't bother to do the select.
944 ndes
= 0; /* signify timer expiration */
948 /* select with timer */
952 tm
.tv_sec
= next_time
;
954 ndes
= select(maxfd
+ 1, &readfds
, &writefds
, NULL
, &tm
);
961 exit_log_errno((e
, "select() failed in call_server()"));
963 /* retry if terminated by signal */
966 /* figure out what is interesting */
973 DBG_log(BLANK_FORMAT
);
974 DBG_log("*time to handle event"));
976 handle_timer_event();
977 passert(GLOBALS_ARE_RESET());
981 /* at least one file descriptor is ready */
983 if (adns_qfd
!= NULL_FD
&& FD_ISSET(adns_qfd
, &writefds
))
986 send_unsent_ADNS_queries();
987 passert(GLOBALS_ARE_RESET());
991 if (adns_afd
!= NULL_FD
&& FD_ISSET(adns_afd
, &readfds
))
995 DBG_log(BLANK_FORMAT
);
996 DBG_log("*received adns message"));
997 handle_adns_answer();
998 passert(GLOBALS_ARE_RESET());
1003 if (!no_klips
&& FD_ISSET(*kernel_ops
->async_fdp
, &readfds
))
1007 DBG_log(BLANK_FORMAT
);
1008 DBG_log("*received kernel message"));
1009 kernel_ops
->process_msg();
1010 passert(GLOBALS_ARE_RESET());
1015 for (ifp
= interfaces
; ifp
!= NULL
; ifp
= ifp
->next
)
1017 if (FD_ISSET(ifp
->fd
, &readfds
))
1019 /* comm_handle will print DBG_CONTROL intro,
1020 * with more info than we have here.
1025 passert(GLOBALS_ARE_RESET());
1030 if (FD_ISSET(ctl_fd
, &readfds
))
1034 DBG_log(BLANK_FORMAT
);
1035 DBG_log("*received whack message"));
1036 whack_handle(ctl_fd
);
1037 passert(GLOBALS_ARE_RESET());
1042 if (FD_ISSET(info_fd
, &readfds
))
1046 DBG_log(BLANK_FORMAT
);
1047 DBG_log("*received info message"));
1048 info_handle(info_fd
);
1049 passert(GLOBALS_ARE_RESET());