resolve: move sd-* api into libsystemd-network
authorRonan Pigott <ronan@rjp.ie>
Wed, 26 Jun 2024 00:01:59 +0000 (17:01 -0700)
committerRonan Pigott <ronan@rjp.ie>
Mon, 21 Oct 2024 16:10:20 +0000 (09:10 -0700)
This duplicates the svc param constants for the benefit of the
resolved-core library.

12 files changed:
src/libsystemd-network/dns-resolver-internal.h [new file with mode: 0644]
src/libsystemd-network/meson.build
src/libsystemd-network/sd-dns-resolver.c [new file with mode: 0644]
src/libsystemd-network/sd-dns-resolver.h [new file with mode: 0644]
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-rr.c
src/shared/dns-resolver-internal.h [deleted file]
src/shared/meson.build
src/shared/sd-dns-resolver.c [deleted file]
src/systemd/meson.build
src/systemd/sd-dns-resolver.h [deleted file]

diff --git a/src/libsystemd-network/dns-resolver-internal.h b/src/libsystemd-network/dns-resolver-internal.h
new file mode 100644 (file)
index 0000000..e5c185c
--- /dev/null
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <errno.h>
+
+#include "sd-dns-resolver.h"
+
+#include "macro.h"
+#include "list.h"
+#include "socket-netlink.h"
+
+/* https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys */
+enum {
+        DNS_SVC_PARAM_KEY_MANDATORY       = 0, /* RFC 9460 § 8 */
+        DNS_SVC_PARAM_KEY_ALPN            = 1, /* RFC 9460 § 7.1 */
+        DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN = 2, /* RFC 9460 § 7.1 */
+        DNS_SVC_PARAM_KEY_PORT            = 3, /* RFC 9460 § 7.2 */
+        DNS_SVC_PARAM_KEY_IPV4HINT        = 4, /* RFC 9460 § 7.3 */
+        DNS_SVC_PARAM_KEY_ECH             = 5, /* RFC 9460 */
+        DNS_SVC_PARAM_KEY_IPV6HINT        = 6, /* RFC 9460 § 7.3  */
+        DNS_SVC_PARAM_KEY_DOHPATH         = 7, /* RFC 9461 */
+        DNS_SVC_PARAM_KEY_OHTTP           = 8,
+        _DNS_SVC_PARAM_KEY_MAX_DEFINED,
+        DNS_SVC_PARAM_KEY_INVALID         = 65535 /* RFC 9460 */
+};
+
+const char* dns_svc_param_key_to_string(int i) _const_;
+const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]);
+#define FORMAT_DNS_SVC_PARAM_KEY(i) format_dns_svc_param_key(i, (char [DECIMAL_STR_MAX(uint16_t)+3]) {})
+
+/* Represents a "designated resolver" */
+/* typedef struct sd_dns_resolver sd_dns_resolver; */
+struct sd_dns_resolver {
+        uint16_t priority;
+        char *auth_name;
+        int family;
+        union in_addr_union *addrs;
+        size_t n_addrs;
+        sd_dns_alpn_flags transports;
+        uint16_t port;
+        char *dohpath;
+};
+
+void siphash24_compress_resolver(const sd_dns_resolver *res, struct siphash *state);
+
+int dns_resolver_transports_to_strv(sd_dns_alpn_flags transports, char ***ret);
+
+int dns_resolvers_to_dot_addrs(const sd_dns_resolver *resolvers, size_t n_resolvers,
+                struct in_addr_full ***ret_addrs, size_t *ret_n_addrs);
+
+int dns_resolver_prio_compare(const sd_dns_resolver *a, const sd_dns_resolver *b);
+
+int dnr_parse_svc_params(const uint8_t *option, size_t len, sd_dns_resolver *resolver);
+
+int dns_resolvers_to_dot_strv(const sd_dns_resolver *resolvers, size_t n_resolvers, char ***ret_names);
+
+void sd_dns_resolver_done(sd_dns_resolver *res);
+
+void dns_resolver_done_many(sd_dns_resolver *resolvers, size_t n);
index 718495cd8eb5558a7d263e34844aad1c532ccab3..262ce9c4effa100aead588cab89508265bab32c8 100644 (file)
@@ -23,6 +23,7 @@ sources = files(
         'sd-dhcp-server.c',
         'sd-dhcp6-client.c',
         'sd-dhcp6-lease.c',
+        'sd-dns-resolver.c',
         'sd-ipv4acd.c',
         'sd-ipv4ll.c',
         'sd-lldp-rx.c',
diff --git a/src/libsystemd-network/sd-dns-resolver.c b/src/libsystemd-network/sd-dns-resolver.c
new file mode 100644 (file)
index 0000000..548672c
--- /dev/null
@@ -0,0 +1,388 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "dns-resolver-internal.h"
+#include "macro.h"
+#include "unaligned.h"
+#include "socket-netlink.h"
+#include "string-table.h"
+#include "string-util.h"
+#include "strv.h"
+
+void sd_dns_resolver_done(sd_dns_resolver *res) {
+        assert(res);
+
+        res->auth_name = mfree(res->auth_name);
+        res->addrs = mfree(res->addrs);
+        res->dohpath = mfree(res->dohpath);
+}
+
+sd_dns_resolver *sd_dns_resolver_unref(sd_dns_resolver *res) {
+        if (!res)
+                return NULL;
+
+        sd_dns_resolver_done(res);
+        return mfree(res);
+}
+
+void dns_resolver_done_many(sd_dns_resolver resolvers[], size_t n) {
+        assert(resolvers || n == 0);
+
+        FOREACH_ARRAY(res, resolvers, n)
+                sd_dns_resolver_done(res);
+
+        free(resolvers);
+}
+
+int dns_resolver_prio_compare(const sd_dns_resolver *a, const sd_dns_resolver *b) {
+        return CMP(ASSERT_PTR(a)->priority, ASSERT_PTR(b)->priority);
+}
+
+int sd_dns_resolver_get_priority(sd_dns_resolver *res, uint16_t *ret_priority) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_priority, -EINVAL);
+
+        *ret_priority = res->priority;
+        return 0;
+}
+
+int sd_dns_resolver_get_adn(sd_dns_resolver *res, const char **ret_adn) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_adn, -EINVAL);
+
+        /* Without adn only Do53 can be supported */
+        if (!res->auth_name)
+                return -ENODATA;
+
+        *ret_adn = res->auth_name;
+        return 0;
+}
+
+int sd_dns_resolver_get_inet_addresses(sd_dns_resolver *res, const struct in_addr **ret_addrs, size_t
+                *ret_n_addrs) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_addrs, -EINVAL);
+        assert_return(ret_n_addrs, -EINVAL);
+        assert_return(res->family == AF_INET, -EINVAL);
+
+        /* ADN-only mode has no addrs */
+        if (res->n_addrs == 0)
+                return -ENODATA;
+
+        struct in_addr *addrs = new(struct in_addr, res->n_addrs);
+        if (!addrs)
+                return -ENOMEM;
+
+        for (size_t i = 0; i < res->n_addrs; i++)
+                addrs[i] = res->addrs[i].in;
+        *ret_addrs = addrs;
+        *ret_n_addrs = res->n_addrs;
+
+        return 0;
+}
+
+int sd_dns_resolver_get_inet6_addresses(sd_dns_resolver *res, const struct in6_addr **ret_addrs, size_t
+                *ret_n_addrs) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_addrs, -EINVAL);
+        assert_return(ret_n_addrs, -EINVAL);
+        assert_return(res->family == AF_INET6, -EINVAL);
+
+        /* ADN-only mode has no addrs */
+        if (res->n_addrs == 0)
+                return -ENODATA;
+
+        struct in6_addr *addrs = new(struct in6_addr, res->n_addrs);
+        if (!addrs)
+                return -ENOMEM;
+
+        for (size_t i = 0; i < res->n_addrs; i++)
+                addrs[i] = res->addrs[i].in6;
+        *ret_addrs = addrs;
+        *ret_n_addrs = res->n_addrs;
+
+        return 0;
+}
+
+int sd_dns_resolver_get_alpn(sd_dns_resolver *res, sd_dns_alpn_flags *ret_alpn) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_alpn, -EINVAL);
+
+        /* ADN-only mode has no transports */
+        if (!res->transports)
+                return -ENODATA;
+
+        *ret_alpn = res->transports;
+        return 0;
+}
+
+int sd_dns_resolver_get_port(sd_dns_resolver *res, uint16_t *ret_port) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_port, -EINVAL);
+
+        /* port = 0 is the default port */
+        *ret_port = res->port;
+        return 0;
+}
+
+int sd_dns_resolver_get_dohpath(sd_dns_resolver *res, const char **ret_dohpath) {
+        assert_return(res, -EINVAL);
+        assert_return(ret_dohpath, -EINVAL);
+
+        /* only present in DoH resolvers */
+        if (!res->dohpath)
+                return -ENODATA;
+
+        *ret_dohpath = res->dohpath;
+        return 0;
+}
+
+void siphash24_compress_resolver(const sd_dns_resolver *res, struct siphash *state) {
+        assert(res);
+
+        siphash24_compress_typesafe(res->priority, state);
+        siphash24_compress_typesafe(res->transports, state);
+        siphash24_compress_typesafe(res->port, state);
+
+        siphash24_compress_string(res->auth_name, state);
+        siphash24_compress_string(res->dohpath, state);
+
+        siphash24_compress_typesafe(res->family, state);
+        FOREACH_ARRAY(addr, res->addrs, res->n_addrs)
+                siphash24_compress_typesafe(*addr, state);
+}
+
+static const char* const dns_svc_param_key_table[_DNS_SVC_PARAM_KEY_MAX_DEFINED] = {
+        [DNS_SVC_PARAM_KEY_MANDATORY]       = "mandatory",
+        [DNS_SVC_PARAM_KEY_ALPN]            = "alpn",
+        [DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN] = "no-default-alpn",
+        [DNS_SVC_PARAM_KEY_PORT]            = "port",
+        [DNS_SVC_PARAM_KEY_IPV4HINT]        = "ipv4hint",
+        [DNS_SVC_PARAM_KEY_ECH]             = "ech",
+        [DNS_SVC_PARAM_KEY_IPV6HINT]        = "ipv6hint",
+        [DNS_SVC_PARAM_KEY_DOHPATH]         = "dohpath",
+        [DNS_SVC_PARAM_KEY_OHTTP]           = "ohttp",
+};
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dns_svc_param_key, int);
+
+const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]) {
+        assert(buf);
+
+        const char *p = dns_svc_param_key_to_string(i);
+        if (p)
+                return p;
+
+        return snprintf_ok(buf, DECIMAL_STR_MAX(uint16_t)+3, "key%i", i);
+}
+
+int dns_resolver_transports_to_strv(sd_dns_alpn_flags transports, char ***ret) {
+        _cleanup_strv_free_ char **ans = NULL;
+
+        assert(ret);
+
+        if (FLAGS_SET(transports, SD_DNS_ALPN_DO53)) {
+                /* Do53 has no ALPN, this flag is only for our own usage. */
+        }
+
+        if (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_2_TLS))
+                if (strv_extend(&ans, "h2") < 0)
+                        return -ENOMEM;
+        if (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_3))
+                if (strv_extend(&ans, "h3") < 0)
+                        return -ENOMEM;
+        if (FLAGS_SET(transports, SD_DNS_ALPN_DOT))
+                if (strv_extend(&ans, "dot") < 0)
+                        return -ENOMEM;
+        if (FLAGS_SET(transports, SD_DNS_ALPN_DOQ))
+                if (strv_extend(&ans, "doq") < 0)
+                        return -ENOMEM;
+
+        *ret = TAKE_PTR(ans);
+        return 0;
+}
+
+int dnr_parse_svc_params(const uint8_t *option, size_t len, sd_dns_resolver *resolver) {
+        size_t offset = 0;
+        int r;
+
+        assert(option || len == 0);
+        assert(resolver);
+
+        sd_dns_alpn_flags transports = 0;
+        uint16_t port = 0;
+        _cleanup_free_ char *dohpath = NULL;
+        bool alpn = false;
+
+        uint16_t lastkey = 0;
+        while (offset < len) {
+                if (offset + 4 > len)
+                        return -EBADMSG;
+
+                uint16_t key = unaligned_read_be16(&option[offset]);
+                offset += 2;
+
+                /* RFC9460 § 2.2 SvcParam MUST appear in strictly increasing numeric order */
+                if (lastkey >= key)
+                        return -EBADMSG;
+                lastkey = key;
+
+                uint16_t plen = unaligned_read_be16(&option[offset]);
+                offset += 2;
+                if (offset + plen > len)
+                        return -EBADMSG;
+
+                switch (key) {
+                /* Mandatory keys must be understood by the client, otherwise the record should be discarded.
+                 * Automatic mandatory keys must not appear in the mandatory parameter, so these are all
+                 * supplementary. We don't understand any supplementary keys, so if the mandatory parameter
+                 * is present, we cannot use this record.*/
+                case DNS_SVC_PARAM_KEY_MANDATORY:
+                        if (plen > 0)
+                                return -EBADMSG;
+                        break;
+
+                case DNS_SVC_PARAM_KEY_ALPN:
+                        if (plen == 0)
+                                return 0;
+                        alpn = true; /* alpn is required. Record that the requirement is met. */
+
+                        size_t poff = offset;
+                        size_t pend = offset + plen;
+                        while (poff < pend) {
+                                uint8_t alen = option[poff++];
+                                if (poff + alen > len)
+                                        return -EBADMSG;
+                                if (memcmp_nn(&option[poff], alen, "dot", STRLEN("dot")) == 0)
+                                        transports |= SD_DNS_ALPN_DOT;
+                                if (memcmp_nn(&option[poff], alen, "h2", STRLEN("h2")) == 0)
+                                        transports |= SD_DNS_ALPN_HTTP_2_TLS;
+                                if (memcmp_nn(&option[poff], alen, "h3", STRLEN("h3")) == 0)
+                                        transports |= SD_DNS_ALPN_HTTP_3;
+                                if (memcmp_nn(&option[poff], alen, "doq", STRLEN("doq")) == 0)
+                                        transports |= SD_DNS_ALPN_DOQ;
+                                poff += alen;
+                        }
+                        if (poff != pend)
+                                return -EBADMSG;
+                        break;
+
+                case DNS_SVC_PARAM_KEY_PORT:
+                        if (plen != sizeof(uint16_t))
+                                return -EBADMSG;
+                        port = unaligned_read_be16(&option[offset]);
+                        /* Server should indicate default port by omitting this param */
+                        if (port == 0)
+                                return -EBADMSG;
+                        break;
+
+                /* RFC9463 § 5.1 service params MUST NOT include ipv4hint/ipv6hint */
+                case DNS_SVC_PARAM_KEY_IPV4HINT:
+                case DNS_SVC_PARAM_KEY_IPV6HINT:
+                        return -EBADMSG;
+
+                case DNS_SVC_PARAM_KEY_DOHPATH:
+                        r = make_cstring((const char*) &option[offset], plen,
+                                        MAKE_CSTRING_REFUSE_TRAILING_NUL, &dohpath);
+                        if (ERRNO_IS_NEG_RESOURCE(r))
+                                return r;
+                        if (r < 0)
+                                return -EBADMSG;
+                        /* dohpath is a RFC6750 URI template. We don't parse these, but at least check the
+                         * charset is reasonable. */
+                        if (!in_charset(dohpath, URI_VALID "{}"))
+                                return -EBADMSG;
+                        break;
+
+                default:
+                        break;
+                }
+                offset += plen;
+        }
+        if (offset != len)
+                return -EBADMSG;
+
+        /* DNR cannot be used without alpn */
+        if (!alpn)
+                return -EBADMSG;
+
+        /* RFC9461 § 5: If the [SvcParam] indicates support for HTTP, "dohpath" MUST be present. */
+        if (!dohpath && (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_2_TLS) ||
+                        FLAGS_SET(transports, SD_DNS_ALPN_HTTP_3)))
+                return -EBADMSG;
+
+        /* No useful transports */
+        if (!transports)
+                return 0;
+
+        resolver->transports = transports;
+        resolver->port = port;
+        free_and_replace(resolver->dohpath, dohpath);
+        return transports;
+}
+
+int dns_resolvers_to_dot_addrs(const sd_dns_resolver *resolvers, size_t n_resolvers,
+                struct in_addr_full ***ret_addrs, size_t *ret_n_addrs) {
+        assert(ret_addrs);
+        assert(ret_n_addrs);
+        assert(resolvers || n_resolvers == 0);
+
+        struct in_addr_full **addrs = NULL;
+        size_t n = 0;
+        CLEANUP_ARRAY(addrs, n, in_addr_full_array_free);
+
+        FOREACH_ARRAY(res, resolvers, n_resolvers) {
+                if (!FLAGS_SET(res->transports, SD_DNS_ALPN_DOT))
+                        continue;
+
+                FOREACH_ARRAY(i, res->addrs, res->n_addrs) {
+                        _cleanup_(in_addr_full_freep) struct in_addr_full *addr = NULL;
+                        int r;
+
+                        addr = new0(struct in_addr_full, 1);
+                        if (!addr)
+                                return -ENOMEM;
+                        if (!GREEDY_REALLOC(addrs, n+1))
+                                return -ENOMEM;
+
+                        r = free_and_strdup(&addr->server_name, res->auth_name);
+                        if (r < 0)
+                                return r;
+                        addr->family = res->family;
+                        addr->port = res->port;
+                        addr->address = *i;
+
+                        addrs[n++] = TAKE_PTR(addr);
+                }
+        }
+
+        *ret_addrs = TAKE_PTR(addrs);
+        *ret_n_addrs = n;
+        return n;
+}
+
+int dns_resolvers_to_dot_strv(const sd_dns_resolver *resolvers, size_t n_resolvers, char ***ret_names) {
+        assert(ret_names);
+        int r;
+
+        _cleanup_strv_free_ char **names = NULL;
+        size_t len = 0;
+
+        struct in_addr_full **addrs = NULL;
+        size_t n = 0;
+        CLEANUP_ARRAY(addrs, n, in_addr_full_array_free);
+
+        r = dns_resolvers_to_dot_addrs(resolvers, n_resolvers, &addrs, &n);
+        if (r < 0)
+                return r;
+
+        FOREACH_ARRAY(addr, addrs, n) {
+                const char *name = in_addr_full_to_string(*addr);
+                if (!name)
+                        return -ENOMEM;
+                r = strv_extend_with_size(&names, &len, name);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret_names = TAKE_PTR(names);
+        return len;
+}
diff --git a/src/libsystemd-network/sd-dns-resolver.h b/src/libsystemd-network/sd-dns-resolver.h
new file mode 100644 (file)
index 0000000..79d00ba
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef SD_DNS_RESOLVER_H
+#define SD_DNS_RESOLVER_H
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "_sd-common.h"
+
+_SD_BEGIN_DECLARATIONS;
+
+typedef struct sd_dns_resolver sd_dns_resolver;
+
+/* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
+typedef enum sd_dns_alpn_flags {
+        /* There isn't really an alpn reserved for Do53 service, but designated resolvers may or may not offer
+         * Do53 service, so we should probably have a flag to represent this capability. Unfortunately DNR
+         * does not indicate the status to us.*/
+        SD_DNS_ALPN_DO53           = 1 << 0,
+        /* SD_DNS_ALPN_HTTP_1_1,                "http/1.1" [RFC9112] */
+        SD_DNS_ALPN_HTTP_2_TLS     = 1 << 1, /* "h2"  [RFC9113] [RFC9461] */
+        /* SD_DNS_ALPN_HTTP_2_TCP,              "h2c" [RFC9113] */
+        SD_DNS_ALPN_HTTP_3         = 1 << 2, /* "h3"  [RFC9114] [RFC9461] */
+        SD_DNS_ALPN_DOT            = 1 << 3, /* "dot" [RFC7858] [RFC9461] */
+        SD_DNS_ALPN_DOQ            = 1 << 4, /* "doq" [RFC9250] [RFC9461] */
+
+        _SD_ENUM_FORCE_S64(SD_DNS_ALPN)
+} sd_dns_alpn_flags;
+
+int sd_dns_resolver_get_priority(sd_dns_resolver *res, uint16_t *ret_priority);
+int sd_dns_resolver_get_adn(sd_dns_resolver *res, const char **ret_adn);
+int sd_dns_resolver_get_inet_addresses(sd_dns_resolver *res, const struct in_addr **ret_addrs, size_t *n);
+int sd_dns_resolver_get_inet6_addresses(sd_dns_resolver *res, const struct in6_addr **ret_addrs, size_t *n);
+int sd_dns_resolver_get_alpn(sd_dns_resolver *res, sd_dns_alpn_flags *ret_alpn);
+int sd_dns_resolver_get_port(sd_dns_resolver *res, uint16_t *ret_port);
+int sd_dns_resolver_get_dohpath(sd_dns_resolver *res, const char **ret_dohpath);
+
+sd_dns_resolver *sd_dns_resolver_unref(sd_dns_resolver *res);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dns_resolver, sd_dns_resolver_unref);
+
+_SD_END_DECLARATIONS;
+
+#endif /* SD_DNS_RESOLVER_H */
index 1ab09f26d6e304a1f114ba3538fb738609acfad0..f9991d86aba0284f142a8d18b895e45a224f271e 100644 (file)
@@ -4,8 +4,6 @@
 #  include <gcrypt.h>
 #endif
 
