From: Yu Watanabe Date: Fri, 4 Sep 2020 06:01:21 +0000 (+0900) Subject: resolve: use in_addr_union to store addresses for extra dns stub listeners X-Git-Tag: v247-rc1~292^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ca8b62b522e0c5944143c0d90428fa88ea0cb434;p=thirdparty%2Fsystemd.git resolve: use in_addr_union to store addresses for extra dns stub listeners --- diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index 1c934b34cfe..57154f86332 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -30,20 +30,15 @@ static const char* const dns_stub_listener_mode_table[_DNS_STUB_LISTENER_MODE_MA DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dns_stub_listener_mode, DnsStubListenerMode, DNS_STUB_LISTENER_YES); static void dns_stub_listener_extra_hash_func(const DNSStubListenerExtra *a, struct siphash *state) { - unsigned port; - assert(a); siphash24_compress(&a->mode, sizeof(a->mode), state); - siphash24_compress(&socket_address_family(&a->address), sizeof(a->address.type), state); - siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(socket_address_family(&a->address)), state); - - (void) sockaddr_port(&a->address.sockaddr.sa, &port); - siphash24_compress(&port, sizeof(port), state); + siphash24_compress(&a->family, sizeof(a->family), state); + siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); + siphash24_compress(&a->port, sizeof(a->port), state); } static int dns_stub_listener_extra_compare_func(const DNSStubListenerExtra *a, const DNSStubListenerExtra *b) { - unsigned p, q; int r; assert(a); @@ -53,18 +48,15 @@ static int dns_stub_listener_extra_compare_func(const DNSStubListenerExtra *a, c if (r != 0) return r; - r = CMP(socket_address_family(&a->address), socket_address_family(&b->address)); + r = CMP(a->family, b->family); if (r != 0) return r; - r = memcmp(&a->address, &b->address, FAMILY_ADDRESS_SIZE(socket_address_family(&a->address))); + r = memcmp(&a->address, &b->address, FAMILY_ADDRESS_SIZE(a->family)); if (r != 0) return r; - (void) sockaddr_port(&a->address.sockaddr.sa, &p); - (void) sockaddr_port(&b->address.sockaddr.sa, &q); - - return CMP(p, q); + return CMP(a->port, b->port); } DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( @@ -476,7 +468,7 @@ int config_parse_dns_stub_listener_extra( } } - r = socket_addr_port_from_string_auto(p, 53, &stub->address); + r = in_addr_port_from_string_auto(p, &stub->family, &stub->address, &stub->port); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse address in %s=%s, ignoring assignment: %m", diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index 02c60b91d4e..fc169ee0ef4 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +#include + #include "errno-util.h" #include "fd-util.h" #include "missing_network.h" @@ -460,12 +462,26 @@ static int manager_dns_stub_udp_fd(Manager *m) { static int manager_dns_stub_udp_fd_extra(Manager *m, DNSStubListenerExtra *l) { _cleanup_free_ char *pretty = NULL; _cleanup_close_ int fd = -1; + union sockaddr_union sa; int r; if (l->udp_fd >= 0) return 0; - fd = socket(socket_address_family(&l->address), SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (l->family == AF_INET) + sa = (union sockaddr_union) { + .in.sin_family = l->family, + .in.sin_port = htobe16(l->port != 0 ? l->port : 53U), + .in.sin_addr = l->address.in, + }; + else + sa = (union sockaddr_union) { + .in6.sin6_family = l->family, + .in6.sin6_port = htobe16(l->port != 0 ? l->port : 53U), + .in6.sin6_addr = l->address.in6, + }; + + fd = socket(l->family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) { r = -errno; goto fail; @@ -479,7 +495,7 @@ static int manager_dns_stub_udp_fd_extra(Manager *m, DNSStubListenerExtra *l) { if (r < 0) goto fail; - if (bind(fd, &l->address.sockaddr.sa, l->address.size) < 0) { + if (bind(fd, &sa.sa, SOCKADDR_LEN(sa)) < 0) { r = -errno; goto fail; } @@ -491,7 +507,7 @@ static int manager_dns_stub_udp_fd_extra(Manager *m, DNSStubListenerExtra *l) { (void) sd_event_source_set_description(l->udp_event_source, "dns-stub-udp-extra"); if (DEBUG_LOGGING) { - (void) sockaddr_pretty(&l->address.sockaddr.sa, FAMILY_ADDRESS_SIZE(l->address.sockaddr.sa.sa_family), true, true, &pretty); + (void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty); log_debug("Listening on UDP socket %s.", strnull(pretty)); } @@ -500,7 +516,7 @@ static int manager_dns_stub_udp_fd_extra(Manager *m, DNSStubListenerExtra *l) { return 0; fail: - (void) sockaddr_pretty(&l->address.sockaddr.sa, FAMILY_ADDRESS_SIZE(l->address.sockaddr.sa.sa_family), true, true, &pretty); + (void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty); if (r == -EADDRINUSE) return log_warning_errno(r, "Another process is already listening on UDP socket %s.\n" @@ -607,12 +623,26 @@ static int manager_dns_stub_tcp_fd(Manager *m) { static int manager_dns_stub_tcp_fd_extra(Manager *m, DNSStubListenerExtra *l) { _cleanup_free_ char *pretty = NULL; _cleanup_close_ int fd = -1; + union sockaddr_union sa; int r; if (l->tcp_fd >= 0) return 0; - fd = socket(socket_address_family(&l->address), SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (l->family == AF_INET) + sa = (union sockaddr_union) { + .in.sin_family = l->family, + .in.sin_port = htobe16(l->port != 0 ? l->port : 53U), + .in.sin_addr = l->address.in, + }; + else + sa = (union sockaddr_union) { + .in6.sin6_family = l->family, + .in6.sin6_port = htobe16(l->port != 0 ? l->port : 53U), + .in6.sin6_addr = l->address.in6, + }; + + fd = socket(l->family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) { r = -errno; goto fail; @@ -630,7 +660,7 @@ static int manager_dns_stub_tcp_fd_extra(Manager *m, DNSStubListenerExtra *l) { if (r < 0) goto fail; - if (bind(fd, &l->address.sockaddr.sa, l->address.size) < 0) { + if (bind(fd, &sa.sa, SOCKADDR_LEN(sa)) < 0) { r = -errno; goto fail; } @@ -647,7 +677,7 @@ static int manager_dns_stub_tcp_fd_extra(Manager *m, DNSStubListenerExtra *l) { (void) sd_event_source_set_description(l->tcp_event_source, "dns-stub-tcp-extra"); if (DEBUG_LOGGING) { - (void) sockaddr_pretty(&l->address.sockaddr.sa, FAMILY_ADDRESS_SIZE(l->address.sockaddr.sa.sa_family), true, true, &pretty); + (void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty); log_debug("Listening on TCP socket %s.", strnull(pretty)); } @@ -656,7 +686,7 @@ static int manager_dns_stub_tcp_fd_extra(Manager *m, DNSStubListenerExtra *l) { return 0; fail: - (void) sockaddr_pretty(&l->address.sockaddr.sa, FAMILY_ADDRESS_SIZE(l->address.sockaddr.sa.sa_family), true, true, &pretty); + (void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty); if (r == -EADDRINUSE) return log_warning_errno(r, "Another process is already listening on TCP socket %s.\n" diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 2c6adfbcbd3..9eee30761c7 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -36,7 +36,11 @@ typedef struct DNSStubListenerExtra { int tcp_fd; DnsStubListenerMode mode; - SocketAddress address; + + int family; + union in_addr_union address; + uint16_t port; + sd_event_source *udp_event_source; sd_event_source *tcp_event_source; } DNSStubListenerExtra;