2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Back out changes #3182 and #3202

This commit is contained in:
Evan Hunt
2011-12-05 17:10:51 +00:00
parent bd71be982f
commit 4122abdc3c
12 changed files with 18 additions and 971 deletions

View File

@@ -1,3 +1,6 @@
3236. [bug] Backed out changes #3182 and #3202, related to
EDNS(0) fallback behavior. [RT #26416]
3235. [func] dns_db_diffx, a extended dns_db_diff which returns
the generated diff and optionally writes it to a
journal. [RT #26386]

View File

@@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: conf.sh.in,v 1.70 2011/10/27 20:18:41 smann Exp $
# $Id: conf.sh.in,v 1.71 2011/12/05 17:10:50 each Exp $
#
# Common configuration data for system tests, to be sourced into
@@ -54,7 +54,7 @@ JOURNALPRINT=$TOP/bin/tools/named-journalprint
# v6synth
SUBDIRS="acl allow_query addzone autosign builtin cacheclean checkconf
checknames checkzone database dlv dlvauto dlz dlzexternal
dname dns64 dnssec edns forward glue gost ixfr inline limits
dname dns64 dnssec forward glue gost ixfr inline limits
logfileconfig lwresd masterfile masterformat metadata notify
nsupdate pending pkcs11 redirect resolver rndc rpz rrsetorder
sortlist smartsign staticstub stub tkey tsig tsiggss unknown

View File

@@ -1,419 +0,0 @@
#!/usr/bin/perl
#
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: ans.pl,v 1.2 2011/10/27 20:18:41 smann Exp $
#
# This is the name server from hell. It provides canned
# responses based on pattern matching the queries, and
# can be reprogrammed on-the-fly over a TCP connection.
#
# The server listens for control connections on port 5301.
# A control connection is a TCP stream of lines like
#
# /pattern/
# name ttl type rdata
# name ttl type rdata
# ...
# /pattern/
# name ttl type rdata
# name ttl type rdata
# ...
#
# There can be any number of patterns, each associated
# with any number of response RRs. Each pattern is a
# Perl regular expression.
#
# Each incoming query is converted into a string of the form
# "qname qtype" (the printable query domain name, space,
# printable query type) and matched against each pattern.
#
# The first pattern matching the query is selected, and
# the RR following the pattern line are sent in the
# answer section of the response.
#
# Each new control connection causes the current set of
# patterns and responses to be cleared before adding new
# ones.
#
# The server handles UDP and TCP queries. Zone transfer
# responses work, but must fit in a single 64 k message.
#
# Now you can add TSIG, just specify key/key data with:
#
# /pattern <key> <key_data>/
# name ttl type rdata
# name ttl type rdata
#
# Note that this data will still be sent with any request for
# pattern, only this data will be signed. Currently, this is only
# done for TCP.
use IO::File;
use IO::Socket;
use Data::Dumper;
use Net::DNS;
use Net::DNS::Packet;
use Net::DNS::RR;
use strict;
# Ignore SIGPIPE so we won't fail if peer closes a TCP socket early
local $SIG{PIPE} = 'IGNORE';
# Flush logged output after every line
local $| = 1;
# We default to listening on 10.53.0.2 for historical reasons
# XXX: we should also be able to specify IPv6
my $server_addr = "10.53.0.2";
if (@ARGV > 0) {
$server_addr = @ARGV[0];
}
# XXX: we should also be able to set the port numbers to listen on.
my $ctlsock = IO::Socket::INET->new(LocalAddr => "$server_addr",
LocalPort => 5301, Proto => "tcp", Listen => 5, Reuse => 1) or die "$!";
my $udpsock = IO::Socket::INET->new(LocalAddr => "$server_addr",
LocalPort => 5300, Proto => "udp", Reuse => 1) or die "$!";
my $tcpsock = IO::Socket::INET->new(LocalAddr => "$server_addr",
LocalPort => 5300, Proto => "tcp", Listen => 5, Reuse => 1) or die "$!";
print "listening on $server_addr:5300,5301.\n";
my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";;
sub rmpid { unlink "ans.pid"; exit 1; };
$SIG{INT} = \&rmpid;
$SIG{TERM} = \&rmpid;
#my @answers = ();
my @rules;
sub handleUDP {
my ($buf) = @_;
my $squeeze = 1;
my ($packet, $err) = new Net::DNS::Packet(\$buf, 0);
$err and die $err;
$packet->header->qr(1);
$packet->header->aa(1);
my @questions = $packet->question;
my $qname = $questions[0]->qname;
my $qtype = $questions[0]->qtype;
# check additional section for edns, if found, then set squeeze
# to false
my @additional = $packet->additional;
my $ra;
foreach $ra (@additional) {
if ("OPT" eq $ra->type) {
$squeeze = 0;
my $raclass = $ra->class;
print "[handleUDP] edns size: $raclass\n";
last;
}
}
# get the existing signature if any, and clear the additional section
my $prev_tsig;
while (my $rr = $packet->pop("additional")) {
if ($rr->type eq "TSIG") {
$prev_tsig = $rr;
}
}
my $r;
foreach $r (@rules) {
my $pattern = $r->{pattern};
my($dbtype, $key_name, $key_data) = split(/ /,$pattern);
print "[handleUDP] $dbtype, $key_name, $key_data \n";
if ("$qname $qtype" =~ /$dbtype/) {
my $a;
foreach $a (@{$r->{answer}}) {
$packet->push("answer", $a);
}
if(defined($key_name) && defined($key_data)) {
# Sign the packet
print " Signing the response with " .
"$key_name/$key_data\n";
my $tsig = Net::DNS::RR->
new("$key_name TSIG $key_data");
# These kluges are necessary because Net::DNS
# doesn't know how to sign responses. We
# clear compnames so that the TSIG key and
# algorithm name won't be compressed, and
# add one to arcount because the signing
# function will attempt to decrement it,
# which is incorrect in a response. Finally
# we set request_mac to the previous digest.
$packet->{"compnames"} = {};
$packet->{"header"}{"arcount"} += 1;
if (defined($prev_tsig)) {
my $rmac = pack('n H*',
$prev_tsig->mac_size,
$prev_tsig->mac);
$tsig->{"request_mac"} =
unpack("H*", $rmac);
}
$packet->sign_tsig($tsig);
}
last;
}
}
#$packet->print;
$packet->truncate(512) && print " Truncating UDP packet\n"
if ($squeeze);
return $packet->data;
}
# namelen:
# given a stream of data, reads a DNS-formatted name and returns its
# total length, thus making it possible to skip past it.
sub namelen {
my ($data) = @_;
my $len = 0;
my $label_len = 0;
do {
$label_len = unpack("c", $data);
$data = substr($data, $label_len + 1);
$len += $label_len + 1;
} while ($label_len != 0);
return ($len);
}
# packetlen:
# given a stream of data, reads a DNS wire-format packet and returns
# its total length, making it possible to skip past it.
sub packetlen {
my ($data) = @_;
my $q;
my $rr;
my ($header, $offset) = Net::DNS::Header->parse(\$data);
for (1 .. $header->qdcount) {
($q, $offset) = Net::DNS::Question->parse(\$data, $offset);
}
for (1 .. $header->ancount) {
($rr, $offset) = Net::DNS::RR->parse(\$data, $offset);
}
for (1 .. $header->nscount) {
($rr, $offset) = Net::DNS::RR->parse(\$data, $offset);
}
for (1 .. $header->arcount) {
($rr, $offset) = Net::DNS::RR->parse(\$data, $offset);
}
return $offset;
}
# sign_tcp_continuation:
# This is a hack to correct the problem that Net::DNS has no idea how
# to sign multiple-message TCP responses. Several data that are included
# in the digest when signing a query or the first message of a response are
# omitted when signing subsequent messages in a TCP stream.
#
# Net::DNS::Packet->sign_tsig() has the ability to use a custom signing
# function (specified by calling Packet->sign_func()). We use this
# function as the signing function for TCP continuations, and it removes
# the unwanted data from the digest before calling the default sign_hmac
# function.
sub sign_tcp_continuation {
my ($key, $data) = @_;
# copy out first two bytes: size of the previous MAC
my $rmacsize = unpack("n", $data);
$data = substr($data, 2);
# copy out previous MAC
my $rmac = substr($data, 0, $rmacsize);
$data = substr($data, $rmacsize);
# try parsing out the packet information
my $plen = packetlen($data);
my $pdata = substr($data, 0, $plen);
$data = substr($data, $plen);
# remove the keyname, ttl, class, and algorithm name
$data = substr($data, namelen($data));
$data = substr($data, 6);
$data = substr($data, namelen($data));
# preserve the TSIG data
my $tdata = substr($data, 0, 8);
# prepare a new digest and sign with it
$data = pack("n", $rmacsize) . $rmac . $pdata . $tdata;
return Net::DNS::RR::TSIG::sign_hmac($key, $data);
}
sub handleTCP {
my ($buf) = @_;
my ($packet, $err) = new Net::DNS::Packet(\$buf, 0);
$err and die $err;
$packet->header->qr(1);
$packet->header->aa(1);
my @questions = $packet->question;
my $qname = $questions[0]->qname;
my $qtype = $questions[0]->qtype;
# get the existing signature if any, and clear the additional section
my $prev_tsig;
my $signer;
while (my $rr = $packet->pop("additional")) {
if ($rr->type eq "TSIG") {
$prev_tsig = $rr;
}
}
my @results = ();
my $count_these = 0;
my $r;
foreach $r (@rules) {
my $pattern = $r->{pattern};
my($dbtype, $key_name, $key_data) = split(/ /,$pattern);
print "[handleTCP] $dbtype, $key_name, $key_data \n";
if ("$qname $qtype" =~ /$dbtype/) {
$count_these++;
my $a;
foreach $a (@{$r->{answer}}) {
$packet->push("answer", $a);
}
if(defined($key_name) && defined($key_data)) {
# sign the packet
print " Signing the data with " .
"$key_name/$key_data\n";
my $tsig = Net::DNS::RR->
new("$key_name TSIG $key_data");
# These kluges are necessary because Net::DNS
# doesn't know how to sign responses. We
# clear compnames so that the TSIG key and
# algorithm name won't be compressed, and
# add one to arcount because the signing
# function will attempt to decrement it,
# which is incorrect in a response. Finally
# we set request_mac to the previous digest.
$packet->{"compnames"} = {};
$packet->{"header"}{"arcount"} += 1;
if (defined($prev_tsig)) {
my $rmac = pack('n H*',
$prev_tsig->mac_size,
$prev_tsig->mac);
$tsig->{"request_mac"} =
unpack("H*", $rmac);
}
$tsig->sign_func($signer) if defined($signer);
$packet->sign_tsig($tsig);
$signer = \&sign_tcp_continuation;
my $copy =
Net::DNS::Packet->new(\($packet->data));
$prev_tsig = $copy->pop("additional");
}
#$packet->print;
push(@results,$packet->data);
$packet = new Net::DNS::Packet(\$buf, 0);
$packet->header->qr(1);
$packet->header->aa(1);
}
}
print " A total of $count_these patterns matched\n";
return \@results;
}
# Main
my $rin;
my $rout;
for (;;) {
$rin = '';
vec($rin, fileno($ctlsock), 1) = 1;
vec($rin, fileno($tcpsock), 1) = 1;
vec($rin, fileno($udpsock), 1) = 1;
select($rout = $rin, undef, undef, undef);
if (vec($rout, fileno($ctlsock), 1)) {
warn "ctl conn";
my $conn = $ctlsock->accept;
my $rule = ();
@rules = ();
while (my $line = $conn->getline) {
chomp $line;
if ($line =~ m!^/(.*)/$!) {
$rule = { pattern => $1, answer => [] };
push(@rules, $rule);
} else {
push(@{$rule->{answer}},
new Net::DNS::RR($line));
}
}
$conn->close;
#print Dumper(@rules);
#print "+=+=+ $rules[0]->{'pattern'}\n";
#print "+=+=+ $rules[0]->{'answer'}->[0]->{'rname'}\n";
#print "+=+=+ $rules[0]->{'answer'}->[0]\n";
} elsif (vec($rout, fileno($udpsock), 1)) {
printf "UDP request\n";
my $buf;
$udpsock->recv($buf, 512);
my $result = handleUDP($buf);
# mimic fw and refuse to send packets > 512
my $len = length $result;
if ($len <= 512) {
my $num_chars = $udpsock->send($result);
print " Sent $num_chars bytes via UDP\n";
} else {
print " Dropping UDP packet (size = $len)\n";
}
} elsif (vec($rout, fileno($tcpsock), 1)) {
my $conn = $tcpsock->accept;
my $buf;
for (;;) {
my $lenbuf;
my $n = $conn->sysread($lenbuf, 2);
last unless $n == 2;
my $len = unpack("n", $lenbuf);
$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";
}
}
$conn->close;
}
}

View File

@@ -1,23 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: clean.sh,v 1.3 2011/10/27 23:46:30 tbox Exp $
#
# Clean up after zone transfer tests.
#
exit

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.3 2011/10/27 23:46:31 tbox Exp $ */
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion yes;
forward only;
forwarders { 10.53.0.2; };
dump-file "named.dump";
};

