diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-06-02 06:34:54 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-06-02 06:34:54 +0000 |
commit | 5a10cb14397338e656b90c67b3e074b08a3a2627 (patch) | |
tree | 677edd092fa1a5a927655b4cb0d974f3ff6a7cca /sbin | |
parent | 0abede97b8efa7d1cd38cec70e91fc81a43cd2f2 (diff) |
Merge with EOM 1.16
author: niklas
As PF_KEY per the specs is a best-effort service, expect messages to get lost.
That means both replies in PF_KEY "RPCs" and expirations, the latter we
solve with extra paranoia and sets timeouts in isakmpd too.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/isakmpd/pf_key_v2.c | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/sbin/isakmpd/pf_key_v2.c b/sbin/isakmpd/pf_key_v2.c index 7cd57d27e1e..3c8120f00e7 100644 --- a/sbin/isakmpd/pf_key_v2.c +++ b/sbin/isakmpd/pf_key_v2.c @@ -1,5 +1,5 @@ -/* $OpenBSD: pf_key_v2.c,v 1.10 1999/05/01 20:42:54 niklas Exp $ */ -/* $EOM: pf_key_v2.c,v 1.15 1999/05/01 20:38:45 niklas Exp $ */ +/* $OpenBSD: pf_key_v2.c,v 1.11 1999/06/02 06:34:53 niklas Exp $ */ +/* $EOM: pf_key_v2.c,v 1.16 1999/05/25 08:06:26 niklas Exp $ */ /* * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. @@ -38,6 +38,7 @@ #include <sys/ioctl.h> #include <sys/queue.h> #include <sys/socket.h> +#include <sys/time.h> #include <sys/uio.h> #include <net/pfkeyv2.h> #include <netinet/in.h> @@ -63,6 +64,9 @@ #define PF_KEY_V2_ROUND(x) \ (((x) + PF_KEY_V2_CHUNK - 1) & ~(PF_KEY_V2_CHUNK - 1)) +/* How many microseconds we will wait for a reply from the PF_KEY socket. */ +#define PF_KEY_REPLY_TIMEOUT 1000 + struct pf_key_v2_node { TAILQ_ENTRY (pf_key_v2_node) link; void *seg; @@ -172,10 +176,45 @@ pf_key_v2_read (u_int32_t seq) struct sadb_msg *msg; struct sadb_msg hdr; struct sadb_ext *ext; - struct timeval now; + struct timeval tv; + fd_set *fds; while (1) { + /* + * If this is a read of a reply we should actually expect the reply to + * get lost as PF_KEY is an unreliable service per the specs. + * Currently we do this by setting a short timeout, and if it is not + * readable in that time, we fail the read. + */ + if (seq) + { + fds = calloc (howmany (pf_key_v2_socket + 1, NFDBITS), + sizeof (fd_mask)); + if (!fds) + { + log_error ("pf_key_v2_read: calloc (%d, %d) failed", + howmany (pf_key_v2_socket + 1, NFDBITS), + sizeof (fd_mask)); + goto cleanup; + } + FD_SET (pf_key_v2_socket, fds); + tv.tv_sec = 0; + tv.tv_usec = PF_KEY_REPLY_TIMEOUT; + n = select (pf_key_v2_socket + 1, fds, 0, 0, &tv); + free (fds); + if (n == -1) + { + log_error ("pf_key_v2_read: select (%d, fds, 0, 0, &tv) failed", + pf_key_v2_socket + 1); + goto cleanup; + } + if (!n) + { + log_print ("pf_key_v2_read: no reply from PF_KEY"); + goto cleanup; + } + } n = recv (pf_key_v2_socket, &hdr, sizeof hdr, MSG_PEEK); if (n == -1) { @@ -253,9 +292,9 @@ pf_key_v2_read (u_int32_t seq) /* If the message is not the one we are waiting for, queue it up. */ if (seq && (msg->sadb_msg_pid != getpid () || msg->sadb_msg_seq != seq)) { - gettimeofday (&now, 0); + gettimeofday (&tv, 0); timer_add_event ("pf_key_v2_notify", - (void (*) (void *))pf_key_v2_notify, ret, &now); + (void (*) (void *))pf_key_v2_notify, ret, &tv); ret = 0; continue; } @@ -739,7 +778,7 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming) life->sadb_lifetime_bytes = sa->kilobytes * 1024 * 9 / 10; /* * XXX I am not sure which one is best in security respect. Maybe the - * RFCs actually mandate what a lifetime reaaly is. + * RFCs actually mandate what a lifetime really is. */ #if 0 life->sadb_lifetime_addtime = 0; @@ -871,6 +910,14 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming) inet_ntoa (((struct sockaddr_in *)dst)->sin_addr), ntohl (ssa.sadb_sa_spi)); + /* + * Although PF_KEY knows about expirations, it is unreliable per the specs + * thus we need to do them inside isakmpd as well. + */ + if (sa->seconds) + if (sa_setup_expirations (sa)) + goto cleanup; + ret = pf_key_v2_call (update); pf_key_v2_msg_free (update); update = 0; |