mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 14:02:05 -04:00
Store CNAMEs and their SIGs (if any) in their own name structure on the
name list. I.e. do not mix CNAMEs with non-CNAME data. Do the same thing for DNAMEs.
This commit is contained in:
parent
238c9f5aaa
commit
2f6040ed67
1 changed files with 61 additions and 37 deletions
|
|
@ -587,14 +587,16 @@ dns_message_destroy(dns_message_t **msgp)
|
|||
}
|
||||
|
||||
static dns_result_t
|
||||
findname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section)
|
||||
findname(dns_name_t **foundname, dns_name_t *target, unsigned int attributes,
|
||||
dns_namelist_t *section)
|
||||
{
|
||||
dns_name_t *curr;
|
||||
|
||||
for (curr = ISC_LIST_TAIL(*section) ;
|
||||
curr != NULL ;
|
||||
curr = ISC_LIST_PREV(curr, link)) {
|
||||
if (dns_name_equal(curr, target)) {
|
||||
if (dns_name_equal(curr, target) &&
|
||||
(curr->attributes & attributes) == attributes) {
|
||||
if (foundname != NULL)
|
||||
*foundname = curr;
|
||||
return (DNS_R_SUCCESS);
|
||||
|
|
@ -777,7 +779,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
|||
* name since we no longer need it, and set our name pointer
|
||||
* to point to the name we found.
|
||||
*/
|
||||
result = findname(&name2, name, section);
|
||||
result = findname(&name2, name, 0, section);
|
||||
|
||||
/*
|
||||
* If it is the first name in the section, accept it.
|
||||
|
|
@ -890,8 +892,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
dns_section_t sectionid, isc_boolean_t preserve_order)
|
||||
{
|
||||
isc_region_t r;
|
||||
unsigned int count;
|
||||
unsigned int rdatalen;
|
||||
unsigned int count, rdatalen, attributes;
|
||||
dns_name_t *name;
|
||||
dns_name_t *name2;
|
||||
dns_rdataset_t *rdataset;
|
||||
|
|
@ -905,10 +906,11 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
|
||||
for (count = 0 ; count < msg->counts[sectionid] ; count++) {
|
||||
int recstart = source->current;
|
||||
isc_boolean_t skip_search;
|
||||
isc_boolean_t skip_name_search, skip_type_search;
|
||||
section = &msg->sections[sectionid];
|
||||
|
||||
skip_search = ISC_FALSE;
|
||||
skip_name_search = ISC_FALSE;
|
||||
skip_type_search = ISC_FALSE;
|
||||
name = isc_mempool_get(msg->namepool);
|
||||
if (name == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
|
|
@ -969,7 +971,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
return (DNS_R_FORMERR);
|
||||
section = &msg->sections[DNS_SECTION_TSIG];
|
||||
msg->tsigstart = recstart;
|
||||
skip_search = ISC_TRUE;
|
||||
skip_name_search = ISC_TRUE;
|
||||
skip_type_search = ISC_TRUE;
|
||||
} else if (rdtype == dns_rdatatype_opt) {
|
||||
/*
|
||||
* The name of an OPT record must be ".", it
|
||||
|
|
@ -980,7 +983,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
sectionid != DNS_SECTION_ADDITIONAL ||
|
||||
msg->opt != NULL)
|
||||
return (DNS_R_FORMERR);
|
||||
skip_search = ISC_TRUE;
|
||||
skip_name_search = ISC_TRUE;
|
||||
skip_type_search = ISC_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -992,12 +996,50 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
if (r.length < rdatalen)
|
||||
return (DNS_R_UNEXPECTEDEND);
|
||||
|
||||
/*
|
||||
* Read the rdata from the wire format. Interpret the
|
||||
* rdata according to its actual class, even if it had a
|
||||
* DynDNS meta-class in the packet (unless this is a TSIG).
|
||||
* Then put the meta-class back into the finished rdata.
|
||||
*/
|
||||
rdata = newrdata(msg);
|
||||
if (rdata == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
attributes = 0;
|
||||
if (rdtype != dns_rdatatype_tsig) {
|
||||
if (rdtype == dns_rdatatype_cname) {
|
||||
name->attributes |= DNS_NAMEATTR_CNAME;
|
||||
attributes = DNS_NAMEATTR_CNAME;
|
||||
skip_name_search = ISC_TRUE;
|
||||
} else if (rdtype == dns_rdatatype_dname) {
|
||||
name->attributes |= DNS_NAMEATTR_DNAME;
|
||||
attributes = DNS_NAMEATTR_DNAME;
|
||||
skip_name_search = ISC_TRUE;
|
||||
}
|
||||
result = getrdata(name, source, msg, dctx,
|
||||
msg->rdclass, rdtype,
|
||||
rdatalen, rdata);
|
||||
} else
|
||||
result = getrdata(name, source, msg, dctx,
|
||||
rdclass, rdtype, rdatalen, rdata);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
return (result);
|
||||
rdata->rdclass = rdclass;
|
||||
if (rdtype == dns_rdatatype_sig && rdata->length > 0) {
|
||||
covers = dns_rdata_covers(rdata);
|
||||
if (covers == dns_rdatatype_cname)
|
||||
attributes = DNS_NAMEATTR_CNAME;
|
||||
else if (covers == dns_rdatatype_dname)
|
||||
attributes = DNS_NAMEATTR_DNAME;
|
||||
} else
|
||||
covers = 0;
|
||||
|
||||
/*
|
||||
* If we are doing a dynamic update don't bother searching
|
||||
* for a name, just append this one to the end of the message.
|
||||
*/
|
||||
if (preserve_order || msg->opcode == dns_opcode_update ||
|
||||
skip_search) {
|
||||
skip_name_search) {
|
||||
if (rdtype != dns_rdatatype_opt)
|
||||
ISC_LIST_APPEND(*section, name, link);
|
||||
} else {
|
||||
|
|
@ -1007,7 +1049,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
* allocated name since we no longer need it, and set
|
||||
* our name pointer to point to the name we found.
|
||||
*/
|
||||
result = findname(&name2, name, section);
|
||||
result = findname(&name2, name, attributes, section);
|
||||
|
||||
/*
|
||||
* If it is a new name, append to the section.
|
||||
|
|
@ -1020,36 +1062,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the rdata from the wire format. Interpret the
|
||||
* rdata according to its actual class, even if it had a
|
||||
* DynDNS meta-class in the packet (unless this is a TSIG).
|
||||
* Then put the meta-class back into the finished rdata.
|
||||
*/
|
||||
rdata = newrdata(msg);
|
||||
if (rdata == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
if (rdtype != dns_rdatatype_tsig)
|
||||
result = getrdata(name, source, msg, dctx,
|
||||
msg->rdclass, rdtype,
|
||||
rdatalen, rdata);
|
||||
else
|
||||
result = getrdata(name, source, msg, dctx,
|
||||
rdclass, rdtype, rdatalen, rdata);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
return (result);
|
||||
rdata->rdclass = rdclass;
|
||||
if (rdtype == dns_rdatatype_sig && rdata->length > 0)
|
||||
covers = dns_rdata_covers(rdata);
|
||||
else
|
||||
covers = 0;
|
||||
|
||||
/*
|
||||
* Search name for the particular type and class.
|
||||
* Skip this stage if in update mode, or this is a TSIG.
|
||||
*/
|
||||
if (preserve_order || msg->opcode == dns_opcode_update ||
|
||||
skip_search)
|
||||
skip_type_search)
|
||||
result = DNS_R_NOTFOUND;
|
||||
else {
|
||||
rdataset = NULL;
|
||||
|
|
@ -1063,6 +1081,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
* to create a new rdatalist, store the important bits there,
|
||||
* convert it to an rdataset, and link the latter to the name.
|
||||
* Yuck.
|
||||
*
|
||||
* XXXRTH Check for attempts to create multi-record RRsets
|
||||
* for singleton RR types.
|
||||
*/
|
||||
if (result == DNS_R_NOTFOUND) {
|
||||
rdataset = isc_mempool_get(msg->rdspool);
|
||||
|
|
@ -1555,8 +1576,11 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
|
|||
|
||||
/*
|
||||
* Search through, looking for the name.
|
||||
*
|
||||
* XXXRTH We should probably allow the 'attributes' parameter
|
||||
* to be set in the public API.
|
||||
*/
|
||||
result = findname(&foundname, target, &msg->sections[section]);
|
||||
result = findname(&foundname, target, 0, &msg->sections[section]);
|
||||
if (result == DNS_R_NOTFOUND)
|
||||
return (DNS_R_NXDOMAIN);
|
||||
else if (result != DNS_R_SUCCESS)
|
||||
|
|
|
|||
Loading…
Reference in a new issue