2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 08:05:21 +00:00

make dispatcher hash sizes be primes, and provide an increment to help

resolve hash collisions
This commit is contained in:
Michael Graff
1999-12-15 17:14:52 +00:00
parent 271154eafd
commit 607dc8013a
8 changed files with 46 additions and 40 deletions

View File

@@ -146,11 +146,11 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
/*
* XXXRTH hardwired constants. We're going to need to determine if
* this UDP socket will be shared with the resolver, and if so, we
* need to set the hashsize to be be something bigger than 4.
* need to set the hashsize to be be something bigger than 17.
*/
ifp->udpdispatch = NULL;
result = dns_dispatch_create(mgr->mctx, ifp->udpsocket, ifp->task,
4096, 50, 50, 4, &ifp->udpdispatch);
4096, 50, 50, 17, 19, &ifp->udpdispatch);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"UDP dns_dispatch_create(): %s",

View File

@@ -107,7 +107,7 @@ my_accept(isc_task_t *task, isc_event_t *ev_in)
*/
disp = NULL;
RUNTIME_CHECK(dns_dispatch_create(mctx, ev->newsocket, task,
512, 6, 1024, 4, &disp)
512, 6, 1024, 17, 19, &disp)
== ISC_R_SUCCESS);
resp = NULL;

View File

@@ -405,7 +405,7 @@ main(int argc, char *argv[])
*/
disp = NULL;
RUNTIME_CHECK(dns_dispatch_create(mctx, s0, t0, 512, 6, 1024,
4, &disp) == ISC_R_SUCCESS);
17, 19, &disp) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_mutex_init(&client_lock) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS);

View File

@@ -205,8 +205,8 @@ main(int argc, char *argv[]) {
&view) == ISC_R_SUCCESS);
dispatch = NULL;
RUNTIME_CHECK(dns_dispatch_create(mctx, s, task1, 4096, 1000, 1000, 4,
&dispatch) == DNS_R_SUCCESS);
RUNTIME_CHECK(dns_dispatch_create(mctx, s, task1, 4096, 1000, 1000,
17, 19, &dispatch) == DNS_R_SUCCESS);
#ifdef notyet
res = NULL;

View File

