|
|
964723 |
From a200b2dd994cbb4ff29151ff46342268bc8fb3c2 Mon Sep 17 00:00:00 2001
|
|
|
964723 |
From: Evan Hunt <each@isc.org>
|
|
|
964723 |
Date: Mon, 11 Sep 2017 10:34:10 -0700
|
|
|
964723 |
Subject: [PATCH 2/2] dig: retain domain when retrying with tcp
|
|
|
964723 |
|
|
|
964723 |
4712. [bug] "dig +domain" and "dig +search" didn't retain the
|
|
|
964723 |
search domain when retrying with TCP. [RT #45547]
|
|
|
964723 |
|
|
|
964723 |
(cherry picked from commit 8e014c45ae75a3ca893cec6a0711beb69ecd18a4)
|
|
|
964723 |
(cherry picked from commit 88e2cefcc2e8f48c0fba97661ff79c2506b52b23)
|
|
|
964723 |
(cherry picked from commit 51b00c6c783ccf5dca86119ff8f4f8b994298ca4)
|
|
|
964723 |
|
|
|
964723 |
Modified to pass with libidn
|
|
|
964723 |
|
|
|
964723 |
Fix origin test
|
|
|
964723 |
---
|
|
|
964723 |
bin/dig/dighost.c | 13 ++++-------
|
|
|
964723 |
bin/tests/system/ans.pl | 43 +++++++++++++++++++++++++----------
|
|
|
964723 |
bin/tests/system/digdelv/ans4/startme | 0
|
|
|
964723 |
bin/tests/system/digdelv/tests.sh | 23 ++++++++++++++++++-
|
|
|
964723 |
4 files changed, 58 insertions(+), 21 deletions(-)
|
|
|
964723 |
create mode 100644 bin/tests/system/digdelv/ans4/startme
|
|
|
964723 |
|
|
|
964723 |
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
|
|
|
964723 |
index 5c03d95..3a066c6 100644
|
|
|
964723 |
--- a/bin/dig/dighost.c
|
|
|
964723 |
+++ b/bin/dig/dighost.c
|
|
|
964723 |
@@ -887,6 +887,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
|
|
|
964723 |
looknew->section_answer = lookold->section_answer;
|
|
|
964723 |
looknew->section_authority = lookold->section_authority;
|
|
|
964723 |
looknew->section_additional = lookold->section_additional;
|
|
|
964723 |
+ looknew->origin = lookold->origin;
|
|
|
964723 |
looknew->retries = lookold->retries;
|
|
|
964723 |
looknew->tsigctx = NULL;
|
|
|
964723 |
looknew->need_search = lookold->need_search;
|
|
|
964723 |
@@ -2134,6 +2135,7 @@ setup_lookup(dig_lookup_t *lookup) {
|
|
|
964723 |
|
|
|
964723 |
#ifdef WITH_IDN
|
|
|
964723 |
if (lookup->origin != NULL) {
|
|
|
964723 |
+ debug("trying origin %s", lookup->origin->origin);
|
|
|
964723 |
mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP,
|
|
|
964723 |
lookup->origin->origin, utf8_origin,
|
|
|
964723 |
sizeof(utf8_origin));
|
|
|
964723 |
@@ -2148,6 +2150,7 @@ setup_lookup(dig_lookup_t *lookup) {
|
|
|
964723 |
idn_check_result(mr, "convert UTF-8 textname to IDN encoding");
|
|
|
964723 |
#elif defined (WITH_LIBIDN)
|
|
|
964723 |
if (lookup->origin != NULL) {
|
|
|
964723 |
+ debug("trying origin %s", lookup->origin->origin);
|
|
|
964723 |
result = libidn_locale_to_utf8 (lookup->origin->origin, utf8_str);
|
|
|
964723 |
check_result (result, "convert origin to UTF-8");
|
|
|
964723 |
if (len > 0 && utf8_name[len - 1] != '.') {
|
|
|
964723 |
@@ -3409,7 +3407,6 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
|
|
964723 |
printf(";; Truncated, retrying in TCP mode.\n");
|
|
|
964723 |
n = requeue_lookup(l, ISC_TRUE);
|
|
|
964723 |
n->tcp_mode = ISC_TRUE;
|
|
|
964723 |
- n->origin = query->lookup->origin;
|
|
|
964723 |
dns_message_destroy(&msg;;
|
|
|
964723 |
isc_event_free(&event);
|
|
|
964723 |
clear_query(query);
|
|
|
964723 |
diff --git a/bin/tests/system/ans.pl b/bin/tests/system/ans.pl
|
|
|
964723 |
index d6ff3c2..d8c9f9d 100644
|
|
|
964723 |
--- a/bin/tests/system/ans.pl
|
|
|
964723 |
+++ b/bin/tests/system/ans.pl
|
|
|
964723 |
@@ -35,7 +35,12 @@
|
|
|
964723 |
#
|
|
|
964723 |
# There can be any number of patterns, each associated
|
|
|
964723 |
# with any number of response RRs. Each pattern is a
|
|
|
964723 |
-# Perl regular expression.
|
|
|
964723 |
+# Perl regular expression. If an empty pattern ("//") is
|
|
|
964723 |
+# received, the server will ignore all incoming queries (TCP
|
|
|
964723 |
+# connections will still be accepted, but both UDP queries
|
|
|
964723 |
+# and TCP queries will not be responded to). If a non-empty
|
|
|
964723 |
+# pattern is then received over the same control connection,
|
|
|
964723 |
+# default behavior is restored.
|
|
|
964723 |
#
|
|
|
964723 |
# Each incoming query is converted into a string of the form
|
|
|
964723 |
# "qname qtype" (the printable query domain name, space,
|
|
|
964723 |
@@ -105,6 +110,9 @@ $SIG{TERM} = \&rmpid;
|
|
|
964723 |
|
|
|
964723 |
#my @answers = ();
|
|
|
964723 |
my @rules;
|
|
|
964723 |
+my $udphandler;
|
|
|
964723 |
+my $tcphandler;
|
|
|
964723 |
+
|
|
|
964723 |
sub handleUDP {
|
|
|
964723 |
my ($buf) = @_;
|
|
|
964723 |
my $request;
|
|
|
964723 |
@@ -414,8 +422,15 @@ for (;;) {
|
|
|
964723 |
while (my $line = $conn->getline) {
|
|
|
964723 |
chomp $line;
|
|
|
964723 |
if ($line =~ m!^/(.*)/$!) {
|
|
|
964723 |
- $rule = { pattern => $1, answer => [] };
|
|
|
964723 |
- push(@rules, $rule);
|
|
|
964723 |
+ if (length($1) == 0) {
|
|
|
964723 |
+ $udphandler = sub { return; };
|
|
|
964723 |
+ $tcphandler = sub { return; };
|
|
|
964723 |
+ } else {
|
|
|
964723 |
+ $udphandler = \&handleUDP;
|
|
|
964723 |
+ $tcphandler = \&handleTCP;
|
|
|
964723 |
+ $rule = { pattern => $1, answer => [] };
|
|
|
964723 |
+ push(@rules, $rule);
|
|
|
964723 |
+ }
|
|
|
964723 |
} else {
|
|
|
964723 |
push(@{$rule->{answer}},
|
|
|
964723 |
new Net::DNS::RR($line));
|
|
|
964723 |
@@ -430,9 +445,11 @@ for (;;) {
|
|
|
964723 |
printf "UDP request\n";
|
|
|
964723 |
my $buf;
|
|
|
964723 |
$udpsock->recv($buf, 512);
|
|
|
964723 |
- my $result = handleUDP($buf);
|
|
|
964723 |
- my $num_chars = $udpsock->send($result);
|
|
|
964723 |
- print " Sent $num_chars bytes via UDP\n";
|
|
|
964723 |
+ my $result = &$udphandler($buf);
|
|
|
964723 |
+ if (defined($result)) {
|
|
|
964723 |
+ my $num_chars = $udpsock->send($result);
|
|
|
964723 |
+ print " Sent $num_chars bytes via UDP\n";
|
|
|
964723 |
+ }
|
|
|
964723 |
} elsif (vec($rout, fileno($tcpsock), 1)) {
|
|
|
964723 |
my $conn = $tcpsock->accept;
|
|
|
964723 |
my $buf;
|
|
|
964723 |
@@ -444,12 +461,14 @@ for (;;) {
|
|
|
964723 |
$n = $conn->sysread($buf, $len);
|
|
|
964723 |
last unless $n == $len;
|
|
|
964723 |
print "TCP request\n";
|
|
|
964723 |
- my $result = handleTCP($buf);
|
|
|
964723 |
- foreach my $response (@$result) {
|
|
|
964723 |
- $len = length($response);
|
|
|
964723 |
- $n = $conn->syswrite(pack("n", $len), 2);
|
|
|
964723 |
- $n = $conn->syswrite($response, $len);
|
|
|
964723 |
- print " Sent: $n chars via TCP\n";
|
|
|
964723 |
+ my $result = &$tcphandler($buf);
|
|
|
964723 |
+ if (defined($result)) {
|
|
|
964723 |
+ foreach my $response (@$result) {
|
|
|
964723 |
+ $len = length($response);
|
|
|
964723 |
+ $n = $conn->syswrite(pack("n", $len), 2);
|
|
|
964723 |
+ $n = $conn->syswrite($response, $len);
|
|
|
964723 |
+ print " Sent: $n chars via TCP\n";
|
|
|
964723 |
+ }
|
|
|
964723 |
}
|
|
|
964723 |
}
|
|
|
964723 |
$conn->close;
|
|
|
964723 |
diff --git a/bin/tests/system/digdelv/ans4/startme b/bin/tests/system/digdelv/ans4/startme
|
|
|
964723 |
new file mode 100644
|
|
|
964723 |
index 0000000..e69de29
|
|
|
964723 |
diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh
|
|
|
964723 |
index 988bd52..a19256c 100644
|
|
|
964723 |
--- a/bin/tests/system/digdelv/tests.sh
|
|
|
964723 |
+++ b/bin/tests/system/digdelv/tests.sh
|
|
|
964723 |
@@ -19,6 +19,7 @@ status=0
|
|
|
964723 |
n=0
|
|
|
964723 |
# using dig insecure mode as not testing dnssec here
|
|
|
964723 |
DIGOPTS="-i -p 5300"
|
|
|
964723 |
+SENDCMD="$PERL $SYSTEMTESTTOP/send.pl 10.53.0.4 5301"
|
|
|
964723 |
|
|
|
964723 |
if [ -x ${DIG} ] ; then
|
|
|
964723 |
n=`expr $n + 1`
|
|
|
964723 |
@@ -62,6 +63,24 @@ if [ -x ${DIG} ] ; then
|
|
|
964723 |
if [ $ret != 0 ]; then echo "I:failed"; fi
|
|
|
964723 |
status=`expr $status + $ret`
|
|
|
964723 |
|
|
|
964723 |
+ n=`expr $n + 1`
|
|
|
964723 |
+ echo "I:checking dig preserves origin on TCP retries ($n)"
|
|
|
964723 |
+ ret=0
|
|
|
964723 |
+ # Ask ans4 to still accept TCP connections, but not respond to queries
|
|
|
964723 |
+ echo "//" | $SENDCMD
|
|
|
964723 |
+ $DIG $DIGOPTS -d +tcp @10.53.0.4 +retry=1 +time=1 +domain=bar foo > dig.out.test$n 2>&1 && ret=1
|
|
|
964723 |
+ l=`grep "trying origin bar" dig.out.test$n | wc -l`
|
|
|
964723 |
+ [ ${l:-0} -eq 2 ] || ret=1
|
|
|
964723 |
+ if grep "libidn_locale_to_utf8" dig.out.test$n > /dev/null
|
|
|
964723 |
+ then
|
|
|
964723 |
+ # libidn patch uses always using root origin, but print also name
|
|
|
964723 |
+ grep '^foo\.$' < dig.out.test$n > /dev/null && ret=1
|
|
|
964723 |
+ else
|
|
|
964723 |
+ grep "using root origin" < dig.out.test$n > /dev/null && ret=1
|
|
|
964723 |
+ fi
|
|
|
964723 |
+ if [ $ret != 0 ]; then echo "I:failed"; fi
|
|
|
964723 |
+ status=`expr $status + $ret`
|
|
|
964723 |
+
|
|
|
964723 |
else
|
|
|
964723 |
echo "W:$DIG is needed, so skipping these dig tests"
|
|
|
964723 |
fi
|
|
|
964723 |
@@ -131,7 +150,9 @@ if [ -n "${DELV}" -a -x "${DELV}" ] ; then
|
|
|
964723 |
if [ $ret != 0 ]; then echo "I:failed"; fi
|
|
|
964723 |
status=`expr $status + $ret`
|
|
|
964723 |
|
|
|
964723 |
- exit $status
|
|
|
964723 |
else
|
|
|
964723 |
echo "W:${DELV:-delv} is not available, so skipping these delv tests"
|
|
|
964723 |
fi
|
|
|
964723 |
+
|
|
|
964723 |
+echo "I:exit status: $status"
|
|
|
964723 |
+[ $status -eq 0 ] || exit 1
|
|
|
964723 |
--
|
|
|
964723 |
2.9.5
|
|
|
964723 |
|