]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
conversion from parsed message to iterator region storage.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 1 Jun 2007 12:52:07 +0000 (12:52 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 1 Jun 2007 12:52:07 +0000 (12:52 +0000)
git-svn-id: file:///svn/unbound/trunk@357 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_scrub.c
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
util/data/msgreply.c
util/data/msgreply.h

index 57b1c8a026680a9082150a315b963c18fd6d85ae..b8974c8255d872c88a83fa5f5eab4310d79d23c2 100644 (file)
@@ -3,6 +3,7 @@
          checked, DNAME checked, CNAME's synthesized, glue checked.
        - sanitize incoming messages.
        - split msgreply encode functions into own file msgencode.c.
+       - msg_parse to queryinfo/replyinfo conversion more versatile.
 
 31 May 2007: Wouter
        - querytargets state.
index 6d8cfc56d3d275c12590807338013147d4d99cc5..bedce57f0ae909e419d161d0dce8619e9c7c6e62 100644 (file)
@@ -235,7 +235,10 @@ synth_cname_rrset(uint8_t** sname, size_t* snamelen, uint8_t* alias,
                return NULL;
        cn->rr_last = cn->rr_first;
        /* CNAME from sname to alias */
-       cn->dname = (uint8_t*)region_alloc_init(region, *sname, *snamelen);
+       cn->dname = (uint8_t*)region_alloc(region, *snamelen);
+       if(!cn->dname)
+               return NULL;
+       dname_pkt_copy(pkt, cn->dname, *sname);
        cn->dname_len = *snamelen;
        cn->type = LDNS_RR_TYPE_CNAME;
        cn->section = rrset->section;
index d0d9cc4132c9a56a836bc37b0af6c2aeb1447bc4..4dc70e6e55f393771a1f03c37fb5742bf2e68938 100644 (file)
@@ -155,12 +155,16 @@ struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
 }
 
 struct dns_msg* 
-dns_alloc_msg(struct msg_parse* msg, struct region* region)
+dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg, struct region* region)
 {
        struct dns_msg* m = (struct dns_msg*)region_alloc(region,
                sizeof(struct dns_msg));
        if(!m)
                return NULL;
        memset(m, 0, sizeof(*m));
+       if(!parse_create_msg(pkt, msg, NULL, &m->qinfo, &m->rep, region)) {
+               log_err("malloc failure: allocating incoming dns_msg");
+               return NULL;
+       }
        return m;
 }
index 7954b07feb79ac210a24c65c7218c3fb7ca66e05..59205a8540029d4ab9c23d70978c369af1d9fbac 100644 (file)
@@ -78,10 +78,12 @@ struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
 
 /**
  * Allocate dns_msg from parsed msg, in region.
+ * @param pkt: packet.
  * @param msg: parsed message (cleaned and ready for region allocation).
  * @param region: region to use for allocation.
  * @return newly allocated dns_msg, or NULL on memory error.
  */
-struct dns_msg* dns_alloc_msg(struct msg_parse* msg, struct region* region);
+struct dns_msg* dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg, 
+       struct region* region);
 
 #endif /* ITERATOR_ITER_UTILS_H */
index 49eb818fef14cf77f85122121bd24c437095904b..1e0e96cbff85ddf8814b8e511743882b5eec4c10 100644 (file)
@@ -1224,7 +1224,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
                goto handle_it;
 
        /* allocate response dns_msg in region */
-       iq->response = dns_alloc_msg(prs, qstate->region);
+       iq->response = dns_alloc_msg(pkt, prs, qstate->region);
        if(!iq->response)
                goto handle_it;
 
