]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
machined: refresh resolve hook addresses per machine
authordongshengyuan <545258830@qq.com>
Fri, 17 Jul 2026 07:55:57 +0000 (15:55 +0800)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Jul 2026 04:19:11 +0000 (13:19 +0900)
Track which machine the cached address list belongs to and refresh it
when ResolveRecord() advances to another machine. This keeps A/AAAA
reuse for the same machine while avoiding mixed name/address records.

Reproducer: register two machines with private addresses 10.88.1.1
and 10.88.2.1, then call io.systemd.Resolve.Hook.ResolveRecord
with both A questions in one request.

Before: the answer for the second machine used its own name but
reused the first machine's address, e.g. resolve-bug-m2 returned
10.88.1.1 instead of 10.88.2.1.

Follow-up: 3cd929f837854e96cd0a856f9a96518701841782

src/machine/machined-resolve-hook.c
test/units/TEST-13-NSPAWN.nss-mymachines.sh

index 1d1a9ad0a93311c124f3c735819faf7061ca6feb..8c5c81b29ba79693f93edde0342496f409b23244 100644 (file)
@@ -125,6 +125,7 @@ int vl_method_resolve_record(
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
 
         _cleanup_free_ struct local_address *addresses = NULL;
+        Machine *addresses_machine = NULL;
         bool found = false, nxdomain = false;
         int n_addresses = -1;
 
@@ -138,10 +139,13 @@ int vl_method_resolve_record(
                         if (!dns_resource_key_is_address(key))
                                 continue;
 
-                        if (n_addresses < 0) {
+                        if (addresses_machine != machine) {
+                                addresses = mfree(addresses);
                                 n_addresses = machine_get_addresses(machine, &addresses);
                                 if (n_addresses < 0)
                                         return n_addresses;
+
+                                addresses_machine = machine;
                         }
 
                         int family = dns_type_to_af(key->type);
index e4a961671288ef90d2b4885ffe4a40983db86ce9..2468227c06b1c7bfe3f98b3b8e305b7e5118810a 100755 (executable)
@@ -148,4 +148,10 @@ for i in {100..120}; do
     run_and_grep "10\.2\.0\.$i" resolvectl query nss-mymachines-manyips
 done
 
+hook_question='{"question":[{"key":{"class":1,"type":1,"name":"nss-mymachines-singleip"}},{"key":{"class":1,"type":1,"name":"nss-mymachines-manyips"}}]}'
+hook_answer="$(varlinkctl --json=short call /run/systemd/resolve.hook/io.systemd.Machine io.systemd.Resolve.Hook.ResolveRecord "$hook_question")"
+jq -e '.answer[] | select(.rr.key.name == "nss-mymachines-singleip" and .rr.address == [10, 1, 0, 2])' <<<"$hook_answer"
+jq -e '.answer[] | select(.rr.key.name == "nss-mymachines-manyips" and .rr.address == [10, 2, 0, 2])' <<<"$hook_answer"
+(! jq -e '.answer[] | select(.rr.key.name == "nss-mymachines-manyips" and .rr.address == [10, 1, 0, 2])' <<<"$hook_answer")
+
 machinectl stop nss-mymachines-{noip,singleip,manyips}