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