[Dnsmasq-discuss] [RESEND PATCH] Only bind IPv6 wildcard when it is enabled

Pali Rohár pali.rohar at gmail.com
Thu Jan 21 13:20:58 UTC 2021


Hello!

On Thursday 21 January 2021 14:00:10 Matthias May wrote:
> On Linux when IPv6 is disabled, one would not expect Dnsmasq to bind
> the IPv6 wildcard.

And it is a problem? I would expect that if IPv6 is disabled then
applications (including dnsmasq) cannot bind to the IPv6 address for
listening... Or can applications bind to IPv6 address also when IPv6 is
disabled? I just have not caught what is the problem (from description).

> This patch adds a condition to the wildcard bind function, which checks
> on Linux if IPv6 is disabled.
> 
> Signed-off-by: Matthias May <matthias.may at westermo.com>
> Signed-off-by: Zefir Kurtisi <zefir.kurtisi at westermo.com>
> ---
>  src/dnsmasq.h |  1 +
>  src/network.c | 24 +++++++++++++-----------
>  src/util.c    | 22 ++++++++++++++++++++++
>  3 files changed, 36 insertions(+), 11 deletions(-)
> 
> diff --git a/src/dnsmasq.h b/src/dnsmasq.h
> index 4220798..2cfb1cb 100644
> --- a/src/dnsmasq.h
> +++ b/src/dnsmasq.h
> @@ -1292,6 +1292,7 @@ int read_write(int fd, unsigned char *packet, int size, int rw);
>  void close_fds(long max_fd, int spare1, int spare2, int spare3);
>  int wildcard_match(const char* wildcard, const char* match);
>  int wildcard_matchn(const char* wildcard, const char* match, int num);
> +int is_ipv6_disabled(void);
>  #ifdef HAVE_LINUX_NETWORK
>  int kernel_version(void);
>  #endif
> diff --git a/src/network.c b/src/network.c
> index c7d002b..0d35fb7 100644
> --- a/src/network.c
> +++ b/src/network.c
> @@ -990,19 +990,21 @@ void create_wildcard_listeners(void)
> 
>    l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
> 
> -  memset(&addr, 0, sizeof(addr));
> +  if (!is_ipv6_disabled()) {
> +    memset(&addr, 0, sizeof(addr));
>  #ifdef HAVE_SOCKADDR_SA_LEN
> -  addr.in6.sin6_len = sizeof(addr.in6);
> +    addr.in6.sin6_len = sizeof(addr.in6);
>  #endif
> -  addr.in6.sin6_family = AF_INET6;
> -  addr.in6.sin6_addr = in6addr_any;
> -  addr.in6.sin6_port = htons(daemon->port);
> -
> -  l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
> -  if (l)
> -    l->next = l6;
> -  else
> -    l = l6;
> +    addr.in6.sin6_family = AF_INET6;
> +    addr.in6.sin6_addr = in6addr_any;
> +    addr.in6.sin6_port = htons(daemon->port);
> +
> +    l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
> +    if (l)
> +      l->next = l6;
> +    else
> +      l = l6;
> +  }
> 
>    daemon->listeners = l;
>  }
> diff --git a/src/util.c b/src/util.c
> index 5f13027..5cd461f 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -787,6 +787,28 @@ int wildcard_matchn(const char* wildcard, const char* match, int num)
>    return (!num) || (*wildcard == *match);
>  }
> 
> +#ifndef HAVE_LINUX_NETWORK
> +/* implement for other platforms */
> +int is_ipv6_disabled(void)
> +{
> +	return 0;
> +}
> +#else /* HAVE_LINUX_NETWORK */
> +int is_ipv6_disabled(void)
> +{
> +	FILE *f;
> +	char *fname = "/proc/sys/net/ipv6/conf/all/disable_ipv6";
> +	char buf[4];
> +	int ipv6_disabled = 0;
> +	if ((f = fopen(fname, "r"))) {
> +		if (fgets(buf, 4, f))
> +			ipv6_disabled = atoi(buf) == 1;
> +		fclose(f);
> +	}
> +	return ipv6_disabled;

This check is incorrect. If IPv6 support is disabled at kernel compile
time then fopen() fails and this function returns 0, meaning IPv6 is
enabled.

> +}
> +#endif /* HAVE_LINUX_NETWORK */
> +
>  #ifdef HAVE_LINUX_NETWORK
>  int kernel_version(void)
>  {
> -- 
> 2.27.0
> 
> _______________________________________________
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss

-- 
Pali Rohár
pali.rohar at gmail.com



More information about the Dnsmasq-discuss mailing list