dnsmasq: fix resolv.conf for round-robin DNS configuration

Adds the ability to configure what types of addresses (IPv4/IPv6)
are used in resolv.conf to query the local nameserver.
This is achieved by using 'add_local_ipv4_nameserver' and
'add_local_ipv6_nameserver' options in dhcp config file,
dnsmasq configuration section.

Default behavior change:
Now only one localhost IPv4 address is used in resolv.conf
to query the local nameserver instead of IPv4 and IPv6
localhost addresses (127.0.0.1 and ::1).

Fixes resolv.conf to not query the same nameserver twice.
Querying the same nameserver twice introduces issues
with answers for records that have multiple IP values.
Those types of records are used for high availability
by utilizing round-robin DNS for client side load balancing.

Additional information on how musl libc resolver works:

Name Resolver/DNS section:
https://wiki.musl-libc.org/functional-differences-from-glibc.html

Comments from the lead developer of musl libc Rich Felker:
https://www.openwall.com/lists/musl/2022/07/11/1

Fixes: https://github.com/openwrt/openwrt/issues/10278

Signed-off-by: Felix Tailor <felix.tailor@pm.me>
This commit is contained in:
Felix Tailor 2022-07-23 22:49:08 +03:00
parent 0f301b0b1d
commit 6c1e29422e
No known key found for this signature in database
GPG Key ID: 7C7381A758540422

View File

@ -8,6 +8,8 @@ PROG=/usr/sbin/dnsmasq
ADD_LOCAL_DOMAIN=1
ADD_LOCAL_HOSTNAME=1
ADD_LOCAL_IPV4_NAMESERVER=1
ADD_LOCAL_IPV6_NAMESERVER=0
ADD_WAN_FQDN=0
ADD_LOCAL_FQDN=""
@ -993,6 +995,8 @@ dnsmasq_start()
config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1
config_get_bool ADD_LOCAL_IPV4_NAMESERVER "$cfg" add_local_ipv4_nameserver 1
config_get_bool ADD_LOCAL_IPV6_NAMESERVER "$cfg" add_local_ipv6_nameserver 0
config_get ADD_LOCAL_FQDN "$cfg" add_local_fqdn ""
config_get ADD_WAN_FQDN "$cfg" add_wan_fqdn 0
@ -1150,8 +1154,12 @@ dnsmasq_start()
[ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {
echo "search $DOMAIN" >> /tmp/resolv.conf
}
DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
[ -e /proc/sys/net/ipv6 ] && DNS_SERVERS="$DNS_SERVERS ::1"
[ "$ADD_LOCAL_IPV4_NAMESERVER" -eq 1 ] && {
DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
}
[ -e /proc/sys/net/ipv6 ] && [ "$ADD_LOCAL_IPV6_NAMESERVER" -eq 1 ] && {
DNS_SERVERS="$DNS_SERVERS ::1"
}
for DNS_SERVER in $DNS_SERVERS ; do
echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf
done