]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Message create.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 17 Apr 2007 10:18:39 +0000 (10:18 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 17 Apr 2007 10:18:39 +0000 (10:18 +0000)
git-svn-id: file:///svn/unbound/trunk@244 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
util/data/msgreply.c
util/data/msgreply.h

index a6231cf57ea1ee6a6105fa4b49a296e1c3fafb54..2564bc28e4497beaa831216fac014c64e098d626 100644 (file)
@@ -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
index 041ae7d6df7eb78100ae8dc0621a3cced200d7ea..deb8ca2cdbd37bfbd77d97d5d1b679ca590c14ad 100644 (file)
@@ -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; i<data->count; 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; i<num_rrsets; i++) {
+               if(!packed_rrset_iov(rep->rrsets[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)
index dfcce46d4eea32fbf4bf3bef901820903596dfc3..565765d1d30302f34d9a6b4649f6ea6995bfd5a4 100644 (file)
@@ -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.