mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-20 21:58:03 -04:00
551. [func] Implemented the 'sortlist' option.
This commit is contained in:
parent
9a6314a09a
commit
febaa09184
17 changed files with 572 additions and 152 deletions
2
CHANGES
2
CHANGES
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
551. [func] Implemented the 'sortlist' option.
|
||||
|
||||
550. [func] Support unknown rdata types and classes.
|
||||
|
||||
549. [bug] "make" did not immediately abort the build when a
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.143 2000/11/09 19:55:16 mws Exp $ */
|
||||
/* $Id: query.c,v 1.144 2000/11/10 03:16:14 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -2097,6 +2097,147 @@ do { \
|
|||
want_restart = ISC_FALSE; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Extract a network address from the RDATA of an A or AAAA
|
||||
* record.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS
|
||||
* ISC_R_NOTIMPLEMENTED The rdata is not a known address type.
|
||||
*/
|
||||
|
||||
static isc_result_t
|
||||
rdata_tonetaddr(dns_rdata_t *rdata, isc_netaddr_t *netaddr) {
|
||||
struct in_addr ina;
|
||||
struct in6_addr in6a;
|
||||
|
||||
switch (rdata->type) {
|
||||
case dns_rdatatype_a:
|
||||
INSIST(rdata->length == 4);
|
||||
memcpy(&ina.s_addr, rdata->data, 4);
|
||||
isc_netaddr_fromin(netaddr, &ina);
|
||||
return (ISC_R_SUCCESS);
|
||||
case dns_rdatatype_aaaa:
|
||||
INSIST(rdata->length == 16);
|
||||
memcpy(in6a.s6_addr, rdata->data, 16);
|
||||
isc_netaddr_fromin6(netaddr, &in6a);
|
||||
return (ISC_R_SUCCESS);
|
||||
default:
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the sort order of 'rdata' in the topology-like
|
||||
* ACL forming the second element in a 2-element top-level
|
||||
* sortlist statement.
|
||||
*/
|
||||
static int
|
||||
sortlist_order_2element(dns_rdata_t *rdata, void *arg) {
|
||||
dns_acl_t *sortacl = (dns_acl_t *) arg;
|
||||
isc_netaddr_t netaddr;
|
||||
int match;
|
||||
|
||||
if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
|
||||
return (INT_MAX);
|
||||
|
||||
(void)dns_acl_match(&netaddr, NULL, sortacl,
|
||||
&ns_g_server->aclenv,
|
||||
&match, NULL);
|
||||
if (match > 0)
|
||||
return (match);
|
||||
else
|
||||
return (INT_MAX - (-match));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the sort order of 'rdata' in the matching element
|
||||
* of a 1-element top-level sortlist statement.
|
||||
*/
|
||||
static int
|
||||
sortlist_order_1element(dns_rdata_t *rdata, void *arg) {
|
||||
dns_aclelement_t *matchelt = (dns_aclelement_t *) arg;
|
||||
isc_netaddr_t netaddr;
|
||||
|
||||
if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
|
||||
return (INT_MAX);
|
||||
|
||||
if (dns_aclelement_match(&netaddr, NULL, matchelt,
|
||||
&ns_g_server->aclenv,
|
||||
NULL)) {
|
||||
return (0);
|
||||
} else {
|
||||
return (INT_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the sortlist element that applies to 'client',
|
||||
* store data identifying it in '*data', and set up
|
||||
* the sortlist info in in client->message appropriately.
|
||||
*
|
||||
* '*data' must persist until the message has been rendered.
|
||||
*/
|
||||
static void
|
||||
setup_sortlist(ns_client_t *client) {
|
||||
isc_netaddr_t netaddr;
|
||||
dns_acl_t *acl = client->view->sortlist;
|
||||
unsigned int i;
|
||||
|
||||
if (acl == NULL)
|
||||
goto dont_sort;
|
||||
|
||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||
|
||||
for (i = 0; i < acl->length; i++) {
|
||||
/*
|
||||
* 'e' refers to the current 'top level statement'
|
||||
* in the sortlist (see ARM).
|
||||
*/
|
||||
dns_aclelement_t *e = &acl->elements[i];
|
||||
dns_aclelement_t *matchelt = NULL;
|
||||
dns_acl_t *inner;
|
||||
|
||||
if (e->type != dns_aclelementtype_nestedacl)
|
||||
goto dont_sort;
|
||||
|
||||
inner = e->u.nestedacl;
|
||||
|
||||
if (inner->length < 1 || inner->length > 2)
|
||||
goto dont_sort;
|
||||
|
||||
if (inner->elements[0].negative)
|
||||
goto dont_sort;
|
||||
|
||||
if (dns_aclelement_match(&netaddr, client->signer,
|
||||
&inner->elements[0],
|
||||
&ns_g_server->aclenv,
|
||||
&matchelt)) {
|
||||
if (inner->length == 2) {
|
||||
dns_aclelement_t *elt1 = &inner->elements[1];
|
||||
if (elt1->type != dns_aclelementtype_nestedacl)
|
||||
goto dont_sort;
|
||||
dns_message_setsortorder(client->message,
|
||||
sortlist_order_2element,
|
||||
elt1->u.nestedacl);
|
||||
return;
|
||||
} else {
|
||||
INSIST(matchelt != NULL);
|
||||
dns_message_setsortorder(client->message,
|
||||
sortlist_order_1element,
|
||||
matchelt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* No match; don't sort. */
|
||||
dont_sort:
|
||||
dns_message_setsortorder(client->message, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
query_find(ns_client_t *client, dns_fetchevent_t *event) {
|
||||
dns_db_t *db, *zdb;
|
||||
|
|
@ -3009,10 +3150,13 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
|
|||
ns_client_detach(&client);
|
||||
} else if (!RECURSING(client)) {
|
||||
/*
|
||||
* We are done. Make a final tweak to the AA bit if the
|
||||
* auth-nxdomain config option says so, then send the
|
||||
* response.
|
||||
* We are done. Set up sortlist data for the message
|
||||
* rendering code, make a final tweak to the AA bit if the
|
||||
* auth-nxdomain config option says so, then render and
|
||||
* send the response.
|
||||
*/
|
||||
setup_sortlist(client);
|
||||
|
||||
if (client->message->rcode == dns_rcode_nxdomain &&
|
||||
client->view->auth_nxdomain == ISC_TRUE)
|
||||
client->message->flags |= DNS_MESSAGEFLAG_AA;
|
||||
|
|
|
|||
23
bin/tests/system/sortlist/clean.sh
Normal file
23
bin/tests/system/sortlist/clean.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2000 Internet Software Consortium.
|
||||
#
|
||||
# Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
# CONSORTIUM 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.1 2000/11/10 03:16:16 gson Exp $
|
||||
|
||||
rm -f *.dig *.good
|
||||
|
||||
|
||||
|
||||
1
bin/tests/system/sortlist/ns1/.cvsignore
Normal file
1
bin/tests/system/sortlist/ns1/.cvsignore
Normal file
|
|
@ -0,0 +1 @@
|
|||
named.run
|
||||
42
bin/tests/system/sortlist/ns1/example.db
Normal file
42
bin/tests/system/sortlist/ns1/example.db
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
; Copyright (C) 2000 Internet Software Consortium.
|
||||
;
|
||||
; Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM
|
||||
; DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
; INTERNET SOFTWARE CONSORTIUM 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: example.db,v 1.1 2000/11/10 03:16:16 gson Exp $
|
||||
|
||||
$TTL 300 ; 5 minutes
|
||||
@ IN SOA ns2.example. hostmaster.example. (
|
||||
2000042795 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
example. NS ns1.example.
|
||||
ns2.example. A 10.53.0.1
|
||||
|
||||
; Let's see what the sortlist picks out of this...
|
||||
a A 1.1.1.1
|
||||
a A 1.1.1.2
|
||||
a A 192.168.3.1
|
||||
a A 1.1.1.3
|
||||
a A 192.168.1.1
|
||||
a A 1.1.1.4
|
||||
|
||||
b A 10.53.0.1
|
||||
b A 10.53.0.2
|
||||
b A 10.53.0.3
|
||||
b A 10.53.0.4
|
||||
b A 10.53.0.5
|
||||
|
||||
46
bin/tests/system/sortlist/ns1/named.conf
Normal file
46
bin/tests/system/sortlist/ns1/named.conf
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM 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.1 2000/11/10 03:16:16 gson Exp $ */
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
port 5300;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
|
||||
sortlist {
|
||||
{ 10.53.0.1; // IF 10.53.0.1
|
||||
{ // THEN first fit on the
|
||||
192.168.3/24; // following nets
|
||||
{ 192.168.2/24; 192.168.1/24; }; }; };
|
||||
{ { 10.53.0.2; 10.53.0.3; }; }; // Prefer self
|
||||
};
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type master;
|
||||
file "root.db";
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
type master;
|
||||
file "example.db";
|
||||
};
|
||||
30
bin/tests/system/sortlist/ns1/root.db
Normal file
30
bin/tests/system/sortlist/ns1/root.db
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
; Copyright (C) 2000 Internet Software Consortium.
|
||||
;
|
||||
; Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM
|
||||
; DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
; INTERNET SOFTWARE CONSORTIUM 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: root.db,v 1.1 2000/11/10 03:16:16 gson Exp $
|
||||
|
||||
$TTL 300
|
||||
. IN SOA gson.nominum.com. a.root.servers.nil. (
|
||||
2000042100 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
. NS a.root-servers.nil.
|
||||
a.root-servers.nil. A 10.53.0.1
|
||||
|
||||
example. NS ns2.example.
|
||||
ns2.example. A 10.53.0.2
|
||||
49
bin/tests/system/sortlist/tests.sh
Normal file
49
bin/tests/system/sortlist/tests.sh
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2000 Internet Software Consortium.
|
||||
#
|
||||
# Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM
|
||||
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# INTERNET SOFTWARE CONSORTIUM 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.1 2000/11/10 03:16:16 gson Exp $
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
status=0
|
||||
|
||||
echo "I:test 2-element sortlist statement"
|
||||
cat <<EOF >test1.good
|
||||
a.example. 300 IN A 192.168.3.1
|
||||
a.example. 300 IN A 192.168.1.1
|
||||
EOF
|
||||
$DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd a.example. \
|
||||
@10.53.0.1 -b 10.53.0.1 -p 5300 | head -2 >test1.dig
|
||||
# Note that this can't use digcomp.pl because here, the ordering of the
|
||||
# result RRs is significant.
|
||||
diff test1.dig test1.good || status=1
|
||||
|
||||
echo "I:test 1-element sortlist statement"
|
||||
for n in 2 3
|
||||
do
|
||||
cat <<EOF >test2.good
|
||||
b.example. 300 IN A 10.53.0.$n
|
||||
EOF
|
||||
$DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd \
|
||||
b.example. \
|
||||
@10.53.0.1 -b 10.53.0.$n -p 5300 | head -1 >test2.dig
|
||||
diff test2.dig test2.good || status=1
|
||||
done
|
||||
|
||||
echo "I:exit status: $status"
|
||||
exit $status
|
||||
156
lib/dns/acl.c
156
lib/dns/acl.c
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: acl.c,v 1.14 2000/08/11 01:53:46 gson Exp $ */
|
||||
/* $Id: acl.c,v 1.15 2000/11/10 03:16:16 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -130,84 +130,17 @@ dns_acl_match(isc_netaddr_t *reqaddr,
|
|||
int *match,
|
||||
dns_aclelement_t **matchelt)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned int i;
|
||||
int indirectmatch;
|
||||
|
||||
REQUIRE(reqaddr != NULL);
|
||||
REQUIRE(matchelt == NULL || *matchelt == NULL);
|
||||
|
||||
|
||||
for (i = 0; i < acl->length; i++) {
|
||||
dns_aclelement_t *e = &acl->elements[i];
|
||||
dns_acl_t *inner = NULL;
|
||||
|
||||
switch (e->type) {
|
||||
case dns_aclelementtype_ipprefix:
|
||||
if (isc_netaddr_eqprefix(reqaddr,
|
||||
&e->u.ip_prefix.address,
|
||||
e->u.ip_prefix.prefixlen))
|
||||
goto matched;
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_keyname:
|
||||
if (reqsigner != NULL &&
|
||||
dns_name_equal(reqsigner, &e->u.keyname))
|
||||
goto matched;
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_nestedacl:
|
||||
inner = e->u.nestedacl;
|
||||
nested:
|
||||
result = dns_acl_match(reqaddr, reqsigner,
|
||||
inner,
|
||||
env,
|
||||
&indirectmatch, matchelt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
/*
|
||||
* Treat negative matches in indirect ACLs as
|
||||
* "no match".
|
||||
* That way, a negated indirect ACL will never become
|
||||
* a surprise positive match through double negation.
|
||||
* XXXDCL this should be documented.
|
||||
*/
|
||||
if (indirectmatch > 0)
|
||||
goto matched;
|
||||
|
||||
/*
|
||||
* A negative indirect match may have set *matchelt,
|
||||
* but we don't want it set when we return.
|
||||
*/
|
||||
if (matchelt != NULL)
|
||||
*matchelt = NULL;
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_any:
|
||||
matched:
|
||||
if (dns_aclelement_match(reqaddr, reqsigner, e, env, matchelt)) {
|
||||
*match = e->negative ? -(i+1) : (i+1);
|
||||
if (matchelt != NULL)
|
||||
*matchelt = e;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
case dns_aclelementtype_localhost:
|
||||
if (env != NULL && env->localhost != NULL) {
|
||||
inner = env->localhost;
|
||||
goto nested;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
case dns_aclelementtype_localnets:
|
||||
if (env != NULL && env->localnets != NULL) {
|
||||
inner = env->localnets;
|
||||
goto nested;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
INSIST(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* No match. */
|
||||
|
|
@ -215,6 +148,89 @@ dns_acl_match(isc_netaddr_t *reqaddr,
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_aclelement_match(isc_netaddr_t *reqaddr,
|
||||
dns_name_t *reqsigner,
|
||||
dns_aclelement_t *e,
|
||||
dns_aclenv_t *env,
|
||||
dns_aclelement_t **matchelt)
|
||||
{
|
||||
dns_acl_t *inner = NULL;
|
||||
int indirectmatch;
|
||||
isc_result_t result;
|
||||
|
||||
switch (e->type) {
|
||||
case dns_aclelementtype_ipprefix:
|
||||
if (isc_netaddr_eqprefix(reqaddr,
|
||||
&e->u.ip_prefix.address,
|
||||
e->u.ip_prefix.prefixlen))
|
||||
goto matched;
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_keyname:
|
||||
if (reqsigner != NULL &&
|
||||
dns_name_equal(reqsigner, &e->u.keyname))
|
||||
goto matched;
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_nestedacl:
|
||||
inner = e->u.nestedacl;
|
||||
nested:
|
||||
result = dns_acl_match(reqaddr, reqsigner,
|
||||
inner,
|
||||
env,
|
||||
&indirectmatch, matchelt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
/*
|
||||
* Treat negative matches in indirect ACLs as
|
||||
* "no match".
|
||||
* That way, a negated indirect ACL will never become
|
||||
* a surprise positive match through double negation.
|
||||
* XXXDCL this should be documented.
|
||||
*/
|
||||
if (indirectmatch > 0)
|
||||
goto matchelt_set;
|
||||
|
||||
/*
|
||||
* A negative indirect match may have set *matchelt,
|
||||
* but we don't want it set when we return.
|
||||
*/
|
||||
if (matchelt != NULL)
|
||||
*matchelt = NULL;
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_any:
|
||||
matched:
|
||||
if (matchelt != NULL)
|
||||
*matchelt = e;
|
||||
matchelt_set:
|
||||
return (ISC_TRUE);
|
||||
|
||||
case dns_aclelementtype_localhost:
|
||||
if (env != NULL && env->localhost != NULL) {
|
||||
inner = env->localhost;
|
||||
goto nested;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
case dns_aclelementtype_localnets:
|
||||
if (env != NULL && env->localnets != NULL) {
|
||||
inner = env->localnets;
|
||||
goto nested;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
INSIST(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
|
||||
REQUIRE(DNS_ACL_VALID(source));
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: confctx.c,v 1.99 2000/11/08 03:53:13 marka Exp $ */
|
||||
/* $Id: confctx.c,v 1.100 2000/11/10 03:16:21 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -515,13 +515,6 @@ dns_c_checkconfig(dns_c_ctx_t *cfg)
|
|||
"option 'topology' is deprecated");
|
||||
}
|
||||
|
||||
if (dns_c_ctx_getsortlist(cfg, &ipml) != ISC_R_NOTFOUND) {
|
||||
dns_c_ipmatchlist_detach(&ipml);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
|
||||
DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
|
||||
"option 'sortlist' is not yet implemented");
|
||||
}
|
||||
|
||||
if (dns_c_ctx_getrrsetorderlist(cfg, &olist) != ISC_R_NOTFOUND) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
|
||||
DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: acl.h,v 1.14 2000/11/07 23:43:23 bwelling Exp $ */
|
||||
/* $Id: acl.h,v 1.15 2000/11/10 03:16:23 gson Exp $ */
|
||||
|
||||
#ifndef DNS_ACL_H
|
||||
#define DNS_ACL_H 1
|
||||
|
|
@ -167,6 +167,21 @@ dns_acl_match(isc_netaddr_t *reqaddr,
|
|||
* ISC_R_SUCCESS Always succeeds.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_aclelement_match(isc_netaddr_t *reqaddr,
|
||||
dns_name_t *reqsigner,
|
||||
dns_aclelement_t *e,
|
||||
dns_aclenv_t *env,
|
||||
dns_aclelement_t **matchelt);
|
||||
/*
|
||||
* Like dns_acl_match, but matches against the single ACL element 'e'
|
||||
* rather than a complete list and returns ISC_TRUE iff it matched.
|
||||
* To determine whether the match was prositive or negative, the
|
||||
* caller should examine e->negative. Since the element 'e' may be
|
||||
* a reference to a named ACL or a nested ACL, the matching element
|
||||
* returned through 'matchelt' is not necessarily 'e' itself.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_ACL_H */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: message.h,v 1.80 2000/11/10 03:13:03 gson Exp $ */
|
||||
/* $Id: message.h,v 1.81 2000/11/10 03:16:24 gson Exp $ */
|
||||
|
||||
#ifndef DNS_MESSAGE_H
|
||||
#define DNS_MESSAGE_H 1
|
||||
|
|
@ -1188,6 +1188,20 @@ dns_message_getrawmessage(dns_message_t *msg);
|
|||
* a pointer to a region which refers the dns message.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
|
||||
void *order_arg);
|
||||
/*
|
||||
* Define the order in which RR sets get rendered by
|
||||
* dns_message_rendersection() to be the ascending order
|
||||
* defined by the integer value returned by 'order' when
|
||||
* given each RR and 'arg' as arguments. If 'order' and
|
||||
* 'order_arg' are NULL, a default order is used.
|
||||
*
|
||||
* Requires:
|
||||
* order_arg is NULL if and only if order is NULL.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_MESSAGE_H */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: types.h,v 1.97 2000/11/03 07:16:07 marka Exp $ */
|
||||
/* $Id: types.h,v 1.98 2000/11/10 03:16:25 gson Exp $ */
|
||||
|
||||
#ifndef DNS_TYPES_H
|
||||
#define DNS_TYPES_H 1
|
||||
|
|
@ -280,4 +280,7 @@ typedef void
|
|||
typedef void
|
||||
(*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *);
|
||||
|
||||
typedef int
|
||||
(*dns_rdatasetorderfunc_t)(dns_rdata_t *rdata, void *arg);
|
||||
|
||||
#endif /* DNS_TYPES_H */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.h,v 1.55 2000/11/03 18:35:31 gson Exp $ */
|
||||
/* $Id: view.h,v 1.56 2000/11/10 03:16:26 gson Exp $ */
|
||||
|
||||
#ifndef DNS_VIEW_H
|
||||
#define DNS_VIEW_H 1
|
||||
|
|
@ -106,6 +106,7 @@ struct dns_view {
|
|||
dns_transfer_format_t transfer_format;
|
||||
dns_acl_t * queryacl;
|
||||
dns_acl_t * recursionacl;
|
||||
dns_acl_t * sortlist;
|
||||
isc_boolean_t requestixfr;
|
||||
isc_boolean_t provideixfr;
|
||||
dns_ttl_t maxcachettl;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: message.c,v 1.156 2000/10/27 21:56:56 bwelling Exp $ */
|
||||
/* $Id: message.c,v 1.157 2000/11/10 03:16:18 gson Exp $ */
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
|
|
@ -372,6 +372,8 @@ msginit(dns_message_t *m) {
|
|||
m->tcp_continuation = 0;
|
||||
m->verified_sig = 0;
|
||||
m->verify_attempted = 0;
|
||||
m->order = NULL;
|
||||
m->order_arg = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -468,7 +470,7 @@ msgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
|
|||
|
||||
/*
|
||||
* Free all but one (or everything) for this message. This is used by
|
||||
* both dns_message_reset() and dns_message_parse().
|
||||
* both dns_message_reset() and dns_message_destroy().
|
||||
*/
|
||||
static void
|
||||
msgreset(dns_message_t *msg, isc_boolean_t everything) {
|
||||
|
|
@ -1744,10 +1746,13 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
|||
st = *(msg->buffer);
|
||||
|
||||
count = 0;
|
||||
result = dns_rdataset_towire(rdataset, name,
|
||||
&msg->cctx,
|
||||
msg->buffer,
|
||||
&count);
|
||||
result = dns_rdataset_towiresorted(rdataset,
|
||||
name,
|
||||
&msg->cctx,
|
||||
msg->buffer,
|
||||
msg->order,
|
||||
msg->order_arg,
|
||||
&count);
|
||||
|
||||
total += count;
|
||||
|
||||
|
|
@ -2948,3 +2953,12 @@ dns_message_getrawmessage(dns_message_t *msg) {
|
|||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
return (msg->saved);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
|
||||
void *order_arg)
|
||||
{
|
||||
msg->order = order;
|
||||
msg->order_arg = order_arg;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.c,v 1.51 2000/10/25 04:26:47 marka Exp $ */
|
||||
/* $Id: rdataset.c,v 1.52 2000/11/10 03:16:19 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -256,25 +256,38 @@ dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
|
|||
|
||||
#define MAX_SHUFFLE 32
|
||||
#define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
|
||||
#define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
|
||||
|
||||
struct towire_sort {
|
||||
int key;
|
||||
dns_rdata_t *rdata;
|
||||
};
|
||||
|
||||
static int
|
||||
towire_compare(const void *av, const void *bv) {
|
||||
const struct towire_sort *a = (const struct towire_sort *) av;
|
||||
const struct towire_sort *b = (const struct towire_sort *) bv;
|
||||
return (a->key - b->key);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towire(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
unsigned int *countp)
|
||||
dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
dns_rdatasetorderfunc_t order,
|
||||
void *order_arg,
|
||||
unsigned int *countp)
|
||||
{
|
||||
dns_rdata_t rdata;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
unsigned int i, count, tcount, choice;
|
||||
unsigned int i, count;
|
||||
isc_buffer_t savedbuffer, rdlen;
|
||||
unsigned int headlen;
|
||||
isc_boolean_t question = ISC_FALSE;
|
||||
isc_boolean_t shuffle = ISC_FALSE;
|
||||
dns_rdata_t shuffled[MAX_SHUFFLE];
|
||||
struct towire_sort sorted[MAX_SHUFFLE];
|
||||
|
||||
/*
|
||||
* Convert 'rdataset' to wire format, compressing names as specified
|
||||
|
|
@ -283,6 +296,7 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|||
|
||||
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
||||
REQUIRE(countp != NULL);
|
||||
REQUIRE((order == NULL) == (order_arg == NULL));
|
||||
|
||||
count = 0;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
|
||||
|
|
@ -304,60 +318,64 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|||
return (result);
|
||||
}
|
||||
|
||||
choice = 0;
|
||||
if (!question && count > 1 && !WANT_FIXED(rdataset)) {
|
||||
/*
|
||||
* We'll only shuffle if we've got enough slots in our
|
||||
* deck.
|
||||
*
|
||||
* There's no point to shuffling SIGs.
|
||||
*/
|
||||
if (!question &&
|
||||
count > 1 &&
|
||||
!WANT_FIXED(rdataset) &&
|
||||
count <= MAX_SHUFFLE &&
|
||||
rdataset->type != dns_rdatatype_sig)
|
||||
{
|
||||
shuffle = ISC_TRUE;
|
||||
/*
|
||||
* We'll only shuffle if we've got enough slots in our
|
||||
* deck.
|
||||
*
|
||||
* There's no point to shuffling SIGs.
|
||||
* First we get handles to all of the rdata.
|
||||
*/
|
||||
if (count <= MAX_SHUFFLE &&
|
||||
rdataset->type != dns_rdatatype_sig) {
|
||||
shuffle = ISC_TRUE;
|
||||
i = 0;
|
||||
do {
|
||||
INSIST(i < count);
|
||||
dns_rdata_init(&shuffled[i]);
|
||||
dns_rdataset_current(rdataset, &shuffled[i]);
|
||||
i++;
|
||||
result = dns_rdataset_next(rdataset);
|
||||
} while (result == ISC_R_SUCCESS);
|
||||
if (result != ISC_R_NOMORE)
|
||||
return (result);
|
||||
INSIST(i == count);
|
||||
/*
|
||||
* Now we shuffle.
|
||||
*/
|
||||
if (order != NULL) {
|
||||
/*
|
||||
* First we get handles to all of the rdata.
|
||||
* Sorted order.
|
||||
*/
|
||||
i = 0;
|
||||
do {
|
||||
INSIST(i < count);
|
||||
dns_rdata_init(&shuffled[i]);
|
||||
dns_rdataset_current(rdataset, &shuffled[i]);
|
||||
i++;
|
||||
result = dns_rdataset_next(rdataset);
|
||||
} while (result == ISC_R_SUCCESS);
|
||||
if (result != ISC_R_NOMORE)
|
||||
return (result);
|
||||
INSIST(i == count);
|
||||
for (i = 0; i < count; i++) {
|
||||
sorted[i].key = (*order)(&shuffled[i],
|
||||
order_arg);
|
||||
sorted[i].rdata = &shuffled[i];
|
||||
}
|
||||
qsort(sorted, count, sizeof(sorted[0]),
|
||||
towire_compare);
|
||||
} else {
|
||||
/*
|
||||
* Now we shuffle.
|
||||
* "Cyclic" order.
|
||||
*/
|
||||
if (WANT_RANDOM(rdataset)) {
|
||||
/*
|
||||
* "Random" order.
|
||||
*/
|
||||
tcount = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
choice = (((unsigned int)rand()) >> 3)
|
||||
% tcount;
|
||||
rdata = shuffled[i];
|
||||
shuffled[i] = shuffled[i + choice];
|
||||
shuffled[i + choice] = rdata;
|
||||
tcount--;
|
||||
}
|
||||
choice = 0;
|
||||
} else {
|
||||
/*
|
||||
* "Cyclic" order.
|
||||
*/
|
||||
choice = (((unsigned int)rand()) >> 3) % count;
|
||||
unsigned int j = (((unsigned int)rand()) >> 3) % count;
|
||||
for (i = 0; i < count; i++) {
|
||||
sorted[j].key = 0; /* Unused */
|
||||
sorted[j].rdata = &shuffled[i];
|
||||
j++;
|
||||
if (j == count)
|
||||
j = 0; /* Wrap around. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
savedbuffer = *target;
|
||||
i = choice;
|
||||
tcount = 0;
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
/*
|
||||
|
|
@ -391,7 +409,7 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|||
* Copy out the rdata
|
||||
*/
|
||||
if (shuffle)
|
||||
rdata = shuffled[i];
|
||||
rdata = *(sorted[i].rdata);
|
||||
else {
|
||||
dns_rdata_init(&rdata);
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
|
|
@ -408,18 +426,13 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|||
|
||||
if (shuffle) {
|
||||
i++;
|
||||
/*
|
||||
* Wrap around in case we're doing cyclic ordering.
|
||||
*/
|
||||
if (i == count)
|
||||
i = 0;
|
||||
tcount++;
|
||||
if (tcount == count)
|
||||
result = ISC_R_NOMORE;
|
||||
else
|
||||
result = ISC_R_SUCCESS;
|
||||
} else
|
||||
} else {
|
||||
result = dns_rdataset_next(rdataset);
|
||||
}
|
||||
} while (result == ISC_R_SUCCESS);
|
||||
|
||||
if (result != ISC_R_NOMORE)
|
||||
|
|
@ -438,6 +451,17 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towire(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
unsigned int *countp)
|
||||
{
|
||||
return (dns_rdataset_towiresorted(rdataset, owner_name, cctx, target,
|
||||
NULL, NULL, countp));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
dns_additionaldatafunc_t add, void *arg)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.c,v 1.84 2000/11/03 18:27:31 gson Exp $ */
|
||||
/* $Id: view.c,v 1.85 2000/11/10 03:16:20 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -156,6 +156,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||
view->transfer_format = dns_one_answer;
|
||||
view->queryacl = NULL;
|
||||
view->recursionacl = NULL;
|
||||
view->sortlist = NULL;
|
||||
view->requestixfr = ISC_TRUE;
|
||||
view->provideixfr = ISC_TRUE;
|
||||
view->maxcachettl = 7 * 24 * 3600;
|
||||
|
|
@ -248,6 +249,8 @@ destroy(dns_view_t *view) {
|
|||
dns_acl_detach(&view->queryacl);
|
||||
if (view->recursionacl != NULL)
|
||||
dns_acl_detach(&view->recursionacl);
|
||||
if (view->sortlist != NULL)
|
||||
dns_acl_detach(&view->sortlist);
|
||||
dns_keytable_detach(&view->trustedkeys);
|
||||
dns_keytable_detach(&view->secroots);
|
||||
dns_fwdtable_destroy(&view->fwdtable);
|
||||
|
|
|
|||
Loading…
Reference in a new issue