diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-07-02 16:24:49 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-07-02 16:24:49 +0000 |
commit | 124525fab14c69cf346fb0d20f82b26f3506af2a (patch) | |
tree | 49ae224e2c43ed12bbc253e5a206c1e55136e0a4 /usr.sbin | |
parent | d4cccab8312becec1de098111e872e959600c3af (diff) |
To avoid copying the socket creation code for upcoming TCP listen
again, move it to the common function socket_bind().
OK millert@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/syslogd/syslogd.c | 231 |
1 files changed, 114 insertions, 117 deletions
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index a7d70b04d24..8bc8e6d40c1 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syslogd.c,v 1.167 2015/06/30 18:41:24 bluhm Exp $ */ +/* $OpenBSD: syslogd.c,v 1.168 2015/07/02 16:24:48 bluhm Exp $ */ /* * Copyright (c) 1983, 1988, 1993, 1994 @@ -216,10 +216,9 @@ int MarkInterval = 20 * 60; /* interval between marks in seconds */ int MarkSeq = 0; /* mark sequence number */ int SecureMode = 1; /* when true, speak only unix domain socks */ int NoDNS = 0; /* when true, will refrain from doing DNS lookups */ -int IPv4Only = 0; /* when true, disable IPv6 */ -int IPv6Only = 0; /* when true, disable IPv4 */ int IncludeHostname = 0; /* include RFC 3164 style hostnames when forwarding */ -char *bind_host = NULL; +int Family = PF_UNSPEC; /* protocol family, may disable IPv4 or IPv6 */ +char *bind_host = NULL; /* bind UDP receive socket */ char *bind_port = NULL; char *path_ctlsock = NULL; /* Path to control socket */ @@ -318,6 +317,8 @@ void usage(void); void wallmsg(struct filed *, struct iovec *); int loghost_parse(char *, char **, char **, char **); int getmsgbufsize(void); +int socket_bind(const char *, const char *, const char *, int, int, + int *, int *); int unix_socket(char *, int, mode_t); void double_rbuf(int); void tailify_replytext(char *, int); @@ -325,7 +326,6 @@ void tailify_replytext(char *, int); int main(int argc, char *argv[]) { - struct addrinfo hints, *res, *res0; struct timeval to; const char *errstr; char *p; @@ -335,12 +335,10 @@ main(int argc, char *argv[]) while ((ch = getopt(argc, argv, "46a:C:dFf:hm:np:s:U:uV")) != -1) switch (ch) { case '4': /* disable IPv6 */ - IPv4Only = 1; - IPv6Only = 0; + Family = PF_INET; break; case '6': /* disable IPv4 */ - IPv6Only = 1; - IPv4Only = 0; + Family = PF_INET6; break; case 'a': if (nunix >= MAXUNIX) @@ -426,118 +424,20 @@ main(int argc, char *argv[]) die(0); } - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - hints.ai_flags = AI_PASSIVE; - - if (getaddrinfo(NULL, "syslog", &hints, &res0)) { + if (socket_bind("udp", NULL, "syslog", 0, SecureMode, + &fd_udp, &fd_udp6) == -1) { errno = 0; - logerror("syslog/udp: unknown service"); - die(0); - } - - fd_udp = fd_udp6 = -1; - for (res = res0; res; res = res->ai_next) { - int *fdp; - - switch (res->ai_family) { - case AF_INET: - if (IPv6Only) - continue; - fdp = &fd_udp; - break; - case AF_INET6: - if (IPv4Only) - continue; - fdp = &fd_udp6; - break; - default: - continue; - } - - if (*fdp >= 0) - continue; - - *fdp = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (*fdp == -1) - continue; - - if (bind(*fdp, res->ai_addr, res->ai_addrlen) < 0) { - logerror("bind"); - close(*fdp); - *fdp = -1; - if (!Debug) - die(0); - continue; - } - - if (SecureMode) - shutdown(*fdp, SHUT_RD); - else - double_rbuf(*fdp); + logerror("socket bind *"); + if (!Debug) + die(0); } - - freeaddrinfo(res0); - fd_bind = -1; - if (bind_host) { - if (bind_port == NULL) - bind_port = "syslog"; - if (getaddrinfo(bind_host, bind_port, &hints, &res0)) { - errno = 0; - logerror("syslog/udp: unknown bind address"); - die(0); - } - - for (res = res0; res; res = res->ai_next) { - switch (res->ai_family) { - case AF_INET: - if (IPv6Only) - continue; - break; - case AF_INET6: - if (IPv4Only) - continue; - break; - default: - continue; - } - - fd_bind = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (fd_bind == -1) - continue; - - i = 1; - if (setsockopt(fd_bind, SOL_SOCKET, SO_REUSEADDR, - &i, sizeof(i)) == -1) { - logerror("setsockopt udp"); - close(fd_bind); - fd_bind = -1; - if (!Debug) - die(0); - continue; - } - if (bind(fd_bind, res->ai_addr, res->ai_addrlen) < 0) { - logerror("bind udp"); - close(fd_bind); - fd_bind = -1; - if (!Debug) - die(0); - continue; - } - double_rbuf(fd_bind); - break; - } - if (fd_bind == -1) { - logerror("socket udp"); + if (bind_host && socket_bind("udp", bind_host, bind_port, 1, 0, + &fd_bind, &fd_bind) == -1) { + errno = 0; + logerror("socket bind udp"); + if (!Debug) die(0); - } - - freeaddrinfo(res0); } #ifndef SUN_LEN @@ -755,6 +655,103 @@ main(int argc, char *argv[]) return (0); } +int +socket_bind(const char *proto, const char *host, const char *port, + int reuseaddr, int shutread, int *fd, int *fd6) +{ + struct addrinfo hints, *res, *res0; + char hostname[NI_MAXHOST], servname[NI_MAXSERV]; + char ebuf[ERRBUFSIZE]; + int *fdp, error; + + *fd = *fd6 = -1; + if (proto == NULL) + proto = "udp"; + if (port == NULL) + port = "syslog"; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = Family; + if (strcmp(proto, "udp") == 0) { + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + } + hints.ai_flags = AI_PASSIVE; + + if ((error = getaddrinfo(host, port, &hints, &res0))) { + snprintf(ebuf, sizeof(ebuf), "getaddrinfo " + "proto %s, host %s, port %s: %s", + proto, host ? host : "*", port, gai_strerror(error)); + logerror(ebuf); + die(0); + } + + for (res = res0; res; res = res->ai_next) { + switch (res->ai_family) { + case AF_INET: + fdp = fd; + break; + case AF_INET6: + fdp = fd6; + break; + default: + continue; + } + if (*fdp >= 0) + continue; + + if ((*fdp = socket(res->ai_family, res->ai_socktype, + res->ai_protocol)) == -1) + continue; + + if (getnameinfo(res->ai_addr, res->ai_addrlen, hostname, + sizeof(hostname), servname, sizeof(servname), + NI_NUMERICHOST | NI_NUMERICSERV | + (res->ai_socktype == SOCK_DGRAM ? NI_DGRAM : 0)) != 0) { + hostname[0] = servname[0] = '\0'; + } + if (shutread && shutdown(*fdp, SHUT_RD) == -1) { + snprintf(ebuf, sizeof(ebuf), "shutdown SHUT_RD " + "protocol %d, address %s, portnum %s", + res->ai_protocol, hostname, servname); + logerror(ebuf); + close(*fdp); + *fdp = -1; + continue; + } + if (setsockopt(*fdp, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, + sizeof(reuseaddr)) == -1) { + snprintf(ebuf, sizeof(ebuf), "setsockopt SO_REUSEADDR " + "protocol %d, address %s, portnum %s", + res->ai_protocol, hostname, servname); + logerror(ebuf); + close(*fdp); + *fdp = -1; + continue; + } + if (bind(*fdp, res->ai_addr, res->ai_addrlen) == -1) { + snprintf(ebuf, sizeof(ebuf), "bind " + "protocol %d, address %s, portnum %s", + res->ai_protocol, hostname, servname); + logerror(ebuf); + close(*fdp); + *fdp = -1; + continue; + } + if (!shutread && res->ai_protocol == IPPROTO_UDP) + double_rbuf(*fdp); + } + + freeaddrinfo(res0); + + if (*fd == -1 && *fd6 == -1) + return (-1); + return (0); +} + void klog_readcb(int fd, short event, void *arg) { |