mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-18 10:09:27 -05:00
libunbound: add interface for reading authority response sections
Adds support to libunbound for accessing the AUTHORITY section of a DNS response. This allows the client to read NS records from non-authoritative, non-recursive nameservers (such as a TLD.)
This commit is contained in:
parent
6c82f4ae9b
commit
d42138976d
2 changed files with 72 additions and 0 deletions
|
|
@ -520,6 +520,57 @@ fill_res(struct ub_result* res, struct ub_packed_rrset_key* answer,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** fill authority_data into result */
|
||||
static int
|
||||
fill_res_authority(struct ub_result* res, struct ub_packed_rrset_key* answer,
|
||||
struct query_info* rq, struct reply_info* rep)
|
||||
{
|
||||
size_t i;
|
||||
struct packed_rrset_data* authority_data;
|
||||
res->authority_ttl = 0;
|
||||
if(!answer) {
|
||||
if(rep->rrset_count != 0)
|
||||
res->authority_ttl = (int)rep->ttl;
|
||||
res->authority_data = (char**)calloc(1, sizeof(char*));
|
||||
res->authority_len = (int*)calloc(1, sizeof(int));
|
||||
return (res->authority_data && res->authority_len);
|
||||
}
|
||||
authority_data = (struct packed_rrset_data*)answer->entry.data;
|
||||
if(query_dname_compare(rq->qname, answer->rk.dname) != 0) {
|
||||
if(!fill_canon(res, answer->rk.dname))
|
||||
return 0; /* out of memory */
|
||||
} else res->canonname = NULL;
|
||||
res->authority_data = (char**)calloc(authority_data->count+1, sizeof(char*));
|
||||
res->authority_len = (int*)calloc(authority_data->count+1, sizeof(int));
|
||||
if(!res->authority_data || !res->authority_len)
|
||||
return 0; /* out of memory */
|
||||
for(i=0; i<authority_data->count; i++) {
|
||||
/* remove rdauthority_length from rauthority_data */
|
||||
res->authority_len[i] = (int)(authority_data->rr_len[i] - 2);
|
||||
res->authority_data[i] = memdup(authority_data->rr_data[i]+2, (size_t)res->authority_len[i]);
|
||||
if(!res->authority_data[i])
|
||||
return 0; /* out of memory */
|
||||
}
|
||||
/* authority_ttl for positive answers, from CNAME and answer RRs */
|
||||
if(authority_data->count != 0) {
|
||||
size_t j;
|
||||
res->authority_ttl = (int)authority_data->ttl;
|
||||
for(j=0; j<rep->ns_numrrsets; j++) {
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)rep->rrsets[rep->an_numrrsets + j]->
|
||||
entry.data;
|
||||
if((int)d->ttl < res->authority_ttl)
|
||||
res->authority_ttl = (int)d->ttl;
|
||||
}
|
||||
}
|
||||
/* authority_ttl for negative answers */
|
||||
if(authority_data->count == 0 && rep->rrset_count != 0)
|
||||
res->authority_ttl = (int)rep->ttl;
|
||||
res->authority_data[authority_data->count] = NULL;
|
||||
res->authority_len[authority_data->count] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** fill result from parsed message, on error fills servfail */
|
||||
void
|
||||
libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
||||
|
|
@ -533,6 +584,10 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
|||
log_err("cannot parse buf");
|
||||
return; /* error parsing buf, or out of memory */
|
||||
}
|
||||
struct ub_packed_rrset_key *authority_rrset = reply_find_rrset_section_ns(rep, rq.qname, rq.qname_len, rq.qtype, rq.qclass);
|
||||
if(!fill_res_authority(res, authority_rrset, &rq, rep))
|
||||
return; /* out of memory */
|
||||
|
||||
if(!fill_res(res, reply_find_answer_rrset(&rq, rep),
|
||||
reply_find_final_cname_target(&rq, rep), &rq, rep))
|
||||
return; /* out of memory */
|
||||
|
|
|
|||
|
|
@ -136,9 +136,20 @@ struct ub_result {
|
|||
*/
|
||||
char** data;
|
||||
|
||||
/**
|
||||
* a list of network order DNS rdata items, terminated with a
|
||||
* NULL pointer, so that authority_data[0] is the first result entry,
|
||||
* data[1] the second, and the last entry is NULL.
|
||||
* If there was no data, authority_data[0] is NULL.
|
||||
*/
|
||||
char** authority_data;
|
||||
|
||||
/** the length in bytes of the data items, len[i] for data[i] */
|
||||
int* len;
|
||||
|
||||
/** the length in bytes of the authority_data items, authority_len[i] for autority_data[i] */
|
||||
int* authority_len;
|
||||
|
||||
/**
|
||||
* canonical name for the result (the final cname).
|
||||
* zero terminated string.
|
||||
|
|
@ -215,6 +226,12 @@ struct ub_result {
|
|||
* you also cannot trust this value.
|
||||
*/
|
||||
int ttl;
|
||||
|
||||
/**
|
||||
* TTL for the authority results, in seconds. If the security is bogus, then
|
||||
* you also cannot trust this value.
|
||||
*/
|
||||
int authority_ttl;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue