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
selected (non-reserved) port being used. [RT #2537]
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -35,6 +35,7 @@
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
#include <dns/tsig.h>
#include <dns/zone.h>
......@@ -218,6 +219,27 @@ ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass,
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
ns_config_getzonetype(cfg_obj_t *zonetypeobj) {
dns_zonetype_t ztype = dns_zone_none;
......
......@@ -15,7 +15,7 @@
* 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
#define NAMED_CONFIG_H 1
......@@ -38,6 +38,10 @@ isc_result_t
ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass,
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
ns_config_getzonetype(cfg_obj_t *zonetypeobj);
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -29,6 +29,7 @@
#include <dns/db.h>
#include <dns/events.h>
#include <dns/message.h>
#include <dns/order.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdatalist.h>
......@@ -1536,6 +1537,10 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
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))
return;
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -47,8 +47,10 @@
#include <dns/journal.h>
#include <dns/keytable.h>
#include <dns/master.h>
#include <dns/order.h>
#include <dns/peer.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/resolver.h>
#include <dns/rootns.h>
......@@ -404,6 +406,56 @@ get_view_querysource_dispatch(cfg_obj_t **maps,
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
configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
isc_sockaddr_t *sa;
......@@ -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;
int i;
char *str;
dns_order_t *order = NULL;
REQUIRE(DNS_VIEW_VALID(view));
......@@ -741,6 +794,28 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
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.
*/
......@@ -863,6 +938,8 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
result = ISC_R_SUCCESS;
cleanup:
if (order != NULL)
dns_order_detach(&order);
if (cmctx != NULL)
isc_mem_detach(&cmctx);
......
......@@ -15,7 +15,7 @@
* 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
#define DNS_VIEW_H 1
......@@ -100,6 +100,7 @@ struct dns_view {
dns_tsig_keyring_t * statickeys;
dns_tsig_keyring_t * dynamickeys;
dns_peerlist_t * peers;
dns_order_t * order;
dns_fwdtable_t * fwdtable;
isc_boolean_t recursion;
isc_boolean_t auth_nxdomain;
......
......@@ -15,7 +15,7 @@
* 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/mem.h>
......@@ -63,6 +63,7 @@ dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) {
order->mctx = NULL;
isc_mem_attach(mctx, &order->mctx);
order->magic = DNS_ORDER_MAGIC;
*orderp = order;
return (ISC_R_SUCCESS);
}
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -256,6 +256,7 @@ 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;
......@@ -279,7 +280,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_region_t r;
isc_result_t result;
unsigned int i, count, added;
unsigned int i, count, added, choice;
isc_buffer_t savedbuffer, rdlen, rrbuffer;
unsigned int headlen;
isc_boolean_t question = ISC_FALSE;
......@@ -330,7 +331,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
*/
if (!question &&
count > 1 &&
!WANT_FIXED(rdataset) &&
(!WANT_FIXED(rdataset) || order != NULL) &&
count <= MAX_SHUFFLE &&
rdataset->type != dns_rdatatype_sig)
{
......@@ -349,33 +350,61 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
if (result != ISC_R_NOMORE)
return (result);
INSIST(i == count);
/*
* Now we shuffle.
*/
if (order != NULL) {
if (WANT_FIXED(rdataset)) {
/*
* Sorted order.
* 'Fixed' order.
*/
INSIST(order != NULL);
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 if (WANT_RANDOM(rdataset)) {
/*
* '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 {
/*
* "Cyclic" order.
*/
unsigned int j = (((unsigned int)rand()) >> 3) % count;
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];
j++;
if (j == count)
j = 0; /* Wrap around. */
}
}
/*
* Sorted order.
*/
if (order != NULL)
qsort(sorted, count, sizeof(sorted[0]),
towire_compare);
}
savedbuffer = *target;
......
......@@ -15,7 +15,7 @@
* 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>
......@@ -32,6 +32,7 @@
#include <dns/keytable.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/order.h>
#include <dns/peer.h>
#include <dns/rdataset.h>
#include <dns/request.h>
......@@ -139,6 +140,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
if (result != ISC_R_SUCCESS)
goto cleanup_fwdtable;
view->peers = NULL;
view->order = NULL;
/*
* Initialize configuration data with default values.
......@@ -159,10 +161,14 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->maxncachettl = 3 * 3600;
view->dstport = 53;
result = dns_peerlist_new(view->mctx, &view->peers);
result = dns_order_create(view->mctx, &view->order);
if (result != ISC_R_SUCCESS)
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);
if (result != ISC_R_SUCCESS)
goto cleanup_peerlist;
......@@ -186,6 +192,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
cleanup_peerlist:
dns_peerlist_detach(&view->peers);
cleanup_order:
dns_order_detach(&view->order);
cleanup_dynkeys:
dns_tsigkeyring_destroy(&view->dynamickeys);
......@@ -222,6 +231,8 @@ destroy(dns_view_t *view) {
REQUIRE(ADBSHUTDOWN(view));
REQUIRE(REQSHUTDOWN(view));
if (view->order != NULL)
dns_order_detach(&view->order);
if (view->peers != NULL)
dns_peerlist_detach(&view->peers);
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