Save progress again
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user