From: Willy Tarreau Date: Thu, 24 Apr 2025 14:31:47 +0000 (+0200) Subject: MINOR: resolvers: add command-line argument -4 to force IPv4-only DNS X-Git-Tag: v3.2-dev12~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2c46c2c042127c60a5efbd7a5304a36624f32786;p=thirdparty%2Fhaproxy.git MINOR: resolvers: add command-line argument -4 to force IPv4-only DNS In order to ease troubleshooting and testing, the new "-4" command line argument enforces queries and processing of "A" DNS records only, i.e. those representing IPv4 addresses. This can be useful when a host lack end-to-end dual-stack connectivity. This overrides the global "dns-accept-family" directive and is equivalent to value "ipv4". --- diff --git a/doc/management.txt b/doc/management.txt index 246368500..b4f21d3cc 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -192,6 +192,11 @@ list of options is : -Ws : master-worker mode with support of `notify` type of systemd service. + -4 : force DNS resolvers to query and accept IPv4 addresses only ("A" + records). This can be used when facing difficulties in certain + environments lacking end-to-end dual-stack connectivity. It overrides + the global "dns-accept-family" directive and forces it to "ipv4". + -c : only performs a check of the configuration files and exits before trying to bind. The exit status is zero if everything is OK, or non-zero if an error is encountered. Presence of warnings will be reported if any. diff --git a/include/haproxy/resolvers-t.h b/include/haproxy/resolvers-t.h index 916d6d2b5..5e758838d 100644 --- a/include/haproxy/resolvers-t.h +++ b/include/haproxy/resolvers-t.h @@ -97,6 +97,7 @@ enum { RSLV_ACCEPT_IPV4 = 0x01, RSLV_ACCEPT_IPV6 = 0x02, RSLV_ACCEPT_MASK = RSLV_ACCEPT_IPV4 | RSLV_ACCEPT_IPV6, + RSLV_FORCED_FAMILY = 0x04, }; /* NOTE: big endian structure */ diff --git a/src/haproxy.c b/src/haproxy.c index a663fa638..d2a9c8e6a 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -110,6 +110,7 @@ #include #include #include +#include #include #include #include @@ -662,6 +663,7 @@ static void usage(char *name) " -q quiet mode : don't display messages\n" " -c check mode : only check config files and exit\n" " -cc check condition : evaluate a condition and exit\n" + " -4 force resolvers to consider IPv4 responses only\n" " -n sets the maximum total # of connections (uses ulimit -n)\n" " -m limits the usable amount of memory (in MB)\n" " -N sets the default, per-proxy maximum # of connections (%d)\n" @@ -1591,6 +1593,8 @@ static void init_args(int argc, char **argv) argc--; check_condition = *argv; } + else if (*flag == '4') + resolv_accept_families = RSLV_ACCEPT_IPV4 | RSLV_FORCED_FAMILY; else if (*flag == 'c') arg_mode |= MODE_CHECK; else if (*flag == 'D') diff --git a/src/resolvers.c b/src/resolvers.c index 5a886162c..562296313 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -3962,7 +3962,11 @@ static int cfg_parse_dns_accept_family(char **args, int section_type, struct pro goto usage; } - resolv_accept_families = accept_families; + /* we ignore the settings if it was forced on the cmdline, but we still + * parse it for config validity checks. + */ + if (!(resolv_accept_families & RSLV_FORCED_FAMILY)) + resolv_accept_families = accept_families; return 0; usage: memprintf(err, "'%s' expects a comma-delimited list of 'ipv4' and 'ipv6' but got '%s'.", args[0], args[1]);