sortlist.c revision 34613b2e39478a83076f6a626a4b855cebb19533
1336066b632d14017167c052fae5eb4df64726deDanny Mayer/*
1336066b632d14017167c052fae5eb4df64726deDanny Mayer * Copyright (C) 2000, 2001 Internet Software Consortium.
1336066b632d14017167c052fae5eb4df64726deDanny Mayer *
1336066b632d14017167c052fae5eb4df64726deDanny Mayer * Permission to use, copy, modify, and distribute this software for any
1336066b632d14017167c052fae5eb4df64726deDanny Mayer * purpose with or without fee is hereby granted, provided that the above
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews * copyright notice and this permission notice appear in all copies.
b4eaa17e82f439a0b70b1b7079d1592564d9f621Mark Andrews *
7641867b4c39914cdcd3711ba0c89ed9c49f3c83Francis Dupont * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
b4eaa17e82f439a0b70b1b7079d1592564d9f621Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
b4eaa17e82f439a0b70b1b7079d1592564d9f621Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1336066b632d14017167c052fae5eb4df64726deDanny Mayer * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1336066b632d14017167c052fae5eb4df64726deDanny Mayer */
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews/* $Id: sortlist.c,v 1.5 2001/03/26 23:36:00 gson Exp $ */
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews#include <config.h>
1336066b632d14017167c052fae5eb4df64726deDanny Mayer
1336066b632d14017167c052fae5eb4df64726deDanny Mayer#include <isc/mem.h>
cfd262045c23cadb8415f0111f56995258f17361Evan Hunt#include <isc/util.h>
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews#include <dns/acl.h>
1336066b632d14017167c052fae5eb4df64726deDanny Mayer#include <dns/result.h>
1336066b632d14017167c052fae5eb4df64726deDanny Mayer
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews#include <named/globals.h>
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews#include <named/server.h>
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews#include <named/sortlist.h>
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrewsns_sortlisttype_t
1336066b632d14017167c052fae5eb4df64726deDanny Mayerns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, void **argp) {
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews unsigned int i;
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews if (acl == NULL)
ace73367affd419f1baf620f21b45999ef62bf5dDanny Mayer goto dont_sort;
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews for (i = 0; i < acl->length; i++) {
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews /*
7641867b4c39914cdcd3711ba0c89ed9c49f3c83Francis Dupont * 'e' refers to the current 'top level statement'
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews * in the sortlist (see ARM).
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews */
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews dns_aclelement_t *e = &acl->elements[i];
9edd523c2295757f1e1c5e93ea369cae892f0754Evan Hunt dns_aclelement_t *matchelt = NULL;
5a61d4774900ea2c14b71b90c9a705a3f08234beMark Andrews dns_acl_t *inner;
1336066b632d14017167c052fae5eb4df64726deDanny Mayer
1336066b632d14017167c052fae5eb4df64726deDanny Mayer if (e->type != dns_aclelementtype_nestedacl)
1336066b632d14017167c052fae5eb4df64726deDanny Mayer goto dont_sort;
1336066b632d14017167c052fae5eb4df64726deDanny Mayer
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(clientaddr, NULL,
&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)
*argp = elt1->u.nestedacl;
else if (elt1->type == dns_aclelementtype_localhost &&
ns_g_server->aclenv.localhost != NULL)
*argp = ns_g_server->aclenv.localhost;
else if (elt1->type == dns_aclelementtype_localnets &&
ns_g_server->aclenv.localnets != NULL)
*argp = ns_g_server->aclenv.localnets;
else
goto dont_sort;
return (NS_SORTLISTTYPE_2ELEMENT);
} else {
INSIST(matchelt != NULL);
*argp = matchelt;
return (NS_SORTLISTTYPE_1ELEMENT);
}
}
}
/* No match; don't sort. */
dont_sort:
*argp = NULL;
return (NS_SORTLISTTYPE_NONE);
}
int
ns_sortlist_addrorder2(isc_netaddr_t *addr, void *arg) {
dns_acl_t *sortacl = (dns_acl_t *) arg;
int match;
(void)dns_acl_match(addr, NULL, sortacl,
&ns_g_server->aclenv,
&match, NULL);
if (match > 0)
return (match);
else if (match < 0)
return (INT_MAX - (-match));
else
return (INT_MAX / 2);
}
int
ns_sortlist_addrorder1(isc_netaddr_t *addr, void *arg) {
dns_aclelement_t *matchelt = (dns_aclelement_t *) arg;
if (dns_aclelement_match(addr, NULL, matchelt,
&ns_g_server->aclenv,
NULL)) {
return (0);
} else {
return (INT_MAX);
}
}
void
ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr,
dns_addressorderfunc_t *orderp,
void **argp)
{
ns_sortlisttype_t sortlisttype;
sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp);
switch (sortlisttype) {
case NS_SORTLISTTYPE_1ELEMENT:
*orderp = ns_sortlist_addrorder1;
break;
case NS_SORTLISTTYPE_2ELEMENT:
*orderp = ns_sortlist_addrorder2;
break;
case NS_SORTLISTTYPE_NONE:
*orderp = NULL;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unexpected return from ns_sortlist_setup(): "
"%d", sortlisttype);
break;
}
}