]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/resolve: kr_extended_error_t and related func
authorTomas Krizek <tomas.krizek@nic.cz>
Tue, 26 Oct 2021 12:43:12 +0000 (14:43 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Tue, 21 Dec 2021 13:16:54 +0000 (14:16 +0100)
daemon/lua/kres-gen-29.lua
daemon/lua/kres-gen-31.lua
daemon/lua/kres-gen.sh
lib/resolve.c
lib/resolve.h

index 554d44702b29ccb3bdfacf2ea307c5fe151b7dec..8e5380c90185a270993f4a05071c265627ec2fed 100644 (file)
@@ -194,6 +194,10 @@ struct kr_request_qsource_flags {
        _Bool http : 1;
        _Bool xdp : 1;
 };
+struct kr_extended_error {
+       int32_t info_code;
+       const char *extra_text;
+};
 struct kr_request {
        struct kr_context *ctx;
        knot_pkt_t *answer;
@@ -234,6 +238,7 @@ struct kr_request {
        unsigned int count_no_nsaddr;
        unsigned int count_fail_row;
        alloc_wire_f alloc_wire_cb;
+       struct kr_extended_error extended_error;
 };
 enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
 typedef struct kr_cdb * kr_cdb_pt;
@@ -380,6 +385,7 @@ void knot_pkt_free(knot_pkt_t *);
 int knot_pkt_parse(knot_pkt_t *, unsigned int);
 knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
 knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
+int kr_request_set_extended_error(struct kr_request *, int, const char *);
 struct kr_rplan *kr_resolve_plan(struct kr_request *);
 knot_mm_t *kr_resolve_pool(struct kr_request *);
 struct kr_query *kr_rplan_push(struct kr_rplan *, struct kr_query *, const knot_dname_t *, uint16_t, uint16_t);
index e44966113f85a77c81adad5204878b325ec98137..237df69b4b0a405d70a64d2ebe384f0885383702 100644 (file)
@@ -194,6 +194,10 @@ struct kr_request_qsource_flags {
        _Bool http : 1;
        _Bool xdp : 1;
 };
+struct kr_extended_error {
+       int32_t info_code;
+       const char *extra_text;
+};
 struct kr_request {
        struct kr_context *ctx;
        knot_pkt_t *answer;
@@ -234,6 +238,7 @@ struct kr_request {
        unsigned int count_no_nsaddr;
        unsigned int count_fail_row;
        alloc_wire_f alloc_wire_cb;
+       struct kr_extended_error extended_error;
 };
 enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
 typedef struct kr_cdb * kr_cdb_pt;
@@ -380,6 +385,7 @@ void knot_pkt_free(knot_pkt_t *);
 int knot_pkt_parse(knot_pkt_t *, unsigned int);
 knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
 knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
+int kr_request_set_extended_error(struct kr_request *, int, const char *);
 struct kr_rplan *kr_resolve_plan(struct kr_request *);
 knot_mm_t *kr_resolve_pool(struct kr_request *);
 struct kr_query *kr_rplan_push(struct kr_rplan *, struct kr_query *, const knot_dname_t *, uint16_t, uint16_t);
index fb730266dd8f361114f45cb0e95c6638f3099337..064fb0e4bd5cd5da419436681369f18025abbc46 100755 (executable)
@@ -125,6 +125,7 @@ ${CDEFS} ${LIBKRES} types <<-EOF
        kr_qarray_t
        struct kr_rplan
        struct kr_request_qsource_flags
+       struct kr_extended_error
        struct kr_request
        enum kr_rank
        typedef kr_cdb_pt
@@ -203,6 +204,7 @@ ${CDEFS} ${LIBKRES} functions <<-EOF
 # Resolution request
        kr_request_ensure_edns
        kr_request_ensure_answer
+       kr_request_set_extended_error
        kr_resolve_plan
        kr_resolve_pool
 # Resolution plan
index 1ffd07ec72c1ca3d455c414c36f5ef0902c7f50b..12cb14a169fea867a553507fcbf69c8784ade417 100644 (file)
@@ -1615,4 +1615,70 @@ knot_mm_t *kr_resolve_pool(struct kr_request *request)
        return NULL;
 }
 
+static int ede_priority(int info_code)
+{
+       switch(info_code) {
+       case KNOT_EDNS_EDE_DNSKEY_BIT:
+       case KNOT_EDNS_EDE_DNSKEY_MISS:
+       case KNOT_EDNS_EDE_SIG_EXPIRED:
+       case KNOT_EDNS_EDE_SIG_NOTYET:
+       case KNOT_EDNS_EDE_RRSIG_MISS:
+       case KNOT_EDNS_EDE_NSEC_MISS:
+               return 900;  /* Specific DNSSEC failures */
+       case KNOT_EDNS_EDE_BOGUS:
+               return 800;  /* Generic DNSSEC failure */
+       case KNOT_EDNS_EDE_FORGED:
+       case KNOT_EDNS_EDE_FILTERED:
+               return 700;  /* Considered hard fail by firefox */
+       case KNOT_EDNS_EDE_PROHIBITED:
+       case KNOT_EDNS_EDE_BLOCKED:
+       case KNOT_EDNS_EDE_CENSORED:
+               return 600;  /* Policy related */
+       case KNOT_EDNS_EDE_DNSKEY_ALG:
+       case KNOT_EDNS_EDE_DS_DIGEST:
+               return 500;  /* Non-critical DNSSEC issues */
+       case KNOT_EDNS_EDE_STALE:
+       case KNOT_EDNS_EDE_INDETERMINATE:
+       case KNOT_EDNS_EDE_CACHED_ERR:
+       case KNOT_EDNS_EDE_NOT_READY:
+       case KNOT_EDNS_EDE_STALE_NXD:
+       case KNOT_EDNS_EDE_NOTAUTH:
+       case KNOT_EDNS_EDE_NOTSUP:
+       case KNOT_EDNS_EDE_NREACH_AUTH:
+       case KNOT_EDNS_EDE_NETWORK:
+       case KNOT_EDNS_EDE_INV_DATA:
+               return 200;  /* Assorted codes */
+       case KNOT_EDNS_EDE_OTHER:
+               return 100;  /* Most generic catch-all error */
+       case KNOT_EDNS_EDE_NONE:
+               return 0;  /* No error - allow overriding */
+       default:
+               kr_assert(false);  /* Unknown info_code */
+               return 50;
+       }
+}
+
+int kr_request_set_extended_error(struct kr_request *request, int info_code, const char *extra_text)
+{
+       if (kr_fails_assert(request))
+               return KNOT_EDNS_EDE_NONE;
+
+       struct kr_extended_error *ede = &request->extended_error;
+
+       /* Clear any previously set error. */
+       if (info_code == KNOT_EDNS_EDE_NONE) {
+               kr_assert(extra_text == NULL);
+               ede->info_code = KNOT_EDNS_EDE_NONE;
+               ede->extra_text = NULL;
+               return KNOT_EDNS_EDE_NONE;
+       }
+
+       if (ede_priority(info_code) >= ede_priority(ede->info_code)) {
+               ede->info_code = info_code;
+               ede->extra_text = extra_text;
+       }
+
+       return ede->info_code;
+}
+
 #undef VERBOSE_MSG
index beea663a01824ea3b152071203c08d41d9a0ee9d..c973318aff6a670a0a3cbe0c412d8f17a353406b 100644 (file)
@@ -184,6 +184,13 @@ struct kr_request_qsource_flags {
        bool xdp:1; /**< true if the request is on AF_XDP; only meaningful if (dst_addr). */
 };
 
+/* Extended DNS Errors, RFC 8914 */
+struct kr_extended_error {
+       int32_t info_code;  /**< May contain -1 (KNOT_EDNS_EDE_NONE); filter before converting to uint16_t. */
+       const char *extra_text; /**< Can be NULL.  Allocated on the kr_request::pool or static. */
+};
+
+
 typedef bool (*addr_info_f)(struct sockaddr*);
 typedef void (*async_resolution_f)(knot_dname_t*, enum knot_rr_type);
 typedef array_t(union kr_sockaddr) kr_sockaddr_array_t;
@@ -251,6 +258,7 @@ struct kr_request {
        unsigned int count_no_nsaddr;
        unsigned int count_fail_row;
        alloc_wire_f alloc_wire_cb; /**< CB to allocate answer wire (can be NULL). */
+       struct kr_extended_error extended_error;  /**< EDE info; don't modify directly, use kr_request_set_extended_error() */
 };
 
 /** Initializer for an array of *_selected. */
@@ -365,3 +373,19 @@ struct kr_rplan *kr_resolve_plan(struct kr_request *request);
  */
 KR_EXPORT KR_PURE
 knot_mm_t *kr_resolve_pool(struct kr_request *request);
+
+/**
+ * Set the extended DNS error for request.
+ *
+ * The error is set only if it has a higher or the same priority as the one
+ * already assigned.  The provided extra_text may be NULL, or a string that is
+ * allocated either statically, or on the request's mempool. To clear any
+ * error, call it with KNOT_EDNS_EDE_NONE and NULL as extra_text.
+ *
+ * @param  request     request state
+ * @param  info_code   extended DNS error code
+ * @param  extra_text  optional string with additional information
+ * @return             info_code that is set after the call
+ */
+KR_EXPORT
+int kr_request_set_extended_error(struct kr_request *request, int info_code, const char *extra_text);