From 0001a42efce544d88eb42a821c97fca9551aa322 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 1 Jun 2007 12:52:07 +0000 Subject: [PATCH] conversion from parsed message to iterator region storage. git-svn-id: file:///svn/unbound/trunk@357 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + iterator/iter_scrub.c | 5 ++- iterator/iter_utils.c | 6 +++- iterator/iter_utils.h | 4 ++- iterator/iterator.c | 2 +- util/data/msgreply.c | 79 +++++++++++++++++++++++++++++-------------- util/data/msgreply.h | 20 +++++++++++ 7 files changed, 87 insertions(+), 30 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 57b1c8a02..b8974c825 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c index 6d8cfc56d..bedce57f0 100644 --- a/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c @@ -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; diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index d0d9cc413..4dc70e6e5 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -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; } diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index 7954b07fe..59205a854 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -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 */ diff --git a/iterator/iterator.c b/iterator/iterator.c index 49eb818fe..1e0e96cbf 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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; diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 3c904eaaa..0912780fa 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -53,10 +53,13 @@ /** 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; irrset_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; irrset_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; diff --git a/util/data/msgreply.h b/util/data/msgreply.h index f3e21aeee..b3a06cc96 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -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. -- 2.47.2