Skip to content
Snippets Groups Projects
Commit 17d20d8d authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman
Browse files

DS push: fix querying parent SOA if CNAME present at non-terminal

parent 7f8a4bec
Branches
Tags
1 merge request!1387DS push: fix querying parent SOA if CNAME present at non-terminal
Pipeline #90393 passed with stages
in 5 minutes and 9 seconds
/* Copyright (C) 2019 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
......@@ -25,6 +25,7 @@
struct ds_push_data {
const knot_dname_t *zone;
const knot_dname_t *parent_query;
knot_dname_t *parent_soa;
knot_rrset_t del_old_ds;
knot_rrset_t new_ds;
......@@ -49,9 +50,10 @@ static int ds_push_begin(knot_layer_t *layer, void *params)
static int parent_soa_produce(struct ds_push_data *data, knot_pkt_t *pkt)
{
const knot_dname_t *query_name = knot_wire_next_label(data->zone, NULL);
assert(data->parent_query[0] != '\0');
data->parent_query = knot_wire_next_label(data->parent_query, NULL);
int ret = knot_pkt_put_question(pkt, query_name, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
int ret = knot_pkt_put_question(pkt, data->parent_query, KNOT_CLASS_IN, KNOT_RRTYPE_SOA);
if (ret != KNOT_EOK) {
return KNOT_STATE_FAIL;
}
......@@ -123,18 +125,20 @@ static int ds_push_consume(knot_layer_t *layer, knot_pkt_t *pkt)
}
const knot_rrset_t *parent_soa = sect_soa(pkt, KNOT_ANSWER);
if (parent_soa == NULL) {
parent_soa = sect_soa(pkt, KNOT_AUTHORITY);
if (parent_soa != NULL) {
// parent SOA obtained, continue with DS push
data->parent_soa = knot_dname_copy(parent_soa->owner, NULL);
return KNOT_STATE_RESET;
}
if (parent_soa == NULL) {
if (data->parent_query[0] == '\0') {
// query for parent SOA systematicly fails
DS_PUSH_LOG(LOG_WARNING, data->zone, data->remote,
"malformed message");
"unable to query parent SOA");
return KNOT_STATE_FAIL;
}
data->parent_soa = knot_dname_copy(parent_soa->owner, NULL);
return KNOT_STATE_RESET;
return KNOT_STATE_RESET; // cut off one more label and re-query
}
static int ds_push_reset(knot_layer_t *layer)
......@@ -170,6 +174,7 @@ static int send_ds_push(conf_t *conf, zone_t *zone,
struct ds_push_data data = {
.zone = zone->name,
.parent_query = zone->name,
.new_ds = zone_cds,
.remote = (struct sockaddr *)&parent->addr,
};
......
......@@ -4,3 +4,4 @@ $TTL 1200
@ SOA ns admin 20110100 7 7 16 600
ns AAAA ::0
example.com. CNAME intentionally.disruptive.cname.
example.com. 3 SOA dns1.example.com. hostmaster.example.com. 2010111227 21600 3600 604800 3
example.com. 0 NS dns1.example.com.
example.com. 2 MX 10 mail.example.com.
dns1.example.com. 4 A 192.0.2.1
dns1.example.com. 3 AAAA 2001:db8::1
foo.example.com. 5 A 192.0.2.4
mail.example.com. 3 A 192.0.2.3
mail.example.com. 1 AAAA 2001:db8::3
sub.example.com. 3 SOA dns1 hostmaster 2010111227 21600 3600 604800 3
sub.example.com. 0 NS dns1
sub.example.com. 2 MX 10 mail
dns1 4 A 192.0.2.1
dns1 3 AAAA 2001:db8::1
foo 5 A 192.0.2.4
mail 3 A 192.0.2.3
mail 1 AAAA 2001:db8::3
......@@ -15,6 +15,8 @@ from dnstest.utils import *
from dnstest.keys import Keymgr
from dnstest.test import Test
ZONE = "sub.example.com."
def pregenerate_key(server, zone, alg):
class a_class_with_name:
def __init__(self, name):
......@@ -25,16 +27,16 @@ def pregenerate_key(server, zone, alg):
# check zone if keys are present and used for signing
def check_zone(server, zone, dnskeys, dnskey_rrsigs, cdnskeys, soa_rrsigs, msg):
qdnskeys = server.dig("example.com", "DNSKEY", bufsize=4096)
qdnskeys = server.dig(ZONE, "DNSKEY", bufsize=4096)
found_dnskeys = qdnskeys.count("DNSKEY")
qdnskeyrrsig = server.dig("example.com", "DNSKEY", dnssec=True, bufsize=4096)
qdnskeyrrsig = server.dig(ZONE, "DNSKEY", dnssec=True, bufsize=4096)
found_rrsigs = qdnskeyrrsig.count("RRSIG")
qcdnskey = server.dig("example.com", "CDNSKEY", bufsize=4096)
qcdnskey = server.dig(ZONE, "CDNSKEY", bufsize=4096)
found_cdnskeys = qcdnskey.count("CDNSKEY")
qsoa = server.dig("example.com", "SOA", dnssec=True, bufsize=4096)
qsoa = server.dig(ZONE, "SOA", dnssec=True, bufsize=4096)
found_soa_rrsigs = qsoa.count("RRSIG")
check_log("DNSKEYs: %d (expected %d)" % (found_dnskeys, dnskeys));
......@@ -66,7 +68,7 @@ def check_zone(server, zone, dnskeys, dnskey_rrsigs, cdnskeys, soa_rrsigs, msg):
def wait_for_rrsig_count(t, server, rrtype, rrsig_count, timeout):
rtime = 0.0
while True:
qdnskeyrrsig = server.dig("example.com", rrtype, dnssec=True, bufsize=4096)
qdnskeyrrsig = server.dig(ZONE, rrtype, dnssec=True, bufsize=4096)
found_rrsigs = qdnskeyrrsig.count("RRSIG")
if found_rrsigs == rrsig_count:
break
......@@ -78,7 +80,7 @@ def wait_for_rrsig_count(t, server, rrtype, rrsig_count, timeout):
def wait_for_dnskey_count(t, server, dnskey_count, timeout):
rtime = 0.0
while True:
qdnskeyrrsig = server.dig("example.com", "DNSKEY", dnssec=True, bufsize=4096)
qdnskeyrrsig = server.dig(ZONE, "DNSKEY", dnssec=True, bufsize=4096)
found_dnskeys = qdnskeyrrsig.count("DNSKEY")
if found_dnskeys == dnskey_count:
break
......@@ -107,7 +109,7 @@ t.link(parent_zone, parent, ddns=True)
parent.dnssec(parent_zone).enable = True
child = t.server("knot")
child_zone = t.zone("example.com.", storage=".")
child_zone = t.zone(ZONE, storage=".")
t.link(child_zone, child)
child.zonefile_sync = 24 * 60 * 60
......@@ -125,9 +127,6 @@ child.dnssec(child_zone).ds_push = parent
child.dnssec(child_zone).ksk_shared = True
child.dnssec(child_zone).cds_publish = "always"
# parameters
ZONE = "example.com."
#t.start()
t.generate_conf()
parent.start()
......@@ -140,7 +139,7 @@ t.sleep(5)
pregenerate_key(child, child_zone, "ECDSAP256SHA256")
watch_ksk_rollover(t, child, child_zone, 2, 2, 3, "KSK rollover")
resp = parent.dig("example.com.", "DS")
resp = parent.dig(ZONE, "DS")
resp.check_count(1, rtype="DS")
t.end()
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