- Applied patch from Daisuke HIGASHI for rrset-roundrobin and

minimal-responses features.


git-svn-id: file:///svn/unbound/trunk@2658 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards
2012-04-10 09:16:39 +00:00
parent 279f409636
commit cf147df593
14 changed files with 1668 additions and 1479 deletions
+76 -39
View File
@@ -443,9 +443,9 @@ static int
packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
uint16_t* num_rrs, uint32_t timenow, struct regional* region,
int do_data, int do_sig, struct compress_tree_node** tree,
ldns_pkt_section s, uint16_t qtype, int dnssec)
ldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
{
size_t i, owner_pos;
size_t i, j, owner_pos;
int r, owner_labs;
uint16_t owner_ptr = 0;
struct packed_rrset_data* data = (struct packed_rrset_data*)
@@ -461,26 +461,28 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
if(do_data) {
const ldns_rr_descriptor* c = type_rdata_compressable(key);
for(i=0; i<data->count; i++) {
/* rrset roundrobin */
j = (i + rr_offset) % data->count;
if((r=compress_owner(key, pkt, region, tree,
owner_pos, &owner_ptr, owner_labs))
!= RETVAL_OK)
return r;
ldns_buffer_write(pkt, &key->rk.type, 2);
ldns_buffer_write(pkt, &key->rk.rrset_class, 2);
if(data->rr_ttl[i] < timenow)
if(data->rr_ttl[j] < timenow)
ldns_buffer_write_u32(pkt, 0);
else ldns_buffer_write_u32(pkt,
data->rr_ttl[i]-timenow);
data->rr_ttl[j]-timenow);
if(c) {
if((r=compress_rdata(pkt, data->rr_data[i],
data->rr_len[i], region, tree, c))
if((r=compress_rdata(pkt, data->rr_data[j],
data->rr_len[j], region, tree, c))
!= RETVAL_OK)
return r;
} else {
if(ldns_buffer_remaining(pkt) < data->rr_len[i])
if(ldns_buffer_remaining(pkt) < data->rr_len[j])
return RETVAL_TRUNC;
ldns_buffer_write(pkt, data->rr_data[i],
data->rr_len[i]);
ldns_buffer_write(pkt, data->rr_data[j],
data->rr_len[j]);
}
}
}
@@ -528,7 +530,7 @@ static int
insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
ldns_buffer* pkt, size_t rrsets_before, uint32_t timenow,
struct regional* region, struct compress_tree_node** tree,
ldns_pkt_section s, uint16_t qtype, int dnssec)
ldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
{
int r;
size_t i, setstart;
@@ -540,7 +542,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
setstart = ldns_buffer_position(pkt);
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
pkt, num_rrs, timenow, region, 1, 1, tree,
s, qtype, dnssec))
s, qtype, dnssec, rr_offset))
!= RETVAL_OK) {
/* Bad, but if due to size must set TC bit */
/* trim off the rrset neatly. */
@@ -553,7 +555,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
setstart = ldns_buffer_position(pkt);
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
pkt, num_rrs, timenow, region, 1, 0, tree,
s, qtype, dnssec))
s, qtype, dnssec, rr_offset))
!= RETVAL_OK) {
ldns_buffer_set_position(pkt, setstart);
return r;
@@ -564,7 +566,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
setstart = ldns_buffer_position(pkt);
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
pkt, num_rrs, timenow, region, 0, 1, tree,
s, qtype, dnssec))
s, qtype, dnssec, rr_offset))
!= RETVAL_OK) {
ldns_buffer_set_position(pkt, setstart);
return r;
@@ -595,6 +597,31 @@ insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
return RETVAL_OK;
}
static int
positive_answer(struct reply_info* rep, uint16_t qtype) {
size_t i;
if (FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR)
return 0;
for(i=0;i<rep->an_numrrsets; i++) {
if(ntohs(rep->rrsets[i]->rk.type) == qtype) {
/* in case it is a wildcard with DNSSEC, there will
* be NSEC/NSEC3 records in the authority section
* that we cannot remove */
for(i=rep->an_numrrsets; i<rep->an_numrrsets+
rep->ns_numrrsets; i++) {
if(ntohs(rep->rrsets[i]->rk.type) ==
LDNS_RR_TYPE_NSEC ||
ntohs(rep->rrsets[i]->rk.type) ==
LDNS_RR_TYPE_NSEC3)
return 0;
}
return 1;
}
}
return 0;
}
int
reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
uint16_t id, uint16_t flags, ldns_buffer* buffer, uint32_t timenow,
@@ -603,6 +630,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
uint16_t ancount=0, nscount=0, arcount=0;
struct compress_tree_node* tree = 0;
int r;
size_t rr_offset;
ldns_buffer_clear(buffer);
if(udpsize < ldns_buffer_limit(buffer))
@@ -630,11 +658,13 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
return 0;
}
}
/* roundrobin offset. using query id for random number */
rr_offset = RRSET_ROUNDROBIN?id:0;
/* insert answer section */
if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
dnssec)) != RETVAL_OK) {
dnssec, rr_offset)) != RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* create truncated message */
ldns_buffer_write_u16_at(buffer, 6, ancount);
@@ -646,35 +676,42 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
}
ldns_buffer_write_u16_at(buffer, 6, ancount);
/* insert auth section */
if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
rep->an_numrrsets, timenow, region, &tree,
LDNS_SECTION_AUTHORITY, qinfo->qtype, dnssec)) != RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* create truncated message */
ldns_buffer_write_u16_at(buffer, 8, nscount);
LDNS_TC_SET(ldns_buffer_begin(buffer));
ldns_buffer_flip(buffer);
return 1;
/* if response is positive answer, auth/add sections are not required */
if( ! (MINIMAL_RESPONSES && positive_answer(rep, qinfo->qtype)) ) {
/* insert auth section */
if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
rep->an_numrrsets, timenow, region, &tree,
LDNS_SECTION_AUTHORITY, qinfo->qtype,
dnssec, rr_offset)) != RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* create truncated message */
ldns_buffer_write_u16_at(buffer, 8, nscount);
LDNS_TC_SET(ldns_buffer_begin(buffer));
ldns_buffer_flip(buffer);
return 1;
}
return 0;
}
return 0;
}
ldns_buffer_write_u16_at(buffer, 8, nscount);
ldns_buffer_write_u16_at(buffer, 8, nscount);
/* insert add section */
if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
dnssec)) != RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* no need to set TC bit, this is the additional */
ldns_buffer_write_u16_at(buffer, 10, arcount);
ldns_buffer_flip(buffer);
return 1;
/* insert add section */
if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
dnssec, rr_offset)) != RETVAL_OK) {
if(r == RETVAL_TRUNC) {
/* no need to set TC bit, this is the additional */
ldns_buffer_write_u16_at(buffer, 10, arcount);
ldns_buffer_flip(buffer);
return 1;
}
return 0;
}
return 0;
ldns_buffer_write_u16_at(buffer, 10, arcount);
} else {
ldns_buffer_write_u16_at(buffer, 8, nscount);
ldns_buffer_write_u16_at(buffer, 10, arcount);
}
ldns_buffer_write_u16_at(buffer, 10, arcount);
ldns_buffer_flip(buffer);
return 1;
}