mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 22:57:08 +00:00
save about 90 bytes per rrset and fix NSEC cover finding.
git-svn-id: file:///svn/unbound/trunk@4188 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
115c8f8dd5
commit
632c1e83f8
@ -121,6 +121,23 @@ get_rrset_ttl(struct ub_packed_rrset_key* k)
|
||||
return d->ttl;
|
||||
}
|
||||
|
||||
/** Copy rrset into region from domain-datanode and packet rrset */
|
||||
static struct ub_packed_rrset_key*
|
||||
auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
|
||||
struct auth_rrset* rrset, struct regional* region, time_t adjust)
|
||||
{
|
||||
struct ub_packed_rrset_key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.entry.key = &key;
|
||||
key.entry.data = rrset->data;
|
||||
key.rk.dname = node->name;
|
||||
key.rk.dname_len = node->namelen;
|
||||
key.rk.type = htons(rrset->type);
|
||||
key.rk.rrset_class = htons(z->dclass);
|
||||
key.entry.hash = rrset_key_hash(&key.rk);
|
||||
return packed_rrset_copy_region(&key, region, adjust);
|
||||
}
|
||||
|
||||
/** fix up msg->rep TTL and prefetch ttl */
|
||||
static void
|
||||
msg_ttl(struct dns_msg* msg)
|
||||
@ -139,8 +156,8 @@ msg_ttl(struct dns_msg* msg)
|
||||
|
||||
/** add rrset to answer section (no auth, add rrsets yet) */
|
||||
static int
|
||||
msg_add_rrset_an(struct regional* region, struct dns_msg* msg,
|
||||
struct auth_rrset* rrset)
|
||||
msg_add_rrset_an(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
log_assert(msg->rep->ns_numrrsets == 0);
|
||||
log_assert(msg->rep->ar_numrrsets == 0);
|
||||
@ -151,7 +168,7 @@ msg_add_rrset_an(struct regional* region, struct dns_msg* msg,
|
||||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset->rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->an_numrrsets++;
|
||||
@ -161,8 +178,8 @@ msg_add_rrset_an(struct regional* region, struct dns_msg* msg,
|
||||
|
||||
/** add rrset to authority section (no additonal section rrsets yet) */
|
||||
static int
|
||||
msg_add_rrset_ns(struct regional* region, struct dns_msg* msg,
|
||||
struct auth_rrset* rrset)
|
||||
msg_add_rrset_ns(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
log_assert(msg->rep->ar_numrrsets == 0);
|
||||
if(!rrset)
|
||||
@ -172,7 +189,7 @@ msg_add_rrset_ns(struct regional* region, struct dns_msg* msg,
|
||||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset->rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->ns_numrrsets++;
|
||||
@ -182,8 +199,8 @@ msg_add_rrset_ns(struct regional* region, struct dns_msg* msg,
|
||||
|
||||
/** add rrset to additional section */
|
||||
static int
|
||||
msg_add_rrset_ar(struct regional* region, struct dns_msg* msg,
|
||||
struct auth_rrset* rrset)
|
||||
msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
if(!rrset)
|
||||
return 1;
|
||||
@ -192,7 +209,7 @@ msg_add_rrset_ar(struct regional* region, struct dns_msg* msg,
|
||||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset->rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->ar_numrrsets++;
|
||||
@ -246,9 +263,7 @@ static void
|
||||
auth_rrset_delete(struct auth_rrset* rrset)
|
||||
{
|
||||
if(!rrset) return;
|
||||
free(rrset->rrset->entry.data); /* struct packed_rrset_data */
|
||||
free(rrset->rrset->rk.dname);
|
||||
free(rrset->rrset); /* struct ub_packed_rrset_key */
|
||||
free(rrset->data);
|
||||
free(rrset);
|
||||
}
|
||||
|
||||
@ -486,13 +501,6 @@ az_domain_find_or_create(struct auth_zone* z, uint8_t* dname,
|
||||
return n;
|
||||
}
|
||||
|
||||
/** return rr type of rrset */
|
||||
static uint16_t
|
||||
az_rrset_type(struct auth_rrset* entry)
|
||||
{
|
||||
return ntohs(entry->rrset->rk.type);
|
||||
}
|
||||
|
||||
/** find rrset of given type in the domain */
|
||||
static struct auth_rrset*
|
||||
az_domain_rrset(struct auth_data* n, uint16_t t)
|
||||
@ -501,7 +509,7 @@ az_domain_rrset(struct auth_data* n, uint16_t t)
|
||||
if(!n) return NULL;
|
||||
rrset = n->rrsets;
|
||||
while(rrset) {
|
||||
if(az_rrset_type(rrset) == t)
|
||||
if(rrset->type == t)
|
||||
return rrset;
|
||||
rrset = rrset->next;
|
||||
}
|
||||
@ -517,7 +525,7 @@ domain_remove_rrset(struct auth_data* node, uint16_t rr_type)
|
||||
prev = NULL;
|
||||
rrset = node->rrsets;
|
||||
while(rrset) {
|
||||
if(az_rrset_type(rrset) == rr_type) {
|
||||
if(rrset->type == rr_type) {
|
||||
/* found it, now delete it */
|
||||
if(prev) prev->next = rrset->next;
|
||||
else node->rrsets = rrset->next;
|
||||
@ -531,10 +539,8 @@ domain_remove_rrset(struct auth_data* node, uint16_t rr_type)
|
||||
|
||||
/** see if rdata is duplicate */
|
||||
static int
|
||||
rdata_duplicate(struct ub_packed_rrset_key* k, uint8_t* rdata, size_t len)
|
||||
rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata, size_t len)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
k->entry.data;
|
||||
size_t i;
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(d->rr_len[i] != len)
|
||||
@ -564,9 +570,7 @@ static int
|
||||
rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
size_t rdatalen, int insert_sig)
|
||||
{
|
||||
struct packed_rrset_data* old = (struct packed_rrset_data*)rrset->
|
||||
rrset->entry.data;
|
||||
struct packed_rrset_data* d;
|
||||
struct packed_rrset_data* d, *old = rrset->data;
|
||||
size_t total, old_total;
|
||||
|
||||
d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old)
|
||||
@ -626,7 +630,7 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
memmove(d->rr_data[total-1], rdata, rdatalen);
|
||||
}
|
||||
|
||||
rrset->rrset->entry.data = d;
|
||||
rrset->data = d;
|
||||
free(old);
|
||||
return 1;
|
||||
}
|
||||
@ -634,51 +638,28 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
/** Create new rrset for node with packed rrset with one RR element */
|
||||
static struct auth_rrset*
|
||||
rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
uint8_t* rdata, size_t rdatalen, uint16_t dclass)
|
||||
uint8_t* rdata, size_t rdatalen)
|
||||
{
|
||||
struct auth_rrset* rrset = (struct auth_rrset*)calloc(1,
|
||||
sizeof(*rrset));
|
||||
struct auth_rrset* p, *prev;
|
||||
struct ub_packed_rrset_key* k;
|
||||
struct packed_rrset_data* d;
|
||||
if(!rrset) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* the rrset key structure */
|
||||
k = (struct ub_packed_rrset_key*)calloc(1, sizeof(*k));
|
||||
if(!k) {
|
||||
free(rrset);
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
rrset->rrset = k;
|
||||
k->entry.key = k;
|
||||
k->rk.dname = memdup(node->name, node->namelen);
|
||||
if(!k->rk.dname) {
|
||||
free(rrset);
|
||||
free(k);
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
k->rk.dname_len = node->namelen;
|
||||
k->rk.type = htons(rr_type);
|
||||
k->rk.rrset_class = htons(dclass);
|
||||
k->entry.hash = rrset_key_hash(&k->rk);
|
||||
rrset->type = rr_type;
|
||||
|
||||
/* the rrset data structure, with one RR */
|
||||
d = (struct packed_rrset_data*)calloc(1,
|
||||
sizeof(struct packed_rrset_data) + sizeof(size_t) +
|
||||
sizeof(uint8_t*) + sizeof(time_t) + rdatalen);
|
||||
if(!d) {
|
||||
free(k->rk.dname);
|
||||
free(k);
|
||||
free(rrset);
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
k->entry.data = d;
|
||||
rrset->data = d;
|
||||
d->ttl = rr_ttl;
|
||||
d->trust = rrset_trust_prim_noglue;
|
||||
d->rr_len = (size_t*)((uint8_t*)d + sizeof(struct packed_rrset_data));
|
||||
@ -696,7 +677,7 @@ rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
/* find sorted place to link the rrset into the list */
|
||||
prev = NULL;
|
||||
p = node->rrsets;
|
||||
while(p && az_rrset_type(p)<=rr_type) {
|
||||
while(p && p->type<=rr_type) {
|
||||
prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
@ -711,11 +692,10 @@ rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
static size_t
|
||||
rrsig_num_that_cover(struct auth_rrset* rrsig, uint16_t rr_type, size_t* sigsz)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrsig->
|
||||
rrset->entry.data;
|
||||
struct packed_rrset_data* d = rrsig->data;
|
||||
size_t i, num = 0;
|
||||
*sigsz = 0;
|
||||
log_assert(d && az_rrset_type(rrsig) == LDNS_RR_TYPE_RRSIG);
|
||||
log_assert(d && rrsig->type == LDNS_RR_TYPE_RRSIG);
|
||||
for(i=0; i<d->count+d->rrsig_count; i++) {
|
||||
if(rrsig_rdata_get_type_covered(d->rr_data[i],
|
||||
d->rr_len[i]) == rr_type) {
|
||||
@ -732,14 +712,12 @@ rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type,
|
||||
struct auth_rrset* rrset, struct auth_rrset* rrsig)
|
||||
{
|
||||
size_t sigs, sigsz, i, j, total;
|
||||
struct packed_rrset_data* sigold = (struct packed_rrset_data*)rrsig->
|
||||
rrset->entry.data;
|
||||
struct packed_rrset_data* old = (struct packed_rrset_data*)rrset->
|
||||
rrset->entry.data;
|
||||
struct packed_rrset_data* sigold = rrsig->data;
|
||||
struct packed_rrset_data* old = rrset->data;
|
||||
struct packed_rrset_data* d, *sigd;
|
||||
|
||||
log_assert(az_rrset_type(rrset) == rr_type);
|
||||
log_assert(az_rrset_type(rrsig) == LDNS_RR_TYPE_RRSIG);
|
||||
log_assert(rrset->type == rr_type);
|
||||
log_assert(rrsig->type == LDNS_RR_TYPE_RRSIG);
|
||||
sigs = rrsig_num_that_cover(rrsig, rr_type, &sigsz);
|
||||
if(sigs == 0) {
|
||||
/* 0 rrsigs to move over, done */
|
||||
@ -801,7 +779,7 @@ rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type,
|
||||
}
|
||||
|
||||
/* put it in and deallocate the old rrset */
|
||||
rrset->rrset->entry.data = d;
|
||||
rrset->data = d;
|
||||
free(old);
|
||||
|
||||
/* now make rrsig set smaller */
|
||||
@ -856,7 +834,7 @@ rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type,
|
||||
}
|
||||
|
||||
/* put it in and deallocate the old rrset */
|
||||
rrsig->rrset->entry.data = sigd;
|
||||
rrsig->data = sigd;
|
||||
free(sigold);
|
||||
|
||||
return 1;
|
||||
@ -865,8 +843,8 @@ rrset_moveover_rrsigs(struct auth_data* node, uint16_t rr_type,
|
||||
/** Add rr to node, ignores duplicate RRs,
|
||||
* rdata points to buffer with rdatalen octets, starts with 2bytelength. */
|
||||
static int
|
||||
az_domain_add_rr(struct auth_zone* z, struct auth_data* node,
|
||||
uint16_t rr_type, uint32_t rr_ttl, uint8_t* rdata, size_t rdatalen)
|
||||
az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
uint8_t* rdata, size_t rdatalen)
|
||||
{
|
||||
struct auth_rrset* rrset;
|
||||
/* packed rrsets have their rrsigs along with them, sort them out */
|
||||
@ -875,27 +853,27 @@ az_domain_add_rr(struct auth_zone* z, struct auth_data* node,
|
||||
if((rrset=az_domain_rrset(node, ctype))!= NULL) {
|
||||
/* a node of the correct type exists, add the RRSIG
|
||||
* to the rrset of the covered data type */
|
||||
if(rdata_duplicate(rrset->rrset, rdata, rdatalen))
|
||||
if(rdata_duplicate(rrset->data, rdata, rdatalen))
|
||||
return 1;
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 1))
|
||||
return 0;
|
||||
} else if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
|
||||
/* add RRSIG to rrset of type RRSIG */
|
||||
if(rdata_duplicate(rrset->rrset, rdata, rdatalen))
|
||||
if(rdata_duplicate(rrset->data, rdata, rdatalen))
|
||||
return 1;
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
|
||||
return 0;
|
||||
} else {
|
||||
/* create rrset of type RRSIG */
|
||||
if(!rrset_create(node, rr_type, rr_ttl, rdata,
|
||||
rdatalen, z->dclass))
|
||||
rdatalen))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* normal RR type */
|
||||
if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
|
||||
/* add data to existing node with data type */
|
||||
if(rdata_duplicate(rrset->rrset, rdata, rdatalen))
|
||||
if(rdata_duplicate(rrset->data, rdata, rdatalen))
|
||||
return 1;
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
|
||||
return 0;
|
||||
@ -903,7 +881,7 @@ az_domain_add_rr(struct auth_zone* z, struct auth_data* node,
|
||||
struct auth_rrset* rrsig;
|
||||
/* create new node with data type */
|
||||
if(!(rrset=rrset_create(node, rr_type, rr_ttl, rdata,
|
||||
rdatalen, z->dclass)))
|
||||
rdatalen)))
|
||||
return 0;
|
||||
|
||||
/* see if node of type RRSIG has signatures that
|
||||
@ -943,7 +921,7 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
||||
log_err("cannot create domain");
|
||||
return 0;
|
||||
}
|
||||
if(!az_domain_add_rr(z, node, rr_type, rr_ttl, rdata, rdatalen)) {
|
||||
if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen)) {
|
||||
log_err("cannot add RR to domain");
|
||||
return 0;
|
||||
}
|
||||
@ -1093,14 +1071,21 @@ write_out(FILE* out, const char* str)
|
||||
|
||||
/** write rrset to file */
|
||||
static int
|
||||
auth_zone_write_rrset(struct auth_rrset* r, FILE* out)
|
||||
auth_zone_write_rrset(struct auth_zone* z, struct auth_data* node,
|
||||
struct auth_rrset* r, FILE* out)
|
||||
{
|
||||
size_t i, count = ((struct packed_rrset_data*)r->rrset->entry.data)
|
||||
->count +((struct packed_rrset_data*)r->rrset->entry.data)
|
||||
->rrsig_count;
|
||||
size_t i, count = r->data->count + r->data->rrsig_count;
|
||||
char buf[LDNS_RR_BUF_SIZE];
|
||||
for(i=0; i<count; i++) {
|
||||
if(!packed_rr_to_string(r->rrset, i, 0, buf, sizeof(buf))) {
|
||||
struct ub_packed_rrset_key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.entry.key = &key;
|
||||
key.entry.data = r->data;
|
||||
key.rk.dname = node->name;
|
||||
key.rk.dname_len = node->namelen;
|
||||
key.rk.type = htons(r->type);
|
||||
key.rk.rrset_class = htons(z->dclass);
|
||||
if(!packed_rr_to_string(&key, i, 0, buf, sizeof(buf))) {
|
||||
verbose(VERB_ALGO, "failed to rr2str rr %d", (int)i);
|
||||
continue;
|
||||
}
|
||||
@ -1119,16 +1104,16 @@ auth_zone_write_domain(struct auth_zone* z, struct auth_data* n, FILE* out)
|
||||
if(z->namelen == n->namelen) {
|
||||
struct auth_rrset* soa = az_domain_rrset(n, LDNS_RR_TYPE_SOA);
|
||||
if(soa) {
|
||||
if(!auth_zone_write_rrset(soa, out))
|
||||
if(!auth_zone_write_rrset(z, n, soa, out))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* write all the RRsets for this domain */
|
||||
for(r = n->rrsets; r; r = r->next) {
|
||||
if(z->namelen == n->namelen &&
|
||||
az_rrset_type(r) == LDNS_RR_TYPE_SOA)
|
||||
r->type == LDNS_RR_TYPE_SOA)
|
||||
continue; /* skip SOA here */
|
||||
if(!auth_zone_write_rrset(r, out))
|
||||
if(!auth_zone_write_rrset(z, n, r, out))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -1258,9 +1243,9 @@ domain_has_only_nsec3(struct auth_data* n)
|
||||
struct auth_rrset* rrset = n->rrsets;
|
||||
int nsec3_seen = 0;
|
||||
while(rrset) {
|
||||
if(az_rrset_type(rrset) == LDNS_RR_TYPE_NSEC3) {
|
||||
if(rrset->type == LDNS_RR_TYPE_NSEC3) {
|
||||
nsec3_seen = 1;
|
||||
} else if(az_rrset_type(rrset) != LDNS_RR_TYPE_RRSIG) {
|
||||
} else if(rrset->type != LDNS_RR_TYPE_RRSIG) {
|
||||
return 0;
|
||||
}
|
||||
rrset = rrset->next;
|
||||
@ -1419,8 +1404,7 @@ static int
|
||||
az_add_additionals_from(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_rrset* rrset, size_t offset)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
rrset->rrset->entry.data;
|
||||
struct packed_rrset_data* d = rrset->data;
|
||||
size_t i;
|
||||
if(!d) return 0;
|
||||
for(i=0; i<d->count; i++) {
|
||||
@ -1436,27 +1420,17 @@ az_add_additionals_from(struct auth_zone* z, struct regional* region,
|
||||
if(!domain)
|
||||
continue;
|
||||
if((ref=az_domain_rrset(domain, LDNS_RR_TYPE_A)) != NULL) {
|
||||
if(!msg_add_rrset_ar(region, msg, ref))
|
||||
if(!msg_add_rrset_ar(z, region, msg, domain, ref))
|
||||
return 0;
|
||||
}
|
||||
if((ref=az_domain_rrset(domain, LDNS_RR_TYPE_AAAA)) != NULL) {
|
||||
if(!msg_add_rrset_ar(region, msg, ref))
|
||||
if(!msg_add_rrset_ar(z, region, msg, domain, ref))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** find SOA rrset (if any) for this zone */
|
||||
static struct auth_rrset*
|
||||
az_find_soa(struct auth_zone* z)
|
||||
{
|
||||
struct auth_data* node = az_find_name(z, z->name, z->namelen);
|
||||
if(!node)
|
||||
return NULL;
|
||||
return az_domain_rrset(node, LDNS_RR_TYPE_SOA);
|
||||
}
|
||||
|
||||
/** add negative SOA record (with negative TTL) */
|
||||
static int
|
||||
az_add_negative_soa(struct auth_zone* z, struct regional* region,
|
||||
@ -1465,12 +1439,15 @@ az_add_negative_soa(struct auth_zone* z, struct regional* region,
|
||||
uint32_t minimum;
|
||||
struct packed_rrset_data* d;
|
||||
struct auth_rrset* soa;
|
||||
if(!(soa = az_find_soa(z))) return 0;
|
||||
struct auth_data* apex = az_find_name(z, z->name, z->namelen);
|
||||
if(!apex) return 0;
|
||||
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
|
||||
if(!soa) return 0;
|
||||
/* must be first to put in message; we want to fix the TTL with
|
||||
* one RRset here, otherwise we'd need to loop over the RRs to get
|
||||
* the resulting lower TTL */
|
||||
log_assert(msg->rep->rrset_count == 0);
|
||||
if(!msg_add_rrset_ns(region, msg, soa)) return 0;
|
||||
if(!msg_add_rrset_ns(z, region, msg, apex, soa)) return 0;
|
||||
/* fixup TTL */
|
||||
d = (struct packed_rrset_data*)msg->rep->rrsets[msg->rep->rrset_count-1]->entry.data;
|
||||
/* last 4 bytes are minimum ttl in network format */
|
||||
@ -1538,20 +1515,27 @@ synth_cname_buf(uint8_t* qname, size_t qname_len, size_t dname_len,
|
||||
* false on alloc failure, cname==NULL when name too long. */
|
||||
static int
|
||||
create_synth_cname(struct query_info* qinfo, struct regional* region,
|
||||
struct ub_packed_rrset_key* dname, struct ub_packed_rrset_key** cname)
|
||||
struct auth_data* node, struct auth_rrset* dname, uint16_t dclass,
|
||||
struct ub_packed_rrset_key** cname)
|
||||
{
|
||||
uint8_t buf[LDNS_MAX_DOMAINLEN];
|
||||
uint8_t* dtarg;
|
||||
size_t dtarglen, newlen;
|
||||
struct packed_rrset_data* d;
|
||||
|
||||
/* get DNAME target name */
|
||||
if(dname->data->count < 1) return 0;
|
||||
if(dname->data->rr_len[0] < 3) return 0; /* at least rdatalen +1 */
|
||||
dtarg = dname->data->rr_data[0]+2;
|
||||
dtarglen = dname->data->rr_len[0]-2;
|
||||
if(sldns_read_uint16(dname->data->rr_data[0]) != dtarglen)
|
||||
return 0; /* rdatalen in DNAME rdata is malformed */
|
||||
if(dname_valid(dtarg, dtarglen) != dtarglen)
|
||||
return 0; /* DNAME RR has malformed rdata */
|
||||
|
||||
/* synthesize a CNAME */
|
||||
get_cname_target(dname, &dtarg, &dtarglen);
|
||||
if(!dtarg) {
|
||||
/* DNAME RR has malformed rdata */
|
||||
return 0;
|
||||
}
|
||||
newlen = synth_cname_buf(qinfo->qname, qinfo->qname_len,
|
||||
dname->rk.dname_len, dtarg, dtarglen, buf, sizeof(buf));
|
||||
node->namelen, dtarg, dtarglen, buf, sizeof(buf));
|
||||
if(newlen == 0) {
|
||||
/* YXDOMAIN error */
|
||||
*cname = NULL;
|
||||
@ -1564,7 +1548,7 @@ create_synth_cname(struct query_info* qinfo, struct regional* region,
|
||||
memset(&(*cname)->entry, 0, sizeof((*cname)->entry));
|
||||
(*cname)->entry.key = (*cname);
|
||||
(*cname)->rk.type = htons(LDNS_RR_TYPE_CNAME);
|
||||
(*cname)->rk.rrset_class = dname->rk.rrset_class;
|
||||
(*cname)->rk.rrset_class = htons(dclass);
|
||||
(*cname)->rk.flags = 0;
|
||||
(*cname)->rk.dname = regional_alloc_init(region, qinfo->qname,
|
||||
qinfo->qname_len);
|
||||
@ -1611,22 +1595,28 @@ az_change_dnames(struct dns_msg* msg, uint8_t* oldname, uint8_t* newname,
|
||||
|
||||
/** find NSEC record covering the query */
|
||||
static struct auth_rrset*
|
||||
az_find_nsec_cover(struct auth_zone* z, struct auth_data* node)
|
||||
az_find_nsec_cover(struct auth_zone* z, struct auth_data** node)
|
||||
{
|
||||
uint8_t* nm = (*node)->name;
|
||||
size_t nmlen = (*node)->namelen;
|
||||
struct auth_rrset* rrset;
|
||||
/* either the NSEC for the smallest-or-equal node */
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_NSEC)) != NULL)
|
||||
return rrset;
|
||||
/* or node == NULL, we did not find any smaller name, but the last
|
||||
* name NSEC wraps around, find the last NSEC in the zone */
|
||||
if(node == NULL) {
|
||||
struct auth_data* last = (struct auth_data*)rbtree_last(
|
||||
&z->data);
|
||||
if(!last || (rbnode_type*)last == RBTREE_NULL)
|
||||
return NULL;
|
||||
return az_domain_rrset(last, LDNS_RR_TYPE_NSEC);
|
||||
/* find the NSEC for the smallest-or-equal node */
|
||||
/* if node == NULL, we did not find a smaller name. But the zone
|
||||
* name is the smallest name and should have an NSEC. So there is
|
||||
* no NSEC to return (for a properly signed zone) */
|
||||
/* for empty nonterminals, the auth-data node should not exist,
|
||||
* and thus we don't need to go rbtree_previous here to find
|
||||
* a domain with an NSEC record */
|
||||
/* but there could be glue, and if this is node, then it has no NSEC.
|
||||
* Go up to find nonglue (previous) NSEC-holding nodes */
|
||||
while((rrset=az_domain_rrset(*node, LDNS_RR_TYPE_NSEC)) == NULL) {
|
||||
if(dname_is_root(nm)) return NULL;
|
||||
if(nmlen == z->namelen) return NULL;
|
||||
dname_remove_label(&nm, &nmlen);
|
||||
/* adjust *node for the nsec rrset to find in */
|
||||
*node = az_find_name(z, nm, nmlen);
|
||||
}
|
||||
return NULL;
|
||||
return rrset;
|
||||
}
|
||||
|
||||
/** Find NSEC and add for wildcard denial */
|
||||
@ -1652,8 +1642,8 @@ az_nsec_wildcard_denial(struct auth_zone* z, struct regional* region,
|
||||
qinfo.qtype = 0;
|
||||
qinfo.qclass = 0;
|
||||
az_find_domain(z, &qinfo, &node_exact, &node);
|
||||
if((nsec=az_find_nsec_cover(z, node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(region, msg, nsec)) return 0;
|
||||
if((nsec=az_find_nsec_cover(z, &node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1665,17 +1655,35 @@ az_nsec3_param(struct auth_zone* z, int* algo, size_t* iter, uint8_t** salt,
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* param;
|
||||
size_t i;
|
||||
apex = az_find_name(z, z->name, z->namelen);
|
||||
if(!apex) return 0;
|
||||
param = az_domain_rrset(apex, LDNS_RR_TYPE_NSEC3PARAM);
|
||||
if(!param || !param->rrset || ((struct packed_rrset_data*)param->
|
||||
rrset->entry.data)->count==0)
|
||||
if(!param || param->data->count==0)
|
||||
return 0; /* no RRset or no RRs in rrset */
|
||||
if(!nsec3_get_params(param->rrset, 0, algo, iter, salt, saltlen))
|
||||
return 0; /* malformed NSEC3PARAM */
|
||||
if(!nsec3_hash_algo_size_supported(*algo))
|
||||
return 0; /* unsupported NSEC3 algo */
|
||||
return 1;
|
||||
/* find out which NSEC3PARAM RR has supported parameters */
|
||||
/* skip unknown flags (dynamic signer is recalculating nsec3 chain) */
|
||||
for(i=0; i<param->data->count; i++) {
|
||||
uint8_t* rdata = param->data->rr_data[i]+2;
|
||||
size_t rdatalen = param->data->rr_len[i];
|
||||
if(rdatalen < 2+5)
|
||||
continue; /* too short */
|
||||
if(!nsec3_hash_algo_size_supported(rdata[0]))
|
||||
continue; /* unsupported algo */
|
||||
if(rdatalen < (size_t)(2+5+(size_t)rdata[4]))
|
||||
continue; /* salt missing */
|
||||
if((rdata[1]&NSEC3_UNKNOWN_FLAGS)!=0)
|
||||
continue; /* unknown flags */
|
||||
*algo = rdata[0];
|
||||
*iter = sldns_read_uint16(rdata+2);
|
||||
*saltlen = rdata[4];
|
||||
if(*saltlen == 0)
|
||||
*salt = NULL;
|
||||
else *salt = rdata+5;
|
||||
return 1;
|
||||
}
|
||||
/* no supported params */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Hash a name with nsec3param into buffer, it has zone name appended.
|
||||
@ -1842,14 +1850,14 @@ az_nsec3_find_ce(struct auth_zone* z, uint8_t** cenm, size_t* cenmlen,
|
||||
|
||||
/* Insert NSEC3 record in authority section, if NULL does nothing */
|
||||
static int
|
||||
az_nsec3_insert(struct regional* region, struct dns_msg* msg,
|
||||
struct auth_data* node)
|
||||
az_nsec3_insert(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node)
|
||||
{
|
||||
struct auth_rrset* nsec3;
|
||||
if(!node) return 1; /* no node, skip this */
|
||||
nsec3 = az_domain_rrset(node, LDNS_RR_TYPE_NSEC3);
|
||||
if(!nsec3) return 1; /* if no nsec3 RR, skip it */
|
||||
if(!msg_add_rrset_ns(region, msg, nsec3)) return 0;
|
||||
if(!msg_add_rrset_ns(z, region, msg, node, nsec3)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1883,7 +1891,7 @@ az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
|
||||
node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
|
||||
algo, iter, salt, saltlen);
|
||||
if(no_exact_ce) nxproof = 1;
|
||||
if(!az_nsec3_insert(region, msg, node))
|
||||
if(!az_nsec3_insert(z, region, msg, node))
|
||||
return 0;
|
||||
|
||||
if(nxproof) {
|
||||
@ -1894,7 +1902,7 @@ az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
|
||||
/* find nsec3 that matches or covers it */
|
||||
node = az_nsec3_find_cover(z, nx, nxlen, algo, iter, salt,
|
||||
saltlen);
|
||||
if(!az_nsec3_insert(region, msg, node))
|
||||
if(!az_nsec3_insert(z, region, msg, node))
|
||||
return 0;
|
||||
}
|
||||
if(wcproof) {
|
||||
@ -1910,7 +1918,7 @@ az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
|
||||
/* find nsec3 that matches or covers it */
|
||||
node = az_nsec3_find_cover(z, wc, wclen, algo, iter, salt,
|
||||
saltlen);
|
||||
if(!az_nsec3_insert(region, msg, node))
|
||||
if(!az_nsec3_insert(z, region, msg, node))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -1919,17 +1927,17 @@ az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
|
||||
/** generate answer for positive answer */
|
||||
static int
|
||||
az_generate_positive_answer(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_rrset* rrset)
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
/* see if we want additional rrs */
|
||||
if(az_rrset_type(rrset) == LDNS_RR_TYPE_MX) {
|
||||
if(rrset->type == LDNS_RR_TYPE_MX) {
|
||||
if(!az_add_additionals_from(z, region, msg, rrset, 2))
|
||||
return 0;
|
||||
} else if(az_rrset_type(rrset) == LDNS_RR_TYPE_SRV) {
|
||||
} else if(rrset->type == LDNS_RR_TYPE_SRV) {
|
||||
if(!az_add_additionals_from(z, region, msg, rrset, 6))
|
||||
return 0;
|
||||
} else if(az_rrset_type(rrset) == LDNS_RR_TYPE_NS) {
|
||||
} else if(rrset->type == LDNS_RR_TYPE_NS) {
|
||||
if(!az_add_additionals_from(z, region, msg, rrset, 0))
|
||||
return 0;
|
||||
}
|
||||
@ -1938,40 +1946,41 @@ az_generate_positive_answer(struct auth_zone* z, struct regional* region,
|
||||
|
||||
/** generate answer for type ANY answer */
|
||||
static int
|
||||
az_generate_any_answer(struct regional* region, struct dns_msg* msg,
|
||||
struct auth_data* node)
|
||||
az_generate_any_answer(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node)
|
||||
{
|
||||
struct auth_rrset* rrset;
|
||||
int added = 0;
|
||||
/* add a couple (at least one) RRs */
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_SOA)) != NULL) {
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
added++;
|
||||
}
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_MX)) != NULL) {
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
added++;
|
||||
}
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_A)) != NULL) {
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
added++;
|
||||
}
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_AAAA)) != NULL) {
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
added++;
|
||||
}
|
||||
if(added == 0 && node->rrsets) {
|
||||
if(!msg_add_rrset_an(region, msg, node->rrsets)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node,
|
||||
node->rrsets)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** generate answer for cname answer */
|
||||
static int
|
||||
az_generate_cname_answer(struct regional* region, struct dns_msg* msg,
|
||||
struct auth_rrset* rrset)
|
||||
az_generate_cname_answer(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1984,7 +1993,7 @@ az_generate_notype_answer(struct auth_zone* z, struct regional* region,
|
||||
if(!az_add_negative_soa(z, region, msg)) return 0;
|
||||
/* DNSSEC denial NSEC */
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_NSEC))!=NULL) {
|
||||
if(!msg_add_rrset_ns(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_ns(z, region, msg, node, rrset)) return 0;
|
||||
} else if(node) {
|
||||
/* DNSSEC denial NSEC3 */
|
||||
if(!az_add_nsec3_proof(z, region, msg, node->name,
|
||||
@ -2002,16 +2011,18 @@ az_generate_referral_answer(struct auth_zone* z, struct regional* region,
|
||||
{
|
||||
struct auth_rrset* ds, *nsec;
|
||||
/* turn off AA flag, referral is nonAA because it leaves the zone */
|
||||
log_assert(ce);
|
||||
msg->rep->flags &= ~BIT_AA;
|
||||
if(!msg_add_rrset_ns(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_ns(z, region, msg, ce, rrset)) return 0;
|
||||
/* add DS or deny it */
|
||||
if((ds=az_domain_rrset(ce, LDNS_RR_TYPE_DS))!=NULL) {
|
||||
if(!msg_add_rrset_ns(region, msg, ds)) return 0;
|
||||
if(!msg_add_rrset_ns(z, region, msg, ce, ds)) return 0;
|
||||
} else {
|
||||
/* deny the DS */
|
||||
if((nsec=az_domain_rrset(ce, LDNS_RR_TYPE_NSEC))!=NULL) {
|
||||
if(!msg_add_rrset_ns(region, msg, nsec)) return 0;
|
||||
} else if(ce) {
|
||||
if(!msg_add_rrset_ns(z, region, msg, ce,
|
||||
nsec)) return 0;
|
||||
} else {
|
||||
if(!az_add_nsec3_proof(z, region, msg, ce->name,
|
||||
ce->namelen, msg->qinfo.qname,
|
||||
msg->qinfo.qname_len, 0, 0))
|
||||
@ -2025,14 +2036,16 @@ az_generate_referral_answer(struct auth_zone* z, struct regional* region,
|
||||
|
||||
/** generate answer for DNAME answer */
|
||||
static int
|
||||
az_generate_dname_answer(struct query_info* qinfo, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_rrset* rrset)
|
||||
az_generate_dname_answer(struct auth_zone* z, struct query_info* qinfo,
|
||||
struct regional* region, struct dns_msg* msg, struct auth_data* ce,
|
||||
struct auth_rrset* rrset)
|
||||
{
|
||||
struct ub_packed_rrset_key* cname;
|
||||
log_assert(ce);
|
||||
/* add the DNAME */
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, ce, rrset)) return 0;
|
||||
/* synthesize a CNAME */
|
||||
if(!create_synth_cname(qinfo, region, rrset->rrset, &cname)) {
|
||||
if(!create_synth_cname(qinfo, region, ce, rrset, z->dclass, &cname)) {
|
||||
/* out of memory */
|
||||
return 0;
|
||||
}
|
||||
@ -2066,13 +2079,15 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
|
||||
}
|
||||
if((rrset=az_domain_rrset(wildcard, qinfo->qtype)) != NULL) {
|
||||
/* wildcard has type, add it */
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, wildcard,
|
||||
rrset)) return 0;
|
||||
} else if((rrset=az_domain_rrset(wildcard, LDNS_RR_TYPE_CNAME))!=NULL) {
|
||||
/* wildcard has cname instead, do that */
|
||||
if(!msg_add_rrset_an(region, msg, rrset)) return 0;
|
||||
if(!msg_add_rrset_an(z, region, msg, wildcard,
|
||||
rrset)) return 0;
|
||||
} else if(qinfo->qtype == LDNS_RR_TYPE_ANY && wildcard->rrsets) {
|
||||
/* add ANY rrsets from wildcard node */
|
||||
if(!az_generate_any_answer(region, msg, wildcard))
|
||||
if(!az_generate_any_answer(z, region, msg, wildcard))
|
||||
return 0;
|
||||
} else {
|
||||
/* wildcard has nodata, notype answer */
|
||||
@ -2082,8 +2097,8 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
|
||||
}
|
||||
|
||||
/* ce and node for dnssec denial of wildcard original name */
|
||||
if((nsec=az_find_nsec_cover(z, node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(region, msg, nsec)) return 0;
|
||||
if((nsec=az_find_nsec_cover(z, &node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0;
|
||||
} else if(ce) {
|
||||
if(!az_add_nsec3_proof(z, region, msg, ce->name,
|
||||
ce->namelen, msg->qinfo.qname,
|
||||
@ -2106,8 +2121,8 @@ az_generate_nxdomain_answer(struct auth_zone* z, struct regional* region,
|
||||
struct auth_rrset* nsec;
|
||||
msg->rep->flags |= LDNS_RCODE_NXDOMAIN;
|
||||
if(!az_add_negative_soa(z, region, msg)) return 0;
|
||||
if((nsec=az_find_nsec_cover(z, node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(region, msg, nsec)) return 0;
|
||||
if((nsec=az_find_nsec_cover(z, &node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0;
|
||||
if(ce && !az_nsec_wildcard_denial(z, region, msg, ce->name,
|
||||
ce->namelen)) return 0;
|
||||
} else if(ce) {
|
||||
@ -2127,15 +2142,15 @@ az_generate_answer_with_node(struct auth_zone* z, struct query_info* qinfo,
|
||||
struct auth_rrset* rrset;
|
||||
/* positive answer, rrset we are looking for exists */
|
||||
if((rrset=az_domain_rrset(node, qinfo->qtype)) != NULL) {
|
||||
return az_generate_positive_answer(z, region, msg, rrset);
|
||||
return az_generate_positive_answer(z, region, msg, node, rrset);
|
||||
}
|
||||
/* CNAME? */
|
||||
if((rrset=az_domain_rrset(node, LDNS_RR_TYPE_CNAME)) != NULL) {
|
||||
return az_generate_cname_answer(region, msg, rrset);
|
||||
return az_generate_cname_answer(z, region, msg, node, rrset);
|
||||
}
|
||||
/* type ANY ? */
|
||||
if(qinfo->qtype == LDNS_RR_TYPE_ANY) {
|
||||
return az_generate_any_answer(region, msg, node);
|
||||
return az_generate_any_answer(z, region, msg, node);
|
||||
}
|
||||
/* NOERROR/NODATA (no such type at domain name) */
|
||||
return az_generate_notype_answer(z, region, msg, node);
|
||||
@ -2152,11 +2167,12 @@ az_generate_answer_nonexistnode(struct auth_zone* z, struct query_info* qinfo,
|
||||
|
||||
/* we do not have an exact matching name (that exists) */
|
||||
/* see if we have a NS or DNAME in the ce */
|
||||
if(ce && rrset && az_rrset_type(rrset) == LDNS_RR_TYPE_NS) {
|
||||
if(ce && rrset && rrset->type == LDNS_RR_TYPE_NS) {
|
||||
return az_generate_referral_answer(z, region, msg, ce, rrset);
|
||||
}
|
||||
if(ce && rrset && az_rrset_type(rrset) == LDNS_RR_TYPE_DNAME) {
|
||||
return az_generate_dname_answer(qinfo, region, msg, rrset);
|
||||
if(ce && rrset && rrset->type == LDNS_RR_TYPE_DNAME) {
|
||||
return az_generate_dname_answer(z, qinfo, region, msg, ce,
|
||||
rrset);
|
||||
}
|
||||
/* if there is an empty nonterminal, wildcard and nxdomain don't
|
||||
* happen, it is a notype answer */
|
||||
@ -2209,8 +2225,8 @@ auth_zone_generate_answer(struct auth_zone* z, struct query_info* qinfo,
|
||||
sldns_wire2str_dname_buf(ce->name, ce->namelen,
|
||||
cename, sizeof(cename));
|
||||
else snprintf(cename, sizeof(cename), "NULL");
|
||||
if(rrset) sldns_wire2str_type_buf(az_rrset_type(rrset),
|
||||
rrstr, sizeof(rrstr));
|
||||
if(rrset) sldns_wire2str_type_buf(rrset->type, rrstr,
|
||||
sizeof(rrstr));
|
||||
else snprintf(rrstr, sizeof(rrstr), "NULL");
|
||||
log_info("auth_zone %s query %s %s, domain %s %s %s, "
|
||||
"ce %s, rrset %s", zname, qname, tpstr, nname,
|
||||
|
@ -75,7 +75,7 @@ struct auth_zone {
|
||||
size_t namelen;
|
||||
/** number of labels in zone name */
|
||||
int namelabs;
|
||||
/** the class of this zone.
|
||||
/** the class of this zone, in host byteorder.
|
||||
* uses 'dclass' to not conflict with c++ keyword class. */
|
||||
uint16_t dclass;
|
||||
|
||||
@ -121,8 +121,10 @@ struct auth_data {
|
||||
struct auth_rrset {
|
||||
/** next in list */
|
||||
struct auth_rrset* next;
|
||||
/** RR type in host byteorder */
|
||||
uint16_t type;
|
||||
/** RRset data item */
|
||||
struct ub_packed_rrset_key* rrset;
|
||||
struct packed_rrset_data* data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user