]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: resolvers: don't ignore records not matching a resolve-net family
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 29 Sep 2026 07:12:41 +0000 (09:12 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 10 Nov 2026 14:47:52 +0000 (15:47 +0100)
When selecting an IP address in a response, resolv_get_ip_from_response()
walks over the "resolve-net" networks to give a better score to records
belonging to one of them, and skips networks of another address family
than the record's. Commit 3023e9819 ("BUG/MINOR: resolvers: Restore
round-robin selection on records in DNS answers") changed the outer loop
into a do/while loop with a "next" label, and turned all "continue"
statements into "goto next", including the one skipping networks of the
other family in this inner loop. As a result, as soon as a network of
another family is met before a matching one, the whole record is ignored
instead of just this network, and no address may be found at all.

This is easily reproduced with:

    server s1 www.test:80 resolvers dns resolve-prefer ipv4 \
                          resolve-net 2001:db8::/32,10.0.0.0/8

and a nameserver returning A 127.0.0.1: the server never gets an address
and remains in maintenance, while it works with "resolve-net 10.0.0.0/8".

The same commit also changed the "continue" skipping the owner server
itself in the list of servers attached to the record, into a "goto next".
It's currently harmless because the function returns early when the
owner is attached to any record, but it's wrong as well, so let's restore
it too.

This must be backported wherever the commit above was backported, so as
far as 2.8.

src/resolvers.c

index bddb457c907590c320bd9356c3c4c145e88cd51b..776b8a999fc65b77e1c28c20c57e3a58a6fba3d4 100644 (file)
@@ -1749,7 +1749,7 @@ int resolv_get_ip_from_response(struct resolv_response *r_res,
 
                        /* Compare only the same addresses class. */
                        if (resolv_opts->pref_net[j].family != ip_type)
-                               goto next;
+                               continue;
 
                        if ((ip_type == AF_INET &&
                             in_net_ipv4(ip,
@@ -1773,7 +1773,7 @@ int resolv_get_ip_from_response(struct resolv_response *r_res,
 
                        list_for_each_entry(srv, &record->attached_servers, ip_rec_item) {
                                if (srv == owner)
-                                       goto next;
+                                       continue;
                                if (srv->proxy == owner->proxy) {
                                        already_used = 1;
                                        break;