summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/sasyncd/conf.y83
-rw-r--r--usr.sbin/sasyncd/net.c405
-rw-r--r--usr.sbin/sasyncd/sasyncd.conf.536
-rw-r--r--usr.sbin/sasyncd/sasyncd.h3
4 files changed, 328 insertions, 199 deletions
diff --git a/usr.sbin/sasyncd/conf.y b/usr.sbin/sasyncd/conf.y
index b9ddc7a965d..1ae00cf5879 100644
--- a/usr.sbin/sasyncd/conf.y
+++ b/usr.sbin/sasyncd/conf.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.y,v 1.2 2005/05/22 20:35:48 ho Exp $ */
+/* $OpenBSD: conf.y,v 1.3 2005/05/24 19:18:10 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -29,6 +29,7 @@
%{
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/socket.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
@@ -40,10 +41,10 @@
#include "net.h"
/* Global configuration context. */
-struct cfgstate cfgstate;
+struct cfgstate cfgstate;
-struct syncpeer *peer;
-int conflen = 0;
+/* Local variables */
+int conflen = 0;
char *confbuf, *confptr;
int yyparse(void);
@@ -57,9 +58,10 @@ void yyerror(const char *);
}
%token MODE CARP INTERFACE INTERVAL LISTEN ON PORT PEER SHAREDKEY
-%token Y_SLAVE Y_MASTER
+%token Y_SLAVE Y_MASTER INET INET6
%token <string> STRING
-%token <val> VALUE
+%token <val> VALUE
+%type <val> af port interval mode
%%
/* Rules */
@@ -68,21 +70,37 @@ settings : /* empty */
| settings setting
;
-setting : CARP INTERFACE STRING
+af : /* empty */ { $$ = AF_UNSPEC; }
+ | INET { $$ = AF_INET; }
+ | INET6 { $$ = AF_INET6; }
+ ;
+
+port : /* empty */ { $$ = SASYNCD_DEFAULT_PORT; }
+ | PORT VALUE { $$ = $2; }
+ ;
+
+mode : MODE Y_MASTER { $$ = MASTER; }
+ | MODE Y_SLAVE { $$ = SLAVE; }
+ ;
+
+interval : /* empty */ { $$ = CARP_DEFAULT_INTERVAL; }
+ | INTERVAL VALUE { $$ = $2; }
+ ;
+
+setting : CARP INTERFACE STRING interval
{
if (cfgstate.carp_ifname)
free(cfgstate.carp_ifname);
cfgstate.carp_ifname = $3;
- log_msg(2, "config: carp interface %s", $3);
- }
- | CARP INTERVAL VALUE
- {
- cfgstate.carp_check_interval = $3;
- log_msg(2, "config: carp interval %d", $3);
+ cfgstate.carp_check_interval = $4;
+ log_msg(2, "config: carp interface %s interval %d",
+ $3, $4);
}
| PEER STRING
{
- int dup = 0;
+ struct syncpeer *peer;
+ int dup = 0;
+
for (peer = LIST_FIRST(&cfgstate.peerlist); peer;
peer = LIST_NEXT(peer, link))
if (strcmp($2, peer->name) == 0) {
@@ -104,34 +122,33 @@ setting : CARP INTERFACE STRING
LIST_INSERT_HEAD(&cfgstate.peerlist, peer, link);
log_msg(2, "config: add peer %s", peer->name);
}
- | LISTEN ON STRING
+ | LISTEN ON STRING af port
{
+ char pstr[20];
+
if (cfgstate.listen_on)
free(cfgstate.listen_on);
cfgstate.listen_on = $3;
- log_msg(2, "config: listen on %s", cfgstate.listen_on);
- }
- | LISTEN PORT VALUE
- {
- cfgstate.listen_port = $3;
+ cfgstate.listen_family = $4;
+ cfgstate.listen_port = $5;
if (cfgstate.listen_port < 1 ||
cfgstate.listen_port > 65534) {
cfgstate.listen_port = SASYNCD_DEFAULT_PORT;
log_msg(0, "config: bad port, listen-port "
"reset to %u", SASYNCD_DEFAULT_PORT);
- } else
- log_msg(2, "config: listen port %u",
- cfgstate.listen_port);
- }
- | MODE Y_MASTER
- {
- cfgstate.lockedstate = MASTER;
- log_msg(2, "config: mode set to MASTER");
+ }
+ if ($5 != SASYNCD_DEFAULT_PORT)
+ snprintf(pstr, sizeof pstr, "port %d",$5);
+ log_msg(2, "config: listen on %s %s%s",
+ cfgstate.listen_on, $4 == AF_INET6 ? "(IPv6) " :
+ ($4 == AF_INET ? "(IPv4) " : ""),
+ $5 != SASYNCD_DEFAULT_PORT ? pstr : "");
}
- | MODE Y_SLAVE
+ | mode
{
- cfgstate.lockedstate = SLAVE;
- log_msg(2, "config: mode set to SLAVE");
+ cfgstate.lockedstate = $1;
+ log_msg(2, "config: mode set to %s",
+ $1 == MASTER ? "MASTER" : "SLAVE");
}
| SHAREDKEY STRING
{
@@ -162,6 +179,8 @@ match(char *token)
/* Sorted */
static const struct keyword keywords[] = {
{ "carp", CARP },
+ { "inet", INET },
+ { "inet6", INET6 },
{ "interface", INTERFACE },
{ "interval", INTERVAL },
{ "listen", LISTEN },
@@ -209,7 +228,7 @@ yylex(void)
yylval.val = v;
return VALUE;
}
-
+
is_string:
v = match(confptr);
if (v == STRING) {
diff --git a/usr.sbin/sasyncd/net.c b/usr.sbin/sasyncd/net.c
index 71812e2735b..63b6b938038 100644
--- a/usr.sbin/sasyncd/net.c
+++ b/usr.sbin/sasyncd/net.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: net.c,v 1.5 2005/05/24 02:35:39 ho Exp $ */
+/* $OpenBSD: net.c,v 1.6 2005/05/24 19:18:11 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 <sys/socket.h>
#include <sys/time.h>
@@ -61,7 +60,7 @@ struct qmsg {
struct msg *msg;
};
-int listen_socket;
+int *listeners;
AES_KEY aes_key[2];
#define AES_IV_LEN AES_BLOCK_SIZE
@@ -88,7 +87,7 @@ dump_buf(int lvl, u_int8_t *b, u_int32_t len, char *title)
blen = 2 * (len + len / 36) + 3 + (title ? strlen(title) : sizeof def);
if (!(buf = (u_int8_t *)calloc(1, blen)))
return;
-
+
snprintf(buf, blen, "%s\n ", title ? title : def);
off = strlen(buf);
for (i = 0; i < len; i++, off+=2) {
@@ -102,69 +101,193 @@ dump_buf(int lvl, u_int8_t *b, u_int32_t len, char *title)
free(buf);
}
-int
-net_init(void)
+/* Add a listening socket. */
+static int
+net_add_listener(struct sockaddr *sa)
{
- struct sockaddr_storage sa_storage;
- struct sockaddr *sa = (struct sockaddr *)&sa_storage;
- struct syncpeer *p;
- char host[NI_MAXHOST], port[NI_MAXSERV];
- int r;
+ char host[NI_MAXHOST], port[NI_MAXSERV];
+ int r, s;
- /* The shared key needs to be 128, 192 or 256 bits */
- r = strlen(cfgstate.sharedkey) << 3;
- if (r != 128 && r != 192 && r != 256) {
- fprintf(stderr, "Bad shared key length (%d bits), "
- "should be 128, 192 or 256\n", r);
+ s = socket(sa->sa_family, SOCK_STREAM, 0);
+ if (s < 0) {
+ perror("net_add_listener: socket()");
+ close(s);
return -1;
}
-
- if (AES_set_encrypt_key(cfgstate.sharedkey, r, &aes_key[0]) ||
- AES_set_decrypt_key(cfgstate.sharedkey, r, &aes_key[1])) {
- fprintf(stderr, "Bad AES shared key\n");
+
+ r = 1;
+ if (setsockopt(s, SOL_SOCKET,
+ cfgstate.listen_on ? SO_REUSEADDR : SO_REUSEPORT, (void *)&r,
+ sizeof r)) {
+ perror("net_add_listener: setsockopt()");
+ close(s);
return -1;
}
- /* Setup listening socket. */
+ if (bind(s, sa, sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) :
+ sizeof (struct sockaddr_in6))) {
+ perror("net_add_listener: bind()");
+ close(s);
+ return -1;
+ }
+
+ if (listen(s, 3)) {
+ perror("net_add_listener: listen()");
+ close(s);
+ return -1;
+ }
+
+ 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,
+ s);
+ else
+ log_msg(2, "listening on %s port %s fd %d", host, port, s);
+
+ return s;
+}
+
+/* Allocate and fill in listeners array. */
+static int
+net_setup_listeners(void)
+{
+ struct sockaddr_storage sa_storage;
+ struct sockaddr *sa = (struct sockaddr *)&sa_storage;
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ struct ifaddrs *ifap = 0, *ifa;
+ int i, count;
+
+ /* Setup listening sockets. */
memset(&sa_storage, 0, sizeof sa_storage);
- if (net_set_sa(sa, cfgstate.listen_on, cfgstate.listen_port)) {
- log_msg(0, "net_init: could not find listen address (%s)",
- cfgstate.listen_on);
+ if (net_set_sa(sa, cfgstate.listen_on, cfgstate.listen_port) == 0) {
+ listeners = (int *)calloc(2, sizeof(int));
+ if (!listeners) {
+ perror("net_setup_listeners: calloc()");
+ return -1;
+ }
+ listeners[1] = -1;
+ listeners[0] = net_add_listener(sa);
+ if (listeners[0] == -1) {
+ log_msg(0, "net_setup_listeners: could not find "
+ "listen address (%s)", cfgstate.listen_on);
+ goto errout;
+ }
+ return 0;
+ }
+
+ /*
+ * If net_set_sa() failed, cfgstate.listen_on is probably an
+ * interface name, so we should listen on all it's addresses.
+ */
+
+ if (getifaddrs(&ifap) != 0) {
+ perror("net_setup_listeners: getifaddrs()");
return -1;
}
- listen_socket = socket(sa->sa_family, SOCK_STREAM, 0);
- if (listen_socket < 0) {
- perror("socket()");
- close(listen_socket);
+ /* How many addresses matches? */
+ for (count = 0, ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_name || !ifa->ifa_addr ||
+ (ifa->ifa_addr->sa_family != AF_INET &&
+ ifa->ifa_addr->sa_family != AF_INET6))
+ continue;
+ if (cfgstate.listen_family &&
+ cfgstate.listen_family != ifa->ifa_addr->sa_family)
+ continue;
+ if (strcmp(ifa->ifa_name, cfgstate.listen_on) != 0)
+ continue;
+ count++;
+ }
+
+ if (!count) {
+ log_msg(0, "net_setup_listeners: no listeners found for %s",
+ cfgstate.listen_on);
return -1;
}
- r = 1;
- if (setsockopt(listen_socket, SOL_SOCKET,
- cfgstate.listen_on ? SO_REUSEADDR : SO_REUSEPORT, (void *)&r,
- sizeof r)) {
- perror("setsockopt()");
- close(listen_socket);
+
+ /* Allocate one extra slot and set to -1, marking end of array. */
+ listeners = (int *)calloc(count + 1, sizeof(int));
+ if (!listeners) {
+ perror("net_setup_listeners: calloc()");
return -1;
}
- if (bind(listen_socket, sa, sizeof(struct sockaddr_in))) {
- perror("bind()");
- close(listen_socket);
+ for (i = 0; i <= count; i++)
+ listeners[i] = -1;
+
+ /* Create listening sockets */
+ for (count = 0, ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_name || !ifa->ifa_addr ||
+ (ifa->ifa_addr->sa_family != AF_INET &&
+ ifa->ifa_addr->sa_family != AF_INET6))
+ continue;
+ if (cfgstate.listen_family &&
+ cfgstate.listen_family != ifa->ifa_addr->sa_family)
+ continue;
+ if (strcmp(ifa->ifa_name, cfgstate.listen_on) != 0)
+ continue;
+
+ memset(&sa_storage, 0, sizeof sa_storage);
+ sa->sa_family = ifa->ifa_addr->sa_family;
+ switch (sa->sa_family) {
+ case AF_INET:
+ sin->sin_port = htons(cfgstate.listen_port);
+ sin->sin_len = sizeof *sin;
+ memcpy(&sin->sin_addr,
+ &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
+ sizeof sin->sin_addr);
+ break;
+ case AF_INET6:
+ sin6->sin6_port = htons(cfgstate.listen_port);
+ sin6->sin6_len = sizeof *sin6;
+ memcpy(&sin6->sin6_addr,
+ &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
+ sizeof sin6->sin6_addr);
+ break;
+ }
+
+ listeners[count] = net_add_listener(sa);
+ if (listeners[count] == -1) {
+ log_msg(4, "net_setup_listeners(setup): failed to "
+ "add listener, count = %d", count);
+ goto errout;
+ }
+ count++;
+ }
+ freeifaddrs(ifap);
+ return 0;
+
+ errout:
+ if (ifap)
+ freeifaddrs(ifap);
+ for (i = 0; listeners[i] != -1; i++)
+ close(listeners[i]);
+ free(listeners);
+ return -1;
+}
+
+int
+net_init(void)
+{
+ struct syncpeer *p;
+ int r;
+
+ /* The shared key needs to be 128, 192 or 256 bits */
+ r = strlen(cfgstate.sharedkey) << 3;
+ if (r != 128 && r != 192 && r != 256) {
+ fprintf(stderr, "Bad shared key length (%d bits), "
+ "should be 128, 192 or 256\n", r);
return -1;
}
- if (listen(listen_socket, 10)) {
- perror("listen()");
- close(listen_socket);
+
+ if (AES_set_encrypt_key(cfgstate.sharedkey, r, &aes_key[0]) ||
+ AES_set_decrypt_key(cfgstate.sharedkey, r, &aes_key[1])) {
+ fprintf(stderr, "Bad AES shared key\n");
return -1;
}
- 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,
- listen_socket);
- else
- log_msg(2, "listening on %s port %s fd %d", host, port,
- listen_socket);
+ if (net_setup_listeners())
+ return -1;
for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
p->socket = -1;
@@ -185,7 +308,7 @@ net_enqueue(struct syncpeer *p, struct msg *m)
qm = (struct qmsg *)malloc(sizeof *qm);
if (!qm) {
- log_err("malloc()");
+ log_err("net_enqueue: malloc()");
return;
}
@@ -214,7 +337,7 @@ net_queue(struct syncpeer *p0, u_int32_t msgtype, u_int8_t *buf, u_int32_t len)
m = (struct msg *)calloc(1, sizeof *m);
if (!m) {
- log_err("calloc()");
+ log_err("net_queue: calloc()");
free(buf);
return -1;
}
@@ -323,7 +446,7 @@ int
net_set_rfds(fd_set *fds)
{
struct syncpeer *p;
- int max_fd = -1;
+ int i, max_fd = -1;
for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
if (p->socket > -1)
@@ -331,73 +454,82 @@ net_set_rfds(fd_set *fds)
if (p->socket > max_fd)
max_fd = p->socket;
}
- FD_SET(listen_socket, fds);
- if (listen_socket > max_fd)
- max_fd = listen_socket;
+ for (i = 0; listeners[i] != -1; i++) {
+ FD_SET(listeners[i], fds);
+ if (listeners[i] > max_fd)
+ max_fd = listeners[i];
+ }
return max_fd + 1;
}
+static void
+net_accept(int accept_socket)
+{
+ struct sockaddr_storage sa_storage, sa_storage2;
+ struct sockaddr *sa = (struct sockaddr *)&sa_storage;
+ struct sockaddr *sa2 = (struct sockaddr *)&sa_storage2;
+ struct sockaddr_in *sin, *sin2;
+ struct sockaddr_in6 *sin6, *sin62;
+ struct syncpeer *p;
+ socklen_t socklen;
+ int s, found;
+
+ /* Accept a new incoming connection */
+ socklen = sizeof sa_storage;
+ memset(&sa_storage, 0, socklen);
+ memset(&sa_storage2, 0, socklen);
+ s = accept(accept_socket, sa, &socklen);
+ if (s > -1) {
+ /* Setup the syncpeer structure */
+ found = 0;
+ for (p = LIST_FIRST(&cfgstate.peerlist); p && !found;
+ p = LIST_NEXT(p, link)) {
+
+ /* Match? */
+ if (net_set_sa(sa2, p->name, 0))
+ continue;
+ if (sa->sa_family != sa2->sa_family)
+ continue;
+ if (sa->sa_family == AF_INET) {
+ sin = (struct sockaddr_in *)sa;
+ sin2 = (struct sockaddr_in *)sa2;
+ if (memcmp(&sin->sin_addr, &sin2->sin_addr,
+ sizeof(struct in_addr)))
+ continue;
+ } else {
+ sin6 = (struct sockaddr_in6 *)sa;
+ sin62 = (struct sockaddr_in6 *)sa2;
+ if (memcmp(&sin6->sin6_addr, &sin62->sin6_addr,
+ sizeof(struct in6_addr)))
+ continue;
+ }
+ /* Match! */
+ found++;
+ p->socket = s;
+ log_msg(1, "net: peer \"%s\" connected", p->name);
+ if (cfgstate.runstate == MASTER)
+ timer_add("pfkey_snap", 2, pfkey_snapshot, p);
+ }
+ if (!found) {
+ log_msg(1, "net: found no matching peer for accepted "
+ "socket, closing.");
+ close(s);
+ }
+ } else
+ log_err("net: accept()");
+}
+
void
net_handle_messages(fd_set *fds)
{
- struct sockaddr_storage sa_storage, sa_storage2;
- struct sockaddr *sa = (struct sockaddr *)&sa_storage;
- struct sockaddr *sa2 = (struct sockaddr *)&sa_storage2;
- socklen_t socklen;
struct syncpeer *p;
u_int8_t *msg;
u_int32_t msgtype, msglen;
- int newsock, found;
-
- if (FD_ISSET(listen_socket, fds)) {
- /* Accept a new incoming connection */
- socklen = sizeof sa_storage;
- newsock = accept(listen_socket, sa, &socklen);
- if (newsock > -1) {
- /* Setup the syncpeer structure */
- found = 0;
- for (p = LIST_FIRST(&cfgstate.peerlist); p && !found;
- p = LIST_NEXT(p, link)) {
- struct sockaddr_in *sin, *sin2;
- struct sockaddr_in6 *sin6, *sin62;
-
- /* Match? */
- if (net_set_sa(sa2, p->name, 0))
- continue;
- if (sa->sa_family != sa2->sa_family)
- continue;
- if (sa->sa_family == AF_INET) {
- sin = (struct sockaddr_in *)sa;
- sin2 = (struct sockaddr_in *)sa2;
- if (memcmp(&sin->sin_addr,
- &sin2->sin_addr,
- sizeof(struct in_addr)))
- continue;
- } else {
- sin6 = (struct sockaddr_in6 *)sa;
- sin62 = (struct sockaddr_in6 *)sa2;
- if (memcmp(&sin6->sin6_addr,
- &sin62->sin6_addr,
- sizeof(struct in6_addr)))
- continue;
- }
- /* Match! */
- found++;
- p->socket = newsock;
- log_msg(1, "net: peer \"%s\" connected",
- p->name);
- if (cfgstate.runstate == MASTER)
- timer_add("pfkey_snapshot", 2,
- pfkey_snapshot, p);
- }
- if (!found) {
- log_msg(1, "net: found no matching peer for "
- "accepted socket, closing.");
- close(newsock);
- }
- } else
- log_err("accept()");
- }
+ int i;
+
+ for (i = 0; listeners[i] != -1; i++)
+ if (FD_ISSET(listeners[i], fds))
+ net_accept(listeners[i]);
for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) {
if (p->socket < 0 || !FD_ISSET(p->socket, fds))
@@ -500,6 +632,7 @@ net_shutdown(void)
struct syncpeer *p;
struct qmsg *qm;
struct msg *m;
+ int i;
while ((p = LIST_FIRST(&cfgstate.peerlist))) {
while ((qm = SIMPLEQ_FIRST(&p->msgs))) {
@@ -518,8 +651,12 @@ net_shutdown(void)
free(p);
}
- if (listen_socket > -1)
- close(listen_socket);
+ if (listeners) {
+ for (i = 0; listeners[i] != -1; i++)
+ close(listeners[i]);
+ free(listeners);
+ listeners = 0;
+ }
}
/*
@@ -541,7 +678,7 @@ net_read(struct syncpeer *p, u_int32_t *msgtype, u_int32_t *msglen)
net_disconnect_peer(p);
return NULL;
}
-
+
blob_len = ntohl(v);
if (blob_len < sizeof hash + AES_IV_LEN + 2 * sizeof(u_int32_t))
return NULL;
@@ -616,7 +753,6 @@ net_set_sa(struct sockaddr *sa, char *name, in_port_t port)
{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
- struct ifaddrs *ifap, *ifa;
if (!name) {
/* XXX Assume IPv4 */
@@ -632,7 +768,7 @@ net_set_sa(struct sockaddr *sa, char *name, in_port_t port)
sin->sin_len = sizeof *sin;
return 0;
}
-
+
if (inet_pton(AF_INET6, name, &sin6->sin6_addr) == 1) {
sa->sa_family = AF_INET6;
sin6->sin6_port = htons(port);
@@ -640,47 +776,8 @@ net_set_sa(struct sockaddr *sa, char *name, in_port_t port)
return 0;
}
- /* inet_pton failed. fail here if name is not cfgstate.listen_on */
- if (strcmp(cfgstate.listen_on, name) != 0)
- return -1;
-
- /* Is cfgstate.listen_on the name of one our interfaces? */
- if (getifaddrs(&ifap) != 0) {
- perror("getifaddrs()");
- return -1;
- }
- sa->sa_family = AF_UNSPEC;
- for (ifa = ifap; ifa && sa->sa_family == AF_UNSPEC;
- ifa = ifa->ifa_next) {
- if (!ifa->ifa_name || !ifa->ifa_addr)
- continue;
- if (strcmp(ifa->ifa_name, name) != 0)
- continue;
-
- switch (ifa->ifa_addr->sa_family) {
- case AF_INET:
- sa->sa_family = AF_INET;
- sin->sin_port = htons(port);
- sin->sin_len = sizeof *sin;
- memcpy(&sin->sin_addr,
- &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
- sizeof sin->sin_addr);
- break;
-
- case AF_INET6:
- sa->sa_family = AF_INET6;
- sin6->sin6_port = htons(port);
- sin6->sin6_len = sizeof *sin6;
- memcpy(&sin6->sin6_addr,
- &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
- sizeof sin6->sin6_addr);
- break;
- }
- }
- freeifaddrs(ifap);
- return sa->sa_family == AF_UNSPEC ? -1 : 0;
+ return -1;
}
-
static void
got_sigalrm(int s)
@@ -745,7 +842,5 @@ static void
net_check_peers(void *arg)
{
net_connect();
-
(void)timer_add("peer recheck", 600, net_check_peers, 0);
}
-
diff --git a/usr.sbin/sasyncd/sasyncd.conf.5 b/usr.sbin/sasyncd/sasyncd.conf.5
index d12dcc9d9f4..3cc141d45ec 100644
--- a/usr.sbin/sasyncd/sasyncd.conf.5
+++ b/usr.sbin/sasyncd/sasyncd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sasyncd.conf.5,v 1.5 2005/05/23 20:45:41 jmc Exp $
+.\" $OpenBSD: sasyncd.conf.5,v 1.6 2005/05/24 19:18:11 ho Exp $
.\"
.\" Copyright (c) 2005 Håkan Olsson. All rights reserved.
.\"
@@ -58,26 +58,40 @@ pseudo user and be readable only by this owner, e.g.\&
.Pp
The following configuration settings are understood:
.Bl -tag -width Ds
-.It Ic carp interface Ar interface
+.It Xo
+.Ic carp interface
+.Ar interface Op Ic interval Ar seconds
+.Xc
Specify which
.Xr carp 4
interface
.Nm sasyncd
should track master/slave state on.
-.It Ic carp interval Ar seconds
-Specify how often the daemon should check the above interface for
-state changes.
+Optionally state how often the daemon should check the interface
+for state changes.
Defaults to once every 10 seconds.
-.It Ic listen on Ar address
+.It Xo
+.Ic listen on Ar address
+.Op Ar family
+.Op Ic port Ar port
+.Xc
Specify a local IP address, hostname, or interface the
.Xr sasyncd 8
daemon should listen on.
-The default is to listen on all local addresses.
-.It Ic listen port Ar port
-Specify a local TCP port the
+The default is to listen on all local addresses.
+When using an interface name,
+.Ar family
+may be given as
+.Dq inet
+or
+.Dq inet6
+to only bind using the specified address family.
+Finally,
+.Ar port
+can be used to specify which TCP port
.Xr sasyncd 8
-daemon should listen on.
-The default is to listen on port 500.
+should listen to.
+The default is to listen to port 500.
.It Ic mode master | slave
Force the daemon to run as master or slave.
Normally only intended for debugging use.
diff --git a/usr.sbin/sasyncd/sasyncd.h b/usr.sbin/sasyncd/sasyncd.h
index b5f21f01d1f..7409cfff715 100644
--- a/usr.sbin/sasyncd/sasyncd.h
+++ b/usr.sbin/sasyncd/sasyncd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sasyncd.h,v 1.5 2005/05/24 02:35:39 ho Exp $ */
+/* $OpenBSD: sasyncd.h,v 1.6 2005/05/24 19:18:11 ho Exp $ */
/*
* Copyright (c) 2005 Håkan Olsson. All rights reserved.
@@ -53,6 +53,7 @@ struct cfgstate {
char *listen_on;
in_port_t listen_port;
+ sa_family_t listen_family;
LIST_HEAD(, syncpeer) peerlist;
};