@@ -89,8 +89,8 @@ struct dns_dispatch {
ISC_LIST(dns_dispatchevent_t) rq_events; /* holder for rq events */
dns_tcpmsg_t tcpmsg; /* for tcp streams */
isc_lfsr_t qid_lfsr; /* state generator info */
unsigned int qid_hashsize; /* hash table size */
unsigned int qid_mask; /* mask for hash table */
unsigned int qid_nbuckets; /* hash table size */
unsigned int qid_increment; /* id increment on collision */
dns_displist_t *qid_table; /* the table itself */
};
@@ -146,7 +146,7 @@ linear_first(dns_dispatch_t *disp)
bucket = 0;
while (bucket < disp->qid_hashsize) {
while (bucket < disp->qid_nbuckets) {
ret = ISC_LIST_HEAD(disp->qid_table[bucket]);
if (ret != NULL)
return (ret);
@@ -167,7 +167,7 @@ linear_next(dns_dispatch_t *disp, dns_dispentry_t *resp)
return (ret);
bucket = resp->bucket;
while (bucket < disp->qid_hashsize) {
while (bucket < disp->qid_nbuckets) {
ret = ISC_LIST_HEAD(disp->qid_table[bucket]);
if (ret != NULL)
return (ret);
@@ -178,20 +178,18 @@ linear_next(dns_dispatch_t *disp, dns_dispentry_t *resp)
}
/*
* Return a hash of the destination and message id. For now, just return
* the message id bits, and mask off the low order bits of that.
* Return a hash of the destination and message id.
*/
static unsigned int
hash(dns_dispatch_t *disp, isc_sockaddr_t *dest, dns_messageid_t id)
{
unsigned int ret;
(void)dest; /* shut up compiler warning. */
ret = isc_sockaddr_hash(dest, ISC_TRUE);
ret ^= (id & 0x0000ffff); /* important to mask off garbage bits */
ret %= disp->qid_nbuckets;
ret = id;
ret &= disp->qid_mask;
INSIST(ret < disp->qid_hashsize);
INSIST(ret < disp->qid_nbuckets);
return (ret);
}
@@ -235,7 +233,7 @@ destroy(dns_dispatch_t *disp)
isc_mempool_destroy(&disp->bpool);
isc_mempool_destroy(&disp->epool);
isc_mem_put(disp->mctx, disp->qid_table,
disp->qid_hashsize * sizeof(dns_displist_t));
disp->qid_nbuckets * sizeof(dns_displist_t));
isc_mem_put(disp->mctx, disp, sizeof(dns_dispatch_t));
}
@@ -247,7 +245,7 @@ bucket_search(dns_dispatch_t *disp, isc_sockaddr_t *dest, dns_messageid_t id,
{
dns_dispentry_t *res;
REQUIRE(bucket < disp->qid_hashsize);
REQUIRE(bucket < disp->qid_nbuckets);
res = ISC_LIST_HEAD(disp->qid_table[bucket]);
@@ -775,11 +773,10 @@ isc_result_t
dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
unsigned int maxbuffersize,
unsigned int maxbuffers, unsigned int maxrequests,
unsigned int hashsize,
unsigned int buckets, unsigned int increment,
dns_dispatch_t **dispp)
{
dns_dispatch_t *disp;
unsigned int tablesize;
isc_result_t res;
isc_sockettype_t socktype;
unsigned int i;
@@ -787,7 +784,8 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
REQUIRE(mctx != NULL);
REQUIRE(sock != NULL);
REQUIRE(task != NULL);
REQUIRE(hashsize <= 24);
REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
REQUIRE(increment > buckets);
REQUIRE(maxbuffersize >= 512 && maxbuffersize < (64 * 1024));
REQUIRE(maxbuffers > 0);
REQUIRE(dispp != NULL && *dispp == NULL);
@@ -822,20 +820,18 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
ISC_LIST_INIT(disp->rq_handlers);
ISC_LIST_INIT(disp->rq_events);
tablesize = (1 << hashsize);
disp->qid_table = isc_mem_get(disp->mctx,
tablesize * sizeof(dns_displist_t));
buckets * sizeof(dns_displist_t));
if (disp->qid_table == NULL) {
res = DNS_R_NOMEMORY;
goto out1;
}
for (i = 0 ; i < tablesize ; i++)
for (i = 0 ; i < buckets ; i++)
ISC_LIST_INIT(disp->qid_table[i]);
disp->qid_mask = tablesize - 1;
disp->qid_hashsize = tablesize;
disp->qid_nbuckets = buckets;
disp->qid_increment = increment;
if (isc_mutex_init(&disp->lock) != ISC_R_SUCCESS) {
res = DNS_R_UNEXPECTED;
@@ -924,7 +920,7 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
out3:
isc_mutex_destroy(&disp->lock);
out2:
isc_mem_put(mctx, disp->mctx, disp->qid_hashsize * sizeof(void *));
isc_mem_put(mctx, disp->mctx, disp->qid_nbuckets * sizeof(void *));
out1:
isc_mem_put(mctx, disp, sizeof(dns_dispatch_t));
@@ -1015,7 +1011,8 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
ok = ISC_TRUE;
break;
}
id = randomid(disp);
id += disp->qid_increment;
id &= 0x0000ffff;
bucket = hash(disp, dest, id);
}

View File

@@ -91,7 +91,8 @@ isc_result_t
dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
unsigned int maxbuffersize,
unsigned int maxbuffers, unsigned int maxrequests,
unsigned int hashsize, dns_dispatch_t **dispp);
unsigned int buckets, unsigned int increment,
dns_dispatch_t **dispp);
/*
* Create a new dns_dispatch and attach it to the provided isc_socket_t.
*
@@ -102,8 +103,10 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
* overall system and the number of buffers which can be allocated to
* requests.
*
* "hashsize" is the size of the hash table used to handle responses. The
* size is 2^hashsize, maximum of 2^24.
* "buckets" is the number of buckets to use, and should be prime.
*
* "increment" is used in a collision avoidance function, and needs to be
* a prime > buckets, and not 2.
*
* Requires:
*
@@ -120,7 +123,9 @@ dns_dispatch_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
*
* maxrequests <= maxbuffers.
*
* hashsize <= 24.
* buckets < 2097169 (the next prime after 65536 * 32)
*
* increment > buckets (and prime)
*/
void

View File

@@ -594,7 +594,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
if (result != ISC_R_SUCCESS)
goto cleanup_query;
result = dns_dispatch_create(res->mctx, socket, task,
4096, 2, 1, 1, &query->dispatch);
4096, 2, 1, 1, 3,
&query->dispatch);
/*
* Regardless of whether dns_dispatch_create() succeeded or
* not, we don't need our reference to the socket anymore.
@@ -3226,7 +3227,8 @@ dns_resolver_create(dns_view_t *view,
}
result = dns_dispatch_create(res->mctx, res->udpsocket4,
res->buckets[0].task, 4096,
1000, 32768, 14, &res->dispatch4);
1000, 32768, 16411, 16433,
&res->dispatch4);
if (result != ISC_R_SUCCESS)
goto cleanup_udpsocket4;
}
@@ -3247,7 +3249,8 @@ dns_resolver_create(dns_view_t *view,
goto cleanup_dispatch4;
result = dns_dispatch_create(res->mctx, res->udpsocket6,
res->buckets[0].task, 4096,
1000, 32768, 14, &res->dispatch6);
1000, 32768, 16411, 16433,
&res->dispatch6);
if (result != ISC_R_SUCCESS)
goto cleanup_udpsocket6;
}

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: zone.c,v 1.44 1999/12/13 07:56:26 marka Exp $ */
/* $Id: zone.c,v 1.45 1999/12/15 17:14:52 explorer Exp $ */
#include <config.h>
@@ -1815,7 +1815,8 @@ dns_zone_manage(dns_zone_t *zone, isc_taskmgr_t *tmgr) {
isc_sockettype_udp, &s) == ISC_R_SUCCESS);
dispatch = NULL;
RUNTIME_CHECK(dns_dispatch_create(zone->mctx, s, zone->task,
4096, 1000, 1000, 4, &dispatch) == DNS_R_SUCCESS);
4096, 1000, 1000, 17, 19,
&dispatch) == DNS_R_SUCCESS);
result = dns_resolver_create(zone->mctx, tmgr, 10, zone->timgr,
zone->rdclass, dispatch,
&zone->res);