diff --git a/lib/dns/include/dns/lhashmap.h b/lib/dns/include/dns/lhashmap.h index 41dc17b59c..76c2849eb5 100644 --- a/lib/dns/include/dns/lhashmap.h +++ b/lib/dns/include/dns/lhashmap.h @@ -22,10 +22,8 @@ typedef struct { match_func_t match_func; } isc_lhashmap_t; -size_t inc_and_saturate(size_t hash); bool isc_lhashmap_entry_is_empty(isc_lhashmap_entry_t* entry); void isc_lhashmap_entry_put_data(isc_lhashmap_t *map, isc_lhashmap_entry_t* entry, void* elem); -isc_lhashmap_entry_t* lhashmap_entry_pointer(const isc_lhashmap_t* map, size_t elem_hash, size_t offset); isc_lhashmap_t isc_lhashmap_init(size_t size, size_t elem_size, char* array, hash_func_t hash_func, match_func_t match_func); isc_lhashmap_entry_t* isc_lhashmap_entry(const isc_lhashmap_t* map, void* elem); isc_result_t isc_lhashmap_put(isc_lhashmap_t* map, void* elem); diff --git a/lib/dns/lhashmap.c b/lib/dns/lhashmap.c index 4fdc0aa13b..87b6551a81 100644 --- a/lib/dns/lhashmap.c +++ b/lib/dns/lhashmap.c @@ -6,29 +6,15 @@ #include #include #include -#include "isc/result.h" -#include "isc/util.h" +#include +#include + +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-parameter" -typedef struct { - size_t hash; - char data[]; // flexible array member -} isc_lhashmap_entry_t; - -typedef uint64_t (*hash_func_t)(const void *); -typedef bool (*match_func_t)(const void *, const void *); - -typedef struct { - char* array; - size_t size; - size_t elem_size; - hash_func_t hash_func; - match_func_t match_func; -} isc_lhashmap_t; - static inline size_t inc_and_saturate(size_t hash) { size_t result; @@ -38,12 +24,12 @@ inc_and_saturate(size_t hash) { return result; } -static bool +bool isc_lhashmap_entry_is_empty(isc_lhashmap_entry_t* entry) { return entry->hash == 0ul; } -static void +void isc_lhashmap_entry_put_data(isc_lhashmap_t *map, isc_lhashmap_entry_t* entry, void* elem) { size_t elem_hash = map->hash_func(elem); entry->hash = inc_and_saturate(elem_hash); @@ -57,7 +43,7 @@ lhashmap_entry_pointer(const isc_lhashmap_t* map, size_t elem_hash, size_t offse return (isc_lhashmap_entry_t*)(map->array + index * (sizeof(size_t) + map->elem_size)); } -static isc_lhashmap_t +isc_lhashmap_t isc_lhashmap_init(size_t size, size_t elem_size, char* array, hash_func_t hash_func, match_func_t match_func) { REQUIRE(size > 0); // TODO is this precondition even necessary? @@ -83,7 +69,7 @@ isc_lhashmap_init(size_t size, size_t elem_size, char* array, hash_func_t hash_f return map; } -static isc_lhashmap_entry_t* +isc_lhashmap_entry_t* isc_lhashmap_entry(const isc_lhashmap_t* map, void* elem) { size_t elem_hash = map->hash_func(elem); size_t saturated_hash = inc_and_saturate(elem_hash); @@ -99,7 +85,7 @@ isc_lhashmap_entry(const isc_lhashmap_t* map, void* elem) { return NULL; } -static isc_result_t +isc_result_t isc_lhashmap_put(isc_lhashmap_t* map, void* elem) { isc_lhashmap_entry_t *entry = isc_lhashmap_entry(map, elem); if (entry) { diff --git a/lib/dns/message.c b/lib/dns/message.c index 71de8b4024..1808a1be2e 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -1043,24 +1043,24 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx, bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); bool seen_problem = false; bool free_name = false; - bool free_hashmaps = false; - isc_hashmap_t *name_map_2 = NULL; + // bool free_hashmaps = false; + // isc_hashmap_t *name_map_2 = NULL; if (msg->counts[DNS_SECTION_QUESTION] == 0) { return ISC_R_SUCCESS; } - // static _Thread_local char lhashmap_buffer[NAME_BUFFER_SIZE] = {0}; - char* lhashmap_buffer = thread_local_name_buffer(); + static _Thread_local char lhashmap_buffer[NAME_BUFFER_SIZE] = {0}; + // char* lhashmap_buffer = thread_local_name_buffer(); isc_lhashmap_t name_map = isc_lhashmap_init(msg->counts[DNS_SECTION_QUESTION], sizeof(dns_name_t*), lhashmap_buffer, name_hash, name_match); - // static _Thread_local char lhashmap_rd_buffer[NAME_RDTYPE_BUFFER_SIZE] = {0}; - char* lhashmap_rd_buffer = thread_local_rd_buffer(); + static _Thread_local char lhashmap_rd_buffer[NAME_RDTYPE_BUFFER_SIZE] = {0}; + // char* lhashmap_rd_buffer = thread_local_rd_buffer(); isc_lhashmap_t name_rdtype_map = isc_lhashmap_init(msg->counts[DNS_SECTION_QUESTION], sizeof(name_and_rdtype_t), lhashmap_rd_buffer, name_and_rdtype_hash, name_and_rdtype_match); - if (msg->counts[DNS_SECTION_QUESTION] > 1) { - isc_hashmap_create(msg->mctx, 1, &name_map_2); - } + // if (msg->counts[DNS_SECTION_QUESTION] > 1) { + // isc_hashmap_create(msg->mctx, 1, &name_map_2); + // } for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) { name = NULL; @@ -1079,10 +1079,10 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx, } /* If there is only one QNAME, skip the duplicity checks */ - if (name_map_2 == NULL) { - result = ISC_R_SUCCESS; - goto skip_name_check; - } + // if (name_map_2 == NULL) { + // result = ISC_R_SUCCESS; + // goto skip_name_check; + // } /* * Run through the section, looking to see if this name @@ -1090,9 +1090,10 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx, * name since we no longer need it, and set our name pointer * to point to the name we found. */ - result = isc_hashmap_add(name_map_2, dns_name_hash(name), - name_match_2, name, name, - (void **)&found_name); + // result = isc_hashmap_add(name_map_2, dns_name_hash(name), + // name_match_2, name, name, + // (void **)&found_name); + isc_lhashmap_entry_t *entry = isc_lhashmap_entry(&name_map, &name); /* * If it is the first name in the section, accept it. @@ -1104,21 +1105,20 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx, * this should be legal or not. In either case we no longer * need this name pointer. */ - skip_name_check: - switch (result) { - case ISC_R_SUCCESS: - if (!ISC_LIST_EMPTY(*section)) { - DO_ERROR(DNS_R_FORMERR); - } - ISC_LIST_APPEND(*section, name, link); - break; - case ISC_R_EXISTS: + // skip_name_check: + // TODO this is just checking against the first name, we don't + // need a hashmap! + if (!isc_lhashmap_entry_is_empty(entry)) { dns_message_puttempname(msg, &name); - name = found_name; - found_name = NULL; - break; - default: - UNREACHABLE(); + + name = *((dns_name_t**) entry->data); + } else { + if (count > 0) { + DO_ERROR(DNS_R_FORMERR); + } else { + isc_lhashmap_entry_put_data(&name_map, entry, &name); + ISC_LIST_APPEND(*section, name, link); + } } free_name = false; @@ -1152,6 +1152,21 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx, msg->tkey = 1; } + name_and_rdtype_t key = { + .name = name, + .rdclass = rdclass, + .type = rdtype, + .covers = 0, + }; + isc_lhashmap_entry_t *rdtype_entry = isc_lhashmap_entry(&name_rdtype_map, &key); + // TODO NULL check + if (!isc_lhashmap_entry_is_empty(rdtype_entry)) { + result = ISC_R_SUCCESS; + DO_ERROR(DNS_R_FORMERR); + } else { + isc_lhashmap_entry_put_data(&name_rdtype_map, rdtype_entry, &key); + } + /* * Allocate a new rdatalist. */ @@ -1172,37 +1187,37 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx, /* * Skip the duplicity check for first rdataset */ - if (ISC_LIST_EMPTY(name->list)) { - result = ISC_R_SUCCESS; - goto skip_rds_check; - } + // if (ISC_LIST_EMPTY(name->list)) { + // result = ISC_R_SUCCESS; + // goto skip_rds_check; + // } /* * Can't ask the same question twice. */ - if (name->hashmap == NULL) { - isc_hashmap_create(msg->mctx, 1, &name->hashmap); - free_hashmaps = true; + // if (name->hashmap == NULL) { + // isc_hashmap_create(msg->mctx, 1, &name->hashmap); + // free_hashmaps = true; + // + // INSIST(ISC_LIST_HEAD(name->list) == + // ISC_LIST_TAIL(name->list)); + // + // dns_rdataset_t *old_rdataset = + // ISC_LIST_HEAD(name->list); + // + // result = isc_hashmap_add( + // name->hashmap, rds_hash(old_rdataset), + // rds_match, old_rdataset, old_rdataset, NULL); + // + // INSIST(result == ISC_R_SUCCESS); + // } + // result = isc_hashmap_add(name->hashmap, rds_hash(rdataset), + // rds_match, rdataset, rdataset, NULL); + // if (result == ISC_R_EXISTS) { + // DO_ERROR(DNS_R_FORMERR); + // } - INSIST(ISC_LIST_HEAD(name->list) == - ISC_LIST_TAIL(name->list)); - - dns_rdataset_t *old_rdataset = - ISC_LIST_HEAD(name->list); - - result = isc_hashmap_add( - name->hashmap, rds_hash(old_rdataset), - rds_match, old_rdataset, old_rdataset, NULL); - - INSIST(result == ISC_R_SUCCESS); - } - result = isc_hashmap_add(name->hashmap, rds_hash(rdataset), - rds_match, rdataset, rdataset, NULL); - if (result == ISC_R_EXISTS) { - DO_ERROR(DNS_R_FORMERR); - } - - skip_rds_check: + // skip_rds_check: ISC_LIST_APPEND(name->list, rdataset, link); rdataset = NULL; @@ -1225,13 +1240,13 @@ cleanup: dns_message_puttempname(msg, &name); } - if (free_hashmaps) { - cleanup_name_hashmaps(section); - } + // if (free_hashmaps) { + // cleanup_name_hashmaps(section); + // } - if (name_map_2 != NULL) { - isc_hashmap_destroy(&name_map_2); - } + // if (name_map_2 != NULL) { + // isc_hashmap_destroy(&name_map_2); + // } return result; }