Only in systemd-252: build
diff --color -ru systemd-252-orig/man/resolved.conf.xml systemd-252/man/resolved.conf.xml
--- systemd-252-orig/man/resolved.conf.xml	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/man/resolved.conf.xml	2025-02-11 19:51:04.790797439 +0800
@@ -267,6 +267,19 @@
       </varlistentry>
 
       <varlistentry>
+        <term><varname>RefuseRecordTypes=</varname></term>
+        <listitem><para>Takes a list of DNS record types separated by space.
+        Specified record types in each query will be refused. This option can be specified multiple times.
+        If an empty string is specified, then all previous assignments are cleared.</para>
+        <para>Examples:
+        <programlisting>RefuseRecordTypes=AAAA SRV TXT</programlisting>
+        </para>
+        <para>Note that to refuse AAAA record (unlike SRV, TXT, etc.) completely, please also disable IPv6 stack in kernel
+        with "sysctl -w net.ipv6.conf.all.disable_ipv6=1".</para>
+        <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><varname>DNSStubListener=</varname></term>
         <listitem><para>Takes a boolean argument or one of <literal>udp</literal> and
         <literal>tcp</literal>. If <literal>udp</literal>, a DNS stub resolver will listen for UDP requests
diff --color -ru systemd-252-orig/src/libsystemd/sd-bus/bus-common-errors.h systemd-252/src/libsystemd/sd-bus/bus-common-errors.h
--- systemd-252-orig/src/libsystemd/sd-bus/bus-common-errors.h	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/libsystemd/sd-bus/bus-common-errors.h	2025-02-11 20:15:45.661211288 +0800
@@ -69,6 +69,7 @@
 #define BUS_ERROR_ABORTED                      "org.freedesktop.resolve1.Aborted"
 #define BUS_ERROR_NO_SUCH_SERVICE              "org.freedesktop.resolve1.NoSuchService"
 #define BUS_ERROR_DNSSEC_FAILED                "org.freedesktop.resolve1.DnssecFailed"
+#define BUS_ERROR_DNS_REFUSED                  "org.freedesktop.resolve1.DnsRefused"
 #define BUS_ERROR_NO_TRUST_ANCHOR              "org.freedesktop.resolve1.NoTrustAnchor"
 #define BUS_ERROR_RR_TYPE_UNSUPPORTED          "org.freedesktop.resolve1.ResourceRecordTypeUnsupported"
 #define BUS_ERROR_NO_SUCH_LINK                 "org.freedesktop.resolve1.NoSuchLink"
diff --color -ru systemd-252-orig/src/resolve/resolved-bus.c systemd-252/src/resolve/resolved-bus.c
--- systemd-252-orig/src/resolve/resolved-bus.c	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-bus.c	2025-02-11 19:56:00.364057989 +0800
@@ -26,6 +26,22 @@
 
 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_resolve_support, resolve_support, ResolveSupport);
 
+static int dns_query_new_for_bus(
+                Manager *m,
+                DnsQuery **ret,
+                DnsQuestion *question_utf8,
+                DnsQuestion *question_idna,
+                DnsPacket *question_bypass,
+                int ifindex,
+                uint64_t flags,
+                sd_bus_error *error) {
+        int r;
+        r = dns_query_new(m, ret, question_utf8, question_idna, question_bypass, ifindex, flags);
+        if (r == -ENOANO)
+                return sd_bus_error_set(error, BUS_ERROR_DNS_REFUSED, "DNS query type refused.");
+        return r;
+}
+
 static int query_on_bus_track(sd_bus_track *t, void *userdata) {
         DnsQuery *q = ASSERT_PTR(userdata);
 
@@ -509,7 +525,7 @@
 
         bus_client_log(message, "hostname resolution");
 
-        r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, NULL, ifindex, flags);
+        r = dns_query_new_for_bus(m, &q, question_utf8, question_idna ?: question_utf8, NULL, ifindex, flags, error);
         if (r < 0)
                 return r;
 
@@ -650,7 +666,7 @@
 
         bus_client_log(message, "address resolution");
 
-        r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
+        r = dns_query_new_for_bus(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH, error);
         if (r < 0)
                 return r;
 
@@ -829,7 +845,7 @@
 
         /* Setting SD_RESOLVED_CLAMP_TTL: let's request that the TTL is fixed up for locally cached entries,
          * after all we return it in the wire format blob. */
-        r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH|SD_RESOLVED_CLAMP_TTL);
+        r = dns_query_new_for_bus(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH|SD_RESOLVED_CLAMP_TTL, error);
         if (r < 0)
                 return r;
 
