ok = inet_pton(AF_INET, p, &a);
if (ok) {
- state->nsaddr_list[state->nscount] = (struct sockaddr_in) {
+ state->nsaddr_list[nserv] = (struct sockaddr_in) {
.sin_family = AF_INET,
.sin_addr = a,
.sin_port = htons(53),
.sin_zero = { 0 },
};
- state->nscount++;
nserv++;
} else {
#ifdef HAVE_RESOLV_IPV6_NSADDRS
sa6->sin6_flowinfo = 0;
sa6->sin6_addr = a6;
- state->_u._ext.nsaddrs[state->_u._ext.nscount] = sa6;
- state->_u._ext.nssocks[state->_u._ext.nscount] = -1;
- state->_u._ext.nsmap[state->_u._ext.nscount] = MAXNS + 1;
+ state->_u._ext.nsaddrs[nserv] = sa6;
+ state->_u._ext.nssocks[nserv] = -1;
+ state->_u._ext.nsmap[nserv] = MAXNS + 1;
- state->_u._ext.nscount++;
+ state->_u._ext.nscount6++;
nserv++;
} else {
RWRAP_LOG(RWRAP_LOG_ERROR,
} /* TODO: match other keywords */
}
+ /*
+ * note that state->_u._ext.nscount is left as 0,
+ * this matches glibc and allows resolv wrapper
+ * to work with most (maybe all) glibc versions.
+ */
+ state->nscount = nserv;
+
if (ferror(fp)) {
RWRAP_LOG(RWRAP_LOG_ERROR,
"Reading from %s failed",
const char *resolv_conf = getenv("RESOLV_WRAPPER_CONF");
if (resolv_conf != NULL) {
+ /* Delete name servers */
+#ifdef HAVE_RESOLV_IPV6_NSADDRS
uint16_t i;
- (void)i; /* maybe unused */
+ for (i = 0; i < state->nscount; i++) {
+ if (state->_u._ext.nssocks[i] != -1) {
+ close(state->_u._ext.nssocks[i]);
+ state->_u._ext.nssocks[i] = -1;
+ }
+
+ SAFE_FREE(state->_u._ext.nsaddrs[i]);
+ }
+#endif
- /* Delete name servers */
state->nscount = 0;
memset(state->nsaddr_list, 0, sizeof(state->nsaddr_list));
#ifdef HAVE_RESOLV_IPV6_NSADDRS
+ state->ipv6_unavail = false;
+ state->_u._ext.nsinit = 0;
state->_u._ext.nscount = 0;
- for (i = 0; i < state->_u._ext.nscount; i++) {
- SAFE_FREE(state->_u._ext.nsaddrs[i]);
+ state->_u._ext.nscount6 = 0;
+ for (i = 0; i < MAXNS; i++) {
+ state->_u._ext.nsaddrs[i] = NULL;
+ state->_u._ext.nssocks[i] = -1;
+ state->_u._ext.nsmap[i] = MAXNS;
}
#endif
+ /* And parse the new name servers */
rc = rwrap_parse_resolv_conf(state, resolv_conf);
}
}
static void rwrap_res_nclose(struct __res_state *state)
{
-#ifdef HAVE_RESOLV_IPV6_NSADDRS
- int i;
-#endif
-
libc_res_nclose(state);
-
-#ifdef HAVE_RESOLV_IPV6_NSADDRS
- if (state != NULL) {
- for (i = 0; i < state->_u._ext.nscount; i++) {
- SAFE_FREE(state->_u._ext.nsaddrs[i]);
- }
- }
-#endif
}
#if !defined(res_nclose) && defined(HAVE_RES_NCLOSE)
/*
* Validate the number of parsed name servers.
- */
-
- assert_int_equal(dnsstate.nscount + dnsstate._u._ext.nscount, MAXNS);
-
-#ifndef HAVE_RESOLV_IPV6_NSADDRS
- /*
+ *
* On platforms that don't support IPv6, the v6 address is skipped
* and we end up reading three v4 addresses.
- */
- assert_int_equal(dnsstate.nscount, MAXNS);
-#else
- /*
+ *
* test we have two v4 and one v6 server
*
* Note: This test assumes MAXNS == 3, which is the
* case on all systems encountered so far.
*/
- assert_int_equal(dnsstate.nscount, 2);
- assert_int_equal(dnsstate._u._ext.nscount, 1);
-#endif /* HAVE_RESOLV_IPV6_NSADDRS */
+ assert_int_equal(MAXNS, 3);
+ assert_int_equal(dnsstate.nscount, MAXNS);
/* Validate the servers. */
inet_ntop(AF_INET, &(dnsstate.nsaddr_list[0].sin_addr),
straddr, INET6_ADDRSTRLEN);
assert_string_equal(nameservers[0], straddr);
+#ifdef HAVE_RESOLV_IPV6_NSADDRS
+ assert_null(dnsstate._u._ext.nsaddrs[0]);
+#endif
assert_int_equal(dnsstate.nsaddr_list[1].sin_family, AF_INET);
assert_int_equal(dnsstate.nsaddr_list[1].sin_port, htons(53));
inet_ntop(AF_INET, &(dnsstate.nsaddr_list[1].sin_addr),
straddr, INET6_ADDRSTRLEN);
assert_string_equal(nameservers[1], straddr);
+#ifdef HAVE_RESOLV_IPV6_NSADDRS
+ assert_null(dnsstate._u._ext.nsaddrs[1]);
+#endif
#ifndef HAVE_RESOLV_IPV6_NSADDRS
/*
assert_string_equal(nameservers[3], straddr);
#else
/* IPv6 */
- sa6 = dnsstate._u._ext.nsaddrs[0];
+ assert_non_null(dnsstate._u._ext.nsaddrs[2]);
+ sa6 = dnsstate._u._ext.nsaddrs[2];
assert_int_equal(sa6->sin6_family, AF_INET6);
assert_int_equal(sa6->sin6_port, htons(53));
inet_ntop(AF_INET6, &(sa6->sin6_addr), straddr, INET6_ADDRSTRLEN);