summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/sasyncd/conf.y25
-rw-r--r--usr.sbin/sasyncd/log.c3
-rw-r--r--usr.sbin/sasyncd/monitor.c53
-rw-r--r--usr.sbin/sasyncd/net.c12
-rw-r--r--usr.sbin/sasyncd/net_ctl.c8
-rw-r--r--usr.sbin/sasyncd/pfkey.c47
-rw-r--r--usr.sbin/sasyncd/sasyncd.h16
7 files changed, 116 insertions, 48 deletions
diff --git a/usr.sbin/sasyncd/conf.y b/usr.sbin/sasyncd/conf.y
index 1ae00cf5879..f824ecdb894 100644
--- a/usr.sbin/sasyncd/conf.y
+++ b/usr.sbin/sasyncd/conf.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.y,v 1.3 2005/05/24 19:18:10 ho Exp $ */
+/* $OpenBSD: conf.y,v 1.4 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -58,10 +58,10 @@ void yyerror(const char *);
}
%token MODE CARP INTERFACE INTERVAL LISTEN ON PORT PEER SHAREDKEY
-%token Y_SLAVE Y_MASTER INET INET6
+%token Y_SLAVE Y_MASTER INET INET6 FLUSHMODE STARTUP NEVER SYNC
%token <string> STRING
%token <val> VALUE
-%type <val> af port interval mode
+%type <val> af port interval mode flushmode
%%
/* Rules */
@@ -87,6 +87,11 @@ interval : /* empty */ { $$ = CARP_DEFAULT_INTERVAL; }
| INTERVAL VALUE { $$ = $2; }
;
+flushmode : STARTUP { $$ = FM_STARTUP; }
+ | NEVER { $$ = FM_NEVER; }
+ | SYNC { $$ = FM_SYNC; }
+ ;
+
setting : CARP INTERFACE STRING interval
{
if (cfgstate.carp_ifname)
@@ -96,6 +101,12 @@ setting : CARP INTERFACE STRING interval
log_msg(2, "config: carp interface %s interval %d",
$3, $4);
}
+ | FLUSHMODE flushmode
+ {
+ const char *fm[] = FLUSHMODES;
+ cfgstate.flushmode = $2;
+ log_msg(2, "config: flush mode set to %s", fm[$2]);
+ }
| PEER STRING
{
struct syncpeer *peer;
@@ -146,9 +157,9 @@ setting : CARP INTERFACE STRING interval
}
| mode
{
+ const char *m[] = CARPSTATES;
cfgstate.lockedstate = $1;
- log_msg(2, "config: mode set to %s",
- $1 == MASTER ? "MASTER" : "SLAVE");
+ log_msg(2, "config: mode set to %s", m[$1]);
}
| SHAREDKEY STRING
{
@@ -179,6 +190,7 @@ match(char *token)
/* Sorted */
static const struct keyword keywords[] = {
{ "carp", CARP },
+ { "flushmode", FLUSHMODE },
{ "inet", INET },
{ "inet6", INET6 },
{ "interface", INTERFACE },
@@ -186,11 +198,14 @@ match(char *token)
{ "listen", LISTEN },
{ "master", Y_MASTER },
{ "mode", MODE },
+ { "never", NEVER },
{ "on", ON },
{ "peer", PEER },
{ "port", PORT },
{ "sharedkey", SHAREDKEY },
{ "slave", Y_SLAVE },
+ { "startup", STARTUP },
+ { "sync", SYNC },
};
const struct keyword *k;
diff --git a/usr.sbin/sasyncd/log.c b/usr.sbin/sasyncd/log.c
index e7e7aa9fd4b..70003eb89b9 100644
--- a/usr.sbin/sasyncd/log.c
+++ b/usr.sbin/sasyncd/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.3 2005/05/22 12:14:16 ho Exp $ */
+/* $OpenBSD: log.c,v 1.4 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -29,7 +29,6 @@
* This code was written under funding by Multicom Security AB.
*/
-
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
diff --git a/usr.sbin/sasyncd/monitor.c b/usr.sbin/sasyncd/monitor.c
index e3abbe34e24..496f3b9668c 100644
--- a/usr.sbin/sasyncd/monitor.c
+++ b/usr.sbin/sasyncd/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.3 2005/05/26 05:33:48 ho Exp $ */
+/* $OpenBSD: monitor.c,v 1.4 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -123,36 +123,51 @@ sig_to_child(int s)
kill(m_state.pid, s);
}
+static void
+monitor_drain_input(void)
+{
+ int one = 1;
+ u_int8_t tmp;
+
+ ioctl(m_state.s, FIONBIO, &one);
+ while (read(m_state.s, &tmp, 1) > 0)
+ ;
+ ioctl(m_state.s, FIONBIO, 0);
+}
+
/* We only use privsep to get in-kernel SADB and SPD snapshots via sysctl */
void
monitor_loop(void)
{
- extern volatile sig_atomic_t daemon_shutdown;
- pid_t pid;
- int status;
u_int32_t v;
+ ssize_t r;
- while (!daemon_shutdown) {
+ for (;;) {
if (sigchld) {
+ pid_t pid;
+ int status;
do {
pid = waitpid(m_state.pid, &status, WNOHANG);
} while (pid == -1 && errno == EINTR);
if (pid == m_state.pid &&
- (WIFEXITED(status) || WIFSIGNALED(status))) {
- daemon_shutdown++;
+ (WIFEXITED(status) || WIFSIGNALED(status)))
break;
- }
}
/* Wait for next snapshot task. Disregard read data. */
- if (read(m_state.s, &v, sizeof v) != (ssize_t)sizeof v)
+ if ((r = read(m_state.s, &v, sizeof v)) != sizeof v) {
+ if (r == -1)
+ log_err(0, "monitor_loop: read() ");
break;
+ }
/* Get the data. */
m_priv_pfkey_snap(m_state.s);
}
-
+
+ if (!sigchld)
+ log_msg(0, "monitor_loop: priv process exiting abnormally");
exit(0);
}
@@ -160,13 +175,11 @@ int
monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd,
u_int32_t *spdsize)
{
- int one = 1;
- u_int8_t tmp;
u_int32_t rbytes;
/* We write a (any) value to the monitor socket to start a snapshot. */
- *sadbsize = 0;
- if (write(m_state.s, sadbsize, sizeof *sadbsize) < 1)
+ rbytes = 0;
+ if (write(m_state.s, &rbytes, sizeof rbytes) < 1)
return -1;
/* Read SADB data. */
@@ -178,10 +191,7 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd,
*sadb = (u_int8_t *)malloc(*sadbsize);
if (!*sadb) {
log_err("monitor_get_pfkey_snap: malloc()");
- /* Drain input */
- ioctl(m_state.s, FIONBIO, &one);
- while (read(m_state.s, &tmp, 1) > 0);
- ioctl(m_state.s, FIONBIO, 0);
+ monitor_drain_input();
return -1;
}
rbytes = read(m_state.s, *sadb, *sadbsize);
@@ -205,10 +215,7 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd,
*spd = (u_int8_t *)malloc(*spdsize);
if (!*spd) {
log_err("monitor_get_pfkey_snap: malloc()");
- /* Drain input */
- ioctl(m_state.s, FIONBIO, &one);
- while (read(m_state.s, &tmp, 1) > 0);
- ioctl(m_state.s, FIONBIO, 0);
+ monitor_drain_input();
if (*sadbsize) {
memset(*sadb, 0, *sadbsize);
free(*sadb);
@@ -228,7 +235,7 @@ monitor_get_pfkey_snap(u_int8_t **sadb, u_int32_t *sadbsize, u_int8_t **spd,
}
}
- log_msg(5, "monitor_get_pfkey_snap: got %d bytes SADB, %d bytes SPD",
+ log_msg(3, "monitor_get_pfkey_snap: got %d bytes SADB, %d bytes SPD",
*sadbsize, *spdsize);
return 0;
}
diff --git a/usr.sbin/sasyncd/net.c b/usr.sbin/sasyncd/net.c
index 63b6b938038..6e4d4104327 100644
--- a/usr.sbin/sasyncd/net.c
+++ b/usr.sbin/sasyncd/net.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: net.c,v 1.6 2005/05/24 19:18:11 ho Exp $ */
+/* $OpenBSD: net.c,v 1.7 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -139,10 +139,10 @@ net_add_listener(struct sockaddr *sa)
if (getnameinfo(sa, sa->sa_len, host, sizeof host, port, sizeof port,
NI_NUMERICHOST | NI_NUMERICSERV))
- log_msg(2, "listening on port %u fd %d", cfgstate.listen_port,
+ log_msg(3, "listening on port %u fd %d", cfgstate.listen_port,
s);
else
- log_msg(2, "listening on %s port %s fd %d", host, port, s);
+ log_msg(3, "listening on %s port %s fd %d", host, port, s);
return s;
}
@@ -538,7 +538,7 @@ net_handle_messages(fd_set *fds)
if (!msg)
continue;
- log_msg(4, "net_handle_messages: got msg type %u len %u from "
+ log_msg(5, "net_handle_messages: got msg type %u len %u from "
"peer %s", msgtype, msglen, p->name);
switch (msgtype) {
@@ -588,7 +588,7 @@ net_send_messages(fd_set *fds)
}
m = qm->msg;
- log_msg(4, "net_send_messages: msg %p len %d ref %d "
+ log_msg(5, "net_send_messages: msg %p len %d ref %d "
"to peer %s", m, m->len, m->refcnt, p->name);
/* write message */
@@ -607,7 +607,7 @@ net_send_messages(fd_set *fds)
free(qm);
if (--m->refcnt < 1) {
- log_msg(4, "net_send_messages: freeing msg %p", m);
+ log_msg(5, "net_send_messages: freeing msg %p", m);
free(m->buf);
free(m);
}
diff --git a/usr.sbin/sasyncd/net_ctl.c b/usr.sbin/sasyncd/net_ctl.c
index 17d169506f3..820551b4cad 100644
--- a/usr.sbin/sasyncd/net_ctl.c
+++ b/usr.sbin/sasyncd/net_ctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: net_ctl.c,v 1.5 2005/05/24 19:17:07 ho Exp $ */
+/* $OpenBSD: net_ctl.c,v 1.6 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -92,7 +92,7 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
switch (ntohl(ctl->type)) {
case CTL_STATE:
- log_msg(5, "net_ctl: got CTL_STATE from peer \"%s\"", p->name);
+ log_msg(4, "net_ctl: got CTL_STATE from peer \"%s\"", p->name);
nstate = (enum RUNSTATE)ntohl(ctl->data);
if (net_ctl_check_state(p, nstate) == 0)
net_ctl_send_ack(p, CTL_STATE, cfgstate.runstate);
@@ -124,7 +124,7 @@ net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
ct = "<unknown>";
else
ct = ctltype[ctype];
- log_msg(5, "net_ctl: got %s ACK from peer \"%s\"", ct,
+ log_msg(4, "net_ctl: got %s ACK from peer \"%s\"", ct,
p->name);
if (ctype == CTL_STATE) {
nstate = (enum RUNSTATE)ntohl(ctl->data2);
@@ -189,7 +189,7 @@ net_ctl_update_state(void)
for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
if (p->socket == -1)
continue;
- log_msg(3, "net_ctl: sending my state %s to peer \"%s\"",
+ log_msg(4, "net_ctl: sending my state %s to peer \"%s\"",
carpstate[cfgstate.runstate], p->name);
net_ctl_send_state(p);
}
diff --git a/usr.sbin/sasyncd/pfkey.c b/usr.sbin/sasyncd/pfkey.c
index f1955a436ae..4e29c4ee8c6 100644
--- a/usr.sbin/sasyncd/pfkey.c
+++ b/usr.sbin/sasyncd/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.8 2005/05/26 05:34:17 ho Exp $ */
+/* $OpenBSD: pfkey.c,v 1.9 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -46,6 +46,7 @@
#include <unistd.h>
#include "sasyncd.h"
+#include "net.h"
struct pfkey_msg
{
@@ -101,6 +102,28 @@ pfkey_set_promisc(void)
return pfkey_write((u_int8_t *)&msg, sizeof msg);
}
+/* Send a SADB_FLUSH PFKEY message to peer 'p' */
+static void
+pfkey_send_flush(struct syncpeer *p)
+{
+ struct sadb_msg *m = (struct sadb_msg *)calloc(1, sizeof *m);
+ static u_int32_t seq = 1;
+
+ if (m) {
+ memset(m, 0, sizeof *m);
+ m->sadb_msg_version = PF_KEY_V2;
+ m->sadb_msg_seq = seq++;
+ m->sadb_msg_type = SADB_FLUSH;
+ m->sadb_msg_satype = SADB_SATYPE_UNSPEC;
+ m->sadb_msg_pid = getpid();
+ m->sadb_msg_len = sizeof *m / CHUNK;
+
+ log_msg(3, "pfkey_send_flush: sending FLUSH to peer %s",
+ p->name);
+ net_queue(p, MSG_PFKEYDATA, (u_int8_t *)m, sizeof *m);
+ }
+}
+
static const char *
pfkey_print_type(struct sadb_msg *msg)
{
@@ -148,6 +171,12 @@ pfkey_handle_message(struct sadb_msg *m)
return 0;
}
+ if (msg->sadb_msg_type == SADB_FLUSH &&
+ cfgstate.flushmode == FM_NEVER) {
+ free(m);
+ return 0;
+ }
+
switch (msg->sadb_msg_type) {
case SADB_X_PROMISC:
case SADB_DUMP:
@@ -329,9 +358,13 @@ pfkey_snapshot(void *v)
return;
}
+ /* XXX needs moving if snapshot is called more than once per peer */
+ if (cfgstate.flushmode == FM_STARTUP)
+ pfkey_send_flush(p);
+
/* Parse SADB data */
if (sadbsz && sadb) {
- dump_buf(5, sadb, sadbsz, "pfkey_snapshot: SADB data");
+ dump_buf(3, sadb, sadbsz, "pfkey_snapshot: SADB data");
max = sadb + sadbsz;
for (next = sadb; next < max;
next += m->sadb_msg_len * CHUNK) {
@@ -342,25 +375,25 @@ pfkey_snapshot(void *v)
/* Tweak and send this SA to the peer. */
m->sadb_msg_type = SADB_ADD;
- /* XXX Locate lifetime_cur ext and zero bytes */
-
/* Allocate msgbuffer, net_queue() will free it. */
sendbuf = (u_int8_t *)malloc(m->sadb_msg_len * CHUNK);
if (sendbuf) {
memcpy(sendbuf, m, m->sadb_msg_len * CHUNK);
net_queue(p, MSG_PFKEYDATA, sendbuf,
m->sadb_msg_len * CHUNK);
+ log_msg(3, "pfkey_snapshot: sync SA %p to"
+ "peer %s", m, p->name);
}
}
memset(sadb, 0, sadbsz);
free(sadb);
}
-#ifdef notyet
/* Parse SPD data */
if (spdsz && spd) {
+#ifdef notyet
struct ipsec_policy *ip;
- dump_buf(5, spd, spdsz, "pfkey_snapshot: SPD data");
+ dump_buf(3, spd, spdsz, "pfkey_snapshot: SPD data");
max = spd + spdsz;
for (next = spd; next < max;
@@ -370,11 +403,11 @@ pfkey_snapshot(void *v)
continue;
/* XXX incomplete */
}
+#endif
/* Cleanup. */
memset(spd, 0, spdsz);
free(spd);
}
-#endif
return;
}
diff --git a/usr.sbin/sasyncd/sasyncd.h b/usr.sbin/sasyncd/sasyncd.h
index 7409cfff715..f99384a9346 100644
--- a/usr.sbin/sasyncd/sasyncd.h
+++ b/usr.sbin/sasyncd/sasyncd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sasyncd.h,v 1.6 2005/05/24 19:18:11 ho Exp $ */
+/* $OpenBSD: sasyncd.h,v 1.7 2005/05/26 19:19:51 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -35,6 +35,9 @@
enum RUNSTATE { INIT = 0, SLAVE, MASTER, FAIL };
#define CARPSTATES { "INIT", "SLAVE", "MASTER", "FAIL" }
+enum FLUSHMODE { FM_STARTUP = 0, FM_NEVER, FM_SYNC };
+#define FLUSHMODES { "STARTUP", "NEVER", "SYNC" };
+
struct syncpeer;
struct timeval;
@@ -43,6 +46,7 @@ struct cfgstate {
enum RUNSTATE lockedstate;
int debug;
int verboselevel;
+ enum FLUSHMODE flushmode;
char *carp_ifname;
int carp_check_interval;
@@ -88,6 +92,16 @@ void carp_check_state(void);
int carp_init(void);
/* log.c */
+/*
+ * Log levels for log_msg(level, ...) roughly means:
+ * 0 = errors and other important messages
+ * 1 = state changes, ctl message errors and dis-/connecting peers
+ * 2 = configuration and initialization messages
+ * 3 = PF_KEY logging
+ * 4 = misc network
+ * 5 = crypto
+ * 6 = timers
+ */
void log_init(char *);
void log_msg(int, const char *, ...);
void log_err(const char *, ...);