@@ -1188,6 +1204,8 @@
                 return r;
 
         r = dns_query_new(q->manager, &aux, question, question, NULL, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
+        if (r == -ENOANO)
+                return reply_method_errorf(q, BUS_ERROR_DNS_REFUSED, "DNS query type refused.");
         if (r < 0)
                 return r;
 
@@ -1351,7 +1369,7 @@
 
         bus_client_log(message, "service resolution");
 
-        r = dns_query_new(m, &q, question_utf8, question_idna, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
+        r = dns_query_new_for_bus(m, &q, question_utf8, question_idna, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH, error);
         if (r < 0)
                 return r;
 
diff --color -ru systemd-252-orig/src/resolve/resolved-conf.c systemd-252/src/resolve/resolved-conf.c
--- systemd-252-orig/src/resolve/resolved-conf.c	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-conf.c	2025-02-11 20:28:23.692202708 +0800
@@ -501,3 +501,39 @@
         return 0;
 
 }
+
+int config_parse_record_types(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+        Set **types = ASSERT_PTR(data);
+        int r;
+        if (isempty(rvalue)) {
+                *types = set_free(*types);
+                return 1;
+        }
+        for (const char *p = rvalue;;) {
+                _cleanup_free_ char *word = NULL;
+                r = extract_first_word(&p, &word, NULL, 0);
+                if (r < 0)
+                        return log_syntax(unit, LOG_WARNING, filename, line, r,
+                                   "Failed to parse refused record types, ignoring.");
+                if (r == 0)
+                        return 1;
+                r = dns_type_from_string(word);
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid DNS record type, ignoring: %s", word);
+                        continue;
+                }
+                r = set_ensure_put(types, NULL, INT_TO_PTR(r));
+                if (r < 0)
+                        return log_oom();
+        }
+}
diff --color -ru systemd-252-orig/src/resolve/resolved-conf.h systemd-252/src/resolve/resolved-conf.h
--- systemd-252-orig/src/resolve/resolved-conf.h	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-conf.h	2025-02-11 19:57:13.195680286 +0800
@@ -20,3 +20,4 @@
 CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_service_type);
 CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_txt);
 CONFIG_PARSER_PROTOTYPE(config_parse_dns_stub_listener_extra);
+CONFIG_PARSER_PROTOTYPE(config_parse_record_types);
diff --color -ru systemd-252-orig/src/resolve/resolved.conf.in systemd-252/src/resolve/resolved.conf.in
--- systemd-252-orig/src/resolve/resolved.conf.in	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved.conf.in	2025-02-11 20:10:50.779392657 +0800
@@ -32,3 +32,4 @@
 #DNSStubListenerExtra=
 #ReadEtcHosts=yes
 #ResolveUnicastSingleLabel=no
+#RefuseRecordTypes=
diff --color -ru systemd-252-orig/src/resolve/resolved-dns-query.c systemd-252/src/resolve/resolved-dns-query.c
--- systemd-252-orig/src/resolve/resolved-dns-query.c	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-dns-query.c	2025-02-11 21:31:07.819773334 +0800
@@ -114,7 +114,7 @@
         dns_search_domain_unref(c->search_domain);
         c->search_domain = dns_search_domain_ref(next);
 
-        return 1;
+        return 0;
 }
 
 static int dns_query_candidate_add_transaction(
@@ -437,6 +437,38 @@
         return mfree(q);
 }
 
