Make isc_ht optionally case insensitive
Previously, the isc_ht API would always take the key as a literal input to the hashing function. Change the isc_ht_init() function to take an 'options' argument, in which ISC_HT_CASE_SENSITIVE or _INSENSITIVE can be specified, to determine whether to use case-sensitive hashing in isc_hash32() when hashing the key.
This commit is contained in:
@@ -347,7 +347,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
||||
cfg_line, mctx, lctx, actx));
|
||||
}
|
||||
|
||||
isc_ht_init(&inst->ht, mctx, 16);
|
||||
isc_ht_init(&inst->ht, mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
isc_mutex_init(&inst->hlock);
|
||||
|
||||
/*
|
||||
|
||||
@@ -350,7 +350,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
||||
cfg_line, mctx, lctx, actx));
|
||||
}
|
||||
|
||||
isc_ht_init(&inst->ht, mctx, 16);
|
||||
isc_ht_init(&inst->ht, mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
isc_mutex_init(&inst->hlock);
|
||||
|
||||
/*
|
||||
|
||||
@@ -143,7 +143,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
||||
*inst = (async_instance_t){ .mctx = NULL };
|
||||
isc_mem_attach(mctx, &inst->mctx);
|
||||
|
||||
isc_ht_init(&inst->ht, mctx, 16);
|
||||
isc_ht_init(&inst->ht, mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
isc_mutex_init(&inst->hlock);
|
||||
|
||||
/*
|
||||
|
||||
@@ -392,9 +392,9 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) {
|
||||
|
||||
dns_name_format(&target->name, czname, DNS_NAME_FORMATSIZE);
|
||||
|
||||
isc_ht_init(&toadd, target->catzs->mctx, 16);
|
||||
isc_ht_init(&toadd, target->catzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
isc_ht_init(&tomod, target->catzs->mctx, 16);
|
||||
isc_ht_init(&tomod, target->catzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
isc_ht_iter_create(newzone->entries, &iter1);
|
||||
|
||||
@@ -579,7 +579,7 @@ dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
|
||||
|
||||
isc_refcount_init(&new_zones->refs, 1);
|
||||
|
||||
isc_ht_init(&new_zones->zones, mctx, 4);
|
||||
isc_ht_init(&new_zones->zones, mctx, 4, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
isc_mem_attach(mctx, &new_zones->mctx);
|
||||
new_zones->zmm = zmm;
|
||||
@@ -630,7 +630,7 @@ dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep,
|
||||
dns_name_init(&new_zone->name, NULL);
|
||||
dns_name_dup(name, catzs->mctx, &new_zone->name);
|
||||
|
||||
isc_ht_init(&new_zone->entries, catzs->mctx, 4);
|
||||
isc_ht_init(&new_zone->entries, catzs->mctx, 4, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
new_zone->updatetimer = NULL;
|
||||
isc_timer_create(catzs->timermgr, catzs->updater,
|
||||
|
||||
@@ -1530,7 +1530,7 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
|
||||
* simplifies update_from_db
|
||||
*/
|
||||
|
||||
isc_ht_init(&zone->nodes, rpzs->mctx, 1);
|
||||
isc_ht_init(&zone->nodes, rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
dns_name_init(&zone->origin, NULL);
|
||||
dns_name_init(&zone->client_ip, NULL);
|
||||
@@ -1676,30 +1676,12 @@ static isc_result_t
|
||||
setup_update(dns_rpz_zone_t *rpz) {
|
||||
isc_result_t result;
|
||||
char domain[DNS_NAME_FORMATSIZE];
|
||||
unsigned int nodecount;
|
||||
uint32_t hashsize;
|
||||
|
||||
dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_INFO, "rpz: %s: reload start", domain);
|
||||
|
||||
nodecount = dns_db_nodecount(rpz->updb, dns_dbtree_main);
|
||||
hashsize = 1;
|
||||
while (nodecount != 0 &&
|
||||
hashsize <= (DNS_RPZ_HTSIZE_MAX + DNS_RPZ_HTSIZE_DIV)) {
|
||||
hashsize++;
|
||||
nodecount >>= 1;
|
||||
}
|
||||
|
||||
if (hashsize > DNS_RPZ_HTSIZE_DIV) {
|
||||
hashsize -= DNS_RPZ_HTSIZE_DIV;
|
||||
}
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_DEBUG(1), "rpz: %s: using hashtable size %d",
|
||||
domain, hashsize);
|
||||
|
||||
isc_ht_init(&rpz->newnodes, rpz->rpzs->mctx, hashsize);
|
||||
isc_ht_init(&rpz->newnodes, rpz->rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
result = dns_db_createiterator(rpz->updb, DNS_DB_NONSEC3, &rpz->updbit);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
||||
15
lib/isc/ht.c
15
lib/isc/ht.c
@@ -51,6 +51,7 @@ struct isc_ht {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
size_t count;
|
||||
bool case_sensitive;
|
||||
size_t size[2];
|
||||
uint8_t hashbits[2];
|
||||
isc_ht_node_t **table[2];
|
||||
@@ -234,15 +235,19 @@ hashtable_free(isc_ht_t *ht, const uint8_t idx) {
|
||||
}
|
||||
|
||||
void
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits) {
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits,
|
||||
unsigned int options) {
|
||||
isc_ht_t *ht = NULL;
|
||||
bool case_sensitive = ((options & ISC_HT_CASE_INSENSITIVE) == 0);
|
||||
|
||||
REQUIRE(htp != NULL && *htp == NULL);
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(bits >= 1 && bits <= HT_MAX_BITS);
|
||||
|
||||
ht = isc_mem_get(mctx, sizeof(*ht));
|
||||
*ht = (isc_ht_t){ 0 };
|
||||
*ht = (isc_ht_t){
|
||||
.case_sensitive = case_sensitive,
|
||||
};
|
||||
|
||||
isc_mem_attach(mctx, &ht->mctx);
|
||||
|
||||
@@ -313,7 +318,7 @@ isc_ht_add(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize,
|
||||
maybe_rehash(ht, ht->count);
|
||||
}
|
||||
|
||||
hashval = isc_hash32(key, keysize, true);
|
||||
hashval = isc_hash32(key, keysize, ht->case_sensitive);
|
||||
|
||||
if (isc__ht_find(ht, key, keysize, hashval, ht->hindex) != NULL) {
|
||||
return (ISC_R_EXISTS);
|
||||
@@ -361,7 +366,7 @@ isc_ht_find(const isc_ht_t *ht, const unsigned char *key,
|
||||
REQUIRE(key != NULL && keysize > 0);
|
||||
REQUIRE(valuep == NULL || *valuep == NULL);
|
||||
|
||||
hashval = isc_hash32(key, keysize, true);
|
||||
hashval = isc_hash32(key, keysize, ht->case_sensitive);
|
||||
|
||||
node = isc__ht_find(ht, key, keysize, hashval, ht->hindex);
|
||||
if (node == NULL) {
|
||||
@@ -417,7 +422,7 @@ isc_ht_delete(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize) {
|
||||
}
|
||||
|
||||
hindex = ht->hindex;
|
||||
hashval = isc_hash32(key, keysize, true);
|
||||
hashval = isc_hash32(key, keysize, ht->case_sensitive);
|
||||
nexttable:
|
||||
result = isc__ht_delete(ht, key, keysize, hashval, hindex);
|
||||
|
||||
|
||||
@@ -24,9 +24,15 @@
|
||||
typedef struct isc_ht isc_ht_t;
|
||||
typedef struct isc_ht_iter isc_ht_iter_t;
|
||||
|
||||
enum { ISC_HT_CASE_SENSITIVE = 0x00, ISC_HT_CASE_INSENSITIVE = 0x01 };
|
||||
|
||||
/*%
|
||||
* Initialize hashtable at *htp, using memory context and size of (1<<bits)
|
||||
*
|
||||
* If 'options' contains ISC_HT_CASE_INSENSITIVE, then upper- and lower-case
|
||||
* letters in key values will generate the same hash values; this can be used
|
||||
* when the key for a hash table is a DNS name.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'htp' is not NULL and '*htp' is NULL.
|
||||
*\li 'mctx' is a valid memory context.
|
||||
@@ -34,7 +40,8 @@ typedef struct isc_ht_iter isc_ht_iter_t;
|
||||
*
|
||||
*/
|
||||
void
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits);
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits,
|
||||
unsigned int options);
|
||||
|
||||
/*%
|
||||
* Destroy hashtable, freeing everything
|
||||
|
||||
@@ -65,7 +65,7 @@ test_ht_full(uint8_t init_bits, uint8_t finish_bits, uintptr_t count) {
|
||||
isc_result_t result;
|
||||
uintptr_t i;
|
||||
|
||||
isc_ht_init(&ht, test_mctx, init_bits);
|
||||
isc_ht_init(&ht, test_mctx, init_bits, ISC_HT_CASE_SENSITIVE);
|
||||
assert_non_null(ht);
|
||||
|
||||
for (i = 1; i < count; i++) {
|
||||
@@ -212,7 +212,7 @@ test_ht_iterator(void) {
|
||||
unsigned char key[16];
|
||||
size_t tksize;
|
||||
|
||||
isc_ht_init(&ht, test_mctx, HT_MIN_BITS);
|
||||
isc_ht_init(&ht, test_mctx, HT_MIN_BITS, ISC_HT_CASE_SENSITIVE);
|
||||
assert_non_null(ht);
|
||||
for (i = 1; i <= count; i++) {
|
||||
/*
|
||||
|
||||
@@ -1109,7 +1109,7 @@ isc_tlsctx_cache_new(isc_mem_t *mctx) {
|
||||
isc_refcount_init(&nc->references, 1);
|
||||
isc_mem_attach(mctx, &nc->mctx);
|
||||
|
||||
isc_ht_init(&nc->data, mctx, 5);
|
||||
isc_ht_init(&nc->data, mctx, 5, ISC_HT_CASE_SENSITIVE);
|
||||
isc_rwlock_init(&nc->rwlock, 0, 0);
|
||||
|
||||
return (nc);
|
||||
|
||||
Reference in New Issue
Block a user