From: Wouter Wijngaards Date: Tue, 17 Apr 2007 10:18:39 +0000 (+0000) Subject: Message create. X-Git-Tag: release-0.3~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=200993b89f541ea12235120469ec8ee008356888;p=thirdparty%2Funbound.git Message create. git-svn-id: file:///svn/unbound/trunk@244 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index a6231cf57..2564bc28e 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 17 April 2007: Wouter - copy and decompress dnames. - store calculated hash value too. + - routine to create message out of stored information. 16 April 2007: Wouter - following a small change in LDNS, parsing code calculates the diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 041ae7d6d..deb8ca2cd 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -1061,6 +1061,104 @@ reply_info_answer(struct reply_info* rep, uint16_t qflags, ldns_buffer_flip(buffer); } +/** store rrset in iov vector */ +static int +packed_rrset_iov(struct ub_packed_rrset_key* key, struct iovec* iov, + size_t max, uint16_t* num_rrs, uint32_t timenow, region_type* region, + size_t* used) +{ + size_t i; + uint32_t* ttl = (uint32_t*)region_alloc(region, sizeof(uint32_t)); + struct packed_rrset_data* data = (struct packed_rrset_data*) + key->entry.data; + *num_rrs += data->count; + if(!ttl) return 0; + *ttl = data->ttl - timenow; + for(i=0; icount; i++) { + if(max - *used < 3) return 0; + /* no compression of dnames yet */ + iov[*used].iov_base = (void*)key->rk.dname; + iov[*used].iov_len = key->rk.dname_len + 4; + iov[*used+1].iov_base = (void*)ttl; + iov[*used+1].iov_len = sizeof(uint32_t); + iov[*used+2].iov_base = (void*)data->rr_data[i]; + iov[*used+2].iov_len = data->rr_len[i]; + *used += 3; + } + + return 1; +} + +/** store msg section in iov vector */ +static int +insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, + struct iovec* iov, size_t max, size_t rrsets_before, + uint32_t timenow, region_type* region, size_t* used) +{ + size_t i; + *num_rrs = 0; + for(i=0; irrsets[rrsets_before+i], iov, + max, num_rrs, timenow, region, used)) + return 0; + } + *num_rrs = htons(*num_rrs); + return 1; +} + +size_t reply_info_iov_regen(struct query_info* qinfo, struct reply_info* rep, + uint16_t id, uint16_t flags, struct iovec* iov, size_t max, + uint32_t timenow, region_type* region) +{ + size_t used; + uint16_t* hdr = (uint16_t*)region_alloc(region, sizeof(uint16_t)*4); + if(!hdr) return 0; + if(max<3) return 0; + flags = htons(flags); + iov[0].iov_base = (void*)&id; + iov[0].iov_len = sizeof(uint16_t); + iov[1].iov_base = (void*)&flags; + iov[1].iov_len = sizeof(uint16_t); + iov[2].iov_base = (void*)&hdr[0]; + iov[2].iov_len = sizeof(uint16_t)*4; + hdr[0] = htons(rep->qdcount); + used=3; + + /* insert query section */ + if(rep->qdcount) { + uint16_t* qt = (uint16_t*)region_alloc(region,sizeof(uint16_t)); + uint16_t* qc = (uint16_t*)region_alloc(region,sizeof(uint16_t)); + if(!qt || !qc) return 0; + if(max-used < 3) return 0; + iov[used].iov_base = (void*)qinfo->qname; + iov[used].iov_len = qinfo->qnamesize; + *qt = htons(qinfo->qtype); + *qc = htons(qinfo->qclass); + iov[used+1].iov_base = (void*)qt; + iov[used+1].iov_len = sizeof(uint16_t); + iov[used+2].iov_base = (void*)qc; + iov[used+2].iov_len = sizeof(uint16_t); + used += 3; + } + + /* insert answer section */ + if(!insert_section(rep, rep->an_numrrsets, &hdr[1], iov, max, + 0, timenow, region, &used)) + return 0; + + /* insert auth section */ + if(!insert_section(rep, rep->ns_numrrsets, &hdr[2], iov, max, + rep->an_numrrsets, timenow, region, &used)) + return 0; + + /* insert add section */ + if(!insert_section(rep, rep->ar_numrrsets, &hdr[3], iov, max, + rep->an_numrrsets + rep->ns_numrrsets, timenow, region, &used)) + return 0; + + return used; +} + void reply_info_answer_iov(struct reply_info* rep, uint16_t qid, uint16_t qflags, struct comm_reply* comrep, int cached) diff --git a/util/data/msgreply.h b/util/data/msgreply.h index dfcce46d4..565765d1d 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -45,6 +45,8 @@ #include "util/data/packed_rrset.h" struct comm_reply; struct alloc_cache; +struct iovec; +struct region; /** * Structure to store query information that makes answers to queries @@ -248,6 +250,22 @@ hashvalue_t query_info_hash(struct query_info *q); void reply_info_answer(struct reply_info* rep, uint16_t qflags, ldns_buffer* buf); +/** + * Regenerate the wireformat from the parsed msg. + * @param qinfo: query info to store. + * @param rep: reply to store. + * @param id: id value to store, network order. + * @param flags: flags value to store, host order. + * @param iov: iov to store it into (start position to store). + * @param max: max that can be stored. + * @param timenow: time now, to adjust ttl values. + * @param region: to store temporary data in. + * @return: number of items stored, 0 on error. + */ +size_t reply_info_iov_regen(struct query_info* qinfo, struct reply_info* rep, + uint16_t id, uint16_t flags, struct iovec* iov, size_t max, + uint32_t timenow, struct region* region); + /** * Generate and send out answer from reply_info. * @param rep: reply to fill in.