-#include "dns-resolver-internal.h"
-
 #include "alloc-util.h"
 #include "dns-domain.h"
 #include "escape.h"
@@ -2883,6 +2881,27 @@ size_t dns_packet_size_unfragmented(DnsPacket *p) {
         return LESS_BY(p->fragsize, udp_header_size(p->family));
 }
 
+static const char* const dns_svc_param_key_table[_DNS_SVC_PARAM_KEY_MAX_DEFINED] = {
+        [DNS_SVC_PARAM_KEY_MANDATORY]       = "mandatory",
+        [DNS_SVC_PARAM_KEY_ALPN]            = "alpn",
+        [DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN] = "no-default-alpn",
+        [DNS_SVC_PARAM_KEY_PORT]            = "port",
+        [DNS_SVC_PARAM_KEY_IPV4HINT]        = "ipv4hint",
+        [DNS_SVC_PARAM_KEY_ECH]             = "ech",
+        [DNS_SVC_PARAM_KEY_IPV6HINT]        = "ipv6hint",
+        [DNS_SVC_PARAM_KEY_DOHPATH]         = "dohpath",
+        [DNS_SVC_PARAM_KEY_OHTTP]           = "ohttp",
+};
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dns_svc_param_key, int);
+
+const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]) {
+        const char *p = dns_svc_param_key_to_string(i);
+        if (p)
+                return p;
+
+        return snprintf_ok(buf, DECIMAL_STR_MAX(uint16_t)+3, "key%i", i);
+}
+
 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
         [DNS_RCODE_SUCCESS]   = "SUCCESS",
         [DNS_RCODE_FORMERR]   = "FORMERR",
