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:
Ondřej Surý
2022-03-16 21:58:55 +01:00
committed by Evan Hunt
parent e9ef3defa4
commit b05a991ad0
9 changed files with 30 additions and 36 deletions

View File

@@ -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);
/*

View File

@@ -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);
/*

View File

@@ -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);
/*

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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

View File

@@ -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++) {
/*

View File

@@ -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);