diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2020-01-20 18:41:49 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2020-01-20 18:41:49 +0000 |
commit | f53025f14cd9add10ba1a0816557c11c3747bdf6 (patch) | |
tree | 4f5af00176b71ebff93e97fa4ee97df5db9cba8a /usr.sbin | |
parent | b029e7a2c590298a13317dd86b143020651f6966 (diff) |
Fix a address family desynchronisation between lwres_conf and
dig_serverlist.
In one of the first shredding commits lwres unintentionally lost the
ability to track if the user requested IPv4 only or IPv6 only
operations. Parsing of /etc/resolv.conf would add all nameservers,
ignoring their address family.
When dig(1) later populated server_list it would pay attention to
the address family.
If /etc/resolv.conf contains only IPv4 nameservers and it has 3 or
more and the user requests IPv6 only operations dig would fail with
"add_nameserver failed". This happens because lwres_conf already
contains 3 nameservers but server_list is empty so dig tries to add
::1 to lwres_conf.
It feels like this is very convoluted but it restores previous
behavoir the way it was implemented before. Thus sidestepping some
refactoring.
OK millert
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bind/bin/dig/dighost.c | 10 | ||||
-rw-r--r-- | usr.sbin/bind/lib/lwres/include/lwres/lwres.h | 7 | ||||
-rw-r--r-- | usr.sbin/bind/lib/lwres/lwconfig.c | 11 |
3 files changed, 21 insertions, 7 deletions
diff --git a/usr.sbin/bind/bin/dig/dighost.c b/usr.sbin/bind/bin/dig/dighost.c index 9bb012b83a1..79666179a3c 100644 --- a/usr.sbin/bind/bin/dig/dighost.c +++ b/usr.sbin/bind/bin/dig/dighost.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.30 2020/01/20 18:40:55 florian Exp $ */ +/* $Id: dighost.c,v 1.31 2020/01/20 18:41:48 florian Exp $ */ /*! \file * \note @@ -1423,6 +1423,7 @@ void setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { dig_searchlist_t *domain = NULL; lwres_result_t lwresult; + int lwresflags = 0; debug("setup_system()"); @@ -1444,7 +1445,12 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { } } - lwres_conf_init(lwconf); + if (have_ipv4) + lwresflags |= LWRES_USEIPV4; + if (have_ipv6) + lwresflags |= LWRES_USEIPV6; + lwres_conf_init(lwconf, lwresflags); + lwresult = lwres_conf_parse(lwconf, RESOLV_CONF); if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND) fatal("parse of %s failed", RESOLV_CONF); diff --git a/usr.sbin/bind/lib/lwres/include/lwres/lwres.h b/usr.sbin/bind/lib/lwres/include/lwres/lwres.h index 2f64da0807d..5d546dee9cb 100644 --- a/usr.sbin/bind/lib/lwres/include/lwres/lwres.h +++ b/usr.sbin/bind/lib/lwres/include/lwres/lwres.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lwres.h,v 1.5 2020/01/06 17:41:29 florian Exp $ */ +/* $Id: lwres.h,v 1.6 2020/01/20 18:41:48 florian Exp $ */ #ifndef LWRES_LWRES_H #define LWRES_LWRES_H 1 @@ -84,6 +84,8 @@ */ #define LWRES_ADDR_MAXLEN 16 /*%< changing this breaks ABI */ +#define LWRES_USEIPV4 0x0001 +#define LWRES_USEIPV6 0x0002 /*% lwres_addr_t */ typedef struct lwres_addr lwres_addr_t; @@ -133,6 +135,7 @@ typedef struct { uint8_t resdebug; /*%< non-zero if 'options debug' set */ uint8_t ndots; /*%< set to n in 'options ndots:n' */ uint8_t no_tld_query; /*%< non-zero if 'options no_tld_query' */ + int flags; } lwres_conf_t; #define LWRES_ADDRTYPE_V4 0x00000001U /*%< ipv4 */ @@ -169,7 +172,7 @@ lwres_conf_print(lwres_conf_t *confdata, FILE *fp); */ void -lwres_conf_init(lwres_conf_t *confdata); +lwres_conf_init(lwres_conf_t *confdata, int lwresflags); /**< * sets all internal fields to a default state. Used to initialize a new * lwres_conf_t structure (not reset a used on). diff --git a/usr.sbin/bind/lib/lwres/lwconfig.c b/usr.sbin/bind/lib/lwres/lwconfig.c index da6827b1e50..02635b9212b 100644 --- a/usr.sbin/bind/lib/lwres/lwconfig.c +++ b/usr.sbin/bind/lib/lwres/lwconfig.c @@ -200,7 +200,7 @@ lwres_resetaddr(lwres_addr_t *addr) { /*% intializes data structure for subsequent config parsing. */ void -lwres_conf_init(lwres_conf_t *confdata) { +lwres_conf_init(lwres_conf_t *confdata, int lwresflags) { int i; confdata->nsnext = 0; @@ -211,6 +211,7 @@ lwres_conf_init(lwres_conf_t *confdata) { confdata->resdebug = 0; confdata->ndots = 1; confdata->no_tld_query = 0; + confdata->flags = lwresflags; for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++) lwres_resetaddr(&confdata->nameservers[i]); @@ -258,7 +259,7 @@ lwres_conf_clear(lwres_conf_t *confdata) { static lwres_result_t lwres_conf_parsenameserver(lwres_conf_t *confdata, FILE *fp) { char word[LWRES_CONFMAXLINELEN]; - int res; + int res, use_ipv4, use_ipv6; lwres_addr_t address; if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS) @@ -274,7 +275,11 @@ lwres_conf_parsenameserver(lwres_conf_t *confdata, FILE *fp) { return (LWRES_R_FAILURE); /* Extra junk on line. */ res = lwres_create_addr(word, &address, 1); - if (res == LWRES_R_SUCCESS) { + use_ipv4 = confdata->flags & LWRES_USEIPV4; + use_ipv6 = confdata->flags & LWRES_USEIPV4; + if (res == LWRES_R_SUCCESS && + ((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) || + (address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) { confdata->nameservers[confdata->nsnext++] = address; } |