View File

@@ -1,33 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: prereq.sh,v 1.3 2011/10/28 12:20:31 tbox Exp $
if $PERL -e 'use Net::DNS;' 2>/dev/null
then
vers=`perl -MNet::DNS -e 'print "$Net::DNS::VERSION\n"'|awk -F. '{ print $1 }'`
if [ $vers -ge 66 ]
then
:
else
echo "I:This test requires the version 0.66 or later of the Net::DNS library." >&2
exit 255
fi
else
echo "I:This test requires the Net::DNS library." >&2
exit 255
fi

View File

@@ -1,18 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: setup.sh,v 1.3 2011/10/27 23:46:30 tbox Exp $

View File

@@ -1,93 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.3 2011/10/27 23:46:30 tbox Exp $
# ns1 = forward only server
# ans2 = modified ans.pl master
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd"
DIGCMD="$DIG $DIGOPTS @10.53.0.1 -p 5300"
SENDCMD="$PERL ../send.pl 10.53.0.2 5301"
RNDCCMD="$RNDC -s 10.53.0.1 -p 9953 -c ../common/rndc.conf"
echo "I:Setting up master"
$SENDCMD <<EOF
/SOA/
nil. 0 SOA ns.nil. root.nil. 1 300 300 604800 300
/TXT/
nil. 0 TXT ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
"cccccccccccccccccccccccccccccccccccccccccccccccccc"
"dddddddddddddddddddddddddddddddddddddddddddddddddd"
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
"ffffffffffffffffffffffffffffffffffffffffffffffffff"
"gggggggggggggggggggggggggggggggggggggggggggggggggg"
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"
"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"
)
EOF
echo "I:testing forwarder"
$DIGCMD nil. TXT > /dev/null 2>&1
edns_count=`grep -c "edns size: 4096" ans2/ans.run`
if [ $edns_count -ne 1 ]
then
echo "I:failed (EDNS4096 attempt)"
status=1
else
echo "I: EDNS4096 attempt OK"
fi
edns_count=`grep -c "edns size: 512" ans2/ans.run`
if [ $edns_count -ne 3 ]
then
echo "I:failed (EDNS512 attempts)"
status=1
else
echo "I: Three EDNS512 attempt OK"
fi
trunc_count=`grep -c "Truncating UDP packet" ans2/ans.run`
if [ $trunc_count -ne 1 ]
then
echo "I:failed (should be 1 truncation but $trunc_count returned)"
status=1
else
echo "I: packet truncated"
fi
sleep 15
$DIGCMD nil. TXT > /dev/null 2>&1
trunc_count=`grep -c "Truncating UDP packet" ans2/ans.run`
if [ $trunc_count -ne 2 ]
then
echo "I:failed (should be 2 truncations but $trunc_count returned)"
status=1
else
echo "I: packet truncated"
fi
echo "I:exit status: $status"
exit $status

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: adb.c,v 1.263 2011/12/01 00:14:11 smann Exp $ */
/* $Id: adb.c,v 1.264 2011/12/05 17:10:51 each Exp $ */
/*! \file
*
@@ -34,7 +34,6 @@
#include <isc/netaddr.h>
#include <isc/random.h>
#include <isc/stats.h>
#include <isc/stdio.h> /* temporary */
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/task.h>
#include <isc/util.h>
@@ -66,24 +65,6 @@
#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
/***
*** Constants for EDNS0 packets
*** DNS_ADB_EDNS0_MAX_LEN - max udpsize for edns0, should come from
*** named.conf
*** DNS_ADB_EDNS0_MIN_LEN - min udpsize for edns0
*** DNS_ADB_EDNS_RESET_TIME - after this period of time, drop count
*** is set to 0 and EDNS may be tried at
*** bigger size - surface to user?
*** DNS_ADB_EDNS_MAX_DROP_COUNT - after this many times EDNS has been
*** reduced, edns->fetch_flag set
*** DNS_ADB_EDNS_MAX_DROP_TIME - after this time retry EDNS at larger size
***/
#define DNS_ADB_EDNS0_MAX_LEN 4096
#define DNS_ADB_EDNS0_MIN_LEN 512
#define DNS_ADB_EDNS_RESET_TIME 300 /*make this user configurable?*/
#define DNS_ADB_EDNS_MAX_DROP_COUNT 5 /*make this user configurable?*/
#define DNS_ADB_EDNS_MAX_DROP_TIME 3600 /*make this user configurable?*/
/*!
* For type 3 negative cache entries, we will remember that the address is
* broken for this long. XXXMLG This is also used for actual addresses, too.
@@ -271,31 +252,6 @@ struct dns_adbentry {
* name.
*/
unsigned int edns_big_size;
unsigned int edns_last_size;
unsigned int edns_fetch_flag;
unsigned int edns_drop_count;
isc_stdtime_t edns_drop_timestamp;
isc_stdtime_t edns_expires_timestamp;
isc_boolean_t edns_timer_set;
/*%<
* The above fields beginning with edns_* determine
* past success with edns for this server.
* edns_big_size - biggest successful size received (e.g., 512)
* edns_last_size - last packet size received
* edns_fetch_flag - current EDNS state for this server (one of
* DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_EDNS512 or
* 0 meaning use DNS_ADB_EDNS0_MAX_LEN)
* edns_drop_count - keeps count of the number of times EDNS udpsize
* was dropped - reset to 0 every
* DNS_ADB_EDNS_RESET_TIME
* edns_drop_timestamp - The time at which the first EDNS drop
* in packet size was recorded
*
* See also dns_adb_drop/setednssize()
*/
ISC_LIST(dns_adblameinfo_t) lameinfo;
ISC_LINK(dns_adbentry_t) plink;
@@ -1791,13 +1747,6 @@ new_adbentry(dns_adb_t *adb) {
isc_random_get(&r);
e->srtt = (r & 0x1f) + 1;
e->expires = 0;
e->edns_big_size = 0;
e->edns_last_size = 0;
e->edns_fetch_flag = 0;
e->edns_drop_timestamp = 0;
e->edns_drop_count = 0;
e->edns_expires_timestamp = 0;
e->edns_timer_set = isc_boolean_false;
ISC_LIST_INIT(e->lameinfo);
ISC_LINK_INIT(e, plink);
LOCK(&adb->entriescntlock);
@@ -3961,170 +3910,6 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
UNLOCK(&adb->entrylocks[bucket]);
}
unsigned int
dns_adb_getednsflag(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now)
{
int bucket = 0;
int flag_to_use = 0; /* assume max by default */
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
/*
* The purpose of this function is to return
* edns_fetch_flag, which effectively sets the udpsize for EDNS
* or turns off EDNS (if NOEDNS0 has been recorded).
*
* Also, this function checks to see if the timer needs resetting.
* ---> this part should really be done via a callback?
*/
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
if((addr->entry->edns_timer_set) &&
(now >= addr->entry->edns_expires_timestamp)) {
/* Eventually, we may support more sizes */
if((addr->entry->edns_big_size <= 512) &&
(addr->entry->edns_big_size > 0))
flag_to_use = DNS_FETCHOPT_EDNS512;
addr->entry->edns_fetch_flag = flag_to_use;
addr->entry->edns_expires_timestamp = 0;
addr->entry->edns_timer_set = isc_boolean_false;
}
flag_to_use = addr->entry->edns_fetch_flag;
UNLOCK(&adb->entrylocks[bucket]);
return(flag_to_use);
}
void
dns_adb_setednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int length)
{
int bucket = 0;
unsigned int length_to_use;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
/*
* The purpose of this function is to record
* the maximum sized udp response seen from the
* instant server.
*/
length_to_use = addr->entry->edns_big_size;
if (length > DNS_ADB_EDNS0_MAX_LEN)
length = DNS_ADB_EDNS0_MAX_LEN;
if (length < DNS_ADB_EDNS0_MIN_LEN)
length = DNS_ADB_EDNS0_MIN_LEN;
if (length > length_to_use)
length_to_use = length;
addr->entry->edns_big_size = length_to_use;
UNLOCK(&adb->entrylocks[bucket]);
}
void
dns_adb_dropednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int length, isc_stdtime_t now)
{
isc_stdtime_t expires_ts_to_use;
isc_boolean_t timer_setting_to_use;
unsigned int length_to_use;
unsigned int drop_counter_to_use;
unsigned int drop_ts_to_use;
unsigned int flag_to_use;
int bucket = 0;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
if (length > DNS_ADB_EDNS0_MAX_LEN)
length = DNS_ADB_EDNS0_MAX_LEN;
if (length < DNS_ADB_EDNS0_MIN_LEN)
length = DNS_ADB_EDNS0_MIN_LEN;
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
expires_ts_to_use = addr->entry->edns_expires_timestamp;
timer_setting_to_use = addr->entry->edns_timer_set;
length_to_use = addr->entry->edns_big_size;
drop_ts_to_use = addr->entry->edns_drop_timestamp;
flag_to_use = addr->entry->edns_fetch_flag;
/*
* This function keeps a count of the number of times
* within DNS_ADB_EDNS_RESET_TIME that a particular server
* has dropped the udpsize in order to communicate with the
* server. If the number of times this occurs exceeds
* DNS_ADB_EDNS_MAX_DROP_COUNT, then the udpsize is reduced
* by way of edns_fetch_flag for DNS_ADB_EDNS_MAX_DROP_TIME,
* after which the largest size is retried again.
* NOTE: currently, only 4096 and 512 are supported sizes
*/
if (length > length_to_use)
length_to_use = length;
if ((now - addr->entry->edns_drop_timestamp) >=
DNS_ADB_EDNS_RESET_TIME) {
drop_counter_to_use = 1;
drop_ts_to_use = now;
} else {
drop_counter_to_use = addr->entry->edns_drop_count + 1;
if (drop_counter_to_use >= DNS_ADB_EDNS_MAX_DROP_COUNT) {
/*
* At this point, we are dropping down the
* udpsize because we've had too many misses
* at larger sizes.
*/
if (timer_setting_to_use == isc_boolean_false) {
/*
* if we haven't already set a timer,
* do so now. After DNS_ADB_EDNS_MAX_DROP_TIME,
* we'll go back to the largest size
*/
expires_ts_to_use =
now + DNS_ADB_EDNS_MAX_DROP_TIME;
timer_setting_to_use = isc_boolean_true;
}
if (length == 0)
flag_to_use = DNS_FETCHOPT_NOEDNS0;
else /* eventually, more edns sizes here */
flag_to_use = DNS_FETCHOPT_EDNS512;
drop_ts_to_use = 0;
drop_counter_to_use = 0;
}
}
addr->entry->edns_drop_timestamp = drop_ts_to_use;
addr->entry->edns_drop_count = drop_counter_to_use;
addr->entry->edns_fetch_flag = flag_to_use;
addr->entry->edns_expires_timestamp = expires_ts_to_use;
addr->entry->edns_timer_set = timer_setting_to_use;
addr->entry->edns_big_size = length_to_use;
UNLOCK(&adb->entrylocks[bucket]);
}
void
dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int bits, unsigned int mask)

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: adb.h,v 1.87 2011/10/27 23:46:31 tbox Exp $ */
/* $Id: adb.h,v 1.88 2011/12/05 17:10:51 each Exp $ */
#ifndef DNS_ADB_H
#define DNS_ADB_H 1
@@ -548,64 +548,6 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
* srtt value. This may include changes made by others.
*/
unsigned int
dns_adb_getednsflag(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now);
/*%
* Get the EDNS big size
*
*\brief
* Return the edns_fetchopt_flag from the instant dns_adbentry struct
* This value may be DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_EDNS512,
* or 0. If 0, the default maximum EDNS udp size is assumed.
*
* Requires:
*
*\li adb be valid.
*
*\li addr be valid.
*/
void
dns_adb_setednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int length);
/*%
* Set the EDNS size
*
*\brief
* Record the biggest length of received packet and maintain information
* about reductions in udp size.
*
*\li length - size of packet
*\li now - current time in seconds
*
* Requires:
*
*\li adb be valid.
*
*\li addr be valid.
*/
void
dns_adb_dropednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int length, isc_stdtime_t now);
/*%
* Drop the EDNS size
*
*\brief
* Record a notification that the packetsize has been dropped because of
* communication failures. If enough of these occur, this server's EDNS size
* will be dropped for DNS_ADB_EDNS_MAX_DROP_TIME.
*
*\li length - size of packet
*\li now - current time in seconds
*
* Requires:
*
*\li adb be valid.
*
*\li addr be valid.
*/
void
dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int bits, unsigned int mask);

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.h,v 1.71 2011/11/16 22:18:52 marka Exp $ */
/* $Id: resolver.h,v 1.72 2011/12/05 17:10:51 each Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -96,9 +96,6 @@ typedef struct dns_fetchevent {
#define DNS_FETCHOPT_EDNS512 0x40 /*%< Advertise a 512 byte
UDP buffer. */
#define DNS_FETCHOPT_WANTNSID 0x80 /*%< Request NSID */
#define DNS_FETCHOPT_CACHENOEDNS 0x100 /*%< This is a candidate
for setting NOEDNS
in adb. */
#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.c,v 1.443 2011/11/23 22:53:53 each Exp $ */
/* $Id: resolver.c,v 1.444 2011/12/05 17:10:51 each Exp $ */
/*! \file */
@@ -1324,9 +1324,7 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
* We retry every .8 seconds the first two times through the address
* list, and then we do exponential back-off.
*/
if (fctx->restarts == 0)
us = 400000;
else if (fctx->restarts < 3)
if (fctx->restarts < 3)
us = 800000;
else
us = (800000 << (fctx->restarts - 2));
@@ -1687,8 +1685,6 @@ resquery_send(resquery_t *query) {
isc_boolean_t cleanup_cctx = ISC_FALSE;
isc_boolean_t secure_domain;
isc_boolean_t connecting = ISC_FALSE;
unsigned int edns_fetchopt_flag;
isc_stdtime_t now;
fctx = query->fctx;
QTRACE("send");
@@ -1798,16 +1794,6 @@ resquery_send(resquery_t *query) {
isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr);
(void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
/*
* Get the fetchopt flag for this server from the adb cache
* NOTE: if the NOEDNS flag has been set on addrinfo->flags,
* it will over write this below.
*/
isc_stdtime_get(&now);
edns_fetchopt_flag = dns_adb_getednsflag(fctx->adb, query->addrinfo,
now);
query->options |= edns_fetchopt_flag;
/*
* The ADB does not know about servers with "edns no". Check this,
* and then inform the ADB for future use.
@@ -1842,24 +1828,18 @@ resquery_send(resquery_t *query) {
* * packet loss / link outage.
*/
if (fctx->timeout) {
if ((triededns512(fctx, &query->addrinfo->sockaddr) &&
fctx->timeouts > MAX_EDNS0_TIMEOUTS) &&
if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
query->options |= DNS_FETCHOPT_NOEDNS0;
query->options |= DNS_FETCHOPT_CACHENOEDNS;
fctx->reason = "disabling EDNS";
} else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
fctx->timeouts >= 1) &&
fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
query->options |= DNS_FETCHOPT_EDNS512;
if (edns_fetchopt_flag != DNS_FETCHOPT_EDNS512) {
dns_adb_dropednssize(fctx->adb, query->addrinfo,
512, now);
fctx->reason = "reducing the advertised EDNS "
"UDP packet size to 512 octets";
} else
fctx->reason = "continuing to use lower EDNS "
"UDP packet size of 512 octets";
fctx->reason = "reducing the advertised EDNS UDP "
"packet size to 512 octets";
}
fctx->timeout = ISC_FALSE;
}
@@ -1918,12 +1898,11 @@ resquery_send(resquery_t *query) {
goto cleanup_message;
}
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
add_triededns(fctx, &query->addrinfo->sockaddr);
if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
add_triededns512(fctx, &query->addrinfo->sockaddr);
}
if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
add_triededns512(fctx, &query->addrinfo->sockaddr);
/*
* Clear CD if EDNS is not in use.
@@ -6582,25 +6561,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
}
goto done;
#if 0
} else if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0 &&
(query->options & DNS_FETCHOPT_CACHENOEDNS) != 0 &&
triededns512(fctx, &query->addrinfo->sockaddr)) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
sizeof(addrbuf));
/*
* We had a successful response to a DNS_FETCHOPT_NOEDNS0
* query.
*/
isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
"%s: setting NOEDNS flag in adb cache for '%s'",
fctx->info, addrbuf);
dns_adb_changeflags(fctx->adb, query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);
#endif
}
message = fctx->rmessage;
@@ -6744,10 +6704,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
sizeof(addrbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
"%s: changed rcode: setting NOEDNS flag in "
"adb cache for '%s'", fctx->info, addrbuf);
dns_adb_changeflags(fctx->adb, query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);
@@ -6919,16 +6875,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
goto done;
}
/*
* Update the packet received sizes
*/
if (((query->options & DNS_FETCHOPT_NOEDNS0) == 0) &&
((devent->attributes & DNS_DISPATCHATTR_UDP) != 0))
dns_adb_setednssize(fctx->adb,
query->addrinfo,
devent->buffer.length);
/*
* Enforce delegations only zones like NET and COM.
*/