mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-02-03 18:49:28 -05:00
libknot+kdig: support for EDNS DE flag (DELEG-aware signal)
This commit is contained in:
parent
44d9404035
commit
57bbf2b059
11 changed files with 78 additions and 6 deletions
|
|
@ -177,6 +177,9 @@ Options
|
|||
**+**\ [\ **no**\ ]\ **dnssec**
|
||||
Same as **+**\ [\ **no**\ ]\ **doflag**
|
||||
|
||||
**+**\ [\ **no**\ ]\ **deflag**
|
||||
Set the DE flag.
|
||||
|
||||
**+**\ [\ **no**\ ]\ **all**
|
||||
Show all packet sections.
|
||||
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ static int answer_edns_init(const knot_pkt_t *query, knot_pkt_t *resp,
|
|||
/* Set DO bit if set (DNSSEC requested). */
|
||||
if (knot_pkt_has_dnssec(query)) {
|
||||
knot_edns_set_do(&qdata->opt_rr);
|
||||
}
|
||||
} // TODO: also echo back DE bit if we are DELEG-aware?
|
||||
|
||||
/* Append NSID if requested and available. */
|
||||
if (knot_pkt_edns_option(query, KNOT_EDNS_OPTION_NSID) != NULL) {
|
||||
|
|
|
|||
|
|
@ -364,6 +364,15 @@ static inline bool knot_pkt_has_dnssec(const knot_pkt_t *pkt)
|
|||
return knot_pkt_has_edns(pkt) && knot_edns_do(pkt->opt_rr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks if DE bit is set in the packet's OPT RR.
|
||||
*/
|
||||
static inline bool knot_pkt_has_deleg_aware(const knot_pkt_t *pkt)
|
||||
{
|
||||
assert(pkt);
|
||||
return knot_pkt_has_edns(pkt) && knot_edns_de(pkt->opt_rr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Get specific EDNS option from a parsed packet.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ int knot_probe_data_set(knot_probe_data_t *data, knot_probe_proto_t proto,
|
|||
data->query_edns.version = knot_edns_get_version(query->opt_rr);
|
||||
data->query_edns.present = 1;
|
||||
data->query_edns.flag_do = knot_edns_do(query->opt_rr);
|
||||
data->query_edns.flag_de = knot_edns_de(query->opt_rr);
|
||||
if (query->edns_opts != NULL) {
|
||||
for (int i = 0; i <= KNOT_EDNS_MAX_OPTION_CODE; i++) {
|
||||
if (query->edns_opts->ptr[i] != NULL) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ typedef struct {
|
|||
uint8_t version; /*!< EDNS version. */
|
||||
uint8_t present : 1; /*!< EDNS presence indication. */
|
||||
uint8_t flag_do : 1; /*!< DO flag indication. */
|
||||
uint8_t reserved : 6; /*!< Unused. */
|
||||
uint8_t flag_de : 1; /*!< DE flag indication. */
|
||||
uint8_t reserved : 5; /*!< Unused. */
|
||||
} query_edns;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -987,6 +987,8 @@ static void wire_ednsflags_to_str(rrset_dump_params_t *p)
|
|||
|
||||
if ((mask & KNOT_EDNS_DO_MASK)) {
|
||||
dump_string(p, "DO");
|
||||
} else if ((mask & KNOT_EDNS_DE_MASK)) {
|
||||
dump_string(p, "DE");
|
||||
} else {
|
||||
dump_str_uint(p, "BIT", i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ enum {
|
|||
|
||||
/*! \brief Bit mask for DO bit. */
|
||||
KNOT_EDNS_DO_MASK = (uint32_t)(1 << 15),
|
||||
KNOT_EDNS_DE_MASK = (uint32_t)(1 << 13),
|
||||
|
||||
/*! \brief Minimal UDP payload with EDNS enabled. */
|
||||
KNOT_EDNS_MIN_UDP_PAYLOAD = 512,
|
||||
|
|
@ -259,6 +260,12 @@ bool knot_edns_do(const knot_rrset_t *opt_rr)
|
|||
assert(opt_rr != NULL);
|
||||
return opt_rr->ttl & KNOT_EDNS_DO_MASK;
|
||||
}
|
||||
static inline
|
||||
bool knot_edns_de(const knot_rrset_t *opt_rr)
|
||||
{
|
||||
assert(opt_rr != NULL);
|
||||
return opt_rr->ttl & KNOT_EDNS_DE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the DO bit in the OPT RR.
|
||||
|
|
@ -274,6 +281,12 @@ void knot_edns_set_do(knot_rrset_t *opt_rr)
|
|||
assert(opt_rr != NULL);
|
||||
opt_rr->ttl |= KNOT_EDNS_DO_MASK;
|
||||
}
|
||||
static inline
|
||||
void knot_edns_set_de(knot_rrset_t *opt_rr)
|
||||
{
|
||||
assert(opt_rr != NULL);
|
||||
opt_rr->ttl |= KNOT_EDNS_DE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Add EDNS option into the package with empty (zeroed) content.
|
||||
|
|
|
|||
|
|
@ -336,9 +336,22 @@ static void print_section_opt(const knot_pkt_t *packet, const style_t *style)
|
|||
ercode_str = unknown_ercode;
|
||||
}
|
||||
|
||||
printf(";; Version: %u; flags: %s; UDP size: %u B; ext-rcode: %s\n",
|
||||
char flags[96] = " ", *flend = flags;
|
||||
for (uint32_t mask = 1 << 15, bit = 1; mask; mask >>= 1, bit++) {
|
||||
if (packet->opt_rr->ttl & mask) {
|
||||
if (mask & KNOT_EDNS_DO_MASK) {
|
||||
flend += snprintf(flend, 4, " do");
|
||||
} else if (mask & KNOT_EDNS_DE_MASK) {
|
||||
flend += snprintf(flend, 4, " de");
|
||||
} else {
|
||||
flend += snprintf(flend, 7, " bit%u", bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf(";; Version: %u; flags:%s; UDP size: %u B; ext-rcode: %s\n",
|
||||
knot_edns_get_version(packet->opt_rr),
|
||||
(knot_edns_do(packet->opt_rr) != 0) ? "do" : "",
|
||||
flags,
|
||||
knot_edns_get_payload(packet->opt_rr),
|
||||
ercode_str);
|
||||
|
||||
|
|
@ -851,6 +864,8 @@ static void json_print_edns(jsonw_t *w, const knot_pkt_t *pkt)
|
|||
if ((flags & mask)) {
|
||||
if ((mask & KNOT_EDNS_DO_MASK)) {
|
||||
jsonw_str(w, NULL, "DO");
|
||||
} else if ((mask & KNOT_EDNS_DE_MASK)) {
|
||||
jsonw_str(w, NULL, "DE");
|
||||
} else {
|
||||
(void)snprintf(tmp, sizeof(tmp), "BIT%d", i);
|
||||
jsonw_str(w, NULL, tmp);
|
||||
|
|
|
|||
|
|
@ -242,6 +242,9 @@ static int add_query_edns(knot_pkt_t *packet, const query_t *query, uint16_t max
|
|||
if (query->flags.do_flag) {
|
||||
knot_edns_set_do(&opt_rr);
|
||||
}
|
||||
if (query->flags.de_flag) {
|
||||
knot_edns_set_de(&opt_rr);
|
||||
}
|
||||
|
||||
/* Append NSID. */
|
||||
if (query->nsid) {
|
||||
|
|
@ -356,7 +359,7 @@ static bool use_edns(const query_t *query)
|
|||
return query->edns > -1 || query->udp_size > -1 || query->nsid ||
|
||||
query->zoneversion || query->subnet.family != AF_UNSPEC ||
|
||||
query->flags.do_flag || query->cc.len > 0 || do_padding(query) ||
|
||||
!ednsopt_list_empty(&query->edns_opts);
|
||||
query->flags.de_flag || !ednsopt_list_empty(&query->edns_opts);
|
||||
}
|
||||
|
||||
static knot_pkt_t *create_query_packet(const query_t *query)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ static const flags_t DEFAULT_FLAGS_DIG = {
|
|||
.z_flag = false,
|
||||
.ad_flag = true,
|
||||
.cd_flag = false,
|
||||
.do_flag = false
|
||||
.do_flag = false,
|
||||
.de_flag = false,
|
||||
};
|
||||
|
||||
static const style_t DEFAULT_STYLE_DIG = {
|
||||
|
|
@ -275,6 +276,24 @@ static int opt_nodoflag(const char *arg, void *query)
|
|||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
static int opt_deflag(const char *arg, void *query)
|
||||
{
|
||||
query_t *q = query;
|
||||
|
||||
q->flags.de_flag = true;
|
||||
|
||||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
static int opt_nodeflag(const char *arg, void *query)
|
||||
{
|
||||
query_t *q = query;
|
||||
|
||||
q->flags.de_flag = false;
|
||||
|
||||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
static int opt_all(const char *arg, void *query)
|
||||
{
|
||||
query_t *q = query;
|
||||
|
|
@ -1550,6 +1569,9 @@ static const param_t kdig_opts2[] = {
|
|||
{ "dnssec", ARG_NONE, opt_doflag }, // Alias.
|
||||
{ "nodnssec", ARG_NONE, opt_nodoflag },
|
||||
|
||||
{ "deflag", ARG_NONE, opt_deflag },
|
||||
{ "nodeflag", ARG_NONE, opt_nodeflag },
|
||||
|
||||
{ "all", ARG_NONE, opt_all },
|
||||
{ "noall", ARG_NONE, opt_noall },
|
||||
|
||||
|
|
@ -2377,6 +2399,7 @@ static void print_help(void)
|
|||
" +[no]cdflag Set CD flag.\n"
|
||||
" +[no]doflag Set DO flag.\n"
|
||||
" +[no]dnssec Same as +[no]doflag.\n"
|
||||
" +[no]deflag Set DE flag.\n"
|
||||
" +[no]all Show all packet sections.\n"
|
||||
" +[no]qr Show query packet.\n"
|
||||
" +[no]header * Show packet header.\n"
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ typedef struct {
|
|||
bool cd_flag;
|
||||
/*!< DNSSEC OK flag. */
|
||||
bool do_flag;
|
||||
/*!< DELEG-aware flag. */
|
||||
bool de_flag;
|
||||
} flags_t;
|
||||
|
||||
/*! \brief Basic parameters for DNS query. */
|
||||
|
|
|
|||
Loading…
Reference in a new issue