Hi,

As I don't want to copy the socket creation code for upcoming TCP
listen again, move it to the common function socket_bind().

ok?

bluhm

Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.167
diff -u -p -r1.167 syslogd.c
--- usr.sbin/syslogd/syslogd.c  30 Jun 2015 18:41:24 -0000      1.167
+++ usr.sbin/syslogd/syslogd.c  2 Jul 2015 09:09:52 -0000
@@ -216,10 +216,9 @@ int        MarkInterval = 20 * 60; /* interval 
 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
@@ -752,6 +652,103 @@ main(int argc, char *argv[])
 
        event_dispatch();
        /* NOTREACHED */
+       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);
 }
 

Reply via email to