Commit 2dd99c09 authored by Mark Andrews's avatar Mark Andrews

1234. [bug] 'rrset-order' and 'sortlist' should be additive

                        not exclusive.

1223.   [func]          'rrset-order' partially works 'cyclic' and 'random'
                        are supported.
parent df5e0316
1234. [bug] 'rrset-order' and 'sortlist' should be additive
not exclusive.
1223. [func] 'rrset-order' partially works 'cyclic' and 'random'
are supported.
1222. [bug] Specifying 'port *' did not always result in a system 1222. [bug] Specifying 'port *' did not always result in a system
selected (non-reserved) port being used. [RT #2537] selected (non-reserved) port being used. [RT #2537]
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: config.c,v 1.28 2002/03/06 23:52:38 marka Exp $ */ /* $Id: config.c,v 1.29 2002/03/07 13:46:35 marka Exp $ */
#include <config.h> #include <config.h>
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <dns/fixedname.h> #include <dns/fixedname.h>
#include <dns/name.h> #include <dns/name.h>
#include <dns/rdataclass.h> #include <dns/rdataclass.h>
#include <dns/rdatatype.h>
#include <dns/tsig.h> #include <dns/tsig.h>
#include <dns/zone.h> #include <dns/zone.h>
...@@ -218,6 +219,27 @@ ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass, ...@@ -218,6 +219,27 @@ ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass,
return (result); return (result);
} }
isc_result_t
ns_config_gettype(cfg_obj_t *typeobj, dns_rdatatype_t deftype,
dns_rdatatype_t *typep) {
char *str;
isc_textregion_t r;
isc_result_t result;
if (!cfg_obj_isstring(typeobj)) {
*typep = deftype;
return (ISC_R_SUCCESS);
}
str = cfg_obj_asstring(typeobj);
r.base = str;
r.length = strlen(str);
result = dns_rdatatype_fromtext(typep, &r);
if (result != ISC_R_SUCCESS)
cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR,
"unknown type '%s'", str);
return (result);
}
dns_zonetype_t dns_zonetype_t
ns_config_getzonetype(cfg_obj_t *zonetypeobj) { ns_config_getzonetype(cfg_obj_t *zonetypeobj) {
dns_zonetype_t ztype = dns_zone_none; dns_zonetype_t ztype = dns_zone_none;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: config.h,v 1.4 2001/08/09 17:21:06 gson Exp $ */ /* $Id: config.h,v 1.5 2002/03/07 13:46:41 marka Exp $ */
#ifndef NAMED_CONFIG_H #ifndef NAMED_CONFIG_H
#define NAMED_CONFIG_H 1 #define NAMED_CONFIG_H 1
...@@ -38,6 +38,10 @@ isc_result_t ...@@ -38,6 +38,10 @@ isc_result_t
ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass, ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass,
dns_rdataclass_t *classp); dns_rdataclass_t *classp);
isc_result_t
ns_config_gettype(cfg_obj_t *typeobj, dns_rdatatype_t deftype,
dns_rdatatype_t *typep);
dns_zonetype_t dns_zonetype_t
ns_config_getzonetype(cfg_obj_t *zonetypeobj); ns_config_getzonetype(cfg_obj_t *zonetypeobj);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: query.c,v 1.217 2002/02/20 03:33:18 marka Exp $ */ /* $Id: query.c,v 1.218 2002/03/07 13:46:38 marka Exp $ */
#include <config.h> #include <config.h>
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <dns/db.h> #include <dns/db.h>
#include <dns/events.h> #include <dns/events.h>
#include <dns/message.h> #include <dns/message.h>
#include <dns/order.h>
#include <dns/rdata.h> #include <dns/rdata.h>
#include <dns/rdataclass.h> #include <dns/rdataclass.h>
#include <dns/rdatalist.h> #include <dns/rdatalist.h>
...@@ -1536,6 +1537,10 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname, ...@@ -1536,6 +1537,10 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
ISC_LIST_APPEND(fname->list, rdataset, link); ISC_LIST_APPEND(fname->list, rdataset, link);
if (client->view->order != NULL)
rdataset->attributes |= dns_order_find(client->view->order,
fname, rdataset->type,
rdataset->rdclass);
if (NOADDITIONAL(client)) if (NOADDITIONAL(client))
return; return;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: server.c,v 1.371 2002/02/20 03:33:21 marka Exp $ */ /* $Id: server.c,v 1.372 2002/03/07 13:46:40 marka Exp $ */
#include <config.h> #include <config.h>
...@@ -47,8 +47,10 @@ ...@@ -47,8 +47,10 @@
#include <dns/journal.h> #include <dns/journal.h>
#include <dns/keytable.h> #include <dns/keytable.h>
#include <dns/master.h> #include <dns/master.h>
#include <dns/order.h>
#include <dns/peer.h> #include <dns/peer.h>
#include <dns/rdataclass.h> #include <dns/rdataclass.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h> #include <dns/rdatastruct.h>
#include <dns/resolver.h> #include <dns/resolver.h>
#include <dns/rootns.h> #include <dns/rootns.h>
...@@ -404,6 +406,56 @@ get_view_querysource_dispatch(cfg_obj_t **maps, ...@@ -404,6 +406,56 @@ get_view_querysource_dispatch(cfg_obj_t **maps,
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
static isc_result_t
configure_order(dns_order_t *order, cfg_obj_t *ent) {
dns_rdataclass_t rdclass;
dns_rdatatype_t rdtype;
cfg_obj_t *obj;
dns_fixedname_t fixed;
unsigned int mode = 0;
const char *str;
isc_buffer_t b;
isc_result_t result;
result = ns_config_getclass(cfg_tuple_get(ent, "class"),
dns_rdataclass_any, &rdclass);
if (result != ISC_R_SUCCESS)
return (result);
result = ns_config_gettype(cfg_tuple_get(ent, "type"),
dns_rdatatype_any, &rdtype);
if (result != ISC_R_SUCCESS)
return (result);
obj = cfg_tuple_get(ent, "name");
if (cfg_obj_isstring(obj))
str = cfg_obj_asstring(obj);
else
str = "*";
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
dns_fixedname_init(&fixed);
result = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
dns_rootname, ISC_FALSE, NULL);
if (result != ISC_R_SUCCESS)
return (result);
obj = cfg_tuple_get(ent, "ordering");
INSIST(cfg_obj_isstring(obj));
str = cfg_obj_asstring(obj);
if (!strcasecmp(str, "fixed"))
mode = DNS_RDATASETATTR_FIXEDORDER;
else if (!strcasecmp(str, "random"))
mode = DNS_RDATASETATTR_RANDOMIZE;
else if (!strcasecmp(str, "cyclic"))
mode = 0;
else
INSIST(0);
return (dns_order_add(order, dns_fixedname_name(&fixed),
rdtype, rdclass, mode));
}
static isc_result_t static isc_result_t
configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
isc_sockaddr_t *sa; isc_sockaddr_t *sa;
...@@ -510,6 +562,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, ...@@ -510,6 +562,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
isc_boolean_t reused_cache = ISC_FALSE; isc_boolean_t reused_cache = ISC_FALSE;
int i; int i;
char *str; char *str;
dns_order_t *order = NULL;
REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(DNS_VIEW_VALID(view));
...@@ -741,6 +794,28 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, ...@@ -741,6 +794,28 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
view->peers = newpeers; /* Transfer ownership. */ view->peers = newpeers; /* Transfer ownership. */
} }
/*
* Configure the views rrset-order.
*/
{
cfg_obj_t *rrsetorder = NULL;
cfg_listelt_t *element;
(void)ns_config_get(maps, "rrset-order", &rrsetorder);
CHECK(dns_order_create(mctx, &order));
for (element = cfg_list_first(rrsetorder);
element != NULL;
element = cfg_list_next(element))
{
cfg_obj_t *ent = cfg_listelt_value(element);
CHECK(configure_order(order, ent));
}
if (view->order != NULL)
dns_order_detach(&view->order);
dns_order_attach(order, &view->order);
dns_order_detach(&order);
}
/* /*
* Copy the aclenv object. * Copy the aclenv object.
*/ */
...@@ -863,6 +938,8 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, ...@@ -863,6 +938,8 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
cleanup: cleanup:
if (order != NULL)
dns_order_detach(&order);
if (cmctx != NULL) if (cmctx != NULL)
isc_mem_detach(&cmctx); isc_mem_detach(&cmctx);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: view.h,v 1.76 2001/11/27 04:06:15 marka Exp $ */ /* $Id: view.h,v 1.77 2002/03/07 13:46:34 marka Exp $ */
#ifndef DNS_VIEW_H #ifndef DNS_VIEW_H
#define DNS_VIEW_H 1 #define DNS_VIEW_H 1
...@@ -100,6 +100,7 @@ struct dns_view { ...@@ -100,6 +100,7 @@ struct dns_view {
dns_tsig_keyring_t * statickeys; dns_tsig_keyring_t * statickeys;
dns_tsig_keyring_t * dynamickeys; dns_tsig_keyring_t * dynamickeys;
dns_peerlist_t * peers; dns_peerlist_t * peers;
dns_order_t * order;
dns_fwdtable_t * fwdtable; dns_fwdtable_t * fwdtable;
isc_boolean_t recursion; isc_boolean_t recursion;
isc_boolean_t auth_nxdomain; isc_boolean_t auth_nxdomain;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: order.c,v 1.2 2002/03/07 07:48:46 bwelling Exp $ */ /* $Id: order.c,v 1.3 2002/03/07 13:46:30 marka Exp $ */
#include <isc/magic.h> #include <isc/magic.h>
#include <isc/mem.h> #include <isc/mem.h>
...@@ -63,6 +63,7 @@ dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) { ...@@ -63,6 +63,7 @@ dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) {
order->mctx = NULL; order->mctx = NULL;
isc_mem_attach(mctx, &order->mctx); isc_mem_attach(mctx, &order->mctx);
order->magic = DNS_ORDER_MAGIC; order->magic = DNS_ORDER_MAGIC;
*orderp = order;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: rdataset.c,v 1.61 2002/02/20 03:34:18 marka Exp $ */ /* $Id: rdataset.c,v 1.62 2002/03/07 13:46:31 marka Exp $ */
#include <config.h> #include <config.h>
...@@ -256,6 +256,7 @@ dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { ...@@ -256,6 +256,7 @@ dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
#define MAX_SHUFFLE 32 #define MAX_SHUFFLE 32
#define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0) #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
#define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
struct towire_sort { struct towire_sort {
int key; int key;
...@@ -279,7 +280,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, ...@@ -279,7 +280,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT;
isc_region_t r; isc_region_t r;
isc_result_t result; isc_result_t result;
unsigned int i, count, added; unsigned int i, count, added, choice;
isc_buffer_t savedbuffer, rdlen, rrbuffer; isc_buffer_t savedbuffer, rdlen, rrbuffer;
unsigned int headlen; unsigned int headlen;
isc_boolean_t question = ISC_FALSE; isc_boolean_t question = ISC_FALSE;
...@@ -330,7 +331,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, ...@@ -330,7 +331,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
*/ */
if (!question && if (!question &&
count > 1 && count > 1 &&
!WANT_FIXED(rdataset) && (!WANT_FIXED(rdataset) || order != NULL) &&
count <= MAX_SHUFFLE && count <= MAX_SHUFFLE &&
rdataset->type != dns_rdatatype_sig) rdataset->type != dns_rdatatype_sig)
{ {
...@@ -349,33 +350,61 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, ...@@ -349,33 +350,61 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
if (result != ISC_R_NOMORE) if (result != ISC_R_NOMORE)
return (result); return (result);
INSIST(i == count); INSIST(i == count);
/* /*
* Now we shuffle. * Now we shuffle.
*/ */
if (order != NULL) { if (WANT_FIXED(rdataset)) {
/* /*
* Sorted order. * 'Fixed' order.
*/ */
INSIST(order != NULL);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
sorted[i].key = (*order)(&shuffled[i], sorted[i].key = (*order)(&shuffled[i],
order_arg); order_arg);
sorted[i].rdata = &shuffled[i]; sorted[i].rdata = &shuffled[i];
} }
qsort(sorted, count, sizeof(sorted[0]), } else if (WANT_RANDOM(rdataset)) {
towire_compare); /*
* 'Random' order.
*/
for (i = 0; i < count; i++) {
dns_rdata_t rdata;
choice = i + (((u_int)rand()>>3) % (count - i));
rdata = shuffled[i];
shuffled[i] = shuffled[choice];
shuffled[choice] = rdata;
if (order != NULL)
sorted[i].key = (*order)(&shuffled[i],
order_arg);
else
sorted[i].key = 0; /* Unused */
sorted[i].rdata = &shuffled[i];
}
} else { } else {
/* /*
* "Cyclic" order. * "Cyclic" order.
*/ */
unsigned int j = (((unsigned int)rand()) >> 3) % count; unsigned int j = (((unsigned int)rand()) >> 3) % count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
sorted[j].key = 0; /* Unused */ if (order != NULL)
sorted[i].key = (*order)(&shuffled[i],
order_arg);
else
sorted[j].key = 0; /* Unused */
sorted[j].rdata = &shuffled[i]; sorted[j].rdata = &shuffled[i];
j++; j++;
if (j == count) if (j == count)
j = 0; /* Wrap around. */ j = 0; /* Wrap around. */
} }
} }
/*
* Sorted order.
*/
if (order != NULL)
qsort(sorted, count, sizeof(sorted[0]),
towire_compare);
} }
savedbuffer = *target; savedbuffer = *target;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: view.c,v 1.109 2001/11/30 01:59:23 gson Exp $ */ /* $Id: view.c,v 1.110 2002/03/07 13:46:33 marka Exp $ */
#include <config.h> #include <config.h>
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <dns/keytable.h> #include <dns/keytable.h>
#include <dns/master.h> #include <dns/master.h>
#include <dns/masterdump.h> #include <dns/masterdump.h>
#include <dns/order.h>
#include <dns/peer.h> #include <dns/peer.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/request.h> #include <dns/request.h>
...@@ -139,6 +140,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ...@@ -139,6 +140,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto cleanup_fwdtable; goto cleanup_fwdtable;
view->peers = NULL; view->peers = NULL;
view->order = NULL;
/* /*
* Initialize configuration data with default values. * Initialize configuration data with default values.
...@@ -159,10 +161,14 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ...@@ -159,10 +161,14 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->maxncachettl = 3 * 3600; view->maxncachettl = 3 * 3600;
view->dstport = 53; view->dstport = 53;
result = dns_peerlist_new(view->mctx, &view->peers); result = dns_order_create(view->mctx, &view->order);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto cleanup_dynkeys; goto cleanup_dynkeys;
result = dns_peerlist_new(view->mctx, &view->peers);
if (result != ISC_R_SUCCESS)
goto cleanup_order;
result = dns_aclenv_init(view->mctx, &view->aclenv); result = dns_aclenv_init(view->mctx, &view->aclenv);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto cleanup_peerlist; goto cleanup_peerlist;
...@@ -186,6 +192,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ...@@ -186,6 +192,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
cleanup_peerlist: cleanup_peerlist:
dns_peerlist_detach(&view->peers); dns_peerlist_detach(&view->peers);
cleanup_order:
dns_order_detach(&view->order);
cleanup_dynkeys: cleanup_dynkeys:
dns_tsigkeyring_destroy(&view->dynamickeys); dns_tsigkeyring_destroy(&view->dynamickeys);
...@@ -222,6 +231,8 @@ destroy(dns_view_t *view) { ...@@ -222,6 +231,8 @@ destroy(dns_view_t *view) {
REQUIRE(ADBSHUTDOWN(view)); REQUIRE(ADBSHUTDOWN(view));
REQUIRE(REQSHUTDOWN(view)); REQUIRE(REQSHUTDOWN(view));
if (view->order != NULL)
dns_order_detach(&view->order);
if (view->peers != NULL) if (view->peers != NULL)
dns_peerlist_detach(&view->peers); dns_peerlist_detach(&view->peers);
if (view->dynamickeys != NULL) if (view->dynamickeys != NULL)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment