From 0ce78d259f2ea733abc256ee590b513607e24b12 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 27 Apr 2007 14:55:47 +0000 Subject: [PATCH] compression. git-svn-id: file:///svn/unbound/trunk@269 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + testcode/unitmain.c | 2 -- util/data/dname.c | 21 +++++++++++- util/data/dname.h | 8 +++++ util/data/msgreply.c | 78 +++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 102 insertions(+), 8 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 8e090c164..2315a69f5 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/testcode/unitmain.c b/testcode/unitmain.c index e6a85ede3..30dfbb3ac 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -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); diff --git a/util/data/dname.c b/util/data/dname.c index c532f678c..77848e290 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -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; diff --git a/util/data/dname.h b/util/data/dname.h index 13723fb16..d0e5f86fd 100644 --- a/util/data/dname.h +++ b/util/data/dname.h @@ -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. diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 890ffe94e..fb7d78e32 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -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; icount; 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, -- 2.47.2