Skip to content
Snippets Groups Projects
Commit d9a66637 authored by Daniel Salzman's avatar Daniel Salzman
Browse files

Merge branch 'svcb2' into 'master'

svcb: put glue + dnssec into additional section

See merge request knot/knot-dns!1366
parents 2077823c 96d7a9c6
Branches
Tags
1 merge request!1366svcb: put glue + dnssec into additional section
Pipeline #88797 passed with stages
in 9 minutes and 51 seconds
......@@ -423,6 +423,7 @@ src/libknot/rrtype/opt.h
src/libknot/rrtype/rdname.h
src/libknot/rrtype/rrsig.h
src/libknot/rrtype/soa.h
src/libknot/rrtype/svcb.h
src/libknot/rrtype/tsig.c
src/libknot/rrtype/tsig.h
src/libknot/rrtype/zonemd.h
......
......@@ -16,6 +16,7 @@
#include "libknot/libknot.h"
#include "knot/dnssec/rrset-sign.h"
#include "knot/dnssec/zone-nsec.h"
#include "knot/nameserver/internet.h"
#include "knot/nameserver/nsec_proofs.h"
#include "knot/nameserver/query_module.h"
......@@ -193,6 +194,24 @@ static int put_delegation(knot_pkt_t *pkt, knotd_qdata_t *qdata)
KNOT_COMPR_HINT_NONE, 0);
}
static int put_nsec3_bitmap(const zone_node_t *for_node, knot_pkt_t *pkt,
knotd_qdata_t *qdata, uint32_t flags)
{
const zone_node_t *node = node_nsec3_get(for_node);
if (node == NULL) {
return KNOT_EOK;
}
knot_rrset_t nsec3 = node_rrset(node, KNOT_RRTYPE_NSEC3);
if (knot_rrset_empty(&nsec3)) {
return KNOT_EOK;
}
knot_rrset_t rrsig = node_rrset(node, KNOT_RRTYPE_RRSIG);
return process_query_put_rr(pkt, qdata, &nsec3, &rrsig,
KNOT_COMPR_HINT_NONE, flags);
}
/*! \brief Put additional records for given RR. */
static int put_additional(knot_pkt_t *pkt, const knot_rrset_t *rr,
knotd_qdata_t *qdata, knot_rrinfo_t *info, int state)
......@@ -203,8 +222,8 @@ static int put_additional(knot_pkt_t *pkt, const knot_rrset_t *rr,
/* Valid types for ADDITIONALS insertion. */
/* \note Not resolving CNAMEs as MX/NS name must not be an alias. (RFC2181/10.3) */
static const uint16_t ar_type_list[] = { KNOT_RRTYPE_A, KNOT_RRTYPE_AAAA };
static const int ar_type_count = 2;
static uint16_t ar_type_list[] = { KNOT_RRTYPE_A, KNOT_RRTYPE_AAAA, KNOT_RRTYPE_SVCB };
static const int ar_type_count_default = 2;
int ret = KNOT_EOK;
......@@ -220,6 +239,11 @@ static int put_additional(knot_pkt_t *pkt, const knot_rrset_t *rr,
flags |= KNOT_PF_NOTRUNC;
}
int ar_type_count = ar_type_count_default, ar_present = 0;
if (rr->type == KNOT_RRTYPE_SVCB || rr->type == KNOT_RRTYPE_HTTPS) {
ar_type_list[ar_type_count++] = rr->type;
}
uint16_t hint = knot_compr_hint(info, KNOT_COMPR_HINT_RDATA +
glue->ns_pos);
const zone_node_t *gluenode = glue_node(glue, qdata->extra->node);
......@@ -234,6 +258,28 @@ static int put_additional(knot_pkt_t *pkt, const knot_rrset_t *rr,
if (ret != KNOT_EOK) {
break;
}
ar_present++;
}
if ((rr->type == KNOT_RRTYPE_SVCB || rr->type == KNOT_RRTYPE_HTTPS) &&
ar_present < ar_type_count && have_dnssec(qdata)) {
// it would be nicer to have this in solve_additional_dnssec, but
// it seems infeasible to transfer all the context there
// adding an NSEC(3) record proving non-existence of some of the
// glue with its bitmap
if (knot_is_nsec3_enabled(qdata->extra->contents)) {
ret = put_nsec3_bitmap(gluenode, pkt, qdata, flags);
} else {
knot_rrset_t nsec = node_rrset(gluenode, KNOT_RRTYPE_NSEC);
if (!knot_rrset_empty(&nsec)) {
ret = process_query_put_rr(pkt, qdata, &nsec, &rrsigs,
KNOT_COMPR_HINT_NONE, flags);
}
}
if (ret != KNOT_EOK) {
break;
}
}
}
......
......@@ -46,6 +46,7 @@ nobase_include_libknot_HEADERS = \
libknot/rrtype/rdname.h \
libknot/rrtype/rrsig.h \
libknot/rrtype/soa.h \
libknot/rrtype/svcb.h \
libknot/rrtype/tsig.h \
libknot/rrtype/zonemd.h \
libknot/tsig-op.h \
......
......@@ -352,7 +352,9 @@ int knot_rrtype_additional_needed(const uint16_t type)
{
return type == KNOT_RRTYPE_NS ||
type == KNOT_RRTYPE_MX ||
type == KNOT_RRTYPE_SRV;
type == KNOT_RRTYPE_SRV ||
type == KNOT_RRTYPE_SVCB ||
type == KNOT_RRTYPE_HTTPS;
}
_public_
......
......@@ -64,6 +64,7 @@
#include "libknot/rrtype/rdname.h"
#include "libknot/rrtype/rrsig.h"
#include "libknot/rrtype/soa.h"
#include "libknot/rrtype/svcb.h"
#include "libknot/rrtype/tsig.h"
#include "libknot/rrtype/zonemd.h"
#include "libknot/wire.h"
......
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -26,6 +26,7 @@
#include "libknot/descriptor.h"
#include "libknot/dname.h"
#include "libknot/rdata.h"
#include "libknot/rrtype/svcb.h"
static inline
const knot_dname_t *knot_cname_name(const knot_rdata_t *rdata)
......@@ -86,6 +87,9 @@ const knot_dname_t *knot_rdata_name(const knot_rdata_t *rdata, uint16_t type)
return knot_cname_name(rdata);
case KNOT_RRTYPE_DNAME:
return knot_dname_target(rdata);
case KNOT_RRTYPE_SVCB:
case KNOT_RRTYPE_HTTPS:
return knot_svcb_target(rdata);
}
return NULL;
......
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* \addtogroup rrtype
* @{
*/
#pragma once
#include "libknot/dname.h"
#include "libknot/rdata.h"
#include "libknot/wire.h"
static inline
uint32_t knot_svcb_priority(const knot_rdata_t *rdata)
{
assert(rdata);
return knot_wire_read_u16(rdata->data);
}
static inline
const knot_dname_t *knot_svcb_target(const knot_rdata_t *rdata)
{
assert(rdata);
return rdata->data + 2;
}
/*! @} */
......@@ -202,6 +202,50 @@ def do_normal_tests(master, zone, dnssec=False):
resp.check_record(section="additional", rtype="A", rdata="10.20.30.40")
verify(master, zone, dnssec)
# add SVCB w/o glue
check_log("glueless SVCB")
up = master.update(zone)
try:
up.add("svcb.ddns.", 3600, "SVCB", "0 target.svcb.ddns.")
except:
up.add("svcb.ddns.", 3600, "TYPE64", "\# 20 00000674617267657404737663620464646E7300")
up.send("NOERROR")
resp = master.dig("svcb.ddns.", "TYPE64", dnssec=dnssec)
resp.check(rcode="NOERROR")
resp.check_count(0, rtype="AAAA", section="additional")
# add glue to SVCB
check_log("Add glue to SVCB")
up = master.update(zone)
up.add("target.svcb.ddns.", 3600, "AAAA", "1::2")
try:
up.add("target.svcb.ddns.", 3600, "SVCB", "2 . alpn=h2")
except:
up.add("target.svcb.ddns.", 3600, "TYPE64", "\# 10 00020000010003026832")
up.send("NOERROR")
resp = master.dig("svcb.ddns.", "TYPE64", dnssec=dnssec)
resp.check(rcode="NOERROR")
resp.check_count(1, rtype="AAAA", section="additional")
resp.check_count(1, rtype="TYPE64", section="additional")
if dnssec:
resp.check_count(3, rtype="RRSIG", section="additional")
# remove glue from SVCB
check_log("Remove glue from SVCB")
up = master.update(zone)
up.delete("target.svcb.ddns.", "AAAA")
up.delete("target.svcb.ddns.", "TYPE64")
up.send("NOERROR")
resp = master.dig("svcb.ddns.", "TYPE64", dnssec=dnssec)
resp.check(rcode="NOERROR")
resp.check_count(0, rtype="AAAA", section="additional")
resp.check_count(0, rtype="RRSIG", section="additional")
# now remove SVCB in order to make ldns-verify work
up = master.update(zone)
up.delete("svcb.ddns.", "TYPE64")
up.send()
# add CNAME to node with A records, should be ignored
check_log("Add CNAME to A node")
up = master.update(zone)
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment