diff --git a/src/knot/nameserver/process_query.c b/src/knot/nameserver/process_query.c index 52e1a37bc874151a7b0ed44fca54a24b490fb562..37cb93d2b0f67e9aba38af2ba86d5068442bfd96 100644 --- a/src/knot/nameserver/process_query.c +++ b/src/knot/nameserver/process_query.c @@ -315,7 +315,7 @@ static int prepare_answer(const knot_pkt_t *query, knot_pkt_t *resp, knot_proces /* If Extended RCODE is set, do not continue with query processing. */ if (qdata->rcode_ext != 0) { - return KNOT_EMALF; + return KNOT_ERROR; } /* Update maximal answer size. */ @@ -490,7 +490,7 @@ static int process_query_out(knot_pkt_t *pkt, knot_process_t *ctx) finish: /* Default RCODE is SERVFAIL if not specified otherwise. */ if (next_state == NS_PROC_FAIL && qdata->rcode == KNOT_RCODE_NOERROR - && qdata->rcode_ext != KNOT_RCODE_BADVERS) { + && qdata->rcode_ext == 0) { qdata->rcode = KNOT_RCODE_SERVFAIL; } diff --git a/src/libknot/packet/pkt.h b/src/libknot/packet/pkt.h index 3b438f8943cff80ca413b1fb66806933ba56c922..7e7a3fe2e66d940dd753438d8779e9c4c8255f32 100644 --- a/src/libknot/packet/pkt.h +++ b/src/libknot/packet/pkt.h @@ -294,6 +294,17 @@ int knot_pkt_parse_section(knot_pkt_t *pkt, unsigned flags); */ int knot_pkt_parse_payload(knot_pkt_t *pkt, unsigned flags); +/*! + * \brief Get the Extended RCODE from the packet. + * + * Extended RCODE is created by using the Extended RCODE field from OPT RR as + * higher 8 bits and the RCODE from DNS Header as the lower 4 bits, resulting + * in a 12-bit unsigned integer. (See RFC 6891, Section 6.1.3). + * + * \param pkt Packet to get the response code from. + * + * \return + */ uint16_t knot_pkt_get_ext_rcode(const knot_pkt_t *pkt); /*! diff --git a/src/libknot/rrtype/opt.h b/src/libknot/rrtype/opt.h index 0d53b5098beacb39b6a729489ac118d78ca235ec..ab13ba287223143ae8d1202cfcb84063c078c1f5 100644 --- a/src/libknot/rrtype/opt.h +++ b/src/libknot/rrtype/opt.h @@ -138,6 +138,19 @@ void knot_edns_set_payload(knot_rrset_t *opt_rr, uint16_t payload); */ uint8_t knot_edns_get_ext_rcode(const knot_rrset_t *opt_rr); +/*! + * \brief Concatenates OPT RR Extended RCODE field and normal RCODE to get the + * whole Extended RCODE. + * + * Extended RCODE is created by using the Extended RCODE field from OPT RR as + * higher 8 bits and the RCODE from DNS Header as the lower 4 bits, resulting + * in a 12-bit unsigned integer. (See RFC 6891, Section 6.1.3). + * + * \param ext_rcode Extended RCODE field from OPT RR. + * \param rcode RCODE from DNS Header. + * + * \return 12-bit Extended RCODE. + */ static inline uint16_t knot_edns_whole_rcode(uint8_t ext_rcode, uint8_t rcode) { uint16_t high = ext_rcode;