zones. Now it also applies to downstream configured auth zones.
goto send_reply;
}
if(worker->env.auth_zones &&
- auth_zones_answer(worker->env.auth_zones, &worker->env,
- &qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
+ auth_zones_downstream_answer(worker->env.auth_zones,
+ &worker->env, &qinfo, &edns, repinfo, c->buffer,
+ worker->scratchpad)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
/* If we've found a local alias, replace the qname with the alias
* target before resolving it. */
if(qinfo.local_alias) {
- struct ub_packed_rrset_key* rrset = qinfo.local_alias->rrset;
- struct packed_rrset_data* d = rrset->entry.data;
-
- /* Sanity check: our current implementation only supports
- * a single CNAME RRset as a local alias. */
- if(qinfo.local_alias->next ||
- rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) ||
- d->count != 1) {
- log_err("assumption failure: unexpected local alias");
+ if(!local_alias_shallow_copy_qname(qinfo.local_alias, &qinfo.qname,
+ &qinfo.qname_len)) {
regional_free_all(worker->scratchpad);
return 0; /* drop it */
}
- qinfo.qname = d->rr_data[0] + 2;
- qinfo.qname_len = d->rr_len[0] - 2;
}
/* If we may apply IP-based actions to the answer, build the client
+17 June 2025: Yorgos
+ - Fix for consistent use of local zone CNAME alias for configured auth
+ zones. Now it also applies to downstream configured auth zones.
+
16 June 2025: Wouter
- Fix to check control-interface addresses in unbound-checkconf.
- Fix #1295: Windows 32-bit binaries download seems to be missing dll
free(qinfo.qname);
return UB_NOERROR;
}
- if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
- w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
+ if(ctx->env->auth_zones && auth_zones_downstream_answer(
+ ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
+ w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL, 0);
w->back->udp_buff, sec_status_insecure, NULL, 0);
return UB_NOERROR;
}
- if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
- w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
+ if(ctx->env->auth_zones && auth_zones_downstream_answer(
+ ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
+ w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
free(qinfo.qname);
return;
}
- if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
- w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
+ if(w->ctx->env->auth_zones && auth_zones_downstream_answer(
+ w->ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
+ w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
q->msg_security = sec_status_insecure;
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
sldns_buffer_read_u16_at(buf, 2), edns);
}
-int auth_zones_answer(struct auth_zones* az, struct module_env* env,
+int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
- struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp)
+ struct comm_reply* repinfo, struct sldns_buffer* buf,
+ struct regional* temp)
{
struct dns_msg* msg = NULL;
struct auth_zone* z;
int r;
int fallback = 0;
+ /* Copy the qinfo in case of cname aliasing from local-zone */
+ struct query_info zqinfo = *qinfo;
lock_rw_rdlock(&az->lock);
if(!az->have_downstream) {
lock_rw_unlock(&az->lock);
return 0;
}
+
if(qinfo->qtype == LDNS_RR_TYPE_DS) {
uint8_t* delname = qinfo->qname;
size_t delnamelen = qinfo->qname_len;
z = auth_zones_find_zone(az, delname, delnamelen,
qinfo->qclass);
} else {
- z = auth_zones_find_zone(az, qinfo->qname, qinfo->qname_len,
- qinfo->qclass);
+ if(zqinfo.local_alias && !local_alias_shallow_copy_qname(
+ zqinfo.local_alias, &zqinfo.qname,
+ &zqinfo.qname_len)) {
+ lock_rw_unlock(&az->lock);
+ return 0;
+ }
+ z = auth_zones_find_zone(az, zqinfo.qname, zqinfo.qname_len,
+ zqinfo.qclass);
}
if(!z) {
/* no zone above it */
}
/* answer it from zone z */
- r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
+ r = auth_zone_generate_answer(z, &zqinfo, temp, &msg, &fallback);
lock_rw_unlock(&z->lock);
if(!r && fallback) {
/* fallback to regular answering (recursive) */
* @param temp: temporary storage region.
* @return false if not answered
*/
-int auth_zones_answer(struct auth_zones* az, struct module_env* env,
+int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
- struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
+ struct comm_reply* repinfo, struct sldns_buffer* buf,
+ struct regional* temp);
/**
* Find the auth zone that is above the given qname.
local-zone: synth.cname redirect
local-data: "synth.cname. IN CNAME *.from.resolution."
+ # CNAME is pointing to a downstream auth zone
+ local-zone: authdown.example.net. redirect
+ local-data: "authdown.example.net. IN CNAME downstream.zone."
+
+ # CNAME is pointing to an upstream auth zone
+ local-zone: authup.example.net. redirect
+ local-data: "authup.example.net. IN CNAME upstream.zone."
+
### template zone and tag intended to be used for tests with CNAME and
### other data.
##local-zone: ambiguous.example.com redirect
##@TAGDATA1@
##@TAGDATA2@
-
-
target-fetch-policy: "0 0 0 0 0"
# send the queries to the test server (see the 10.0.10.3 entries below)
forward-zone:
name: "."
forward-addr: 10.0.10.3
+
+auth-zone:
+ name: "downstream.zone."
+ for-downstream: yes
+ for-upstream: no
+ fallback-enabled: no
+ ## this line generates zonefile: \n"/tmp/xxx.downstream.zone"\n
+ zonefile:
+TEMPFILE_NAME downstream.zone
+ ## this is the inline file /tmp/xxx.downstream.zone
+ ## the tempfiles are deleted when the testrun is over.
+TEMPFILE_CONTENTS downstream.zone
+$ORIGIN downstream.zone.
+@ 3600 IN SOA a b 1 2 3 4 5
+@ IN TXT "hello from downstream auth zone"
+TEMPFILE_END
+
+server: domain-insecure: upstream.zone.
+auth-zone:
+ name: "upstream.zone."
+ for-downstream: no
+ for-upstream: yes
+ fallback-enabled: no
+ ## this line generates zonefile: \n"/tmp/xxx.upstream.zone"\n
+ zonefile:
+TEMPFILE_NAME upstream.zone
+ ## this is the inline file /tmp/xxx.upstream.zone
+ ## the tempfiles are deleted when the testrun is over.
+TEMPFILE_CONTENTS upstream.zone
+$ORIGIN upstream.zone.
+@ 3600 IN SOA a b 1 2 3 4 5
+@ IN TXT "hello from upstream auth zone"
+TEMPFILE_END
CONFIG_END
; short one-line description of scenario:
SECTION ADDITIONAL
ENTRY_END
+STEP 290 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+authdown.example.net. IN TXT
+ENTRY_END
+
+STEP 300 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+authdown.example.net. IN TXT
+SECTION ANSWER
+authdown.example.net. IN CNAME downstream.zone.
+downstream.zone. IN TXT "hello from downstream auth zone"
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 310 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+authup.example.net. IN TXT
+ENTRY_END
+
+STEP 320 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+authup.example.net. IN TXT
+SECTION ANSWER
+authup.example.net. IN CNAME upstream.zone.
+upstream.zone. IN TXT "hello from upstream auth zone"
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
SCENARIO_END
}
return NULL;
}
+
+int local_alias_shallow_copy_qname(struct local_rrset* local_alias, uint8_t** qname,
+ size_t* qname_len)
+{
+ struct ub_packed_rrset_key* rrset = local_alias->rrset;
+ struct packed_rrset_data* d = rrset->entry.data;
+
+ /* Sanity check: our current implementation only supports
+ * a single CNAME RRset as a local alias. */
+ if(local_alias->next ||
+ rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) ||
+ d->count != 1) {
+ log_err("assumption failure: unexpected local alias");
+ return 0;
+ }
+ *qname = d->rr_data[0] + 2;
+ *qname_len = d->rr_len[0] - 2;
+ return 1;
+}
*/
int edns_opt_list_compare(struct edns_option* p, struct edns_option* q);
+/**
+ * Swallow copy the local_alias into the given qname and qname_len.
+ * @param local_alias: the local_alias.
+ * @param qname: the qname to copy to.
+ * @param qname_len: the qname_len to copy to.
+ * @return false on current local_alias assumptions, true otherwise.
+ */
+int local_alias_shallow_copy_qname(struct local_rrset* local_alias, uint8_t** qname,
+ size_t* qname_len);
+
#endif /* UTIL_DATA_MSGREPLY_H */