conversion from parsed message to iterator region storage.

git-svn-id: file:///svn/unbound/trunk@357 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-06-01 12:52:07 +00:00
parent 3feea76968
commit 0001a42efc
7 changed files with 87 additions and 30 deletions

View 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.

View 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;

View 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;
}

View 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 */

View 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;

View file

@ -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; 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;

View 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.