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.
196 lines
6.7 KiB
196 lines
6.7 KiB
6 years ago
|
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
|
||
|
|