diff options
-rw-r--r-- | usr.bin/sndiod/listen.c | 77 | ||||
-rw-r--r-- | usr.bin/sndiod/listen.h | 6 | ||||
-rw-r--r-- | usr.bin/sndiod/sndiod.c | 11 |
3 files changed, 58 insertions, 36 deletions
diff --git a/usr.bin/sndiod/listen.c b/usr.bin/sndiod/listen.c index c67733886f7..0c47cfdff27 100644 --- a/usr.bin/sndiod/listen.c +++ b/usr.bin/sndiod/listen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: listen.c,v 1.7 2015/12/25 17:16:43 ratchov Exp $ */ +/* $OpenBSD: listen.c,v 1.8 2016/01/08 13:14:11 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -24,12 +24,10 @@ #include <netinet/tcp.h> #include <netdb.h> -#include <err.h> #include <errno.h> #include <fcntl.h> #include <poll.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <unistd.h> @@ -70,14 +68,16 @@ listen_close(struct listen *f) } *pf = f->next; - if (f->path != NULL) + if (f->path != NULL) { + unlink(f->path); xfree(f->path); + } file_del(f->file); close(f->fd); xfree(f); } -void +int listen_new_un(char *path) { int sock, oldumask; @@ -86,11 +86,13 @@ listen_new_un(char *path) sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { - perror("socket"); - exit(1); + log_puts(path); + log_puts(": failed to create socket\n"); + return 0; } if (unlink(path) < 0 && errno != ENOENT) { - perror("unlink"); + log_puts(path); + log_puts(": failed to unlink socket\n"); goto bad_close; } sockname.sun_family = AF_UNIX; @@ -98,11 +100,13 @@ listen_new_un(char *path) oldumask = umask(0111); if (bind(sock, (struct sockaddr *)&sockname, sizeof(struct sockaddr_un)) < 0) { - perror("bind"); + log_puts(path); + log_puts(": failed to bind socket\n"); goto bad_close; } if (listen(sock, 1) < 0) { - perror("listen"); + log_puts(path); + log_puts(": failed to listen\n"); goto bad_close; } umask(oldumask); @@ -111,20 +115,16 @@ listen_new_un(char *path) if (f->file == NULL) goto bad_close; f->path = xstrdup(path); - if (f->path == NULL) { - perror("strdup"); - exit(1); - } f->fd = sock; f->next = listen_list; listen_list = f; - return; + return 1; bad_close: close(sock); - exit(1); + return 0; } -void +int listen_new_tcp(char *addr, unsigned int port) { char *host, serv[sizeof(unsigned int) * 3 + 1]; @@ -143,8 +143,9 @@ listen_new_tcp(char *addr, unsigned int port) aihints.ai_protocol = IPPROTO_TCP; error = getaddrinfo(host, serv, &aihints, &ailist); if (error) { - fprintf(stderr, "%s: %s\n", addr, gai_strerror(error)); - exit(1); + log_puts(addr); + log_puts(": failed to resolve address\n"); + return 0; } /* @@ -154,21 +155,40 @@ listen_new_tcp(char *addr, unsigned int port) for (ai = ailist; ai != NULL; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { - perror("socket"); + log_puts(addr); + log_puts(": failed to create socket\n"); continue; } opt = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) < 0) { - perror("setsockopt"); + log_puts(addr); + log_puts(": failed to set SO_REUSEADDR\n"); goto bad_close; } + if (ai->ai_family == AF_INET6) { + /* + * make sure IPv6 sockets are restricted to IPv6 + * addresses because we already use a IP socket + * for IP addresses + */ + opt = 1; + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + &opt, sizeof(int)) < 0) { + log_puts(addr); + log_puts(": failed to set IPV6_V6ONLY\n"); + goto bad_close; + } + } + if (bind(s, ai->ai_addr, ai->ai_addrlen) < 0) { - perror("bind"); + log_puts(addr); + log_puts(": failed to bind socket\n"); goto bad_close; } if (listen(s, 1) < 0) { - perror("listen"); + log_puts(addr); + log_puts(": failed to listen\n"); goto bad_close; } f = xmalloc(sizeof(struct listen)); @@ -185,8 +205,7 @@ listen_new_tcp(char *addr, unsigned int port) n++; } freeaddrinfo(ailist); - if (n == 0) - exit(1); + return n; } int @@ -232,12 +251,11 @@ listen_in(void *arg) continue; if (errno == ENFILE || errno == EMFILE) file_slowaccept = 1; - else if (errno != ECONNABORTED && errno != EWOULDBLOCK) - perror("accept"); return; } if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { - perror("fcntl(sock, O_NONBLOCK)"); + file_log(f->file); + log_puts(": failed to set non-blocking mode\n"); close(sock); return; } @@ -245,7 +263,8 @@ listen_in(void *arg) opt = 1; if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int)) < 0) { - perror("setsockopt"); + file_log(f->file); + log_puts(": failed to set TCP_NODELAY flag\n"); close(sock); return; } diff --git a/usr.bin/sndiod/listen.h b/usr.bin/sndiod/listen.h index cfef5c4d1a7..aa434548bbb 100644 --- a/usr.bin/sndiod/listen.h +++ b/usr.bin/sndiod/listen.h @@ -1,4 +1,4 @@ -/* $OpenBSD: listen.h,v 1.2 2015/12/14 17:44:29 ratchov Exp $ */ +/* $OpenBSD: listen.h,v 1.3 2016/01/08 13:14:11 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -29,8 +29,8 @@ struct listen { extern struct listen *listen_list; -void listen_new_un(char *); -void listen_new_tcp(char *, unsigned int); +int listen_new_un(char *); +int listen_new_tcp(char *, unsigned int); int listen_init(struct listen *); void listen_close(struct listen *); diff --git a/usr.bin/sndiod/sndiod.c b/usr.bin/sndiod/sndiod.c index 7f32f5bb7ed..002385e5c3c 100644 --- a/usr.bin/sndiod/sndiod.c +++ b/usr.bin/sndiod/sndiod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sndiod.c,v 1.22 2015/12/23 20:12:18 ratchov Exp $ */ +/* $OpenBSD: sndiod.c,v 1.23 2016/01/08 13:14:11 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -520,9 +520,12 @@ main(int argc, char **argv) snprintf(path, SOCKPATH_MAX, "%s/" SOCKPATH_FILE "%u", base, unit); - listen_new_un(path); - if (tcpaddr) - listen_new_tcp(tcpaddr, AUCAT_PORT + unit); + if (!listen_new_un(path)) + return 1; + if (tcpaddr) { + if (!listen_new_tcp(tcpaddr, AUCAT_PORT + unit)) + return 1; + } for (l = listen_list; l != NULL; l = l->next) { if (!listen_init(l)) return 1; |