summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2020-01-20 18:41:49 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2020-01-20 18:41:49 +0000
commitf53025f14cd9add10ba1a0816557c11c3747bdf6 (patch)
tree4f5af00176b71ebff93e97fa4ee97df5db9cba8a /usr.sbin
parentb029e7a2c590298a13317dd86b143020651f6966 (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.c10
-rw-r--r--usr.sbin/bind/lib/lwres/include/lwres/lwres.h7
-rw-r--r--usr.sbin/bind/lib/lwres/lwconfig.c11
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;
}