From: Willy Tarreau Date: Thu, 24 Apr 2025 15:18:06 +0000 (+0200) Subject: MINOR: resolvers: add "dns-accept-family auto" to rely on detected IPv6 X-Git-Tag: v3.2-dev12~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=69b051d1dc053629bbc1577c4e232471b88686dc;p=thirdparty%2Fhaproxy.git MINOR: resolvers: add "dns-accept-family auto" to rely on detected IPv6 Instead of always having to force IPv4 or IPv6, let's now also offer "auto" which will only enable IPv6 if the system has a default gateway for it. This means that properly configured dual-stack systems will default to "ipv4,ipv6" while those lacking a gateway will only use "ipv4". Note that no real connectivity test is performed, so firewalled systems may still get it wrong and might prefer to rely on a manual "ipv4" assignment. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index de28c7f0c..8ddbaa9b8 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2179,6 +2179,7 @@ dns-accept-family [,...] of the following words: - "ipv4": query and accept IPv4 addresses ("A" records) - "ipv6": query and accept IPv6 addresses ("AAAA" records) + - "auto": use IPv4, and IPv6 if the system has a default gateway for it. When a single family is used, no request will be sent to resolvers for the other family, and any response for the othe family will be ignored. The diff --git a/include/haproxy/resolvers-t.h b/include/haproxy/resolvers-t.h index 5e758838d..914b37530 100644 --- a/include/haproxy/resolvers-t.h +++ b/include/haproxy/resolvers-t.h @@ -98,6 +98,7 @@ enum { RSLV_ACCEPT_IPV6 = 0x02, RSLV_ACCEPT_MASK = RSLV_ACCEPT_IPV4 | RSLV_ACCEPT_IPV6, RSLV_FORCED_FAMILY = 0x04, + RSLV_AUTO_FAMILY = 0x08, }; /* NOTE: big endian structure */ diff --git a/src/resolvers.c b/src/resolvers.c index 562296313..cfb50d8ee 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -3935,6 +3936,19 @@ int cfg_post_parse_resolvers() return err_code; } +/* called once the config was fully parsed */ +static int resolvers_late_init(void) +{ + if (resolv_accept_families & RSLV_AUTO_FAMILY) { + /* Let's adjust our default resolver families based on apparent IPv6 connectivity */ + if (sock_inet6_seems_reachable) + resolv_accept_families = RSLV_ACCEPT_IPV4 | RSLV_ACCEPT_IPV6; + else + resolv_accept_families = RSLV_ACCEPT_IPV4; + } + return 0; +} + /* config parser for global "dns-accept-family", accepts "ipv4", "ipv6" or both delimited by a comma */ static int cfg_parse_dns_accept_family(char **args, int section_type, struct proxy *curpx, const struct proxy *defpx, const char *file, int line, @@ -3958,6 +3972,8 @@ static int cfg_parse_dns_accept_family(char **args, int section_type, struct pro accept_families |= RSLV_ACCEPT_IPV4; else if (strcmp(arg, "ipv6") == 0) accept_families |= RSLV_ACCEPT_IPV6; + else if (strcmp(arg, "auto") == 0) + accept_families |= RSLV_AUTO_FAMILY; else goto usage; } @@ -3985,6 +4001,7 @@ REGISTER_CONFIG_SECTION("resolvers", cfg_parse_resolvers, cfg_post_parse_re REGISTER_POST_DEINIT(resolvers_deinit); REGISTER_CONFIG_POSTPARSER("dns runtime resolver", resolvers_finalize_config); REGISTER_PRE_CHECK(resolvers_create_default); +REGISTER_POST_CHECK(resolvers_late_init); #if defined(USE_PROMEX)