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