index 3c904eaaa33e926c9149a323cc6f331e421c1ccf..0912780faef7a94556d2c0a57fa462848a254870 100644 (file)
 /** allocate qinfo, return 0 on error. */
 static int
 parse_create_qinfo(ldns_buffer* pkt, struct msg_parse* msg, 
-       struct query_info* qinf)
+       struct query_info* qinf, struct region* region)
 {
        if(msg->qname) {
-               qinf->qname = (uint8_t*)malloc(msg->qname_len);
+               if(region)
+                       qinf->qname = (uint8_t*)region_alloc(region, 
+                               msg->qname_len);
+               else    qinf->qname = (uint8_t*)malloc(msg->qname_len);
                if(!qinf->qname) return 0;
                dname_pkt_copy(pkt, qinf->qname, msg->qname);
        } else  qinf->qname = 0;
@@ -68,12 +71,16 @@ parse_create_qinfo(ldns_buffer* pkt, struct msg_parse* msg,
 
 /** allocate replyinfo, return 0 on error. */
 static int
-parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep)
+parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep,
+       struct region* region)
 {
        /* rrset_count-1 because the first ref is part of the struct. */
-       *rep = (struct reply_info*)malloc(sizeof(struct reply_info) + 
-               sizeof(struct rrset_ref) * (msg->rrset_count-1)  +
-               sizeof(struct ub_packed_rrset_key*) * msg->rrset_count);
+       size_t s = sizeof(struct reply_info) - sizeof(struct rrset_ref) +
+               sizeof(struct ub_packed_rrset_key*) * msg->rrset_count;
+       if(region)
+               *rep = (struct reply_info*)region_alloc(region, s);
+       else    *rep = (struct reply_info*)malloc(s + 
+                       sizeof(struct rrset_ref) * (msg->rrset_count));
        if(!*rep) return 0;
        (*rep)->flags = msg->flags;
        (*rep)->qdcount = msg->qdcount;
@@ -83,24 +90,38 @@ parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep)
        (*rep)->ar_numrrsets = msg->ar_rrsets;
        (*rep)->rrset_count = msg->rrset_count;
        /* array starts after the refs */
-       (*rep)->rrsets = (struct ub_packed_rrset_key**)
-               &((*rep)->ref[msg->rrset_count]);
+       if(region)
+               (*rep)->rrsets = (struct ub_packed_rrset_key**)
+                       &((*rep)->ref[0]);
+       else    (*rep)->rrsets = (struct ub_packed_rrset_key**)
+                       &((*rep)->ref[msg->rrset_count]);
        /* zero the arrays to assist cleanup in case of malloc failure */
        memset( (*rep)->rrsets, 0, 
                sizeof(struct ub_packed_rrset_key*) * msg->rrset_count);
-       memset( &(*rep)->ref[0], 0, 
-               sizeof(struct rrset_ref) * msg->rrset_count);
+       if(!region)
+               memset( &(*rep)->ref[0], 0, 
+                       sizeof(struct rrset_ref) * msg->rrset_count);
        return 1;
 }
 
 /** allocate (special) rrset keys, return 0 on error. */
 static int
 parse_alloc_rrset_keys(struct msg_parse* msg, struct reply_info* rep,
-       struct alloc_cache* alloc)
+       struct alloc_cache* alloc, struct region* region)
 {
        size_t i;
        for(i=0; i<msg->rrset_count; i++) {
-               rep->rrsets[i] = alloc_special_obtain(alloc);
+               if(region) {
+                       rep->rrsets[i] = (struct ub_packed_rrset_key*)
+                               region_alloc(region, 
+                               sizeof(struct ub_packed_rrset_key));
+                       if(rep->rrsets[i]) {
+                               memset(rep->rrsets[i], 0, 
+                                       sizeof(struct ub_packed_rrset_key));
+                               rep->rrsets[i]->entry.key = rep->rrsets[i];
+                       }
+               }
+               else    rep->rrsets[i] = alloc_special_obtain(alloc);
                if(!rep->rrsets[i])
                        return 0;
                rep->rrsets[i]->entry.data = NULL;
@@ -221,13 +242,16 @@ parse_rr_copy(ldns_buffer* pkt, struct rrset_parse* pset,
 /** create rrset return 0 on failure */
 static int
 parse_create_rrset(ldns_buffer* pkt, struct rrset_parse* pset,
-       struct packed_rrset_data** data)
+       struct packed_rrset_data** data, struct region* region)
 {
        /* allocate */
-       *data = malloc(sizeof(struct packed_rrset_data) + 
+       size_t s = sizeof(struct packed_rrset_data) + 
                (pset->rr_count + pset->rrsig_count) * 
                (sizeof(size_t)+sizeof(uint8_t*)+sizeof(uint32_t)) + 
-               pset->size);
+               pset->size;
+       if(region)
+               *data = region_alloc(region, s);
+       else    *data = malloc(s);
        if(!*data)
                return 0;
        /* copy & decompress */
@@ -270,7 +294,7 @@ get_rrset_trust(struct reply_info* rep, size_t i)
  */
 static int
 parse_copy_decompress(ldns_buffer* pkt, struct msg_parse* msg,
-       struct reply_info* rep)
+       struct reply_info* rep, struct region* region)
 {
        size_t i;
        struct rrset_parse *pset = msg->rrset_first;
@@ -283,7 +307,11 @@ parse_copy_decompress(ldns_buffer* pkt, struct msg_parse* msg,
        for(i=0; i<rep->rrset_count; i++) {
                rep->rrsets[i]->rk.flags = pset->flags;
                rep->rrsets[i]->rk.dname_len = pset->dname_len;
-               rep->rrsets[i]->rk.dname = (uint8_t*)malloc(pset->dname_len);
+               if(region)
+                       rep->rrsets[i]->rk.dname = (uint8_t*)region_alloc(
+                               region, pset->dname_len);
+               else    rep->rrsets[i]->rk.dname = 
+                               (uint8_t*)malloc(pset->dname_len);
                if(!rep->rrsets[i]->rk.dname)
                        return 0;
                /** copy & decompress dname */
@@ -292,7 +320,7 @@ parse_copy_decompress(ldns_buffer* pkt, struct msg_parse* msg,
                rep->rrsets[i]->rk.type = htons(pset->type);
                rep->rrsets[i]->rk.rrset_class = pset->rrset_class;
                /** read data part. */
-               if(!parse_create_rrset(pkt, pset, &data))
+               if(!parse_create_rrset(pkt, pset, &data, region))
                        return 0;
                rep->rrsets[i]->entry.data = (void*)data;
                rep->rrsets[i]->entry.key = (void*)rep->rrsets[i];
@@ -306,20 +334,19 @@ parse_copy_decompress(ldns_buffer* pkt, struct msg_parse* msg,
        return 1;
 }
 
-/** allocate and decompress message and rrsets, returns 0 if failed. */
-static int 
+int 
 parse_create_msg(ldns_buffer* pkt, struct msg_parse* msg,
        struct alloc_cache* alloc, struct query_info* qinf, 
-       struct reply_info** rep)
+       struct reply_info** rep, struct region* region)
 {
        log_assert(pkt && msg);
-       if(!parse_create_qinfo(pkt, msg, qinf))
+       if(!parse_create_qinfo(pkt, msg, qinf, region))
                return 0;
-       if(!parse_create_repinfo(msg, rep))
+       if(!parse_create_repinfo(msg, rep, region))
                return 0;
-       if(!parse_alloc_rrset_keys(msg, *rep, alloc))
+       if(!parse_alloc_rrset_keys(msg, *rep, alloc, region))
                return 0;
-       if(!parse_copy_decompress(pkt, msg, *rep))
+       if(!parse_copy_decompress(pkt, msg, *rep, region))
                return 0;
        return 1;
 }
@@ -348,7 +375,7 @@ int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc,
 
        /* parse OK, allocate return structures */
        /* this also performs dname decompression */
-       if(!parse_create_msg(pkt, msg, alloc, qinf, rep)) {
+       if(!parse_create_msg(pkt, msg, alloc, qinf, rep, NULL)) {
                query_info_clear(qinf);
                reply_info_parsedelete(*rep, alloc);
                *rep = NULL;
index f3e21aeee349e54cf40f171bfe3d4c832946cb5f..b3a06cc96c9748f372cba2210717c993c1f5319d 100644 (file)
@@ -48,6 +48,7 @@ struct alloc_cache;
 struct iovec;
 struct region;
 struct edns_data;
+struct msg_parse;
 
 /**
  * Structure to store query information that makes answers to queries
@@ -193,6 +194,25 @@ int reply_info_parse(ldns_buffer* pkt, struct alloc_cache* alloc,
        struct query_info* qinf, struct reply_info** rep, 
        struct region* region, struct edns_data* edns);
 
+/**
+ * Allocate and decompress parsed message and rrsets.
+ * @param pkt: for name decompression.
+ * @param msg: parsed message in scratch region.
+ * @param alloc: alloc cache for special rrset key structures.
+ *     Not used if region!=NULL, it can be NULL in that case.
+ * @param qinf: where to store query info.
+ *     qinf itself is allocated by the caller.
+ * @param rep: reply info is allocated and returned.
+ * @param region: if this parameter is NULL then malloc and the alloc is used.
+ *     otherwise, everything is allocated in this region.
+ *     In a region, no special rrset key structures are needed (not shared),
+ *     and no rrset_ref array in the reply is built up.
+ * @return 0 if allocation failed.
+ */
+int parse_create_msg(ldns_buffer* pkt, struct msg_parse* msg,
+        struct alloc_cache* alloc, struct query_info* qinf,
+       struct reply_info** rep, struct region* region);
+
 /**
  * Sorts the ref array.
  * @param rep: reply info. rrsets must be filled in.