diff --git a/man/resolvectl.xml b/man/resolvectl.xml
index 7662349cc5..c87b6fd44b 100644
--- a/man/resolvectl.xml
+++ b/man/resolvectl.xml
@@ -55,7 +55,19 @@
queryHOSTNAME|ADDRESS…
- Resolve domain names, IPv4 and IPv6 addresses.
+ Resolve domain names, as well as IPv4 and IPv6 addresses. When used in conjuntion
+ with or (see below), resolves low-level DNS
+ resource records.
+
+ If a single-label domain name is specified it is searched for according to the configured
+ search domains — unless or
+ / are specified, both of which turn this logic
+ off.
+
+ If an international domain name is specified, it is automatically translated according to IDNA
+ rules when resolved via classic DNS — but not for look-ups via MulticastDNS or LLMNR. If
+ / is used IDNA translation is turned off and domain
+ names are processed as specified.
@@ -233,11 +245,19 @@
CLASSCLASS
- Specifies the DNS resource record type (e.g. A, AAAA, MX, …) and class (e.g. IN, ANY, …) to
- look up. If these options are used a DNS resource record set matching the specified class and type is
- requested. The class defaults to IN if only a type is specified.
- The special value help may be used to list known values.
-
+ When used in conjunction with the query command, specifies the DNS
+ resource record type (e.g. A, AAAA, MX, …) and class (e.g. IN, ANY, …) to look up. If these options
+ are used a DNS resource record set matching the specified class and type is requested. The class
+ defaults to IN if only a type is specified. The special value help may be used to
+ list known values.
+
+ Without these options resolvectl query provides high-level domain name to
+ address and address to domain name resolution. With these options it provides low-level DNS resource
+ record resolution. The search domain logic is automatically turned off when these options are used,
+ i.e. specified domain names need to be fully qualified domain names. Moreover, IDNA internal domain
+ name translation is turned off as well, i.e. international domain names should be specified in
+ xn--… notation, unless look-up in MulticastDNS/LLMNR is desired, in which case
+ UTF-8 characters should be used.
@@ -324,9 +344,11 @@
BOOL
- Takes a boolean parameter. If true (the default), any specified single-label hostnames will be
- searched in the domains configured in the search domain list, if it is non-empty. Otherwise, the search domain
- logic is disabled.
+ Takes a boolean parameter. If true (the default), any specified single-label
+ hostnames will be searched in the domains configured in the search domain list, if it is
+ non-empty. Otherwise, the search domain logic is disabled. Note that this option has no effect if
+ is used (see above), in which case the search domain logic is
+ unconditionally turned off.
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index e7ee735428..6301b6ba09 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -407,19 +407,51 @@ static int output_rr_packet(const void *d, size_t l, int ifindex) {
return 0;
}
+static int idna_candidate(const char *name, char **ret) {
+ _cleanup_free_ char *idnafied = NULL;
+ int r;
+
+ assert(name);
+ assert(ret);
+
+ r = dns_name_apply_idna(name, &idnafied);
+ if (r < 0)
+ return log_error_errno(r, "Failed to apply IDNA to name '%s': %m", name);
+ if (r > 0 && !streq(name, idnafied)) {
+ *ret = TAKE_PTR(idnafied);
+ return true;
+ }
+
+ *ret = NULL;
+ return false;
+}
+
static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_t type, bool warn_missing) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *idnafied = NULL;
+ bool needs_authentication = false;
unsigned n = 0;
uint64_t flags;
- int r;
usec_t ts;
- bool needs_authentication = false;
+ int r;
assert(name);
log_debug("Resolving %s %s %s (interface %s).", name, dns_class_to_string(class), dns_type_to_string(type), isempty(arg_ifname) ? "*" : arg_ifname);
+ if (dns_name_is_single_label(name))
+ log_notice("(Note that search domains are not appended when resolving raw record types. "
+ "Please specify fully qualified domain names when resolving raw records, or remove --type= switch from invocation in order to request regular hostname resolution.)");
+
+ r = idna_candidate(name, &idnafied);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ log_notice("(Note that IDNA translation is not applied when resolving raw record types. "
+ "Please specify translated domain names — i.e. '%s' — when resolving raw records, or remove --type= switch from invocation in order to request regular hostname resolution.",
+ idnafied);
+
r = bus_message_new_method_call(bus, &req, bus_resolve_mgr, "ResolveRecord");
if (r < 0)
return bus_log_create_error(r);