+static int validate_and_mangle_question(DnsQuestion **question, Set *types) {
+        int r;
+        if (set_isempty(types))
+                return 0; /* No filtering configured. Let's shortcut. */
+        bool has_good = false, has_bad = false;
+        DnsResourceKey *key;
+        DNS_QUESTION_FOREACH(key, *question)
+                if (set_contains(types, INT_TO_PTR(key->type)))
+                        has_bad = true;
+                else
+                        has_good = true;
+        if (has_bad && !has_good)
+                return -ENOANO; /* All bad, refuse.*/
+        if (!has_bad) {
+                assert(has_good); /* The question should have at least one key. */
+                return 0; /* All good. Not necessary to filter. */
+        }
+        /* Mangle the question suppressing bad entries, leaving good entries */
+        _cleanup_(dns_question_unrefp) DnsQuestion *new_question = dns_question_new(dns_question_size(*question));
+        if (!new_question)
+                return -ENOMEM;
+        DnsQuestionItem *item;
+        DNS_QUESTION_FOREACH_ITEM(item, *question) {
+                if (set_contains(types, INT_TO_PTR(item->key->type)))
+                        continue;
+                r = dns_question_add_raw(new_question, item->key, item->flags);
+                if (r < 0)
+                        return r;
+        }
+        return free_and_replace_full(*question, new_question, dns_question_unref);
+}
+
 int dns_query_new(
                 Manager *m,
                 DnsQuery **ret,
@@ -453,6 +485,14 @@
 
         assert(m);
 
+        /* Check for records that is refused and refuse query for the records if matched in configuration */
+        r = validate_and_mangle_question(&question_utf8, m->refuse_record_types);
+        if (r < 0)
+                return r;
+        r = validate_and_mangle_question(&question_idna, m->refuse_record_types);
+        if (r < 0)
+                return r;
+
         if (question_bypass) {
                 /* It's either a "bypass" query, or a regular one, but can't be both. */
                 if (question_utf8 || question_idna)
diff --color -ru systemd-252-orig/src/resolve/resolved-dns-stub.c systemd-252/src/resolve/resolved-dns-stub.c
--- systemd-252-orig/src/resolve/resolved-dns-stub.c	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-dns-stub.c	2025-02-11 20:02:05.922932360 +0800
@@ -976,6 +976,8 @@
                                   SD_RESOLVED_NO_SEARCH|
                                   (DNS_PACKET_DO(p) ? SD_RESOLVED_REQUIRE_PRIMARY : 0)|
                                   SD_RESOLVED_CLAMP_TTL);
+        if (r == -ENOANO) /* Refuse query if there is -ENOANO */
+                return (void) dns_stub_send_failure(m, l, s, p, DNS_RCODE_REFUSED, false);
         if (r < 0) {
                 log_error_errno(r, "Failed to generate query object: %m");
                 dns_stub_send_failure(m, l, s, p, DNS_RCODE_SERVFAIL, false);
diff --color -ru systemd-252-orig/src/resolve/resolved-gperf.gperf systemd-252/src/resolve/resolved-gperf.gperf
--- systemd-252-orig/src/resolve/resolved-gperf.gperf	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-gperf.gperf	2025-02-11 20:02:21.694919325 +0800
@@ -32,3 +32,4 @@
 Resolve.ResolveUnicastSingleLabel, config_parse_bool,                    0,                   offsetof(Manager, resolve_unicast_single_label)
 Resolve.DNSStubListenerExtra,      config_parse_dns_stub_listener_extra, 0,                   offsetof(Manager, dns_extra_stub_listeners)
 Resolve.CacheFromLocalhost,        config_parse_bool,                    0,                   offsetof(Manager, cache_from_localhost)
+Resolve.RefuseRecordTypes,         config_parse_record_types,            0,                   offsetof(Manager, refuse_record_types)
diff --color -ru systemd-252-orig/src/resolve/resolved-manager.c systemd-252/src/resolve/resolved-manager.c
--- systemd-252-orig/src/resolve/resolved-manager.c	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-manager.c	2025-02-11 21:45:19.907339144 +0800
@@ -682,6 +682,7 @@
         dnstls_manager_free(m);
 #endif
 
+        set_free(m->refuse_record_types);
         hashmap_free(m->links);
         hashmap_free(m->dns_transactions);
 
diff --color -ru systemd-252-orig/src/resolve/resolved-manager.h systemd-252/src/resolve/resolved-manager.h
--- systemd-252-orig/src/resolve/resolved-manager.h	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-manager.h	2025-02-11 20:03:12.814892100 +0800
@@ -134,6 +134,9 @@
         struct stat etc_hosts_stat;
         bool read_etc_hosts;
 
+        /* List of refused DNS Record Types*/
+        Set *refuse_record_types;
+
         OrderedSet *dns_extra_stub_listeners;
 
         /* Local DNS stub on 127.0.0.53:53 */
diff --color -ru systemd-252-orig/src/resolve/resolved-varlink.c systemd-252/src/resolve/resolved-varlink.c
--- systemd-252-orig/src/resolve/resolved-varlink.c	2022-11-01 02:59:18.000000000 +0800
+++ systemd-252/src/resolve/resolved-varlink.c	2025-02-11 20:27:44.835818462 +0800
@@ -20,6 +20,22 @@
         free(p->name);
 }
 
+static int dns_query_new_for_varlink(
+                Manager *m,
+                DnsQuery **ret,
+                DnsQuestion *question_utf8,
+                DnsQuestion *question_idna,
+                DnsPacket *question_bypass,
+                int ifindex,
+                uint64_t flags,
+                Varlink *link) {
+        int r;
+        r = dns_query_new(m, ret, question_utf8, question_idna, question_bypass, ifindex, flags);
+        if (r == -ENOANO)
+                return varlink_error(link, "io.systemd.Resolve.QueryRefused", NULL);
+        return r;
+}
+
 static int reply_query_state(DnsQuery *q) {
 
         assert(q);
@@ -343,7 +359,7 @@
         if (r < 0 && r != -EALREADY)
                 return r;
 
-        r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, NULL, p.ifindex, p.flags);
+        r = dns_query_new_for_varlink(m, &q, question_utf8, question_idna ?: question_utf8, NULL, p.ifindex, p.flags, link);
         if (r < 0)
                 return r;
 
@@ -512,7 +528,7 @@
         if (r < 0)
                 return r;
 
-        r = dns_query_new(m, &q, question, question, NULL, p.ifindex, p.flags|SD_RESOLVED_NO_SEARCH);
+        r = dns_query_new_for_varlink(m, &q, question, question, NULL, p.ifindex, p.flags|SD_RESOLVED_NO_SEARCH, link);
         if (r < 0)
                 return r;
 
Only in systemd-252/tools/chromiumos: __pycache__
