not exclusive.
1223. [func] 'rrset-order' partially works 'cyclic' and 'random'
are supported.
+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]
* 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 <dns/fixedname.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
+#include <dns/rdatatype.h>
#include <dns/tsig.h>
#include <dns/zone.h>
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;
* 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
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);
* 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 <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>
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;
* 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 <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>
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;
isc_boolean_t reused_cache = ISC_FALSE;
int i;
char *str;
+ dns_order_t *order = NULL;
REQUIRE(DNS_VIEW_VALID(view));
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.
*/
result = ISC_R_SUCCESS;
cleanup:
+ if (order != NULL)
+ dns_order_detach(&order);
if (cmctx != NULL)
isc_mem_detach(&cmctx);
* 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
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;
* 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>
order->mctx = NULL;
isc_mem_attach(mctx, &order->mctx);
order->magic = DNS_ORDER_MAGIC;
+ *orderp = order;
return (ISC_R_SUCCESS);
}
* 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>
#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 = 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;
*/
if (!question &&
count > 1 &&
- !WANT_FIXED(rdataset) &&
+ (!WANT_FIXED(rdataset) || order != NULL) &&
count <= MAX_SHUFFLE &&
rdataset->type != dns_rdatatype_sig)
{
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;
* 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 <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>
if (result != ISC_R_SUCCESS)
goto cleanup_fwdtable;
view->peers = NULL;
+ view->order = NULL;
/*
* Initialize configuration data with default values.
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;
cleanup_peerlist:
dns_peerlist_detach(&view->peers);
+ cleanup_order:
+ dns_order_detach(&view->order);
+
cleanup_dynkeys:
dns_tsigkeyring_destroy(&view->dynamickeys);
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)