Commit 49762dff authored by Mark Andrews's avatar Mark Andrews

4282. [func] 'dig +[no]mapped' determine whether the use of mapped

                        IPv4 addresses over IPv6 is permitted or not.  The
                        default is +mapped.  [RT #41307]
parent 757e405d
4282. [func] 'dig +[no]mapped' determine whether the use of mapped
IPv4 addresses over IPv6 is permitted or not. The
default is +mapped. [RT #41307]
4281. [bug] Teach dns_message_totext about BADCOOKIE. [RT #41257]
4280. [performance] Use optimal message sizes to improve compression
......
......@@ -195,6 +195,7 @@ help(void) {
" +[no]identify (ID responders in short answers)\n"
" +[no]ignore (Don't revert to TCP for TC responses.)\n"
" +[no]keepopen (Keep the TCP socket open between queries)\n"
" +[no]mapped (Allow mapped IPv4 over IPv6)\n"
" +[no]multiline (Print records in an expanded format)\n"
" +ndots=### (Set search NDOTS value)\n"
" +[no]nsid (Request Name Server ID)\n"
......@@ -1061,8 +1062,18 @@ plus_option(const char *option, isc_boolean_t is_batchfile,
keep_open = state;
break;
case 'm': /* multiline */
FULLCHECK("multiline");
multiline = state;
switch (cmd[1]) {
case 'a':
FULLCHECK("mapped");
lookup->mapped = state;
break;
case 'u':
FULLCHECK("multiline");
multiline = state;
break;
default:
goto invalid_option;
}
break;
case 'n':
switch (cmd[1]) {
......@@ -1849,7 +1860,7 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
if (is_batchfile && !config_only) {
addresscount = getaddresses(lookup, &rv[0][1],
&result);
if (result != ISC_R_SUCCESS) {
if (addresscount == 0) {
fprintf(stderr, "couldn't get address "
"for '%s': %s: skipping "
"lookup\n", &rv[0][1],
......@@ -1860,9 +1871,13 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
destroy_lookup(lookup);
return;
}
} else
} else {
addresscount = getaddresses(lookup, &rv[0][1],
NULL);
if (addresscount == 0)
fatal("no valid addresses for '%s'\n",
&rv[0][1]);
}
} else if (rv[0][0] == '+') {
plus_option(&rv[0][1], is_batchfile,
lookup);
......
......@@ -789,6 +789,16 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>+[no]mapped</option></term>
<listitem>
<para>
Allow mapped IPv4 over IPv6 addresses to be used. The
default is <option>+mapped</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>+[no]multiline</option></term>
<listitem>
......
......@@ -830,6 +830,7 @@ make_empty_lookup(void) {
looknew->ednsopts = NULL;
looknew->ednsoptscnt = 0;
looknew->ednsneg = ISC_TRUE;
looknew->mapped = ISC_TRUE;
looknew->dscp = -1;
dns_fixedname_init(&looknew->fdomain);
ISC_LINK_INIT(looknew, link);
......@@ -889,6 +890,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->ednsopts = lookold->ednsopts;
looknew->ednsoptscnt = lookold->ednsoptscnt;
looknew->ednsneg = lookold->ednsneg;
looknew->mapped = lookold->mapped;
#ifdef DIG_SIGCHASE
looknew->sigchase = lookold->sigchase;
#if DIG_SIGCHASE_TD
......@@ -2840,6 +2842,28 @@ send_tcp_connect(dig_query_t *query) {
return;
}
if (!l->mapped && isc_sockaddr_pf(&query->sockaddr) == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&query->sockaddr.type.sin6.sin6_addr)) {
isc_netaddr_t netaddr;
char buf[ISC_NETADDR_FORMATSIZE];
isc_netaddr_fromsockaddr(&netaddr, &query->sockaddr);
isc_netaddr_format(&netaddr, buf, sizeof(buf));
printf(";; Skipping mapped address '%s'\n", buf);
query->waiting_connect = ISC_FALSE;
next = ISC_LIST_NEXT(query, link);
l = query->lookup;
clear_query(query);
if (next == NULL) {
printf(";; No acceptable nameservers\n");
check_next_lookup(l);
return;
}
send_tcp_connect(next);
return;
}
if (specified_source &&
(isc_sockaddr_pf(&query->sockaddr) !=
isc_sockaddr_pf(&bind_address))) {
......@@ -2876,6 +2900,7 @@ send_tcp_connect(dig_query_t *query) {
debug("sockcount=%d", sockcount);
if (query->lookup->dscp != -1)
isc_socket_dscp(query->sock, query->lookup->dscp);
isc_socket_ipv6only(query->sock, ISC_TF(!query->lookup->mapped));
if (specified_source)
result = isc_socket_bind(query->sock, &bind_address,
ISC_SOCKET_REUSEADDRESS);
......@@ -2929,6 +2954,7 @@ send_udp(dig_query_t *query) {
dig_lookup_t *l = NULL;
isc_result_t result;
isc_buffer_t *sendbuf;
dig_query_t *next;
debug("send_udp(%p)", query);
......@@ -2946,6 +2972,25 @@ send_udp(dig_query_t *query) {
return;
}
if (!l->mapped &&
isc_sockaddr_pf(&query->sockaddr) == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&query->sockaddr.type.sin6.sin6_addr)) {
isc_netaddr_t netaddr;
char buf[ISC_NETADDR_FORMATSIZE];
isc_netaddr_fromsockaddr(&netaddr, &query->sockaddr);
isc_netaddr_format(&netaddr, buf, sizeof(buf));
printf(";; Skipping mapped address '%s'\n", buf);
next = ISC_LIST_NEXT(query, link);
l = query->lookup;
clear_query(query);
if (next == NULL)
printf(";; No acceptable nameservers\n");
check_next_lookup(l);
return;
}
result = isc_socket_create(socketmgr,
isc_sockaddr_pf(&query->sockaddr),
isc_sockettype_udp, &query->sock);
......@@ -2954,6 +2999,8 @@ send_udp(dig_query_t *query) {
debug("sockcount=%d", sockcount);
if (query->lookup->dscp != -1)
isc_socket_dscp(query->sock, query->lookup->dscp);
isc_socket_ipv6only(query->sock,
ISC_TF(!query->lookup->mapped));
if (specified_source) {
result = isc_socket_bind(query->sock, &bind_address,
ISC_SOCKET_REUSEADDRESS);
......
......@@ -136,7 +136,8 @@ struct dig_lookup {
badcookie,
nsid, /*% Name Server ID (RFC 5001) */
header_only,
ednsneg;
ednsneg,
mapped;
#ifdef DIG_SIGCHASE
isc_boolean_t sigchase;
#if DIG_SIGCHASE_TD
......
......@@ -202,18 +202,46 @@ if [ -x ${DIG} ] ; then
fi
n=`expr $n + 1`
echo "I:checking dig @IPv4addr -6 A a.example ($n)"
echo "I:checking dig @IPv4addr -6 +mapped A a.example ($n)"
if $TESTSOCK6 fd92:7065:b8e:ffff::2
then
ret=0
ret=0
$DIG $DIGOPTS +tcp @10.53.0.2 -6 A a.example > dig.out.test$n 2>&1 || ret=1
$DIG $DIGOPTS +tcp @10.53.0.2 -6 +mapped A a.example > dig.out.test$n 2>&1 || ret=1
grep "SERVER: ::ffff:10.53.0.2#5300" < dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
else
echo "I:IPv6 unavailable; skipping"
fi
n=`expr $n + 1`
echo "I:checking dig +tcp @IPv4addr -6 +nomapped A a.example ($n)"
if $TESTSOCK6 fd92:7065:b8e:ffff::2
then
ret=0
ret=0
$DIG $DIGOPTS +tcp @10.53.0.2 -6 +nomapped A a.example > dig.out.test$n 2>&1 || ret=1
grep "SERVER: ::ffff:10.53.0.2#5300" < dig.out.test$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
else
echo "I:IPv6 unavailable; skipping"
fi
n=`expr $n + 1`
echo "I:checking dig +notcp @IPv4addr -6 +nomapped A a.example ($n)"
if $TESTSOCK6 fd92:7065:b8e:ffff::2
then
ret=0
ret=0
$DIG $DIGOPTS +notcp @10.53.0.2 -6 +nomapped A a.example > dig.out.test$n 2>&1 || ret=1
grep "SERVER: ::ffff:10.53.0.2#5300" < dig.out.test$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
else
echo "I:IPv6 unavailable; skipping"
fi
n=`expr $n + 1`
echo "I:checking dig +subnet ($n)"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment