mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
compression.
git-svn-id: file:///svn/unbound/trunk@269 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
496c39742a
commit
0ce78d259f
5 changed files with 102 additions and 8 deletions
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue