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;
newedns);
l->edns = newedns;
n = requeue_lookup(l, ISC_TRUE);
- n->origin = query->lookup->origin;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
dns_message_destroy(&msg);
printf(";; Truncated, retrying in TCP mode.\n");
n = requeue_lookup(l, ISC_TRUE);
n->tcp_mode = ISC_TRUE;
- n->origin = query->lookup->origin;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
dns_message_destroy(&msg);
if (l->seenbadcookie)
n->tcp_mode = ISC_TRUE;
n->seenbadcookie = ISC_TRUE;
- n->origin = query->lookup->origin;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
dns_message_destroy(&msg);
#
# 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,
#my @answers = ();
my @rules;
+my $udphandler;
+my $tcphandler;
+
sub handleUDP {
my ($buf) = @_;
my $request;
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));
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;
$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;
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`
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
+ grep "using root origin" < dig.out.test$n > /dev/null && ret=1
+ if [ $ret != 0 ]; then echo "I:failed"; fi
+ status=`expr $status + $ret`
+
n=`expr $n + 1`
echo "I:checking dig -6 -4 ($n)"
ret=0