mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-31 03:49:35 -05:00
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:
parent
3feea76968
commit
0001a42efc
7 changed files with 87 additions and 30 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue