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