summaryrefslogtreecommitdiff
path: root/usr.sbin/sasyncd/net_ctl.c
diff options
context:
space:
mode:
authorHakan Olsson <ho@cvs.openbsd.org>2005-03-30 18:44:50 +0000
committerHakan Olsson <ho@cvs.openbsd.org>2005-03-30 18:44:50 +0000
commit1e42720c7d8b17ab1489a1fac2f86ba12229ccf1 (patch)
treea6dc00bfa0b4344cecdbd733263eee02a88b53ec /usr.sbin/sasyncd/net_ctl.c
parentc2c1ef90c70e5f9accfa8a65b07648fae651be03 (diff)
Move sasyncd(8), for IPsec SA synchronization, in-tree. Work in progress.
deraadt@ ok.
Diffstat (limited to 'usr.sbin/sasyncd/net_ctl.c')
-rw-r--r--usr.sbin/sasyncd/net_ctl.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/usr.sbin/sasyncd/net_ctl.c b/usr.sbin/sasyncd/net_ctl.c
new file mode 100644
index 00000000000..97cabfa97f4
--- /dev/null
+++ b/usr.sbin/sasyncd/net_ctl.c
@@ -0,0 +1,197 @@
+/* $OpenBSD: net_ctl.c,v 1.1 2005/03/30 18:44:49 ho Exp $ */
+
+/*
+ * Copyright (c) 2005 Håkan Olsson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This code was written under funding by Multicom Security AB.
+ */
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "sasyncd.h"
+#include "net.h"
+
+struct ctlmsg {
+ u_int32_t type;
+ u_int32_t data;
+ u_int32_t data2;
+};
+
+int listen_socket;
+
+static int
+net_ctl_check_state(struct syncpeer *p, enum RUNSTATE nstate)
+{
+ static char *runstate[] = CARPSTATES;
+
+ if (nstate < INIT || nstate > FAIL) {
+ log_msg(0, "got bad state %d from peer \"%s\"", nstate,
+ p->name);
+ net_ctl_send_error(p, CTL_STATE);
+ return -1;
+ }
+ if (cfgstate.runstate == MASTER &&
+ nstate == MASTER) {
+ log_msg(0, "got bad state MASTER from peer \"%s\"",
+ p->name);
+ net_ctl_send_error(p, CTL_STATE);
+ return -1;
+ }
+ if (p->runstate != nstate) {
+ p->runstate = nstate;
+ log_msg(1, "peer \"%s\" state change to %s", p->name,
+ runstate[nstate]);
+ }
+ return 0;
+}
+
+void
+net_ctl_handle_msg(struct syncpeer *p, u_int8_t *msg, u_int32_t msglen)
+{
+ struct ctlmsg *ctl = (struct ctlmsg *)msg;
+ enum RUNSTATE nstate;
+ enum CTLTYPE ctype;
+ static char *ct, *ctltype[] = CTLTYPES;
+
+ if (msglen < sizeof *ctl) {
+ log_msg(0, "got invalid control message from peer \"%s\"",
+ p->name);
+ net_ctl_send_error(p, CTL_UNKNOWN);
+ return;
+ }
+
+ switch (ntohl(ctl->type)) {
+ case CTL_STATE:
+ log_msg(3, "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);
+ break;
+
+ case CTL_ERROR:
+ log_msg(1, "got ERROR from peer \"%s\"", p->name);
+
+ switch (ntohl(ctl->data)) {
+ case RESERVED: /* PFKEY -- nothing to do here for now */
+ break;
+
+ case CTL_STATE:
+ nstate = cfgstate.runstate;
+ carp_check_state();
+ if (nstate != cfgstate.runstate)
+ net_ctl_send_state(p);
+ break;
+
+ case CTL_UNKNOWN:
+ default:
+ break;
+ }
+ break;
+
+ case CTL_ACK:
+ ctype = (enum CTLTYPE)ntohl(ctl->data);
+ if (ctype < RESERVED || ctype > CTL_UNKNOWN)
+ ct = "<unknown>";
+ else
+ ct = ctltype[ctype];
+ log_msg(3, "got %s ACK from peer \"%s\"", ct, p->name);
+ if (ctype == CTL_STATE) {
+ nstate = (enum RUNSTATE)ntohl(ctl->data2);
+ net_ctl_check_state(p, nstate);
+ }
+ break;
+
+ case CTL_UNKNOWN:
+ default:
+ log_msg(1, "got unknown msg type %u from peer \"%s\"",
+ ntohl(ctl->type), p->name);
+ break;
+ }
+}
+
+static int
+net_ctl_send(struct syncpeer *p, u_int32_t type, u_int32_t d, u_int32_t d2)
+{
+ struct ctlmsg *m = (struct ctlmsg *)malloc(sizeof *m);
+
+ if (!m) {
+ log_err("malloc(%u)", sizeof *m);
+ return -1;
+ }
+
+ memset(m, 0, sizeof *m);
+ m->type = htonl(type);
+ m->data = htonl(d);
+ m->data2 = htonl(d2);
+
+ return net_queue(p, MSG_SYNCCTL, (u_int8_t *)m, 0, sizeof *m);
+}
+
+int
+net_ctl_send_ack(struct syncpeer *p, enum CTLTYPE prevtype, u_int32_t code)
+{
+ return net_ctl_send(p, CTL_ACK, (u_int32_t)prevtype, code);
+}
+
+int
+net_ctl_send_state(struct syncpeer *p)
+{
+ return net_ctl_send(p, CTL_STATE, (u_int32_t)cfgstate.runstate, 0);
+}
+
+int
+net_ctl_send_error(struct syncpeer *p, enum CTLTYPE prevtype)
+{
+ return net_ctl_send(p, CTL_ERROR, (u_int32_t)prevtype, 0);
+}
+
+/* After a CARP tracker state change, send an state ctl msg to all peers. */
+void
+net_ctl_update_state(void)
+{
+ struct syncpeer *p;
+ static char *carpstate[] = CARPSTATES;
+
+ /* We may have new peers available. */
+ net_connect_peers();
+
+ for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
+ if (p->socket == -1)
+ continue;
+ log_msg(2, "sending my state %s to peer \"%s\"",
+ carpstate[cfgstate.runstate], p->name);
+ net_ctl_send_state(p);
+ }
+}