diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c index 1cd7f11a6..045fa93ca 100644 --- a/logsrvd/logsrvd.c +++ b/logsrvd/logsrvd.c @@ -1468,10 +1468,17 @@ create_listener(struct listen_address *addr) goto bad; } on = 1; +#ifdef IPV6_V6ONLY + if (addr->sa_un.sa.sa_family == AF_INET6) { + /* Disable IPv4-mapped IPv6 addresses. */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) + sudo_warn("IPV6_V6ONLY"); + } +#endif if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) sudo_warn("SO_REUSEADDR"); if (bind(sock, &addr->sa_un.sa, addr->sa_len) == -1) { - sudo_warn("bind"); + sudo_warn("%s", addr->sa_str); goto bad; } if (listen(sock, SOMAXCONN) == -1) { @@ -1483,6 +1490,8 @@ create_listener(struct listen_address *addr) sudo_warn("fcntl(O_NONBLOCK)"); goto bad; } + sudo_debug_printf(SUDO_DEBUG_INFO, "listening on %s (AF_INET%s)", + addr->sa_str, addr->sa_un.sa.sa_family == AF_INET6 ? "6" : ""); debug_return_int(sock); bad: diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h index bf49de04a..120880adf 100644 --- a/logsrvd/logsrvd.h +++ b/logsrvd/logsrvd.h @@ -128,6 +128,7 @@ union sockaddr_union { */ struct listen_address { TAILQ_ENTRY(listen_address) entries; + char *sa_str; union sockaddr_union sa_un; socklen_t sa_len; }; diff --git a/logsrvd/logsrvd_conf.c b/logsrvd/logsrvd_conf.c index d9c7195bf..58ecfef4d 100644 --- a/logsrvd/logsrvd_conf.c +++ b/logsrvd/logsrvd_conf.c @@ -410,6 +410,11 @@ cb_listen_address(struct logsrvd_config *config, const char *str) sudo_warn(NULL); goto done; } + if ((addr->sa_str = strdup(str)) == NULL) { + sudo_warn(NULL); + free(addr); + goto done; + } memcpy(&addr->sa_un, res->ai_addr, res->ai_addrlen); addr->sa_len = res->ai_addrlen; TAILQ_INSERT_TAIL(&config->server.addresses, addr, entries); @@ -933,6 +938,7 @@ logsrvd_conf_free(struct logsrvd_config *config) /* struct logsrvd_config_server */ while ((addr = TAILQ_FIRST(&config->server.addresses))) { TAILQ_REMOVE(&config->server.addresses, addr, entries); + free(addr->sa_str); free(addr); } free(config->server.pid_file);