summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorVladimír Čunát <vladimir.cunat@nic.cz>2021-04-06 17:28:52 +0200
committerTomas Krizek <tomas.krizek@nic.cz>2021-04-14 16:04:16 +0200
commit44f67cf4b0c98c92d5dfd5cdcad72e10d0820c89 (patch)
tree30992bb0b0f707b095d9e9b4882f968d3ce4d4c6 /utils
parenttreewide: remove duplicate contrib/wire.h (diff)
downloadknot-resolver-44f67cf4b0c98c92d5dfd5cdcad72e10d0820c89.tar.xz
knot-resolver-44f67cf4b0c98c92d5dfd5cdcad72e10d0820c89.zip
treewide: fix unaligned access
Some less common HW (not x86, usually ARM) doesn't tolerate unaligned access to memory and it's breakage of C as well. It's easiest to check by meson's -Db_sanitize=undefined (on any HW). I pushed millions of real-life QNAME+QTYPE queries over UDP in default mode and the sanitizer seems clear now.
Diffstat (limited to 'utils')
-rw-r--r--utils/cache_gc/db.c31
-rw-r--r--utils/cache_gc/db.h6
-rw-r--r--utils/cache_gc/kr_cache_gc.c6
3 files changed, 21 insertions, 22 deletions
diff --git a/utils/cache_gc/db.c b/utils/cache_gc/db.c
index 1acd37e6..b6bfaaca 100644
--- a/utils/cache_gc/db.c
+++ b/utils/cache_gc/db.c
@@ -64,10 +64,8 @@ void kr_gc_cache_close(struct kr_cache *kres_db, knot_db_t * knot_db)
kr_cache_close(kres_db);
}
-const uint16_t *kr_gc_key_consistent(knot_db_val_t key)
+int kr_gc_key_consistent(knot_db_val_t key)
{
- const static uint16_t NSEC1 = KNOT_RRTYPE_NSEC;
- const static uint16_t NSEC3 = KNOT_RRTYPE_NSEC3;
const uint8_t *kd = key.data;
ssize_t i;
/* CACHE_KEY_DEF */
@@ -80,7 +78,7 @@ const uint16_t *kr_gc_key_consistent(knot_db_val_t key)
for (i = 2; kd[i - 1] || kd[i - 2]; ++i) {
if (i >= key.len) {
// TODO: assert(!EINVAL) -> kr_assume()
- return NULL;
+ return kr_error(EINVAL);
}
}
}
@@ -89,18 +87,20 @@ const uint16_t *kr_gc_key_consistent(knot_db_val_t key)
case 'E':
if (i + 1 + sizeof(uint16_t) > key.len) {
assert(!EINVAL);
- return NULL;
+ return kr_error(EINVAL);
}
- return (uint16_t *) & kd[i + 1];
+ uint16_t type;
+ memcpy(&type, kd + i + 1, sizeof(type));
+ return type;
case '1':
- return &NSEC1;
+ return KNOT_RRTYPE_NSEC;
case '3':
- return &NSEC3;
+ return KNOT_RRTYPE_NSEC3;
case 'S': // the rtt_state entries are considered inconsistent, at least for now
- return NULL;
+ return -1;
default:
assert(!EINVAL);
- return NULL;
+ return kr_error(EINVAL);
}
}
@@ -203,12 +203,11 @@ int kr_gc_cache_iter(knot_db_t * knot_db, const kr_cache_gc_cfg_t *cfg,
info.entry_size = key.len + val.len;
info.valid = false;
- const uint16_t *entry_type =
- ret == KNOT_EOK ? kr_gc_key_consistent(key) : NULL;
+ const int entry_type = ret == KNOT_EOK ? kr_gc_key_consistent(key) : -1;
const struct entry_h *entry = NULL;
- if (entry_type != NULL) {
+ if (entry_type >= 0) {
counter_gc_consistent++;
- entry = val2entry(val, *entry_type);
+ entry = val2entry(val, entry_type);
}
/* TODO: perhaps improve some details around here:
* - rtt_state entries are considered gc_inconsistent;
@@ -219,9 +218,9 @@ int kr_gc_cache_iter(knot_db_t * knot_db, const kr_cache_gc_cfg_t *cfg,
* here as kr_inconsistent */
if (entry != NULL) {
info.valid = true;
- info.rrtype = *entry_type;
+ info.rrtype = entry_type;
info.expires_in = entry->time + entry->ttl - now;
- info.no_labels = entry_labels(&key, *entry_type);
+ info.no_labels = entry_labels(&key, entry_type);
}
counter_iter++;
counter_kr_consistent += info.valid;
diff --git a/utils/cache_gc/db.h b/utils/cache_gc/db.h
index 15d26caa..48dc101a 100644
--- a/utils/cache_gc/db.h
+++ b/utils/cache_gc/db.h
@@ -21,12 +21,12 @@ typedef int (*kr_gc_iter_callback)(const knot_db_val_t * key,
int kr_gc_cache_iter(knot_db_t * knot_db, const kr_cache_gc_cfg_t *cfg,
kr_gc_iter_callback callback, void *ctx);
-/** Return RR type corresponding to the key or NULL.
+/** Return RR type corresponding to the key or negative error code.
*
- * NULL is returned on unexpected values (those also trigger assertion)
+ * Error is returned on unexpected values (those also trigger assertion)
* and on other kinds of data in cache (e.g. struct rtt_state).
*/
-const uint16_t *kr_gc_key_consistent(knot_db_val_t key);
+int kr_gc_key_consistent(knot_db_val_t key);
/** Printf a *binary* string in a human-readable way. */
void debug_printbin(const char *str, unsigned int len);
diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c
index 3843d5ca..068c457e 100644
--- a/utils/cache_gc/kr_cache_gc.c
+++ b/utils/cache_gc/kr_cache_gc.c
@@ -276,9 +276,9 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
switch (ret) {
case KNOT_EOK:
deleted_records++;
- const uint16_t *entry_type = kr_gc_key_consistent(**i);
- if (entry_type != NULL) // some "inconsistent" entries are OK
- rrtypelist_add(&deleted_rrtypes, *entry_type);
+ const int entry_type = kr_gc_key_consistent(**i);
+ if (entry_type >= 0) // some "inconsistent" entries are OK
+ rrtypelist_add(&deleted_rrtypes, entry_type);
break;
case KNOT_ENOENT:
already_gone++;