]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: fix the canonical name returned by hosts lookup by address
authorDmitry V. Levin <ldv@strace.io>
Mon, 10 Jul 2023 08:00:00 +0000 (08:00 +0000)
committerDmitry V. Levin <ldv@strace.io>
Fri, 14 Jul 2023 13:13:53 +0000 (13:13 +0000)
In etc_hosts_lookup_by_address(), make sure the canonical name of the given
address is returned first in the list of names that address resolves to.

Resolves: #25088

src/resolve/resolved-etc-hosts.c
test/units/testsuite-75.sh

index aac7d986ba028e86a1aaf26ba0a56123c322a33b..fd5c6b78148794ea2c40c2e734c71d68c8509084 100644 (file)
@@ -381,6 +381,20 @@ static int manager_etc_hosts_read(Manager *m) {
         return 1;
 }
 
+static int answer_add_ptr(DnsAnswer *answer, DnsResourceKey *key, const char *name) {
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+
+        rr = dns_resource_record_new(key);
+        if (!rr)
+                return -ENOMEM;
+
+        rr->ptr.name = strdup(name);
+        if (!rr->ptr.name)
+                return -ENOMEM;
+
+        return dns_answer_add(answer, rr, 0, DNS_ANSWER_AUTHENTICATED, NULL);
+}
+
 static int etc_hosts_lookup_by_address(
                 EtcHosts *hosts,
                 DnsQuestion *q,
@@ -427,18 +441,17 @@ static int etc_hosts_lookup_by_address(
                 if (r < 0)
                         return r;
 
-                SET_FOREACH(n, item->names) {
-                        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
-
-                        rr = dns_resource_record_new(found_ptr);
-                        if (!rr)
-                                return -ENOMEM;
+                if (item->canonical_name) {
+                        r = answer_add_ptr(*answer, found_ptr, item->canonical_name);
+                        if (r < 0)
+                                return r;
+                }
 
-                        rr->ptr.name = strdup(n);
-                        if (!rr->ptr.name)
-                                return -ENOMEM;
+                SET_FOREACH(n, item->names) {
+                        if (n == item->canonical_name)
+                                continue;
 
-                        r = dns_answer_add(*answer, rr, 0, DNS_ANSWER_AUTHENTICATED, NULL);
+                        r = answer_add_ptr(*answer, found_ptr, n);
                         if (r < 0)
                                 return r;
                 }
index ef0e42a81d597265bbdd40d1482035f9d4ef584a..504d1038e5e648ed3ed1fa27cd2b127120aff860 100755 (executable)
@@ -160,10 +160,12 @@ ip link del hoge.foo
 ### SETUP ###
 # Configure network
 hostnamectl hostname ns1.unsigned.test
-{
-    echo "10.0.0.1               ns1.unsigned.test"
-    echo "fd00:dead:beef:cafe::1 ns1.unsigned.test"
-} >>/etc/hosts
+cat >>/etc/hosts <<EOF
+10.0.0.1               ns1.unsigned.test
+fd00:dead:beef:cafe::1 ns1.unsigned.test
+
+127.128.0.5     localhost5 localhost5.localdomain localhost5.localdomain4 localhost.localdomain5 localhost5.localdomain5
+EOF
 
 mkdir -p /etc/systemd/network
 cat >/etc/systemd/network/dns0.netdev <<EOF
@@ -293,6 +295,11 @@ run getent -s myhostname hosts localhost
 grep -qE "^127\.0\.0\.1\s+localhost" "$RUN_OUT"
 enable_ipv6
 
+# Issue: https://github.com/systemd/systemd/issues/25088
+run getent -s resolve hosts 127.128.0.5
+grep -qEx '127\.128\.0\.5\s+localhost5(\s+localhost5?\.localdomain[45]?){4}' "$RUN_OUT"
+[ "$(wc -l <"$RUN_OUT")" -eq 1 ]
+
 : "--- Basic resolved tests ---"
 # Issue: https://github.com/systemd/systemd/issues/22229
 # PR: https://github.com/systemd/systemd/pull/22231