diff --git a/external/bsd/blacklist/bin/blacklist.h b/external/bsd/blacklist/bin/blacklist.h index 9dd953568b01..f7b05e189e1b 100644 --- a/external/bsd/blacklist/bin/blacklist.h +++ b/external/bsd/blacklist/bin/blacklist.h @@ -1,4 +1,4 @@ -/* $NetBSD: blacklist.h,v 1.1 2015/01/19 18:52:55 christos Exp $ */ +/* $NetBSD: blacklist.h,v 1.2 2015/01/19 19:02:35 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -43,6 +43,7 @@ typedef struct blacklist *bl_t; __BEGIN_DECLS bl_t bl_create(void); +int bl_getfd(bl_t); int bl_send(bl_t, bl_type_t, int, int, const char *); void bl_destroy(bl_t); diff --git a/external/bsd/blacklist/bin/blacklistd.c b/external/bsd/blacklist/bin/blacklistd.c index 883a094eaf23..30fee64f65be 100644 --- a/external/bsd/blacklist/bin/blacklistd.c +++ b/external/bsd/blacklist/bin/blacklistd.c @@ -1,6 +1,6 @@ #include -__RCSID("$NetBSD: blacklistd.c,v 1.2 2015/01/19 18:52:55 christos Exp $"); +__RCSID("$NetBSD: blacklistd.c,v 1.3 2015/01/19 19:02:35 christos Exp $"); #include #include @@ -47,7 +47,8 @@ sighup(int n) static __dead void usage(void) { - fprintf(stderr, "Usage: %s -d [-c ]\n", getprogname()); + fprintf(stderr, "Usage: %s -d [-c ] [-s ]\n", + getprogname()); exit(EXIT_FAILURE); } @@ -111,7 +112,7 @@ process(bl_t bl) rfd = bi->bi_fd[1]; rsl = sizeof(rss); if (getpeername(rfd, (void *)&rss, &rsl) == -1) { - (*bl->b_fun)(LOG_ERR, "getsockname failed (%m)"); + (*lfun)(LOG_ERR, "getsockname failed (%m)"); goto out; } sockaddr_snprintf(rbuf, sizeof(rbuf), "%a:%p", (void *)&rss); @@ -163,11 +164,11 @@ main(int argc, char *argv[]) } bl = bl_create2(true, spath, lfun); - if (bl == NULL || !bl->b_connected) + if (bl == NULL || !bl_isconnected(bl)) return EXIT_FAILURE; struct pollfd pfd; - pfd.fd = bl->b_fd; + pfd.fd = bl_getfd(bl); pfd.events = POLLIN; for (;;) { if (rconf) { diff --git a/external/bsd/blacklist/bin/conf.h b/external/bsd/blacklist/bin/conf.h index cfe7438bd9de..c32eae1155b0 100644 --- a/external/bsd/blacklist/bin/conf.h +++ b/external/bsd/blacklist/bin/conf.h @@ -1,3 +1,35 @@ +/* $NetBSD: conf.h,v 1.2 2015/01/19 19:02:35 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ +#ifndef _CONF_H +#define _CONF_H struct conf { int c_port; @@ -8,5 +40,9 @@ struct conf { int c_duration; }; +__BEGIN_DECLS void parseconf(const char *); const struct conf *findconf(bl_info_t *); +__END_DECLS + +#endif /* _CONF_H */ diff --git a/external/bsd/blacklist/bin/internal.h b/external/bsd/blacklist/bin/internal.h index 88703a748c2f..3832669c3496 100644 --- a/external/bsd/blacklist/bin/internal.h +++ b/external/bsd/blacklist/bin/internal.h @@ -1,16 +1,6 @@ +struct conf *conf; +size_t nconf; +int debug; -typedef struct { - uint32_t bl_len; - uint32_t bl_version; - uint32_t bl_type; - char bl_data[]; -} bl_message_t; - -struct blacklist { - int b_fd; - int b_connected; -}; - - -#define BL_VERSION 1 +void (*lfun)(int, const char *, ...); diff --git a/external/bsd/blacklist/include/bl.h b/external/bsd/blacklist/include/bl.h index 72b79ef9664b..f84897373600 100644 --- a/external/bsd/blacklist/include/bl.h +++ b/external/bsd/blacklist/include/bl.h @@ -1,17 +1,70 @@ +/* $NetBSD: bl.h,v 1.4 2015/01/19 18:52:55 christos Exp $ */ -#include +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ +#ifndef _BL_H +#define _BL_H -typedef enum { - BL_INVALID, - BL_ADD, -} bl_type_t; +#include "blacklist.h" + +struct sockcred; + +typedef struct { + bl_type_t bi_type; + int *bi_fd; + struct sockcred *bi_cred; + char bi_msg[1024]; +} bl_info_t; typedef struct blacklist *bl_t; -bl_t bl_create(bool); -void bl_destroy(bl_t); -int bl_send(bl_t, bl_type_t, int, int, const char *); -int bl_recv(bl_t, bl_type_t *, int *, int *, char *, size_t); +__BEGIN_DECLS +bl_t bl_create2(bool, const char *, void (*)(int, const char *, ...)); +bl_info_t *bl_recv(bl_t); +__END_DECLS #define _PATH_BLSOCK "/tmp/blsock" -#define _PATH_BLCONF "/etc/blacklist.conf" +#define _PATH_BLCONF "/etc/blacklistd/conf" + +#endif /* _BL_H */ +typedef struct { + uint32_t bl_len; + uint32_t bl_version; + uint32_t bl_type; + char bl_data[]; +} bl_message_t; + +struct blacklist { + int b_fd; + int b_connected; + const char *b_path; + void (*b_fun)(int, const char *, ...); + bl_info_t b_info; +}; +#define BL_VERSION 1 diff --git a/external/bsd/blacklist/lib/bl.c b/external/bsd/blacklist/lib/bl.c index 4c871b9bf8fd..3a1da76587a6 100644 --- a/external/bsd/blacklist/lib/bl.c +++ b/external/bsd/blacklist/lib/bl.c @@ -1,8 +1,42 @@ +/* $NetBSD: bl.c,v 1.4 2015/01/19 18:52:55 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ +#include +__RCSID("$NetBSD: bl.c,v 1.4 2015/01/19 18:52:55 christos Exp $"); + #include #include #include #include +#include #include #include #include @@ -11,23 +45,34 @@ #include #include "bl.h" -#include "internal.h" + +static void +bl_reset(bl_t b) +{ + close(b->b_fd); + b->b_fd = -1; + b->b_connected = false; +} static int bl_init(bl_t b, bool srv) { + static int one = 1; /* AF_UNIX address of local logger */ - static const struct sockaddr_un sun = { + struct sockaddr_un sun = { .sun_family = AF_LOCAL, .sun_len = sizeof(sun), - .sun_path = _PATH_BLSOCK, }; + strlcpy(sun.sun_path, b->b_path, sizeof(sun.sun_path)); + if (srv) + (void)unlink(b->b_path); if (b->b_fd == -1) { b->b_fd = socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0); if (b->b_fd == -1) { - syslog(LOG_ERR, "%s: socket failed (%m)", __func__); + (*b->b_fun)(LOG_ERR, "%s: socket failed (%m)", + __func__); return 0; } } @@ -37,63 +82,81 @@ bl_init(bl_t b, bool srv) if ((srv ? bind : connect)(b->b_fd, (const void *)&sun, (socklen_t)sizeof(sun)) == -1) { - syslog(LOG_ERR, "%s: %s failed (%m)", __func__, + (*b->b_fun)(LOG_ERR, "%s: %s failed (%m)", __func__, srv ? "bind" : "connect"); - return -1; + goto out; } + b->b_connected = true; + if (setsockopt(b->b_fd, 0, LOCAL_CREDS, + &one, sizeof(one)) == -1) { + (*b->b_fun)(LOG_ERR, "%s: setsockopt LOCAL_CREDS " + "failed (%m)", __func__); + goto out; + } + if (srv) if (listen(b->b_fd, 5) == -1) { - syslog(LOG_ERR, "%s: listen failed (%m)", __func__); - close(b->b_fd); - b->b_fd = -1; - b->b_connected = false; + (*b->b_fun)(LOG_ERR, "%s: listen failed (%m)", + __func__); + goto out; } return 0; +out: + bl_reset(b); + return -1; } bl_t -bl_create(bool srv) +bl_create2(bool srv, const char *path, void (*fun)(int, const char *, ...)) { bl_t b = malloc(sizeof(*b)); - if (b == NULL) { - syslog(LOG_ERR, "%s: malloc failed (%m)", __func__); - return NULL; - } + bl_info_t *bi; + if (b == NULL) + goto out; + bi = &b->b_info; + bi->bi_fd = malloc(2 * sizeof(int)); + if (bi->bi_fd == NULL) + goto out1; + bi->bi_cred = malloc(SOCKCREDSIZE(NGROUPS_MAX)); + if (bi->bi_cred == NULL) + goto out2; + + b->b_fun = fun == NULL ? syslog : fun; + b->b_fd = -1; + b->b_path = strdup(path ? path : _PATH_BLSOCK); + if (b->b_path == NULL) + goto out3; + b->b_connected = false; bl_init(b, srv); return b; +out3: + free(bi->bi_cred); +out2: + free(bi->bi_fd); +out1: + free(b); +out: + (*fun)(LOG_ERR, "%s: malloc failed (%m)", __func__); + return NULL; +} + +bl_t +bl_create(void) +{ + return bl_create2(false, NULL, NULL); } void bl_destroy(bl_t b) { - close(b->b_fd); + bl_reset(b); + free(__UNCONST(b->b_path)); + free(b->b_info.bi_cred); + free(b->b_info.bi_fd); free(b); } -#if 0 -static int -bl_post(bl_t b, const struct sockaddr_storage *lss, - const struct sockaddr_storage *pss, bl_event_t e, const char *ctx) -{ - - struct sockaddr_storage lss, pss; - socklen_t lsl, psl; - - lsl = sizeof(lss); - psl = sizeof(pss); - if (getsockname(lfd, &lss, &lsl) == -1) { - syslog(LOG_ERR, "%s: getsockname failed (%m)", __func__); - return -1; - } - if (getpeername(pfd, &pss, &psl) == -1) { - syslog(LOG_ERR, "%s: getpeername failed (%m)", __func__); - return -1; - } - return bl_post(&lss, &pss, e, ctx); -} -#endif - int bl_send(bl_t b, bl_type_t e, int lfd, int pfd, const char *ctx) { @@ -102,14 +165,15 @@ bl_send(bl_t b, bl_type_t e, int lfd, int pfd, const char *ctx) union { char ctrl[CMSG_SPACE(2 * sizeof(int))]; uint32_t fd[2]; - } uc; + } ua; struct cmsghdr *cmsg; union { bl_message_t bl; char buf[512]; } ub; int *fd; - size_t ctxlen; + size_t ctxlen, tried; +#define NTRIES 5 ctxlen = strlen(ctx); if (ctxlen > 256) @@ -127,8 +191,8 @@ bl_send(bl_t b, bl_type_t e, int lfd, int pfd, const char *ctx) msg.msg_iov = &iov; msg.msg_iovlen = 1; - msg.msg_control = uc.ctrl; - msg.msg_controllen = sizeof(uc.ctrl); + msg.msg_control = ua.ctrl; + msg.msg_controllen = sizeof(ua.ctrl); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_len = CMSG_LEN(2 * sizeof(int)); @@ -139,33 +203,38 @@ bl_send(bl_t b, bl_type_t e, int lfd, int pfd, const char *ctx) fd[0] = lfd; fd[1] = pfd; + tried = 0; +again: if (bl_init(b, false) == -1) return -1; - return sendmsg(b->b_fd, &msg, 0); + if ((sendmsg(b->b_fd, &msg, 0) == -1) && tried++ < NTRIES) { + bl_reset(b); + goto again; + } + return tried >= NTRIES ? -1 : 0; } -int -bl_recv(bl_t b, bl_type_t *e, int *lfd, int *pfd, char *ctx, size_t clen) +bl_info_t * +bl_recv(bl_t b) { struct msghdr msg; struct iovec iov; union { - char ctrl[CMSG_SPACE(2 * sizeof(int))]; + char ctrl[CMSG_SPACE(2 * sizeof(int)) + + CMSG_SPACE(SOCKCREDSIZE(NGROUPS_MAX))]; uint32_t fd[2]; - } uc; + struct sockcred sc; + } ua; struct cmsghdr *cmsg; + struct sockcred *sc; union { bl_message_t bl; char buf[512]; } ub; int *fd; ssize_t rlen; - - *e = BL_INVALID; - *lfd = *pfd = -1; - if (clen > 0) - *ctx = '\0'; + bl_info_t *bi = &b->b_info; iov.iov_base = ub.buf; iov.iov_len = sizeof(ub); @@ -175,49 +244,59 @@ bl_recv(bl_t b, bl_type_t *e, int *lfd, int *pfd, char *ctx, size_t clen) msg.msg_iov = &iov; msg.msg_iovlen = 1; - msg.msg_control = uc.ctrl; - msg.msg_controllen = sizeof(uc.ctrl); + msg.msg_control = ua.ctrl; + msg.msg_controllen = sizeof(ua.ctrl) + 100; rlen = recvmsg(b->b_fd, &msg, 0); if (rlen == -1) { - syslog(LOG_ERR, "%s: recvmsg failed (%m)", __func__); - return -1; + (*b->b_fun)(LOG_ERR, "%s: recvmsg failed (%m)", __func__); + return NULL; } for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) { - syslog(LOG_ERR, "%s: unexpected cmsg_level %d", + (*b->b_fun)(LOG_ERR, "%s: unexpected cmsg_level %d", __func__, cmsg->cmsg_level); continue; } - if (cmsg->cmsg_type != SCM_RIGHTS) { - syslog(LOG_ERR, "%s: unexpected cmsg_type %d", + switch (cmsg->cmsg_type) { + case SCM_RIGHTS: + if (cmsg->cmsg_len != CMSG_LEN(2 * sizeof(int))) { + (*b->b_fun)(LOG_ERR, + "%s: unexpected cmsg_len %d != %zu", + __func__, cmsg->cmsg_len, + CMSG_LEN(2 * sizeof(int))); + continue; + } + fd = (void *)CMSG_DATA(cmsg); + memcpy(bi->bi_fd, fd, sizeof(bi->bi_fd)); + break; + case SCM_CREDS: + sc = (void *)CMSG_DATA(cmsg); + if (sc->sc_ngroups > NGROUPS_MAX) + sc->sc_ngroups = NGROUPS_MAX; + memcpy(bi->bi_cred, sc, SOCKCREDSIZE(sc->sc_ngroups)); + break; + default: + (*b->b_fun)(LOG_ERR, "%s: unexpected cmsg_type %d", __func__, cmsg->cmsg_type); continue; } - if (cmsg->cmsg_len == CMSG_LEN(2 * sizeof(int))) { - syslog(LOG_ERR, "%s: unexpected cmsg_len %d != %zu", - __func__, cmsg->cmsg_len, - CMSG_LEN(2 * sizeof(int))); - continue; - } - fd = (void *)CMSG_DATA(cmsg); - *lfd = fd[0]; - *pfd = fd[1]; } if (rlen <= sizeof(ub.bl)) { - syslog(LOG_ERR, "message too short %zd", rlen); - return rlen; + (*b->b_fun)(LOG_ERR, "message too short %zd", rlen); + return NULL; } if (ub.bl.bl_version != BL_VERSION) { - syslog(LOG_ERR, "bad version %d", ub.bl.bl_version); - return rlen; + (*b->b_fun)(LOG_ERR, "bad version %d", ub.bl.bl_version); + return NULL; } - *e = ub.bl.bl_type; - strlcpy(ctx, ub.bl.bl_data, MIN(clen, rlen - sizeof(ub.bl))); - return rlen; + bi->bi_type = ub.bl.bl_type; + strlcpy(bi->bi_msg, ub.bl.bl_data, MIN(sizeof(bi->bi_msg), + rlen - sizeof(ub.bl) + 1)); + return bi; } diff --git a/external/bsd/blacklist/test/cltest.c b/external/bsd/blacklist/test/cltest.c index ac2f9c175c46..4de22a83bb6e 100644 --- a/external/bsd/blacklist/test/cltest.c +++ b/external/bsd/blacklist/test/cltest.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -9,34 +10,69 @@ #include static __dead void -usage(const char *msg) +usage(void) { - fprintf(stderr, "Usage: %s %s\n", getprogname(), msg); + fprintf(stderr, "Usage: %s [-a ] [-m ]\n", getprogname()); exit(1); } +static void +getaddr(const char *a, in_port_t p, struct sockaddr_storage *ss) +{ + int c; + + memset(ss, 0, sizeof(*ss)); + p = htons(p); + + if (strchr(a, ':')) { + struct sockaddr_in6 *s6 = (void *)ss; + c = inet_pton(AF_INET6, a, &s6->sin6_addr); + s6->sin6_family = AF_INET6; + s6->sin6_len = sizeof(*s6); + s6->sin6_port = p; + } else { + struct sockaddr_in *s = (void *)ss; + c = inet_pton(AF_INET, a, &s->sin_addr); + s->sin_family = AF_INET; + s->sin_len = sizeof(*s); + s->sin_port = p; + } + if (c == -1) + err(EXIT_FAILURE, "Invalid address `%s'", a); +} + int main(int argc, char *argv[]) { int sfd; - struct sockaddr_in ssin; + int c; + struct sockaddr_storage ss; + const char *msg = "hello"; + const char *addr = "127.0.0.1"; + + while ((c = getopt(argc, argv, "a:m:")) == -1) { + switch (c) { + case 'a': + addr = optarg; + break; + case 'm': + msg = optarg; + break; + default: + usage(); + } + } + + getaddr(addr, 6161, &ss); - if (argc == 1) - usage(""); if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) err(1, "socket"); - memset(&ssin, 0, sizeof(ssin)); - ssin.sin_family = AF_INET; - ssin.sin_len = sizeof(ssin); - ssin.sin_addr.s_addr = htonl(INADDR_ANY); - ssin.sin_port = htons(6161); - - if (connect(sfd, (const void *)&ssin, sizeof(ssin)) == -1) + if (connect(sfd, (const void *)&ss, ss.ss_len) == -1) err(1, "connect"); - size_t len = strlen(argv[1]) + 1; - if (write(sfd, argv[1], len) != (ssize_t)len) + size_t len = strlen(msg) + 1; + if (write(sfd, msg, len) != (ssize_t)len) err(1, "write"); return 0; } diff --git a/external/bsd/blacklist/test/srvtest.c b/external/bsd/blacklist/test/srvtest.c index f32f596ce3d2..4dfa545a811a 100644 --- a/external/bsd/blacklist/test/srvtest.c +++ b/external/bsd/blacklist/test/srvtest.c @@ -5,11 +5,13 @@ #include #include #include +#include #include #include +#include #include -#include "bl.h" +#include "blacklist.h" static void process(bl_t bl, int sfd, int afd) @@ -22,54 +24,86 @@ process(bl_t bl, int sfd, int afd) if ((n = read(afd, buffer, sizeof(buffer))) == -1) err(1, "read"); buffer[sizeof(buffer) - 1] = '\0'; + printf("%s: sending %d %d %s\n", getprogname(), sfd, afd, buffer); bl_send(bl, BL_ADD, sfd, afd, buffer); - printf("received %s\n", buffer); exit(0); } +static int +cr(int af, in_port_t p) +{ + int sfd; + struct sockaddr_storage ss; + sfd = socket(af == AF_INET ? PF_INET : PF_INET6, SOCK_STREAM, 0); + if (sfd == -1) + err(1, "socket"); + + p = htons(p); + memset(&ss, 0, sizeof(ss)); + if (af == AF_INET) { + struct sockaddr_in *s = (void *)&ss; + s->sin_family = AF_INET; + s->sin_len = sizeof(*s); + s->sin_port = p; + } else { + struct sockaddr_in6 *s6 = (void *)&ss; + s6->sin6_family = AF_INET6; + s6->sin6_len = sizeof(*s6); + s6->sin6_port = p; + } + + if (bind(sfd, (const void *)&ss, ss.ss_len) == -1) + err(1, "bind"); + + if (listen(sfd, 5) == -1) + err(1, "listen"); + return sfd; +} + +static void +handle(bl_t bl, int sfd) +{ + struct sockaddr_storage ss; + socklen_t alen = sizeof(ss); + int afd; + if ((afd = accept(sfd, (void *)&ss, &alen)) == -1) + err(1, "accept"); + + /* Create child process */ + switch (fork()) { + case -1: + err(1, "fork"); + case 0: + process(bl, sfd, afd); + break; + default: + close(afd); + break; + } +} + int main(int argc, char *argv[]) { - int sfd; + int s4fd, s6fd; bl_t bl; - struct sockaddr_in ssin; - - if ((sfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) - err(1, "socket"); + struct pollfd pfd[2]; signal(SIGCHLD, SIG_IGN); - memset(&ssin, 0, sizeof(ssin)); - ssin.sin_family = AF_INET; - ssin.sin_len = sizeof(ssin); - ssin.sin_addr.s_addr = htonl(INADDR_ANY); - ssin.sin_port = htons(6161); - - if (bind(sfd, (const void *)&ssin, sizeof(ssin)) == -1) - err(1, "bind"); + pfd[0].fd = cr(AF_INET, 6161); + pfd[1].fd = cr(AF_INET6, 6161); + pfd[0].events = pfd[1].events = POLLIN; - if (listen(sfd, 5) == -1) - err(1, "listen"); - - bl = bl_create(false); + bl = bl_create(); for (;;) { - struct sockaddr_in asin; - socklen_t alen = sizeof(asin); - int afd; - if ((afd = accept(sfd, (void *)&asin, &alen)) == -1) - err(1, "accept"); - - /* Create child process */ - switch (fork()) { - case -1: - err(1, "fork"); - case 0: - process(bl, sfd, afd); - break; - default: - close(afd); - break; + if (poll(pfd, __arraycount(pfd), INFTIM) == -1) + err(1, "poll"); + for (int i = 0; i < __arraycount(pfd); i++) { + if ((pfd[i].revents & POLLIN) == 0) + continue; + handle(bl, pfd[i].fd); } } }