index ddee259b1f94e0b70ce72fa8e94eb4d054e15753..0b22e557cf65a80e9c0e3416a6a578531821b556 100644 (file)
@@ -370,6 +370,25 @@ DnsProtocol dns_protocol_from_string(const char *s) _pure_;
 
 extern const struct hash_ops dns_packet_hash_ops;
 
+/* https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys */
+enum {
+        DNS_SVC_PARAM_KEY_MANDATORY       = 0, /* RFC 9460 § 8 */
+        DNS_SVC_PARAM_KEY_ALPN            = 1, /* RFC 9460 § 7.1 */
+        DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN = 2, /* RFC 9460 § 7.1 */
+        DNS_SVC_PARAM_KEY_PORT            = 3, /* RFC 9460 § 7.2 */
+        DNS_SVC_PARAM_KEY_IPV4HINT        = 4, /* RFC 9460 § 7.3 */
+        DNS_SVC_PARAM_KEY_ECH             = 5, /* RFC 9460 */
+        DNS_SVC_PARAM_KEY_IPV6HINT        = 6, /* RFC 9460 § 7.3  */
+        DNS_SVC_PARAM_KEY_DOHPATH         = 7, /* RFC 9461 */
+        DNS_SVC_PARAM_KEY_OHTTP           = 8,
+        _DNS_SVC_PARAM_KEY_MAX_DEFINED,
+        DNS_SVC_PARAM_KEY_INVALID         = 65535 /* RFC 9460 */
+};
+
+const char* dns_svc_param_key_to_string(int i) _const_;
+const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]);
+#define FORMAT_DNS_SVC_PARAM_KEY(i) format_dns_svc_param_key(i, (char [DECIMAL_STR_MAX(uint16_t)+3]) {})
+
 static inline uint64_t SD_RESOLVED_FLAGS_MAKE(
                 DnsProtocol protocol,
                 int family,
index ed525883f20a09d376f093e38e9267ad74f6f638..6a4bd6aecdd6a2c26296546689f3eb4ef06b4a98 100644 (file)
@@ -2,8 +2,6 @@
 
 #include <math.h>
 
-#include "dns-resolver-internal.h"
-
 #include "alloc-util.h"
 #include "dns-domain.h"
 #include "dns-type.h"
diff --git a/src/shared/dns-resolver-internal.h b/src/shared/dns-resolver-internal.h
deleted file mode 100644 (file)
index e5c185c..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include <errno.h>
-
-#include "sd-dns-resolver.h"
-
-#include "macro.h"
-#include "list.h"
-#include "socket-netlink.h"
-
-/* https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys */
-enum {
-        DNS_SVC_PARAM_KEY_MANDATORY       = 0, /* RFC 9460 § 8 */
-        DNS_SVC_PARAM_KEY_ALPN            = 1, /* RFC 9460 § 7.1 */
-        DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN = 2, /* RFC 9460 § 7.1 */
-        DNS_SVC_PARAM_KEY_PORT            = 3, /* RFC 9460 § 7.2 */
-        DNS_SVC_PARAM_KEY_IPV4HINT        = 4, /* RFC 9460 § 7.3 */
-        DNS_SVC_PARAM_KEY_ECH             = 5, /* RFC 9460 */
-        DNS_SVC_PARAM_KEY_IPV6HINT        = 6, /* RFC 9460 § 7.3  */
-        DNS_SVC_PARAM_KEY_DOHPATH         = 7, /* RFC 9461 */
-        DNS_SVC_PARAM_KEY_OHTTP           = 8,
-        _DNS_SVC_PARAM_KEY_MAX_DEFINED,
-        DNS_SVC_PARAM_KEY_INVALID         = 65535 /* RFC 9460 */
-};
-
-const char* dns_svc_param_key_to_string(int i) _const_;
-const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]);
-#define FORMAT_DNS_SVC_PARAM_KEY(i) format_dns_svc_param_key(i, (char [DECIMAL_STR_MAX(uint16_t)+3]) {})
-
-/* Represents a "designated resolver" */
-/* typedef struct sd_dns_resolver sd_dns_resolver; */
-struct sd_dns_resolver {
-        uint16_t priority;
-        char *auth_name;
-        int family;
-        union in_addr_union *addrs;
-        size_t n_addrs;
-        sd_dns_alpn_flags transports;
-        uint16_t port;
-        char *dohpath;
-};
-
-void siphash24_compress_resolver(const sd_dns_resolver *res, struct siphash *state);
-
-int dns_resolver_transports_to_strv(sd_dns_alpn_flags transports, char ***ret);
-
-int dns_resolvers_to_dot_addrs(const sd_dns_resolver *resolvers, size_t n_resolvers,
-                struct in_addr_full ***ret_addrs, size_t *ret_n_addrs);
-
-int dns_resolver_prio_compare(const sd_dns_resolver *a, const sd_dns_resolver *b);
-
-int dnr_parse_svc_params(const uint8_t *option, size_t len, sd_dns_resolver *resolver);
-
-int dns_resolvers_to_dot_strv(const sd_dns_resolver *resolvers, size_t n_resolvers, char ***ret_names);
-
-void sd_dns_resolver_done(sd_dns_resolver *res);
-
-void dns_resolver_done_many(sd_dns_resolver *resolvers, size_t n);
index 548b26d8c39fa8cac5e8cf24621bc69858c1078f..8fc39429e5e96f2882270fc2d2c7ee663c8e622d 100644 (file)
@@ -154,7 +154,6 @@ shared_sources = files(
         'resize-fs.c',
         'resolve-util.c',
         'rm-rf.c',
-        'sd-dns-resolver.c',
         'securebits-util.c',
         'selinux-util.c',
         'serialize.c',
diff --git a/src/shared/sd-dns-resolver.c b/src/shared/sd-dns-resolver.c
deleted file mode 100644 (file)
index 548672c..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "dns-resolver-internal.h"
-#include "macro.h"
-#include "unaligned.h"
-#include "socket-netlink.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "strv.h"
-
-void sd_dns_resolver_done(sd_dns_resolver *res) {
-        assert(res);
-
-        res->auth_name = mfree(res->auth_name);
-        res->addrs = mfree(res->addrs);
-        res->dohpath = mfree(res->dohpath);
-}
-
-sd_dns_resolver *sd_dns_resolver_unref(sd_dns_resolver *res) {
-        if (!res)
-                return NULL;
-
-        sd_dns_resolver_done(res);
-        return mfree(res);
-}
-
-void dns_resolver_done_many(sd_dns_resolver resolvers[], size_t n) {
-        assert(resolvers || n == 0);
-
-        FOREACH_ARRAY(res, resolvers, n)
-                sd_dns_resolver_done(res);
-
-        free(resolvers);
-}
-
-int dns_resolver_prio_compare(const sd_dns_resolver *a, const sd_dns_resolver *b) {
-        return CMP(ASSERT_PTR(a)->priority, ASSERT_PTR(b)->priority);
-}
-
-int sd_dns_resolver_get_priority(sd_dns_resolver *res, uint16_t *ret_priority) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_priority, -EINVAL);
-
-        *ret_priority = res->priority;
-        return 0;
-}
-
-int sd_dns_resolver_get_adn(sd_dns_resolver *res, const char **ret_adn) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_adn, -EINVAL);
-
-        /* Without adn only Do53 can be supported */
-        if (!res->auth_name)
-                return -ENODATA;
-
-        *ret_adn = res->auth_name;
-        return 0;
-}
-
-int sd_dns_resolver_get_inet_addresses(sd_dns_resolver *res, const struct in_addr **ret_addrs, size_t
-                *ret_n_addrs) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_addrs, -EINVAL);
-        assert_return(ret_n_addrs, -EINVAL);
-        assert_return(res->family == AF_INET, -EINVAL);
-
-        /* ADN-only mode has no addrs */
-        if (res->n_addrs == 0)
-                return -ENODATA;
-
-        struct in_addr *addrs = new(struct in_addr, res->n_addrs);
-        if (!addrs)
-                return -ENOMEM;
-
-        for (size_t i = 0; i < res->n_addrs; i++)
-                addrs[i] = res->addrs[i].in;
-        *ret_addrs = addrs;
-        *ret_n_addrs = res->n_addrs;
-
-        return 0;
-}
-
-int sd_dns_resolver_get_inet6_addresses(sd_dns_resolver *res, const struct in6_addr **ret_addrs, size_t
-                *ret_n_addrs) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_addrs, -EINVAL);
-        assert_return(ret_n_addrs, -EINVAL);
-        assert_return(res->family == AF_INET6, -EINVAL);
-
-        /* ADN-only mode has no addrs */
-        if (res->n_addrs == 0)
-                return -ENODATA;
-
-        struct in6_addr *addrs = new(struct in6_addr, res->n_addrs);
-        if (!addrs)
-                return -ENOMEM;
-
-        for (size_t i = 0; i < res->n_addrs; i++)
-                addrs[i] = res->addrs[i].in6;
-        *ret_addrs = addrs;
-        *ret_n_addrs = res->n_addrs;
-
-        return 0;
-}
-
-int sd_dns_resolver_get_alpn(sd_dns_resolver *res, sd_dns_alpn_flags *ret_alpn) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_alpn, -EINVAL);
-
-        /* ADN-only mode has no transports */
-        if (!res->transports)
-                return -ENODATA;
-
-        *ret_alpn = res->transports;
-        return 0;
-}
-
-int sd_dns_resolver_get_port(sd_dns_resolver *res, uint16_t *ret_port) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_port, -EINVAL);
-
-        /* port = 0 is the default port */
-        *ret_port = res->port;
-        return 0;
-}
-
-int sd_dns_resolver_get_dohpath(sd_dns_resolver *res, const char **ret_dohpath) {
-        assert_return(res, -EINVAL);
-        assert_return(ret_dohpath, -EINVAL);
-
-        /* only present in DoH resolvers */
-        if (!res->dohpath)
-                return -ENODATA;
-
-        *ret_dohpath = res->dohpath;
-        return 0;
-}
-
-void siphash24_compress_resolver(const sd_dns_resolver *res, struct siphash *state) {
-        assert(res);
-
-        siphash24_compress_typesafe(res->priority, state);
-        siphash24_compress_typesafe(res->transports, state);
-        siphash24_compress_typesafe(res->port, state);
-
-        siphash24_compress_string(res->auth_name, state);
-        siphash24_compress_string(res->dohpath, state);
-
-        siphash24_compress_typesafe(res->family, state);
-        FOREACH_ARRAY(addr, res->addrs, res->n_addrs)
-                siphash24_compress_typesafe(*addr, state);
-}
-
-static const char* const dns_svc_param_key_table[_DNS_SVC_PARAM_KEY_MAX_DEFINED] = {
-        [DNS_SVC_PARAM_KEY_MANDATORY]       = "mandatory",
-        [DNS_SVC_PARAM_KEY_ALPN]            = "alpn",
-        [DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN] = "no-default-alpn",
-        [DNS_SVC_PARAM_KEY_PORT]            = "port",
-        [DNS_SVC_PARAM_KEY_IPV4HINT]        = "ipv4hint",
-        [DNS_SVC_PARAM_KEY_ECH]             = "ech",
-        [DNS_SVC_PARAM_KEY_IPV6HINT]        = "ipv6hint",
-        [DNS_SVC_PARAM_KEY_DOHPATH]         = "dohpath",
-        [DNS_SVC_PARAM_KEY_OHTTP]           = "ohttp",
-};
-DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dns_svc_param_key, int);
-
-const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]) {
-        assert(buf);
-
-        const char *p = dns_svc_param_key_to_string(i);
-        if (p)
-                return p;
-
-        return snprintf_ok(buf, DECIMAL_STR_MAX(uint16_t)+3, "key%i", i);
-}
-
-int dns_resolver_transports_to_strv(sd_dns_alpn_flags transports, char ***ret) {
-        _cleanup_strv_free_ char **ans = NULL;
-
-        assert(ret);
-
-        if (FLAGS_SET(transports, SD_DNS_ALPN_DO53)) {
-                /* Do53 has no ALPN, this flag is only for our own usage. */
-        }
-
-        if (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_2_TLS))
-                if (strv_extend(&ans, "h2") < 0)
-                        return -ENOMEM;
-        if (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_3))
-                if (strv_extend(&ans, "h3") < 0)
-                        return -ENOMEM;
-        if (FLAGS_SET(transports, SD_DNS_ALPN_DOT))
-                if (strv_extend(&ans, "dot") < 0)
-                        return -ENOMEM;
-        if (FLAGS_SET(transports, SD_DNS_ALPN_DOQ))
-                if (strv_extend(&ans, "doq") < 0)
-                        return -ENOMEM;
-
-        *ret = TAKE_PTR(ans);
-        return 0;
-}
-
-int dnr_parse_svc_params(const uint8_t *option, size_t len, sd_dns_resolver *resolver) {
-        size_t offset = 0;
-        int r;
-
-        assert(option || len == 0);
-        assert(resolver);
-
-        sd_dns_alpn_flags transports = 0;
-        uint16_t port = 0;
-        _cleanup_free_ char *dohpath = NULL;
-        bool alpn = false;
-
-        uint16_t lastkey = 0;
-        while (offset < len) {
-                if (offset + 4 > len)
-                        return -EBADMSG;
-
-                uint16_t key = unaligned_read_be16(&option[offset]);
-                offset += 2;
-
-                /* RFC9460 § 2.2 SvcParam MUST appear in strictly increasing numeric order */
-                if (lastkey >= key)
-                        return -EBADMSG;
-                lastkey = key;
-
-                uint16_t plen = unaligned_read_be16(&option[offset]);
-                offset += 2;
-                if (offset + plen > len)
-                        return -EBADMSG;
-
-                switch (key) {
-                /* Mandatory keys must be understood by the client, otherwise the record should be discarded.
-                 * Automatic mandatory keys must not appear in the mandatory parameter, so these are all
-                 * supplementary. We don't understand any supplementary keys, so if the mandatory parameter
-                 * is present, we cannot use this record.*/
-                case DNS_SVC_PARAM_KEY_MANDATORY:
-                        if (plen > 0)
-                                return -EBADMSG;
-                        break;
-
-                case DNS_SVC_PARAM_KEY_ALPN:
-                        if (plen == 0)
-                                return 0;
-                        alpn = true; /* alpn is required. Record that the requirement is met. */
-
-                        size_t poff = offset;
-                        size_t pend = offset + plen;
-                        while (poff < pend) {
-                                uint8_t alen = option[poff++];
-                                if (poff + alen > len)
-                                        return -EBADMSG;
-                                if (memcmp_nn(&option[poff], alen, "dot", STRLEN("dot")) == 0)
-                                        transports |= SD_DNS_ALPN_DOT;
-                                if (memcmp_nn(&option[poff], alen, "h2", STRLEN("h2")) == 0)
-                                        transports |= SD_DNS_ALPN_HTTP_2_TLS;
-                                if (memcmp_nn(&option[poff], alen, "h3", STRLEN("h3")) == 0)
-                                        transports |= SD_DNS_ALPN_HTTP_3;
-                                if (memcmp_nn(&option[poff], alen, "doq", STRLEN("doq")) == 0)
-                                        transports |= SD_DNS_ALPN_DOQ;
-                                poff += alen;
-                        }
-                        if (poff != pend)
-                                return -EBADMSG;
-                        break;
-
-                case DNS_SVC_PARAM_KEY_PORT:
-                        if (plen != sizeof(uint16_t))
-                                return -EBADMSG;
-                        port = unaligned_read_be16(&option[offset]);
-                        /* Server should indicate default port by omitting this param */
-                        if (port == 0)
-                                return -EBADMSG;
-                        break;
-
-                /* RFC9463 § 5.1 service params MUST NOT include ipv4hint/ipv6hint */
-                case DNS_SVC_PARAM_KEY_IPV4HINT:
-                case DNS_SVC_PARAM_KEY_IPV6HINT:
-                        return -EBADMSG;
-
-                case DNS_SVC_PARAM_KEY_DOHPATH:
-                        r = make_cstring((const char*) &option[offset], plen,
-                                        MAKE_CSTRING_REFUSE_TRAILING_NUL, &dohpath);
-                        if (ERRNO_IS_NEG_RESOURCE(r))
-                                return r;
-                        if (r < 0)
-                                return -EBADMSG;
-                        /* dohpath is a RFC6750 URI template. We don't parse these, but at least check the
-                         * charset is reasonable. */
-                        if (!in_charset(dohpath, URI_VALID "{}"))
-                                return -EBADMSG;
-                        break;
-
-                default:
-                        break;
-                }
-                offset += plen;
-        }
-        if (offset != len)
-                return -EBADMSG;
-
-        /* DNR cannot be used without alpn */
-        if (!alpn)
-                return -EBADMSG;
-
-        /* RFC9461 § 5: If the [SvcParam] indicates support for HTTP, "dohpath" MUST be present. */
-        if (!dohpath && (FLAGS_SET(transports, SD_DNS_ALPN_HTTP_2_TLS) ||
-                        FLAGS_SET(transports, SD_DNS_ALPN_HTTP_3)))
-                return -EBADMSG;
-
-        /* No useful transports */
-        if (!transports)
-                return 0;
-
-        resolver->transports = transports;
-        resolver->port = port;
-        free_and_replace(resolver->dohpath, dohpath);
-        return transports;
-}
-
-int dns_resolvers_to_dot_addrs(const sd_dns_resolver *resolvers, size_t n_resolvers,
-                struct in_addr_full ***ret_addrs, size_t *ret_n_addrs) {
-        assert(ret_addrs);
-        assert(ret_n_addrs);
-        assert(resolvers || n_resolvers == 0);
-
-        struct in_addr_full **addrs = NULL;
-        size_t n = 0;
-        CLEANUP_ARRAY(addrs, n, in_addr_full_array_free);
-
-        FOREACH_ARRAY(res, resolvers, n_resolvers) {
-                if (!FLAGS_SET(res->transports, SD_DNS_ALPN_DOT))
-                        continue;
-
-                FOREACH_ARRAY(i, res->addrs, res->n_addrs) {
-                        _cleanup_(in_addr_full_freep) struct in_addr_full *addr = NULL;
-                        int r;
-
-                        addr = new0(struct in_addr_full, 1);
-                        if (!addr)
-                                return -ENOMEM;
-                        if (!GREEDY_REALLOC(addrs, n+1))
-                                return -ENOMEM;
-
-                        r = free_and_strdup(&addr->server_name, res->auth_name);
-                        if (r < 0)
-                                return r;
-                        addr->family = res->family;
-                        addr->port = res->port;
-                        addr->address = *i;
-
-                        addrs[n++] = TAKE_PTR(addr);
-                }
-        }
-
-        *ret_addrs = TAKE_PTR(addrs);
-        *ret_n_addrs = n;
-        return n;
-}
-
-int dns_resolvers_to_dot_strv(const sd_dns_resolver *resolvers, size_t n_resolvers, char ***ret_names) {
-        assert(ret_names);
-        int r;
-
-        _cleanup_strv_free_ char **names = NULL;
-        size_t len = 0;
-
-        struct in_addr_full **addrs = NULL;
-        size_t n = 0;
-        CLEANUP_ARRAY(addrs, n, in_addr_full_array_free);
-
-        r = dns_resolvers_to_dot_addrs(resolvers, n_resolvers, &addrs, &n);
-        if (r < 0)
-                return r;
-
-        FOREACH_ARRAY(addr, addrs, n) {
-                const char *name = in_addr_full_to_string(*addr);
-                if (!name)
-                        return -ENOMEM;
-                r = strv_extend_with_size(&names, &len, name);
-                if (r < 0)
-                        return r;
-        }
-
-        *ret_names = TAKE_PTR(names);
-        return len;
-}
index edcbc873e9a00a461b642cfd1a171e0d5c14ab99..06ba4cbc075c58a5ca8425dfce40e86272519133 100644 (file)
@@ -35,7 +35,6 @@ _not_installed_headers = [
         'sd-dhcp6-lease.h',
         'sd-dhcp6-option.h',
         'sd-dhcp6-protocol.h',
-        'sd-dns-resolver.h',
         'sd-ipv4acd.h',
         'sd-ipv4ll.h',
         'sd-lldp-rx.h',
diff --git a/src/systemd/sd-dns-resolver.h b/src/systemd/sd-dns-resolver.h
deleted file mode 100644 (file)
index 79d00ba..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef SD_DNS_RESOLVER_H
-#define SD_DNS_RESOLVER_H
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "_sd-common.h"
-
-_SD_BEGIN_DECLARATIONS;
-
-typedef struct sd_dns_resolver sd_dns_resolver;
-
-/* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
-typedef enum sd_dns_alpn_flags {
-        /* There isn't really an alpn reserved for Do53 service, but designated resolvers may or may not offer
-         * Do53 service, so we should probably have a flag to represent this capability. Unfortunately DNR
-         * does not indicate the status to us.*/
-        SD_DNS_ALPN_DO53           = 1 << 0,
-        /* SD_DNS_ALPN_HTTP_1_1,                "http/1.1" [RFC9112] */
-        SD_DNS_ALPN_HTTP_2_TLS     = 1 << 1, /* "h2"  [RFC9113] [RFC9461] */
-        /* SD_DNS_ALPN_HTTP_2_TCP,              "h2c" [RFC9113] */
-        SD_DNS_ALPN_HTTP_3         = 1 << 2, /* "h3"  [RFC9114] [RFC9461] */
-        SD_DNS_ALPN_DOT            = 1 << 3, /* "dot" [RFC7858] [RFC9461] */
-        SD_DNS_ALPN_DOQ            = 1 << 4, /* "doq" [RFC9250] [RFC9461] */
-
-        _SD_ENUM_FORCE_S64(SD_DNS_ALPN)
-} sd_dns_alpn_flags;
-
-int sd_dns_resolver_get_priority(sd_dns_resolver *res, uint16_t *ret_priority);
-int sd_dns_resolver_get_adn(sd_dns_resolver *res, const char **ret_adn);
-int sd_dns_resolver_get_inet_addresses(sd_dns_resolver *res, const struct in_addr **ret_addrs, size_t *n);
-int sd_dns_resolver_get_inet6_addresses(sd_dns_resolver *res, const struct in6_addr **ret_addrs, size_t *n);
-int sd_dns_resolver_get_alpn(sd_dns_resolver *res, sd_dns_alpn_flags *ret_alpn);
-int sd_dns_resolver_get_port(sd_dns_resolver *res, uint16_t *ret_port);
-int sd_dns_resolver_get_dohpath(sd_dns_resolver *res, const char **ret_dohpath);
-
-sd_dns_resolver *sd_dns_resolver_unref(sd_dns_resolver *res);
-_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dns_resolver, sd_dns_resolver_unref);
-
-_SD_END_DECLARATIONS;
-
-#endif /* SD_DNS_RESOLVER_H */