compression.

git-svn-id: file:///svn/unbound/trunk@269 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-04-27 14:55:47 +00:00
parent 496c39742a
commit 0ce78d259f
5 changed files with 102 additions and 8 deletions

View file

@ -2,6 +2,7 @@
- removed iov usage, it is not good for dns message encoding. - removed iov usage, it is not good for dns message encoding.
- owner name compression more optimal. - owner name compression more optimal.
- rrsig owner name compression. - rrsig owner name compression.
- rdata domain name compression.
26 April 2007: Wouter 26 April 2007: Wouter
- floating point exception fix in lock-verify. - floating point exception fix in lock-verify.

View file

@ -218,13 +218,11 @@ main(int argc, char* argv[])
} }
printf("Start of %s unit test.\n", PACKAGE_STRING); printf("Start of %s unit test.\n", PACKAGE_STRING);
checklock_start(); checklock_start();
if(0) {
net_test(); net_test();
alloc_test(); alloc_test();
msgreply_test(); msgreply_test();
lruhash_test(); lruhash_test();
slabhash_test(); slabhash_test();
}
msgparse_test(); msgparse_test();
checklock_stop(); checklock_stop();
printf("%d checks ok.\n", testcount); printf("%d checks ok.\n", testcount);

View file

@ -349,6 +349,24 @@ dname_count_labels(uint8_t* dname)
return labs; return labs;
} }
int
dname_count_size_labels(uint8_t* dname, size_t* size)
{
uint8_t lablen;
int labs = 1;
*size = 1;
lablen = *dname++;
while(lablen) {
labs++;
*size += lablen+1;
dname += lablen;
lablen = *dname++;
}
return labs;
}
/** /**
* Compare labels in memory, lowercase while comparing. * Compare labels in memory, lowercase while comparing.
* @param p1: label 1 * @param p1: label 1
@ -434,7 +452,8 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
return lastdiff; return lastdiff;
} }
void dname_buffer_write(ldns_buffer* pkt, uint8_t* dname) void
dname_buffer_write(ldns_buffer* pkt, uint8_t* dname)
{ {
uint8_t lablen; uint8_t lablen;

View file

@ -140,6 +140,14 @@ void dname_print(FILE* out, ldns_buffer* pkt, uint8_t* dname);
*/ */
int dname_count_labels(uint8_t* dname); int dname_count_labels(uint8_t* dname);
/**
* Count labels and dname length both, for uncompressed dname in memory.
* @param dname: pointer to uncompressed dname.
* @param size: length of dname, including root label.
* @return: count of labels, including root label, "com." has 2 labels.
*/
int dname_count_size_labels(uint8_t* dname, size_t* size);
/** /**
* Compare dnames, sorted not canonical, but by label. * Compare dnames, sorted not canonical, but by label.
* Such that zone contents follows zone apex. * Such that zone contents follows zone apex.

View file

@ -739,11 +739,10 @@ compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
/** compress any domain name to the packet */ /** compress any domain name to the packet */
static int static int
compress_any_dname(uint8_t* dname, ldns_buffer* pkt, compress_any_dname(uint8_t* dname, ldns_buffer* pkt, int labs,
region_type* region, struct compress_tree_node** tree) region_type* region, struct compress_tree_node** tree)
{ {
struct compress_tree_node* p; struct compress_tree_node* p;
int labs = dname_count_labels(dname);
size_t pos = ldns_buffer_position(pkt); size_t pos = ldns_buffer_position(pkt);
if((p = compress_tree_lookup(*tree, dname, labs))) { if((p = compress_tree_lookup(*tree, dname, labs))) {
write_compressed_dname(pkt, dname, labs, p); write_compressed_dname(pkt, dname, labs, p);
@ -753,6 +752,67 @@ compress_any_dname(uint8_t* dname, ldns_buffer* pkt,
return compress_tree_store(tree, dname, labs, pos, region, p); return compress_tree_store(tree, dname, labs, pos, region, p);
} }
/** return true if type needs domain name compression in rdata */
static const ldns_rr_descriptor*
type_rdata_compressable(struct ub_packed_rrset_key* key)
{
uint16_t t;
memmove(&t, &key->rk.dname[key->rk.dname_len], sizeof(t));
t = ntohs(t);
if(ldns_rr_descript(t) &&
ldns_rr_descript(t)->_compress == LDNS_RR_COMPRESS)
return ldns_rr_descript(t);
return 0;
}
/** compress domain names in rdata */
static int
compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen,
region_type* region, struct compress_tree_node** tree,
const ldns_rr_descriptor* desc)
{
int labs, rdf = 0;
size_t dname_len, len, pos = ldns_buffer_position(pkt);
uint8_t count = desc->_dname_count;
ldns_buffer_skip(pkt, 2); /* rdata len fill in later */
rdata += 2;
todolen -= 2;
while(todolen > 0 && count) {
switch(desc->_wireformat[rdf]) {
case LDNS_RDF_TYPE_DNAME:
labs = dname_count_size_labels(rdata, &dname_len);
if(!compress_any_dname(rdata, pkt, labs, region, tree))
return 0;
rdata += dname_len;
todolen -= dname_len;
count--;
len = 0;
break;
case LDNS_RDF_TYPE_STR:
len = *rdata + 1;
break;
default:
len = get_rdf_size(desc->_wireformat[rdf]);
}
if(len) {
/* copy over */
ldns_buffer_write(pkt, rdata, len);
todolen -= len;
rdata += len;
}
rdf++;
}
/* copy remainder */
if(todolen > 0) {
ldns_buffer_write(pkt, rdata, todolen);
}
/* set rdata len */
ldns_buffer_write_u16_at(pkt, pos, ldns_buffer_position(pkt)-pos-2);
return 1;
}
/** store rrset in iov vector */ /** store rrset in iov vector */
static int static int
packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt, packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
@ -769,6 +829,7 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
owner_pos = ldns_buffer_position(pkt); owner_pos = ldns_buffer_position(pkt);
if(do_data) { if(do_data) {
const ldns_rr_descriptor* c = type_rdata_compressable(key);
*num_rrs += data->count; *num_rrs += data->count;
for(i=0; i<data->count; i++) { for(i=0; i<data->count; i++) {
if(1) { /* compression */ if(1) { /* compression */
@ -781,7 +842,11 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
key->rk.dname_len + 4); key->rk.dname_len + 4);
} }
ldns_buffer_write_u32(pkt, data->rr_ttl[i]-timenow); ldns_buffer_write_u32(pkt, data->rr_ttl[i]-timenow);
ldns_buffer_write(pkt, data->rr_data[i], if(c) {
if(!compress_rdata(pkt, data->rr_data[i],
data->rr_len[i], region, tree, c))
return 0;
} else ldns_buffer_write(pkt, data->rr_data[i],
data->rr_len[i]); data->rr_len[i]);
} }
} }
@ -793,8 +858,11 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
if(1) { /* compression */ if(1) { /* compression */
if(owner_ptr) if(owner_ptr)
ldns_buffer_write(pkt, &owner_ptr, 2); ldns_buffer_write(pkt, &owner_ptr, 2);
else compress_any_dname(key->rk.dname, else {
pkt, region, tree); if(!compress_any_dname(key->rk.dname,
pkt, owner_labs, region, tree))
return 0;
}
} else { } else {
/* no compression */ /* no compression */
ldns_buffer_write(pkt, key->rk.dname, ldns_buffer_write(pkt, key->rk.dname,