summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1999-06-02 06:34:54 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1999-06-02 06:34:54 +0000
commit5a10cb14397338e656b90c67b3e074b08a3a2627 (patch)
tree677edd092fa1a5a927655b4cb0d974f3ff6a7cca /sbin
parent0abede97b8efa7d1cd38cec70e91fc81a43cd2f2 (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.c59
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;