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.
|
||||
- owner name compression more optimal.
|
||||
- rrsig owner name compression.
|
||||
- rdata domain name compression.
|
||||
|
||||
26 April 2007: Wouter
|
||||
- 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);
|
||||
checklock_start();
|
||||
if(0) {
|
||||
net_test();
|
||||
alloc_test();
|
||||
msgreply_test();
|
||||
lruhash_test();
|
||||
slabhash_test();
|
||||
}
|
||||
msgparse_test();
|
||||
checklock_stop();
|
||||
printf("%d checks ok.\n", testcount);
|
||||
|
|
|
|||
|
|
@ -349,6 +349,24 @@ dname_count_labels(uint8_t* dname)
|
|||
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.
|
||||
* @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;
|
||||
}
|
||||
|
||||
void dname_buffer_write(ldns_buffer* pkt, uint8_t* dname)
|
||||
void
|
||||
dname_buffer_write(ldns_buffer* pkt, uint8_t* dname)
|
||||
{
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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 */
|
||||
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)
|
||||
{
|
||||
struct compress_tree_node* p;
|
||||
int labs = dname_count_labels(dname);
|
||||
size_t pos = ldns_buffer_position(pkt);
|
||||
if((p = compress_tree_lookup(*tree, dname, labs))) {
|
||||
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 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 */
|
||||
static int
|
||||
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);
|
||||
|
||||
if(do_data) {
|
||||
const ldns_rr_descriptor* c = type_rdata_compressable(key);
|
||||
*num_rrs += data->count;
|
||||
for(i=0; i<data->count; i++) {
|
||||
if(1) { /* compression */
|
||||
|
|
@ -781,7 +842,11 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
|
|||
key->rk.dname_len + 4);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
|
@ -793,8 +858,11 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
|
|||
if(1) { /* compression */
|
||||
if(owner_ptr)
|
||||
ldns_buffer_write(pkt, &owner_ptr, 2);
|
||||
else compress_any_dname(key->rk.dname,
|
||||
pkt, region, tree);
|
||||
else {
|
||||
if(!compress_any_dname(key->rk.dname,
|
||||
pkt, owner_labs, region, tree))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* no compression */
|
||||
ldns_buffer_write(pkt, key->rk.dname,
|
||||
|
|
|
|||
Loading…
Reference in a new issue