summaryrefslogtreecommitdiff
path: root/src/pluto/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/server.c')
-rw-r--r--src/pluto/server.c1434
1 files changed, 718 insertions, 716 deletions
diff --git a/src/pluto/server.c b/src/pluto/server.c
index b0e158503..21f65f4f8 100644
--- a/src/pluto/server.c
+++ b/src/pluto/server.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: server.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -27,7 +25,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#ifdef SOLARIS
-# include <sys/sockio.h> /* for Solaris 2.6: defines SIOCGIFCONF */
+# include <sys/sockio.h> /* for Solaris 2.6: defines SIOCGIFCONF */
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -38,7 +36,7 @@
#include <net/if.h>
#include <sys/ioctl.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <freeswan.h>
@@ -55,9 +53,9 @@
#include "demux.h" /* needs packet.h */
#include "rcv_whack.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include <pfkeyv2.h>
#include <pfkey.h>
@@ -68,10 +66,10 @@
* Server main loop and socket initialization routines.
*/
-static const int on = TRUE; /* by-reference parameter; constant, we hope */
+static const int on = TRUE; /* by-reference parameter; constant, we hope */
/* control (whack) socket */
-int ctl_fd = NULL_FD; /* file descriptor of control (whack) socket */
+int ctl_fd = NULL_FD; /* file descriptor of control (whack) socket */
struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
/* info (showpolicy) socket */
@@ -86,121 +84,121 @@ struct sockaddr_un info_addr= { AF_UNIX, DEFAULT_CTLBASE INFO_SUFFIX };
err_t
init_ctl_socket(void)
{
- err_t failed = NULL;
-
- delete_ctl_socket(); /* preventative medicine */
- ctl_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ctl_fd == -1)
- failed = "create";
- else if (fcntl(ctl_fd, F_SETFD, FD_CLOEXEC) == -1)
- failed = "fcntl FD+CLOEXEC";
- else if (setsockopt(ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
- failed = "setsockopt";
- else
- {
- /* to keep control socket secure, use umask */
- mode_t ou = umask(~S_IRWXU);
-
- if (bind(ctl_fd, (struct sockaddr *)&ctl_addr
- , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
- failed = "bind";
- umask(ou);
- }
-
- /* 5 is a haphazardly chosen limit for the backlog.
- * Rumour has it that this is the max on BSD systems.
- */
- if (failed == NULL && listen(ctl_fd, 5) < 0)
- failed = "listen() on";
-
- return failed == NULL? NULL : builddiag("could not %s control socket: %d %s"
- , failed, errno, strerror(errno));
+ err_t failed = NULL;
+
+ delete_ctl_socket(); /* preventative medicine */
+ ctl_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ctl_fd == -1)
+ failed = "create";
+ else if (fcntl(ctl_fd, F_SETFD, FD_CLOEXEC) == -1)
+ failed = "fcntl FD+CLOEXEC";
+ else if (setsockopt(ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
+ failed = "setsockopt";
+ else
+ {
+ /* to keep control socket secure, use umask */
+ mode_t ou = umask(~S_IRWXU);
+
+ if (bind(ctl_fd, (struct sockaddr *)&ctl_addr
+ , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
+ failed = "bind";
+ umask(ou);
+ }
+
+ /* 5 is a haphazardly chosen limit for the backlog.
+ * Rumour has it that this is the max on BSD systems.
+ */
+ if (failed == NULL && listen(ctl_fd, 5) < 0)
+ failed = "listen() on";
+
+ return failed == NULL? NULL : builddiag("could not %s control socket: %d %s"
+ , failed, errno, strerror(errno));
}
void
delete_ctl_socket(void)
{
- /* Is noting failure useful? Not when used as preventative medicine. */
- unlink(ctl_addr.sun_path);
+ /* Is noting failure useful? Not when used as preventative medicine. */
+ unlink(ctl_addr.sun_path);
}
-bool listening = FALSE; /* should we pay attention to IKE messages? */
+bool listening = FALSE; /* should we pay attention to IKE messages? */
-struct iface *interfaces = NULL; /* public interfaces */
+struct iface *interfaces = NULL; /* public interfaces */
/* Initialize the interface sockets. */
static void
mark_ifaces_dead(void)
{
- struct iface *p;
+ struct iface *p;
- for (p = interfaces; p != NULL; p = p->next)
- p->change = IFN_DELETE;
+ for (p = interfaces; p != NULL; p = p->next)
+ p->change = IFN_DELETE;
}
static void
free_dead_ifaces(void)
{
- struct iface *p;
- bool some_dead = FALSE
- , some_new = FALSE;
+ struct iface *p;
+ bool some_dead = FALSE
+ , some_new = FALSE;
- for (p = interfaces; p != NULL; p = p->next)
- {
- if (p->change == IFN_DELETE)
- {
- plog("shutting down interface %s/%s %s"
- , p->vname, p->rname, ip_str(&p->addr));
- some_dead = TRUE;
- }
- else if (p->change == IFN_ADD)
+ for (p = interfaces; p != NULL; p = p->next)
{
- some_new = TRUE;
+ if (p->change == IFN_DELETE)
+ {
+ plog("shutting down interface %s/%s %s"
+ , p->vname, p->rname, ip_str(&p->addr));
+ some_dead = TRUE;
+ }
+ else if (p->change == IFN_ADD)
+ {
+ some_new = TRUE;
+ }
}
- }
-
- if (some_dead)
- {
- struct iface **pp;
- release_dead_interfaces();
- for (pp = &interfaces; (p = *pp) != NULL; )
+ if (some_dead)
{
- if (p->change == IFN_DELETE)
- {
- *pp = p->next; /* advance *pp */
- pfree(p->vname);
- pfree(p->rname);
- close(p->fd);
- pfree(p);
- }
- else
- {
- pp = &p->next; /* advance pp */
- }
+ struct iface **pp;
+
+ release_dead_interfaces();
+ for (pp = &interfaces; (p = *pp) != NULL; )
+ {
+ if (p->change == IFN_DELETE)
+ {
+ *pp = p->next; /* advance *pp */
+ free(p->vname);
+ free(p->rname);
+ close(p->fd);
+ free(p);
+ }
+ else
+ {
+ pp = &p->next; /* advance pp */
+ }
+ }
}
- }
-
- /* this must be done after the release_dead_interfaces
- * in case some to the newly unoriented connections can
- * become oriented here.
- */
- if (some_dead || some_new)
- check_orientations();
+
+ /* this must be done after the release_dead_interfaces
+ * in case some to the newly unoriented connections can
+ * become oriented here.
+ */
+ if (some_dead || some_new)
+ check_orientations();
}
void
free_ifaces(void)
{
- mark_ifaces_dead();
- free_dead_ifaces();
+ mark_ifaces_dead();
+ free_dead_ifaces();
}
struct raw_iface {
- ip_address addr;
- char name[IFNAMSIZ + 20]; /* what would be a safe size? */
- struct raw_iface *next;
+ ip_address addr;
+ char name[IFNAMSIZ + 20]; /* what would be a safe size? */
+ struct raw_iface *next;
};
/* Called to handle --interface <ifname>
@@ -212,15 +210,15 @@ static int pluto_ifn_roof = 0;
bool
use_interface(const char *rifn)
{
- if (pluto_ifn_roof >= (int)elemsof(pluto_ifn))
- {
- return FALSE;
- }
- else
- {
- pluto_ifn[pluto_ifn_roof++] = rifn;
- return TRUE;
- }
+ if (pluto_ifn_roof >= (int)countof(pluto_ifn))
+ {
+ return FALSE;
+ }
+ else
+ {
+ pluto_ifn[pluto_ifn_roof++] = rifn;
+ return TRUE;
+ }
}
#ifndef IPSECDEVPREFIX
@@ -230,538 +228,542 @@ use_interface(const char *rifn)
static struct raw_iface *
find_raw_ifaces4(void)
{
- int j; /* index into buf */
- struct ifconf ifconf;
- struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
- struct raw_iface *rifaces = NULL;
- int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
-
- /* get list of interfaces with assigned IPv4 addresses from system */
-
- if (master_sock == -1)
- exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));
-
- if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
- , (const void *)&on, sizeof(on)) < 0)
- exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));
-
- /* bind the socket */
- {
- ip_address any;
-
- happy(anyaddr(AF_INET, &any));
- setportof(htons(pluto_port), &any);
- if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
- exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
- }
-
- /* Get local interfaces. See netdevice(7). */
- ifconf.ifc_len = sizeof(buf);
- ifconf.ifc_buf = (void *) buf;
- zero(buf);
-
- if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
- exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
-
- /* Add an entry to rifaces for each interesting interface. */
- for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
- {
- struct raw_iface ri;
- const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
- struct ifreq auxinfo;
-
- /* ignore all but AF_INET interfaces */
- if (rs->sin_family != AF_INET)
- continue; /* not interesting */
-
- /* build a NUL-terminated copy of the rname field */
- memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
- ri.name[IFNAMSIZ] = '\0';
-
- /* ignore if our interface names were specified, and this isn't one */
- if (pluto_ifn_roof != 0)
+ int j; /* index into buf */
+ struct ifconf ifconf;
+ struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
+ struct raw_iface *rifaces = NULL;
+ int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
+
+ /* get list of interfaces with assigned IPv4 addresses from system */
+
+ if (master_sock == -1)
+ exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));
+
+ if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
+ , (const void *)&on, sizeof(on)) < 0)
+ exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));
+
+ /* bind the socket */
{
- int i;
+ ip_address any;
- for (i = 0; i != pluto_ifn_roof; i++)
- if (streq(ri.name, pluto_ifn[i]))
- break;
- if (i == pluto_ifn_roof)
- continue; /* not found -- skip */
+ happy(anyaddr(AF_INET, &any));
+ setportof(htons(pluto_port), &any);
+ if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
+ exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
}
- /* Find out stuff about this interface. See netdevice(7). */
- zero(&auxinfo); /* paranoia */
- memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
- if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
- exit_log_errno((e
- , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
- , ri.name));
- if (!(auxinfo.ifr_flags & IFF_UP))
- continue; /* ignore an interface that isn't UP */
+ /* Get local interfaces. See netdevice(7). */
+ ifconf.ifc_len = sizeof(buf);
+ ifconf.ifc_buf = (void *) buf;
+ zero(buf);
- /* ignore unconfigured interfaces */
- if (rs->sin_addr.s_addr == 0)
- continue;
+ if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
+ exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
- happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
- , AF_INET, &ri.addr));
+ /* Add an entry to rifaces for each interesting interface. */
+ for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
+ {
+ struct raw_iface ri;
+ const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
+ struct ifreq auxinfo;
- DBG(DBG_CONTROL, DBG_log("found %s with address %s"
- , ri.name, ip_str(&ri.addr)));
- ri.next = rifaces;
- rifaces = clone_thing(ri, "struct raw_iface");
- }
+ /* ignore all but AF_INET interfaces */
+ if (rs->sin_family != AF_INET)
+ continue; /* not interesting */
- close(master_sock);
+ /* build a NUL-terminated copy of the rname field */
+ memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
+ ri.name[IFNAMSIZ] = '\0';
- return rifaces;
+ /* ignore if our interface names were specified, and this isn't one */
+ if (pluto_ifn_roof != 0)
+ {
+ int i;
+
+ for (i = 0; i != pluto_ifn_roof; i++)
+ if (streq(ri.name, pluto_ifn[i]))
+ break;
+ if (i == pluto_ifn_roof)
+ continue; /* not found -- skip */
+ }
+
+ /* Find out stuff about this interface. See netdevice(7). */
+ zero(&auxinfo); /* paranoia */
+ memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
+ if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
+ exit_log_errno((e
+ , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
+ , ri.name));
+ if (!(auxinfo.ifr_flags & IFF_UP))
+ continue; /* ignore an interface that isn't UP */
+
+ /* ignore unconfigured interfaces */
+ if (rs->sin_addr.s_addr == 0)
+ continue;
+
+ happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
+ , AF_INET, &ri.addr));
+
+ DBG(DBG_CONTROL, DBG_log("found %s with address %s"
+ , ri.name, ip_str(&ri.addr)));
+ ri.next = rifaces;
+ rifaces = clone_thing(ri);
+ }
+
+ close(master_sock);
+
+ return rifaces;
}
static struct raw_iface *
find_raw_ifaces6(void)
{
- /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
- *
- * Documentation of format?
- * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
- * linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
- *
- * Sample from Gerhard's laptop:
- * 00000000000000000000000000000001 01 80 10 80 lo
- * 30490009000000000000000000010002 02 40 00 80 ipsec0
- * 30490009000000000000000000010002 07 40 00 80 eth0
- * fe80000000000000025004fffefd5484 02 0a 20 80 ipsec0
- * fe80000000000000025004fffefd5484 07 0a 20 80 eth0
- *
- * Each line contains:
- * - IPv6 address: 16 bytes, in hex, no punctuation
- * - ifindex: 1 byte, in hex
- * - prefix_len: 1 byte, in hex
- * - scope (e.g. global, link local): 1 byte, in hex
- * - flags: 1 byte, in hex
- * - device name: string, followed by '\n'
- */
- struct raw_iface *rifaces = NULL;
- static const char proc_name[] = "/proc/net/if_inet6";
- FILE *proc_sock = fopen(proc_name, "r");
-
- if (proc_sock == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("could not open %s", proc_name));
- }
- else
- {
- for (;;)
+ /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
+ *
+ * Documentation of format?
+ * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
+ * linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
+ *
+ * Sample from Gerhard's laptop:
+ * 00000000000000000000000000000001 01 80 10 80 lo
+ * 30490009000000000000000000010002 02 40 00 80 ipsec0
+ * 30490009000000000000000000010002 07 40 00 80 eth0
+ * fe80000000000000025004fffefd5484 02 0a 20 80 ipsec0
+ * fe80000000000000025004fffefd5484 07 0a 20 80 eth0
+ *
+ * Each line contains:
+ * - IPv6 address: 16 bytes, in hex, no punctuation
+ * - ifindex: 1 byte, in hex
+ * - prefix_len: 1 byte, in hex
+ * - scope (e.g. global, link local): 1 byte, in hex
+ * - flags: 1 byte, in hex
+ * - device name: string, followed by '\n'
+ */
+ struct raw_iface *rifaces = NULL;
+ static const char proc_name[] = "/proc/net/if_inet6";
+ FILE *proc_sock = fopen(proc_name, "r");
+
+ if (proc_sock == NULL)
{
- struct raw_iface ri;
- unsigned short xb[8]; /* IPv6 address as 8 16-bit chunks */
- char sb[8*5]; /* IPv6 address as string-with-colons */
- unsigned int if_idx; /* proc field, not used */
- unsigned int plen; /* proc field, not used */
- unsigned int scope; /* proc field, used to exclude link-local */
- unsigned int dad_status; /* proc field, not used */
- /* ??? I hate and distrust scanf -- DHR */
- int r = fscanf(proc_sock
- , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
- " %02x %02x %02x %02x %20s\n"
- , xb+0, xb+1, xb+2, xb+3, xb+4, xb+5, xb+6, xb+7
- , &if_idx, &plen, &scope, &dad_status, ri.name);
-
- /* ??? we should diagnose any problems */
- if (r != 13)
- break;
-
- /* ignore addresses with link local scope.
- * From linux-2.4.9-13/include/net/ipv6.h:
- * IPV6_ADDR_LINKLOCAL 0x0020U
- * IPV6_ADDR_SCOPE_MASK 0x00f0U
- */
- if ((scope & 0x00f0U) == 0x0020U)
- continue;
-
- snprintf(sb, sizeof(sb)
- , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
- , xb[0], xb[1], xb[2], xb[3], xb[4], xb[5], xb[6], xb[7]);
-
- happy(ttoaddr(sb, 0, AF_INET6, &ri.addr));
-
- if (!isunspecaddr(&ri.addr))
- {
- DBG(DBG_CONTROL
- , DBG_log("found %s with address %s"
- , ri.name, sb));
- ri.next = rifaces;
- rifaces = clone_thing(ri, "struct raw_iface");
- }
+ DBG(DBG_CONTROL, DBG_log("could not open %s", proc_name));
+ }
+ else
+ {
+ for (;;)
+ {
+ struct raw_iface ri;
+ unsigned short xb[8]; /* IPv6 address as 8 16-bit chunks */
+ char sb[8*5]; /* IPv6 address as string-with-colons */
+ unsigned int if_idx; /* proc field, not used */
+ unsigned int plen; /* proc field, not used */
+ unsigned int scope; /* proc field, used to exclude link-local */
+ unsigned int dad_status; /* proc field, not used */
+ /* ??? I hate and distrust scanf -- DHR */
+ int r = fscanf(proc_sock
+ , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
+ " %02x %02x %02x %02x %20s\n"
+ , xb+0, xb+1, xb+2, xb+3, xb+4, xb+5, xb+6, xb+7
+ , &if_idx, &plen, &scope, &dad_status, ri.name);
+
+ /* ??? we should diagnose any problems */
+ if (r != 13)
+ break;
+
+ /* ignore addresses with link local scope.
+ * From linux-2.4.9-13/include/net/ipv6.h:
+ * IPV6_ADDR_LINKLOCAL 0x0020U
+ * IPV6_ADDR_SCOPE_MASK 0x00f0U
+ */
+ if ((scope & 0x00f0U) == 0x0020U)
+ continue;
+
+ snprintf(sb, sizeof(sb)
+ , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
+ , xb[0], xb[1], xb[2], xb[3], xb[4], xb[5], xb[6], xb[7]);
+
+ happy(ttoaddr(sb, 0, AF_INET6, &ri.addr));
+
+ if (!isunspecaddr(&ri.addr))
+ {
+ DBG(DBG_CONTROL
+ , DBG_log("found %s with address %s"
+ , ri.name, sb));
+ ri.next = rifaces;
+ rifaces = clone_thing(ri);
+ }
+ }
+ fclose(proc_sock);
}
- fclose(proc_sock);
- }
- return rifaces;
+ return rifaces;
}
#if 1
static int
create_socket(struct raw_iface *ifp, const char *v_name, int port)
{
- int fd = socket(addrtypeof(&ifp->addr), SOCK_DGRAM, IPPROTO_UDP);
- int fcntl_flags;
+ int fd = socket(addrtypeof(&ifp->addr), SOCK_DGRAM, IPPROTO_UDP);
+ int fcntl_flags;
- if (fd < 0)
- {
- log_errno((e, "socket() in process_raw_ifaces()"));
- return -1;
- }
+ if (fd < 0)
+ {
+ log_errno((e, "socket() in process_raw_ifaces()"));
+ return -1;
+ }
#if 1
- /* Set socket Nonblocking */
- if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
- if (!(fcntl_flags & O_NONBLOCK)) {
- fcntl_flags |= O_NONBLOCK;
- fcntl(fd, F_SETFL, fcntl_flags);
+ /* Set socket Nonblocking */
+ if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
+ if (!(fcntl_flags & O_NONBLOCK)) {
+ fcntl_flags |= O_NONBLOCK;
+ fcntl(fd, F_SETFL, fcntl_flags);
+ }
}
- }
-#endif
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- {
- log_errno((e, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- /* To improve error reporting. See ip(7). */
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- if (setsockopt(fd, SOL_IP, IP_RECVERR
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt IP_RECVERR in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-#endif
-
- /* With IPv6, there is no fragmentation after
- * it leaves our interface. PMTU discovery
- * is mandatory but doesn't work well with IKE (why?).
- * So we must set the IPV6_USE_MIN_MTU option.
- * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
- */
-#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
- if (addrtypeof(&ifp->addr) == AF_INET6
- && setsockopt(fd, SOL_SOCKET, IPV6_USE_MIN_MTU
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
#endif
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- struct sadb_x_policy policy;
- int level, opt;
-
- policy.sadb_x_policy_len = sizeof(policy) / IPSEC_PFKEYv2_ALIGN;
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- policy.sadb_x_policy_reserved = 0;
- policy.sadb_x_policy_id = 0;
- policy.sadb_x_policy_reserved2 = 0;
-
- if (addrtypeof(&ifp->addr) == AF_INET6)
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
{
- level = IPPROTO_IPV6;
- opt = IPV6_IPSEC_POLICY;
+ log_errno((e, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
+ close(fd);
+ return -1;
}
- else
+
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR
+ , (const void *)&on, sizeof(on)) < 0)
{
- level = IPPROTO_IP;
- opt = IP_IPSEC_POLICY;
+ log_errno((e, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
+ close(fd);
+ return -1;
}
- if (setsockopt(fd, level, opt
- , &policy, sizeof(policy)) < 0)
+ /* To improve error reporting. See ip(7). */
+#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
+ if (setsockopt(fd, SOL_IP, IP_RECVERR
+ , (const void *)&on, sizeof(on)) < 0)
{
- log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
- close(fd);
- return -1;
+ log_errno((e, "setsockopt IP_RECVERR in process_raw_ifaces()"));
+ close(fd);
+ return -1;
}
+#endif
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+ /* With IPv6, there is no fragmentation after
+ * it leaves our interface. PMTU discovery
+ * is mandatory but doesn't work well with IKE (why?).
+ * So we must set the IPV6_USE_MIN_MTU option.
+ * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
+ */
+#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
+ if (addrtypeof(&ifp->addr) == AF_INET6
+ && setsockopt(fd, SOL_SOCKET, IPV6_USE_MIN_MTU
+ , (const void *)&on, sizeof(on)) < 0)
+ {
+ log_errno((e, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
+ close(fd);
+ return -1;
+ }
+#endif
- if (setsockopt(fd, level, opt
- , &policy, sizeof(policy)) < 0)
+#if defined(linux) && defined(KERNEL26_SUPPORT)
+ if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
{
- log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
- close(fd);
- return -1;
+ struct sadb_x_policy policy;
+ int level, opt;
+
+ policy.sadb_x_policy_len = sizeof(policy) / IPSEC_PFKEYv2_ALIGN;
+ policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
+ policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+ policy.sadb_x_policy_reserved = 0;
+ policy.sadb_x_policy_id = 0;
+ policy.sadb_x_policy_reserved2 = 0;
+
+ if (addrtypeof(&ifp->addr) == AF_INET6)
+ {
+ level = IPPROTO_IPV6;
+ opt = IPV6_IPSEC_POLICY;
+ }
+ else
+ {
+ level = IPPROTO_IP;
+ opt = IP_IPSEC_POLICY;
+ }
+
+ if (setsockopt(fd, level, opt
+ , &policy, sizeof(policy)) < 0)
+ {
+ log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
+ close(fd);
+ return -1;
+ }
+
+ policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+
+ if (setsockopt(fd, level, opt
+ , &policy, sizeof(policy)) < 0)
+ {
+ log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
+ close(fd);
+ return -1;
+ }
}
- }
#endif
- setportof(htons(port), &ifp->addr);
- if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
- {
- log_errno((e, "bind() for %s/%s %s:%u in process_raw_ifaces()"
- , ifp->name, v_name
- , ip_str(&ifp->addr), (unsigned) port));
- close(fd);
- return -1;
- }
- setportof(htons(pluto_port), &ifp->addr);
- return fd;
+ setportof(htons(port), &ifp->addr);
+ if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
+ {
+ log_errno((e, "bind() for %s/%s %s:%u in process_raw_ifaces()"
+ , ifp->name, v_name
+ , ip_str(&ifp->addr), (unsigned) port));
+ close(fd);
+ return -1;
+ }
+ setportof(htons(pluto_port), &ifp->addr);
+ return fd;
}
#endif
static void
process_raw_ifaces(struct raw_iface *rifaces)
{
- struct raw_iface *ifp;
-
- /* Find all virtual/real interface pairs.
- * For each real interface...
- */
- for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
- {
- struct raw_iface *v = NULL; /* matching ipsecX interface */
- struct raw_iface fake_v;
- bool after = FALSE; /* has vfp passed ifp on the list? */
- bool bad = FALSE;
- struct raw_iface *vfp;
-
- /* ignore if virtual (ipsec*) interface */
- if (strncmp(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
- continue;
-
- for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
+ struct raw_iface *ifp;
+
+ /* Find all virtual/real interface pairs.
+ * For each real interface...
+ */
+ for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
{
- if (vfp == ifp)
- {
- after = TRUE;
- }
- else if (sameaddr(&ifp->addr, &vfp->addr))
- {
- /* Different entries with matching IP addresses.
- * Many interesting cases.
- */
- if (strncmp(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
+ struct raw_iface *v = NULL; /* matching ipsecX interface */
+ struct raw_iface fake_v;
+ bool after = FALSE; /* has vfp passed ifp on the list? */
+ bool bad = FALSE;
+ struct raw_iface *vfp;
+
+ /* ignore if virtual (ipsec*) interface */
+ if (strneq(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
{
- if (v != NULL && !streq(v->name, vfp->name))
- {
- loglog(RC_LOG_SERIOUS
- , "ipsec interfaces %s and %s share same address %s"
- , v->name, vfp->name, ip_str(&ifp->addr));
- bad = TRUE;
- }
- else
- {
- v = vfp; /* current winner */
- }
+ continue;
}
- else
+
+ for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
{
- /* ugh: a second real interface with the same IP address
- * "after" allows us to avoid double reporting.
- */
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- if (after)
+ if (vfp == ifp)
{
- bad = TRUE;
- break;
+ after = TRUE;
}
- continue;
- }
+ else if (sameaddr(&ifp->addr, &vfp->addr))
+ {
+ /* Different entries with matching IP addresses.
+ * Many interesting cases.
+ */
+ if (strneq(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
+ {
+ if (v != NULL && !streq(v->name, vfp->name))
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ipsec interfaces %s and %s share same address %s"
+ , v->name, vfp->name, ip_str(&ifp->addr));
+ bad = TRUE;
+ }
+ else
+ {
+ v = vfp; /* current winner */
+ }
+ }
+ else
+ {
+ /* ugh: a second real interface with the same IP address
+ * "after" allows us to avoid double reporting.
+ */
+#if defined(linux) && defined(KERNEL26_SUPPORT)
+ if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
+ {
+ if (after)
+ {
+ bad = TRUE;
+ break;
+ }
+ continue;
+ }
#endif
- if (after)
- {
- loglog(RC_LOG_SERIOUS
- , "IP interfaces %s and %s share address %s!"
- , ifp->name, vfp->name, ip_str(&ifp->addr));
- }
- bad = TRUE;
+ if (after)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "IP interfaces %s and %s share address %s!"
+ , ifp->name, vfp->name, ip_str(&ifp->addr));
+ }
+ bad = TRUE;
+ }
+ }
}
- }
- }
- if (bad)
- continue;
+ if (bad)
+ continue;
#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- v = ifp;
- goto add_entry;
- }
+ if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
+ {
+ v = ifp;
+ goto add_entry;
+ }
#endif
- /* what if we didn't find a virtual interface? */
- if (v == NULL)
- {
- if (no_klips)
- {
- /* kludge for testing: invent a virtual device */
- static const char fvp[] = "virtual";
- fake_v = *ifp;
- passert(sizeof(fake_v.name) > sizeof(fvp));
- strcpy(fake_v.name, fvp);
- addrtot(&ifp->addr, 0, fake_v.name + sizeof(fvp) - 1
- , sizeof(fake_v.name) - (sizeof(fvp) - 1));
- v = &fake_v;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
- , ifp->name, ip_str(&ifp->addr)));
- continue;
- }
- }
+ /* what if we didn't find a virtual interface? */
+ if (v == NULL)
+ {
+ if (no_klips)
+ {
+ /* kludge for testing: invent a virtual device */
+ static const char fvp[] = "virtual";
+ fake_v = *ifp;
+ passert(sizeof(fake_v.name) > sizeof(fvp));
+ strcpy(fake_v.name, fvp);
+ addrtot(&ifp->addr, 0, fake_v.name + sizeof(fvp) - 1
+ , sizeof(fake_v.name) - (sizeof(fvp) - 1));
+ v = &fake_v;
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
+ , ifp->name, ip_str(&ifp->addr)));
+ continue;
+ }
+ }
- /* We've got all we need; see if this is a new thing:
- * search old interfaces list.
- */
+ /* We've got all we need; see if this is a new thing:
+ * search old interfaces list.
+ */
#if defined(linux) && defined(KERNEL26_SUPPORT)
add_entry:
#endif
- {
- struct iface **p = &interfaces;
-
- for (;;)
- {
- struct iface *q = *p;
-
- /* search is over if at end of list */
- if (q == NULL)
{
- /* matches nothing -- create a new entry */
- int fd = create_socket(ifp, v->name, pluto_port);
-
- if (fd < 0)
- break;
-
- if (nat_traversal_support_non_ike
- && addrtypeof(&ifp->addr) == AF_INET)
- {
- nat_traversal_espinudp_socket(fd, ESPINUDP_WITH_NON_IKE);
- }
-
- q = alloc_thing(struct iface, "struct iface");
- q->rname = clone_str(ifp->name, "real device name");
- q->vname = clone_str(v->name, "virtual device name");
- q->addr = ifp->addr;
- q->fd = fd;
- q->next = interfaces;
- q->change = IFN_ADD;
- interfaces = q;
- plog("adding interface %s/%s %s:%d"
- , q->vname, q->rname, ip_str(&q->addr), pluto_port);
-
- if (nat_traversal_support_port_floating
- && addrtypeof(&ifp->addr) == AF_INET)
- {
- fd = create_socket(ifp, v->name, NAT_T_IKE_FLOAT_PORT);
- if (fd < 0)
- break;
- nat_traversal_espinudp_socket(fd,
- ESPINUDP_WITH_NON_ESP);
- q = alloc_thing(struct iface, "struct iface");
- q->rname = clone_str(ifp->name, "real device name");
- q->vname = clone_str(v->name, "virtual device name");
- q->addr = ifp->addr;
- setportof(htons(NAT_T_IKE_FLOAT_PORT), &q->addr);
- q->fd = fd;
- q->next = interfaces;
- q->change = IFN_ADD;
- q->ike_float = TRUE;
- interfaces = q;
- plog("adding interface %s/%s %s:%d",
- q->vname, q->rname, ip_str(&q->addr), NAT_T_IKE_FLOAT_PORT);
- }
- break;
- }
+ struct iface **p = &interfaces;
- /* search over if matching old entry found */
- if (streq(q->rname, ifp->name)
- && streq(q->vname, v->name)
- && sameaddr(&q->addr, &ifp->addr))
- {
- /* matches -- rejuvinate old entry */
- q->change = IFN_KEEP;
-
- /* look for other interfaces to keep (due to NAT-T) */
- for (q = q->next ; q ; q = q->next)
- {
- if (streq(q->rname, ifp->name)
- && streq(q->vname, v->name)
- && sameaddr(&q->addr, &ifp->addr))
+ for (;;)
{
- q->change = IFN_KEEP;
- }
- }
- break;
+ struct iface *q = *p;
+
+ /* search is over if at end of list */
+ if (q == NULL)
+ {
+ /* matches nothing -- create a new entry */
+ int fd = create_socket(ifp, v->name, pluto_port);
+
+ if (fd < 0)
+ break;
+
+ if (nat_traversal_support_non_ike
+ && addrtypeof(&ifp->addr) == AF_INET)
+ {
+ nat_traversal_espinudp_socket(fd, ESPINUDP_WITH_NON_IKE);
+ }
+
+ q = malloc_thing(struct iface);
+ zero(q);
+ q->rname = clone_str(ifp->name);
+ q->vname = clone_str(v->name);
+ q->addr = ifp->addr;
+ q->fd = fd;
+ q->next = interfaces;
+ q->change = IFN_ADD;
+ interfaces = q;
+ plog("adding interface %s/%s %s:%d"
+ , q->vname, q->rname, ip_str(&q->addr), pluto_port);
+
+ if (nat_traversal_support_port_floating
+ && addrtypeof(&ifp->addr) == AF_INET)
+ {
+ fd = create_socket(ifp, v->name, NAT_T_IKE_FLOAT_PORT);
+ if (fd < 0)
+ break;
+ nat_traversal_espinudp_socket(fd,
+ ESPINUDP_WITH_NON_ESP);
+ q = malloc_thing(struct iface);
+ zero(q);
+ q->rname = clone_str(ifp->name);
+ q->vname = clone_str(v->name);
+ q->addr = ifp->addr;
+ setportof(htons(NAT_T_IKE_FLOAT_PORT), &q->addr);
+ q->fd = fd;
+ q->next = interfaces;
+ q->change = IFN_ADD;
+ q->ike_float = TRUE;
+ interfaces = q;
+ plog("adding interface %s/%s %s:%d",
+ q->vname, q->rname, ip_str(&q->addr), NAT_T_IKE_FLOAT_PORT);
+ }
+ break;
+ }
+
+ /* search over if matching old entry found */
+ if (streq(q->rname, ifp->name)
+ && streq(q->vname, v->name)
+ && sameaddr(&q->addr, &ifp->addr))
+ {
+ /* matches -- rejuvinate old entry */
+ q->change = IFN_KEEP;
+
+ /* look for other interfaces to keep (due to NAT-T) */
+ for (q = q->next ; q ; q = q->next)
+ {
+ if (streq(q->rname, ifp->name)
+ && streq(q->vname, v->name)
+ && sameaddr(&q->addr, &ifp->addr))
+ {
+ q->change = IFN_KEEP;
+ }
+ }
+ break;
+ }
+
+ /* try again */
+ p = &q->next;
+ } /* for (;;) */
}
-
- /* try again */
- p = &q->next;
- } /* for (;;) */
}
- }
- /* delete the raw interfaces list */
- while (rifaces != NULL)
- {
- struct raw_iface *t = rifaces;
+ /* delete the raw interfaces list */
+ while (rifaces != NULL)
+ {
+ struct raw_iface *t = rifaces;
- rifaces = t->next;
- pfree(t);
- }
+ rifaces = t->next;
+ free(t);
+ }
}
void
find_ifaces(void)
{
- mark_ifaces_dead();
- process_raw_ifaces(find_raw_ifaces4());
- process_raw_ifaces(find_raw_ifaces6());
+ mark_ifaces_dead();
+ process_raw_ifaces(find_raw_ifaces4());
+ process_raw_ifaces(find_raw_ifaces6());
- free_dead_ifaces(); /* ditch remaining old entries */
+ free_dead_ifaces(); /* ditch remaining old entries */
- if (interfaces == NULL)
- loglog(RC_LOG_SERIOUS, "no public interfaces found");
+ if (interfaces == NULL)
+ loglog(RC_LOG_SERIOUS, "no public interfaces found");
}
void
show_ifaces_status(void)
{
- struct iface *p;
+ struct iface *p;
- for (p = interfaces; p != NULL; p = p->next)
- whack_log(RC_COMMENT, "interface %s/%s %s:%d"
- , p->vname, p->rname, ip_str(&p->addr), ntohs(portof(&p->addr)));
+ for (p = interfaces; p != NULL; p = p->next)
+ whack_log(RC_COMMENT, "interface %s/%s %s:%d"
+ , p->vname, p->rname, ip_str(&p->addr), ntohs(portof(&p->addr)));
}
void
show_debug_status(void)
{
#ifdef DEBUG
- whack_log(RC_COMMENT, "debug %s"
- , bitnamesof(debug_bit_names, cur_debugging));
+ whack_log(RC_COMMENT, "debug options: %s"
+ , bitnamesof(debug_bit_names, cur_debugging));
#endif
}
@@ -770,7 +772,7 @@ static volatile sig_atomic_t sighupflag = FALSE;
static void
huphandler(int sig UNUSED)
{
- sighupflag = TRUE;
+ sighupflag = TRUE;
}
static volatile sig_atomic_t sigtermflag = FALSE;
@@ -778,7 +780,7 @@ static volatile sig_atomic_t sigtermflag = FALSE;
static void
termhandler(int sig UNUSED)
{
- sigtermflag = TRUE;
+ sigtermflag = TRUE;
}
/* call_server listens for incoming ISAKMP packets and Whack messages,
@@ -787,206 +789,206 @@ termhandler(int sig UNUSED)
void
call_server(void)
{
- struct iface *ifp;
+ struct iface *ifp;
- /* catch SIGHUP and SIGTERM */
- {
- int r;
- struct sigaction act;
+ /* catch SIGHUP and SIGTERM */
+ {
+ int r;
+ struct sigaction act;
+
+ act.sa_handler = &huphandler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0; /* no SA_ONESHOT, no SA_RESTART, no nothing */
+ r = sigaction(SIGHUP, &act, NULL);
+ passert(r == 0);
+
+ act.sa_handler = &termhandler;
+ r = sigaction(SIGTERM, &act, NULL);
+ passert(r == 0);
+ }
- act.sa_handler = &huphandler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0; /* no SA_ONESHOT, no SA_RESTART, no nothing */
- r = sigaction(SIGHUP, &act, NULL);
- passert(r == 0);
+ for (;;)
+ {
+ fd_set readfds;
+ fd_set writefds;
+ int ndes;
- act.sa_handler = &termhandler;
- r = sigaction(SIGTERM, &act, NULL);
- passert(r == 0);
- }
+ /* wait for next interesting thing */
- for (;;)
- {
- fd_set readfds;
- fd_set writefds;
- int ndes;
+ for (;;)
+ {
+ long next_time = next_event(); /* time to any pending timer event */
+ int maxfd = ctl_fd;
- /* wait for next interesting thing */
+ if (sigtermflag)
+ exit_pluto(0);
- for (;;)
- {
- long next_time = next_event(); /* time to any pending timer event */
- int maxfd = ctl_fd;
-
- if (sigtermflag)
- exit_pluto(0);
-
- if (sighupflag)
- {
- /* Ignorant folks think poking any daemon with SIGHUP
- * is polite. We catch it and tell them otherwise.
- * There is one use: unsticking a hung recvfrom.
- * This sticking happens sometimes -- kernel bug?
- */
- sighupflag = FALSE;
- plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
- }
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_SET(ctl_fd, &readfds);
-
- /* the only write file-descriptor of interest */
- if (adns_qfd != NULL_FD && unsent_ADNS_queries)
- {
- if (maxfd < adns_qfd)
- maxfd = adns_qfd;
- FD_SET(adns_qfd, &writefds);
- }
-
- if (adns_afd != NULL_FD)
- {
- if (maxfd < adns_afd)
- maxfd = adns_afd;
- FD_SET(adns_afd, &readfds);
- }
+ if (sighupflag)
+ {
+ /* Ignorant folks think poking any daemon with SIGHUP
+ * is polite. We catch it and tell them otherwise.
+ * There is one use: unsticking a hung recvfrom.
+ * This sticking happens sometimes -- kernel bug?
+ */
+ sighupflag = FALSE;
+ plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
+ }
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_SET(ctl_fd, &readfds);
+
+ /* the only write file-descriptor of interest */
+ if (adns_qfd != NULL_FD && unsent_ADNS_queries)
+ {
+ if (maxfd < adns_qfd)
+ maxfd = adns_qfd;
+ FD_SET(adns_qfd, &writefds);
+ }
+
+ if (adns_afd != NULL_FD)
+ {
+ if (maxfd < adns_afd)
+ maxfd = adns_afd;
+ FD_SET(adns_afd, &readfds);
+ }
#ifdef KLIPS
- if (!no_klips)
- {
- int fd = *kernel_ops->async_fdp;
-
- if (kernel_ops->process_queue)
- kernel_ops->process_queue();
- if (maxfd < fd)
- maxfd = fd;
- passert(!FD_ISSET(fd, &readfds));
- FD_SET(fd, &readfds);
- }
+ if (!no_klips)
+ {
+ int fd = *kernel_ops->async_fdp;
+
+ if (kernel_ops->process_queue)
+ kernel_ops->process_queue();
+ if (maxfd < fd)
+ maxfd = fd;
+ passert(!FD_ISSET(fd, &readfds));
+ FD_SET(fd, &readfds);
+ }
#endif
- if (listening)
- {
- for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
- {
- if (maxfd < ifp->fd)
- maxfd = ifp->fd;
- passert(!FD_ISSET(ifp->fd, &readfds));
- FD_SET(ifp->fd, &readfds);
- }
- }
-
- if (next_time == -1)
- {
- /* select without timer */
-
- ndes = select(maxfd + 1, &readfds, &writefds, NULL, NULL);
- }
- else if (next_time == 0)
- {
- /* timer without select: there is a timer event pending,
- * and it should fire now so don't bother to do the select.
- */
- ndes = 0; /* signify timer expiration */
- }
- else
- {
- /* select with timer */
+ if (listening)
+ {
+ for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
+ {
+ if (maxfd < ifp->fd)
+ maxfd = ifp->fd;
+ passert(!FD_ISSET(ifp->fd, &readfds));
+ FD_SET(ifp->fd, &readfds);
+ }
+ }
- struct timeval tm;
+ if (next_time == -1)
+ {
+ /* select without timer */
- tm.tv_sec = next_time;
- tm.tv_usec = 0;
- ndes = select(maxfd + 1, &readfds, &writefds, NULL, &tm);
- }
+ ndes = select(maxfd + 1, &readfds, &writefds, NULL, NULL);
+ }
+ else if (next_time == 0)
+ {
+ /* timer without select: there is a timer event pending,
+ * and it should fire now so don't bother to do the select.
+ */
+ ndes = 0; /* signify timer expiration */
+ }
+ else
+ {
+ /* select with timer */
- if (ndes != -1)
- break; /* success */
+ struct timeval tm;
- if (errno != EINTR)
- exit_log_errno((e, "select() failed in call_server()"));
+ tm.tv_sec = next_time;
+ tm.tv_usec = 0;
+ ndes = select(maxfd + 1, &readfds, &writefds, NULL, &tm);
+ }
- /* retry if terminated by signal */
- }
+ if (ndes != -1)
+ break; /* success */
- /* figure out what is interesting */
+ if (errno != EINTR)
+ exit_log_errno((e, "select() failed in call_server()"));
- if (ndes == 0)
- {
- /* timer event */
+ /* retry if terminated by signal */
+ }
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*time to handle event"));
+ /* figure out what is interesting */
- handle_timer_event();
- passert(GLOBALS_ARE_RESET());
- }
- else
- {
- /* at least one file descriptor is ready */
-
- if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
- {
- passert(ndes > 0);
- send_unsent_ADNS_queries();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
- if (adns_afd != NULL_FD && FD_ISSET(adns_afd, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received adns message"));
- handle_adns_answer();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
+ if (ndes == 0)
+ {
+ /* timer event */
+
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*time to handle event"));
+
+ handle_timer_event();
+ passert(GLOBALS_ARE_RESET());
+ }
+ else
+ {
+ /* at least one file descriptor is ready */
+
+ if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
+ {
+ passert(ndes > 0);
+ send_unsent_ADNS_queries();
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
+
+ if (adns_afd != NULL_FD && FD_ISSET(adns_afd, &readfds))
+ {
+ passert(ndes > 0);
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received adns message"));
+ handle_adns_answer();
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
#ifdef KLIPS
- if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received kernel message"));
- kernel_ops->process_msg();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
+ if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds))
+ {
+ passert(ndes > 0);
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received kernel message"));
+ kernel_ops->process_msg();
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
#endif
- for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
- {
- if (FD_ISSET(ifp->fd, &readfds))
- {
- /* comm_handle will print DBG_CONTROL intro,
- * with more info than we have here.
- */
-
- passert(ndes > 0);
- comm_handle(ifp);
- passert(GLOBALS_ARE_RESET());
- ndes--;
+ for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
+ {
+ if (FD_ISSET(ifp->fd, &readfds))
+ {
+ /* comm_handle will print DBG_CONTROL intro,
+ * with more info than we have here.
+ */
+
+ passert(ndes > 0);
+ comm_handle(ifp);
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
+ }
+
+ if (FD_ISSET(ctl_fd, &readfds))
+ {
+ passert(ndes > 0);
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received whack message"));
+ whack_handle(ctl_fd);
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
+
+ passert(ndes == 0);
}
- }
-
- if (FD_ISSET(ctl_fd, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received whack message"));
- whack_handle(ctl_fd);
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
- passert(ndes == 0);
}
- }
}
/*