Save progress again

This commit is contained in:
alessio
2025-02-03 18:49:33 +01:00
parent 3ab0fdbed7
commit 00a831745b
3 changed files with 86 additions and 87 deletions

View File

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

View File

@@ -6,29 +6,15 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "isc/result.h"
#include "isc/util.h"
#include <isc/result.h>
#include <isc/util.h>
#include <dns/lhashmap.h>
#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) {

View File

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