_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;
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;
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);
_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;
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;
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);
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
# Resolution request
kr_request_ensure_edns
kr_request_ensure_answer
+ kr_request_set_extended_error
kr_resolve_plan
kr_resolve_pool
# Resolution plan
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
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;
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. */
*/
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);