diff options
author | Oto Šťáva <oto.stava@nic.cz> | 2022-04-29 08:50:35 +0200 |
---|---|---|
committer | Vladimír Čunát <vladimir.cunat@nic.cz> | 2022-05-02 12:17:49 +0200 |
commit | 08d66491af0123d9b4af4fee38e8a8b27bd80a71 (patch) | |
tree | c6e58ac7b73c795d9b16f4a99174cda2dd222204 /lib/utils.h | |
parent | Merge branch !1285: daemon/zimport: close transaction after importing batch (diff) | |
download | knot-resolver-08d66491af0123d9b4af4fee38e8a8b27bd80a71.tar.xz knot-resolver-08d66491af0123d9b4af4fee38e8a8b27bd80a71.zip |
lib/utils: sockaddr key generation
Diffstat (limited to '')
-rw-r--r-- | lib/utils.h | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/lib/utils.h b/lib/utils.h index cdcda131..d9aadfa1 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -28,10 +28,15 @@ #include "lib/generic/array.h" #include "lib/log.h" - /** When knot_pkt is passed from cache without ->wire, this is the ->size. */ static const size_t KR_PKT_SIZE_NOWIRE = -1; +/** Used for reserving enough space for the `kr_sockaddr_key` function + * output. */ +struct kr_sockaddr_key_storage { + char bytes[sizeof(struct sockaddr_storage)]; +}; + /* * Logging and debugging. @@ -262,6 +267,22 @@ int kr_inaddr_len(const struct sockaddr *addr); /** Sockaddr length for given family, i.e. sizeof(struct sockaddr_in*). */ KR_EXPORT KR_PURE int kr_sockaddr_len(const struct sockaddr *addr); + +/** Creates a packed structure from the specified `addr`, safe for use as a key + * in containers like `trie_t`, and writes it into `dst`. On success, returns + * the actual length of the key. + * + * Returns `kr_error(EAFNOSUPPORT)` if the family of `addr` is unsupported. */ +KR_EXPORT +ssize_t kr_sockaddr_key(struct kr_sockaddr_key_storage *dst, + const struct sockaddr *addr); + +/** Creates a `struct sockaddr` from the specified `key` created using the + * `kr_sockaddr_key()` function. */ +KR_EXPORT +struct sockaddr *kr_sockaddr_from_key(struct sockaddr_storage *dst, + const char *key); + /** Compare two given sockaddr. * return 0 - addresses are equal, error code otherwise. */ @@ -353,6 +374,19 @@ int kr_bitcmp(const char *a, const char *b, int bits); KR_EXPORT void kr_bitmask(unsigned char *a, size_t a_len, int bits); +/** Check whether `addr` points to an `AF_INET6` address and whether the address + * is link-local. */ +static inline bool kr_sockaddr_link_local(const struct sockaddr *addr) +{ + if (addr->sa_family != AF_INET6) + return false; + + /* Link-local: https://tools.ietf.org/html/rfc4291#section-2.4 */ + const uint8_t prefix[] = { 0xFE, 0x80 }; + const struct sockaddr_in6 *ip6 = (const struct sockaddr_in6 *) addr; + return kr_bitcmp((char *) ip6->sin6_addr.s6_addr, (char *) prefix, 10) == 0; +} + /** @internal RR map flags. */ static const uint8_t KEY_FLAG_RRSIG = 0x02; static inline uint8_t KEY_FLAG_RANK(const char *key) |