@ IN MX 0 mail
ns IN A 10.53.0.6
mail IN A 10.53.0.6
+www IN HTTPS 0 http-server
+http-server IN A 10.53.0.6
+https-loop IN HTTPS 0 https-next
+https-loop IN A 10.53.0.6
+https-next IN HTTPS 0 https-loop
+https-next IN A 10.53.0.7
+https-cname IN HTTPS 0 cname-server
+cname-server IN CNAME cname-next
+cname-next IN CNAME http-server
+https-cname-loop IN HTTPS 0 https-cname-loop0
+https-cname-loop0 IN CNAME https-cname-loop0
fetch 10 IN TXT A short ttl
non-zero 10 IN TXT A short ttl
zero 0 IN TXT A zero ttl
* has a exclude list.
*/
root-delegation-only exclude { "a"; };
+ max-udp-size 4096;
};
zone "." {
*/
prefetch 0;
querylog yes;
+ edns-udp-size 4096;
};
key rndc_key {
*/
prefetch 0;
querylog yes;
+ edns-udp-size 4096;
};
key rndc_key {
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
+n=`expr $n + 1`
+echo_i "check that the addition section for HTTPS is populated on initial query to a recursive server ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.7 www.example.net https > dig.out.ns7.${n} || ret=1
+grep "status: NOERROR" dig.out.ns7.${n} > /dev/null || ret=1
+grep "flags:[^;]* ra[ ;]" dig.out.ns7.${n} > /dev/null || ret=1
+grep "ADDITIONAL: 2" dig.out.ns7.${n} > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.ns7.${n} > /dev/null || ret=1
+grep "http-server\.example\.net\..*A.*10\.53\.0\.6" dig.out.ns7.${n} > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check HTTPS loop is handled properly ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.7 https-loop.example.net https > dig.out.ns7.${n} || ret=1
+grep "status: NOERROR" dig.out.ns7.${n} > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.ns7.${n} > /dev/null || ret=1
+grep "ADDITIONAL: 2" dig.out.ns7.${n} > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check HTTPS -> CNAME loop is handled properly ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.7 https-cname-loop.example.net https > dig.out.ns7.${n} || ret=1
+grep "status: NOERROR" dig.out.ns7.${n} > /dev/null || ret=1
+grep "ADDITIONAL: 2" dig.out.ns7.${n} > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.ns7.${n} > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check HTTPS cname chains are followed ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.7 https-cname.example.net https > dig.out.ns7.${n} || ret=1
+grep "status: NOERROR" dig.out.ns7.${n} > /dev/null || ret=1
+grep "ADDITIONAL: 4" dig.out.ns7.${n} > /dev/null || ret=1
+grep 'http-server\.example\.net\..*A.10\.53\.0\.6' dig.out.ns7.${n} > /dev/null || ret=1
+grep 'cname-server\.example\.net\..*CNAME.cname-next\.example\.net\.' dig.out.ns7.${n} > /dev/null || ret=1
+grep 'cname-next\.example\.net\..*CNAME.http-server\.example\.net\.' dig.out.ns7.${n} > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
#define COMPARETYPE "rdata1->type"
#define COMPAREDEF "use_default = true"
-#define ADDITIONALDATAARGS "rdata, add, arg"
+#define ADDITIONALDATAARGS "rdata, owner, add, arg"
#define ADDITIONALDATACLASS "rdata->rdclass"
#define ADDITIONALDATATYPE "rdata->type"
#define ADDITIONALDATADEF "use_default = true"
*/
isc_result_t
-dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
- void *arg);
+dns_rdata_additionaldata(dns_rdata_t *rdata, const dns_name_t *owner,
+ dns_additionaldatafunc_t add, void *arg);
/*%<
* Call 'add' for each name and type from 'rdata' which is subject to
* additional section processing.
isc_result_t
dns_rdataset_additionaldata(dns_rdataset_t * rdataset,
+ const dns_name_t * owner_name,
dns_additionaldatafunc_t add, void *arg);
/*%<
* For each rdata in rdataset, call 'add' for each name and type in the
dns_rdataset_t *);
typedef isc_result_t (*dns_additionaldatafunc_t)(void *, const dns_name_t *,
- dns_rdatatype_t);
+ dns_rdatatype_t,
+ dns_rdataset_t *);
typedef isc_result_t (*dns_digestfunc_t)(void *, isc_region_t *);
}
static isc_result_t
-glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
+glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
+ dns_rdataset_t *unused) {
rbtdb_glue_additionaldata_ctx_t *ctx;
isc_result_t result;
dns_fixedname_t fixedname_a;
rbtdb_glue_t *glue = NULL;
dns_name_t *gluename = NULL;
+ UNUSED(unused);
+
/*
* NS records want addresses in additional records.
*/
maybe_rehash_gluetable(rbtversion);
idx = hash_32(hash, rbtversion->glue_table_bits);
- (void)dns_rdataset_additionaldata(rdataset, glue_nsdname_cb, &ctx);
+ (void)dns_rdataset_additionaldata(rdataset, dns_rootname,
+ glue_nsdname_cb, &ctx);
cur = isc_mem_get(rbtdb->common.mctx, sizeof(*cur));
#include <dns/compress.h>
#include <dns/dsdigest.h>
#include <dns/enumtype.h>
+#include <dns/fixedname.h>
#include <dns/keyflags.h>
#include <dns/keyvalues.h>
#include <dns/message.h>
#include <dns/rcode.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
+#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/rdatatype.h>
#include <dns/result.h>
#define CALL_FREESTRUCT source
-#define ARGS_ADDLDATA \
- dns_rdata_t *rdata, dns_additionaldatafunc_t add, void *arg
+#define ARGS_ADDLDATA \
+ dns_rdata_t *rdata, const dns_name_t *owner, \
+ dns_additionaldatafunc_t add, void *arg
-#define CALL_ADDLDATA rdata, add, arg
+#define CALL_ADDLDATA rdata, owner, add, arg
#define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
}
isc_result_t
-dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
- void *arg) {
+dns_rdata_additionaldata(dns_rdata_t *rdata, const dns_name_t *owner,
+ dns_additionaldatafunc_t add, void *arg) {
isc_result_t result = ISC_R_NOTIMPLEMENTED;
bool use_default = false;
REQUIRE(rdata->rdclass == dns_rdataclass_any);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_ch);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_afsdb);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
isc_region_consume(®ion, 2);
dns_name_fromregion(&name, ®ion);
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_amtrelay);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_avc);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->length >= 3U);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_cdnskey);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_cds);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_cert);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
static inline isc_result_t
additionaldata_cname(ARGS_ADDLDATA) {
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_csync);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_dlv);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
static inline isc_result_t
additionaldata_dname(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_dname);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_dname);
-
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_dnskey);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
static inline isc_result_t
additionaldata_doa(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_doa);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_doa);
-
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_ds);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->length == 6);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->length == 8);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_gpos);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
additionaldata_hinfo(ARGS_ADDLDATA) {
REQUIRE(rdata->type == dns_rdatatype_hinfo);
+ UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- UNUSED(rdata);
return (ISC_R_SUCCESS);
}
static inline isc_result_t
additionaldata_hip(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_hip);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_hip);
-
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_ipseckey);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_isdn);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_key);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_keydata);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->length == 6);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->length == 10);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_loc);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_lp);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
isc_region_consume(®ion, 2);
dns_name_fromregion(&name, ®ion);
- result = (add)(arg, &name, dns_rdatatype_l32);
+ result = (add)(arg, &name, dns_rdatatype_l32, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
- return ((add)(arg, &name, dns_rdatatype_l64));
+ return ((add)(arg, &name, dns_rdatatype_l64, NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_mb);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_md);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_mf);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
UNUSED(add);
UNUSED(arg);
UNUSED(rdata);
+ UNUSED(owner);
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_minfo);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_mr);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_mx);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
isc_region_consume(®ion, 2);
return (ISC_R_SUCCESS);
}
- result = (add)(arg, &name, dns_rdatatype_a);
+ result = (add)(arg, &name, dns_rdatatype_a, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
- return ((add)(arg, dns_fixedname_name(&fixed), dns_rdatatype_tlsa));
+ return ((add)(arg, dns_fixedname_name(&fixed), dns_rdatatype_tlsa,
+ NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_naptr);
+ UNUSED(owner);
+
/*
* Order, preference.
*/
dns_name_fromregion(&name, &sr);
if (atype != 0) {
- return ((add)(arg, &name, atype));
+ return ((add)(arg, &name, atype, NULL));
}
return (ISC_R_SUCCESS);
REQUIRE(rdata->length == 10);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_ninfo);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_ns);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
dns_name_fromregion(&name, ®ion);
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_nsec3);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_nsec3param);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_nsec);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
static inline isc_result_t
additionaldata_null(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_null);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_null);
-
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_nxt);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_openpgpkey);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_opt);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_proforma.c #);
REQUIRE(rdata->rdclass == #);
- (void)add;
- (void)arg;
+ UNUSED(owner);
+ UNUSED(add);
+ UNUSED(arg);
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_ptr);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_rkey);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_rp);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_rrsig);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_rt);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
isc_region_consume(®ion, 2);
dns_name_fromregion(&name, ®ion);
- result = (add)(arg, &name, dns_rdatatype_x25);
+ result = (add)(arg, &name, dns_rdatatype_x25, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
- result = (add)(arg, &name, dns_rdatatype_isdn);
+ result = (add)(arg, &name, dns_rdatatype_isdn, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
REQUIRE(rdata->type == dns_rdatatype_sig);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_sink);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_smimea);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
static inline isc_result_t
additionaldata_soa(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_soa);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_soa);
-
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_spf);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_sshfp);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_ta);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
static inline isc_result_t
additionaldata_talink(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_talink);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_talink);
-
return (ISC_R_SUCCESS);
}
static inline isc_result_t
additionaldata_tkey(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_tkey);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_tkey);
-
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->type == dns_rdatatype_tlsa);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_txt);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_uri);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_x25);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_zonemd);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_hs);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_apl);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
- (void)add;
- (void)arg;
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(add);
+ UNUSED(arg);
return (ISC_R_SUCCESS);
}
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
#ifndef RDATA_IN_1_HTTPS_65_C
#define RDATA_IN_1_HTTPS_65_C
-#define RRTYPE_HTTPS_ATTRIBUTES 0
+#define RRTYPE_HTTPS_ATTRIBUTES (DNS_RDATATYPEATTR_FOLLOWADDITIONAL)
/*
* Most of these functions refer to equivalent functions for SVCB,
REQUIRE(rdata->type == dns_rdatatype_kx);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
isc_region_consume(®ion, 2);
dns_name_fromregion(&name, ®ion);
- return ((add)(arg, &name, dns_rdatatype_a));
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
REQUIRE(rdata->type == dns_rdatatype_srv);
REQUIRE(rdata->rdclass == dns_rdataclass_in);
+ UNUSED(owner);
+
dns_name_init(&name, offsets);
dns_rdata_toregion(rdata, ®ion);
isc_region_consume(®ion, 4);
return (ISC_R_SUCCESS);
}
- result = (add)(arg, &name, dns_rdatatype_a);
+ result = (add)(arg, &name, dns_rdatatype_a, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
- return ((add)(arg, dns_fixedname_name(&fixed), dns_rdatatype_tlsa));
+ return ((add)(arg, dns_fixedname_name(&fixed), dns_rdatatype_tlsa,
+ NULL));
}
static inline isc_result_t
#ifndef RDATA_IN_1_SVCB_64_C
#define RDATA_IN_1_SVCB_64_C
-#define RRTYPE_SVCB_ATTRIBUTES 0
+#define RRTYPE_SVCB_ATTRIBUTES (DNS_RDATATYPEATTR_FOLLOWADDITIONAL)
#define SVCB_MAN_KEY 0
#define SVCB_ALPN_KEY 1
#define SVCB_NO_DEFAULT_ALPN_KEY 2
+#define MAX_CNAMES 16 /* See ns/query.c MAX_RESTARTS */
/*
* Service Binding Parameter Registry
static inline isc_result_t
generic_additionaldata_in_svcb(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
+ bool alias, done = false;
+ dns_fixedname_t fixed;
+ dns_name_t name, *fname = NULL;
+ dns_offsets_t offsets;
+ dns_rdataset_t rdataset;
+ isc_region_t region;
+ unsigned int cnames = 0;
- return (ISC_R_SUCCESS);
+ dns_name_init(&name, offsets);
+ dns_rdata_toregion(rdata, ®ion);
+ alias = uint16_fromregion(®ion) == 0;
+ isc_region_consume(®ion, 2);
+
+ dns_name_fromregion(&name, ®ion);
+
+ if (dns_name_equal(&name, dns_rootname)) {
+ /*
+ * "." only means owner name in service form.
+ */
+ if (alias || dns_name_equal(owner, dns_rootname) ||
+ !dns_name_ishostname(owner, false))
+ {
+ return (ISC_R_SUCCESS);
+ }
+ /* Only lookup address records */
+ return ((add)(arg, owner, dns_rdatatype_a, NULL));
+ }
+
+ /*
+ * Follow CNAME chains when processing HTTPS and SVCB records.
+ */
+ dns_rdataset_init(&rdataset);
+ fname = dns_fixedname_initname(&fixed);
+ do {
+ RETERR((add)(arg, &name, dns_rdatatype_cname, &rdataset));
+ if (dns_rdataset_isassociated(&rdataset)) {
+ isc_result_t result;
+ result = dns_rdataset_first(&rdataset);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdata_t current = DNS_RDATA_INIT;
+ dns_rdata_cname_t cname;
+
+ dns_rdataset_current(&rdataset, ¤t);
+
+ result = dns_rdata_tostruct(¤t, &cname,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ dns_name_copy(&cname.cname, fname);
+ dns_name_clone(fname, &name);
+ } else {
+ done = true;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ } else {
+ done = true;
+ }
+ /*
+ * Stop following a potentially infinite CNAME chain.
+ */
+ if (!done && cnames++ > MAX_CNAMES) {
+ return (ISC_R_SUCCESS);
+ }
+ } while (!done);
+
+ /*
+ * Look up HTTPS/SVCB records when processing the alias form.
+ */
+ if (alias) {
+ RETERR((add)(arg, &name, rdata->type, &rdataset));
+ /*
+ * Don't return A or AAAA if this is not the last element
+ * in the HTTP / SVCB chain.
+ */
+ if (dns_rdataset_isassociated(&rdataset)) {
+ dns_rdataset_disassociate(&rdataset);
+ return (ISC_R_SUCCESS);
+ }
+ }
+ return ((add)(arg, &name, dns_rdatatype_a, NULL));
}
static inline isc_result_t
static inline isc_result_t
additionaldata_in_wks(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == dns_rdatatype_wks);
+ REQUIRE(rdata->rdclass == dns_rdataclass_in);
+
UNUSED(rdata);
+ UNUSED(owner);
UNUSED(add);
UNUSED(arg);
- REQUIRE(rdata->type == dns_rdatatype_wks);
- REQUIRE(rdata->rdclass == dns_rdataclass_in);
-
return (ISC_R_SUCCESS);
}
isc_result_t
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
+ const dns_name_t *owner_name,
dns_additionaldatafunc_t add, void *arg) {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
do {
dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_additionaldata(&rdata, add, arg);
+ result = dns_rdata_additionaldata(&rdata, owner_name, add, arg);
if (result == ISC_R_SUCCESS) {
result = dns_rdataset_next(rdataset);
}
static isc_result_t
check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
- dns_section_t section) {
+ dns_rdataset_t *found, dns_section_t section) {
respctx_t *rctx = arg;
fetchctx_t *fctx = rctx->fctx;
isc_result_t result;
result = dns_message_findtype(name, type, 0, &rdataset);
if (result == ISC_R_SUCCESS) {
mark_related(name, rdataset, external, gluing);
+ if (found != NULL) {
+ dns_rdataset_clone(rdataset, found);
+ }
/*
* Do we have its SIG too?
*/
}
static isc_result_t
-check_related(void *arg, const dns_name_t *addname, dns_rdatatype_t type) {
- return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL));
+check_related(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
+ dns_rdataset_t *found) {
+ return (check_section(arg, addname, type, found,
+ DNS_SECTION_ADDITIONAL));
}
#ifndef CHECK_FOR_GLUE_IN_ANSWER
#if CHECK_FOR_GLUE_IN_ANSWER
static isc_result_t
-check_answer(void *arg, const dns_name_t *addname, dns_rdatatype_t type) {
- return (check_section(arg, addname, type, DNS_SECTION_ANSWER));
+check_answer(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
+ dns_rdataset_t *found) {
+ return (check_section(arg, addname, type, found, DNS_SECTION_ANSWER));
}
#endif /* if CHECK_FOR_GLUE_IN_ANSWER */
rdataset->attributes |= DNS_RDATASETATTR_CACHE;
rdataset->trust = rctx->trust;
- (void)dns_rdataset_additionaldata(rdataset, check_related,
- rctx);
+ (void)dns_rdataset_additionaldata(rdataset, rctx->aname,
+ check_related, rctx);
}
return (ISC_R_SUCCESS);
rctx->ardataset->attributes |= DNS_RDATASETATTR_ANSWER;
rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE;
rctx->ardataset->trust = rctx->trust;
- (void)dns_rdataset_additionaldata(rctx->ardataset, check_related, rctx);
+ (void)dns_rdataset_additionaldata(rctx->ardataset, rctx->aname,
+ check_related, rctx);
for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list);
sigrdataset != NULL;
* to this rdataset.
*/
(void)dns_rdataset_additionaldata(
- rdataset, check_related, rctx);
+ rdataset, name, check_related,
+ rctx);
done = true;
}
}
*/
INSIST(rctx->ns_rdataset != NULL);
FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
- (void)dns_rdataset_additionaldata(rctx->ns_rdataset, check_related,
- rctx);
+ (void)dns_rdataset_additionaldata(rctx->ns_rdataset, rctx->ns_name,
+ check_related, rctx);
#if CHECK_FOR_GLUE_IN_ANSWER
/*
* Look in the answer section for "glue" that is incorrectly
if (rctx->glue_in_answer &&
(fctx->type == dns_rdatatype_aaaa || fctx->type == dns_rdatatype_a))
{
- (void)dns_rdataset_additionaldata(rctx->ns_rdataset,
- check_answer, fctx);
+ (void)dns_rdataset_additionaldata(
+ rctx->ns_rdataset, rctx->ns_name, check_answer, fctx);
}
#endif /* if CHECK_FOR_GLUE_IN_ANSWER */
FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING);
if (CHASE(rdataset)) {
rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
(void)dns_rdataset_additionaldata(
- rdataset, check_related, rctx);
+ rdataset, name, check_related, rctx);
rescan = true;
}
}
}
static isc_result_t
-additionaldata_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
+additionaldata_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
+ dns_rdataset_t *found) {
UNUSED(arg);
UNUSED(name);
UNUSED(qtype);
+ UNUSED(found);
return (ISC_R_SUCCESS);
}
*/
static isc_result_t
rdata_additionadata(dns_rdata_t *rdata) {
- return (dns_rdata_additionaldata(rdata, additionaldata_cb, NULL));
+ return (dns_rdata_additionaldata(rdata, dns_rootname, additionaldata_cb,
+ NULL));
}
/*
client->udpsize = 512;
client->extflags = 0;
client->ednsversion = -1;
+ client->additionaldepth = 0;
dns_ecs_init(&client->ecs);
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
uint16_t udpsize;
uint16_t extflags;
int16_t ednsversion; /* -1 noedns */
+ uint16_t additionaldepth;
void (*cleanup)(ns_client_t *);
void (*shutdown)(void *arg, isc_result_t result);
void * shutdown_arg;
}
static isc_result_t
-query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
+query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype,
+ dns_rdataset_t *found) {
query_ctx_t *qctx = arg;
ns_client_t *client = qctx->client;
isc_result_t result, eresult = ISC_R_SUCCESS;
*/
ns_client_keepname(client, fname, dbuf);
+ /*
+ * Does the caller want the found rdataset?
+ */
+ if (found != NULL && dns_rdataset_isassociated(rdataset)) {
+ dns_rdataset_clone(rdataset, found);
+ }
+
/*
* If we have an rdataset, add it to the additional data
* section.
dns_message_addname(client->message, fname,
DNS_SECTION_ADDITIONAL);
}
- fname = NULL;
/*
* In some cases, a record that has been added as additional
* This cannot go more than MAX_RESTARTS levels deep.
*/
if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
- eresult = dns_rdataset_additionaldata(
- trdataset, query_additional_cb, qctx);
+ if (client->additionaldepth++ < MAX_RESTARTS) {
+ eresult = dns_rdataset_additionaldata(
+ trdataset, fname, query_additional_cb, qctx);
+ }
+ client->additionaldepth--;
}
+ /*
+ * Don't release fname.
+ */
+ fname = NULL;
+
cleanup:
CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: cleanup");
ns_client_putrdataset(client, &rdataset);
* Handle glue and fetch any other needed additional data for 'rdataset'.
*/
static void
-query_additional(query_ctx_t *qctx, dns_rdataset_t *rdataset) {
+query_additional(query_ctx_t *qctx, dns_name_t *name,
+ dns_rdataset_t *rdataset) {
ns_client_t *client = qctx->client;
isc_result_t result;
* Add other additional data if needed.
* We don't care if dns_rdataset_additionaldata() fails.
*/
- (void)dns_rdataset_additionaldata(rdataset, query_additional_cb, qctx);
+ (void)dns_rdataset_additionaldata(rdataset, name, query_additional_cb,
+ qctx);
CTRACE(ISC_LOG_DEBUG(3), "query_additional: done");
}
*/
query_addtoname(mname, rdataset);
query_setorder(qctx, mname, rdataset);
- query_additional(qctx, rdataset);
+ query_additional(qctx, mname, rdataset);
/*
* Note: we only add SIGs if we've added the type they cover, so