Copy replyinfo routine.

git-svn-id: file:///svn/unbound/trunk@362 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-06-04 11:34:23 +00:00
parent e08155e86e
commit 5e42374cc8
4 changed files with 100 additions and 62 deletions

View file

@ -1,5 +1,6 @@
4 June 2007: Wouter
- random selection of equally preferred nameserver targets.
- reply info copy routine. Reuses existing code.
1 June 2007: Wouter
- normalize incoming messages. Like unbound-java, with CNAME chain

View file

@ -223,7 +223,7 @@ iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
{
struct reply_info* rep = NULL;
/* alloc, malloc properly (not in region, like msg is) */
rep = reply_info_copy(msg->rep, env->alloc);
rep = reply_info_copy(msg->rep, env->alloc, NULL);
if(!rep)
return 0;

View file

@ -69,48 +69,59 @@ parse_create_qinfo(ldns_buffer* pkt, struct msg_parse* msg,
return 1;
}
/** constructor for replyinfo */
static struct reply_info*
construct_reply_info_base(struct region* region, uint16_t flags, size_t qd,
uint32_t ttl, size_t an, size_t ns, size_t ar, size_t total)
{
struct reply_info* rep;
/* rrset_count-1 because the first ref is part of the struct. */
size_t s = sizeof(struct reply_info) - sizeof(struct rrset_ref) +
sizeof(struct ub_packed_rrset_key*) * total;
if(region)
rep = (struct reply_info*)region_alloc(region, s);
else rep = (struct reply_info*)malloc(s +
sizeof(struct rrset_ref) * (total));
if(!rep)
return NULL;
rep->flags = flags;
rep->qdcount = qd;
rep->ttl = ttl;
rep->an_numrrsets = an;
rep->ns_numrrsets = ns;
rep->ar_numrrsets = ar;
rep->rrset_count = total;
/* array starts after the refs */
if(region)
rep->rrsets = (struct ub_packed_rrset_key**)&(rep->ref[0]);
else rep->rrsets = (struct ub_packed_rrset_key**)&(rep->ref[total]);
/* zero the arrays to assist cleanup in case of malloc failure */
memset( rep->rrsets, 0, sizeof(struct ub_packed_rrset_key*) * total);
if(!region)
memset( &rep->ref[0], 0, sizeof(struct rrset_ref) * total);
return rep;
}
/** allocate replyinfo, return 0 on error. */
static int
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. */
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;
(*rep)->ttl = 0;
(*rep)->an_numrrsets = msg->an_rrsets;
(*rep)->ns_numrrsets = msg->ns_rrsets;
(*rep)->ar_numrrsets = msg->ar_rrsets;
(*rep)->rrset_count = msg->rrset_count;
/* array starts after the refs */
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);
if(!region)
memset( &(*rep)->ref[0], 0,
sizeof(struct rrset_ref) * msg->rrset_count);
*rep = construct_reply_info_base(region, msg->flags, msg->qdcount, 0,
msg->an_rrsets, msg->ns_rrsets, msg->ar_rrsets,
msg->rrset_count);
if(!*rep)
return 0;
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 region* region)
repinfo_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
struct region* region)
{
size_t i;
for(i=0; i<msg->rrset_count; i++) {
for(i=0; i<rep->rrset_count; i++) {
if(region) {
rep->rrsets[i] = (struct ub_packed_rrset_key*)
region_alloc(region,
@ -345,7 +356,7 @@ parse_create_msg(ldns_buffer* pkt, struct msg_parse* msg,
return 0;
if(!parse_create_repinfo(msg, rep, region))
return 0;
if(!parse_alloc_rrset_keys(msg, *rep, alloc, region))
if(!repinfo_alloc_rrset_keys(*rep, alloc, region))
return 0;
if(!parse_copy_decompress(pkt, msg, *rep, region))
return 0;
@ -555,41 +566,62 @@ query_info_entrysetup(struct query_info* q, struct reply_info* r,
return e;
}
/** copy over reply info structure, size it correcly for rrsets */
static struct reply_info*
copy_repinfo(struct reply_info* from)
/** copy rrsets from replyinfo to dest replyinfo */
static int
repinfo_copy_rrsets(struct reply_info* dest, struct reply_info* from,
struct region* region)
{
struct reply_info* cp;
/* rrset_count-1 because the first ref is part of the struct. */
size_t s = sizeof(struct reply_info) - sizeof(struct rrset_ref) +
sizeof(struct ub_packed_rrset_key*) * from->rrset_count;
cp = (struct reply_info*)malloc(s +
sizeof(struct rrset_ref) * (from->rrset_count));
if(!cp) return NULL;
cp->flags = from->flags;
cp->qdcount = from->qdcount;
cp->ttl = from->ttl;
cp->an_numrrsets = from->an_numrrsets;
cp->ns_numrrsets = from->ns_numrrsets;
cp->ar_numrrsets = from->ar_numrrsets;
cp->rrset_count = from->rrset_count;
/* array starts after the refs */
cp->rrsets = (struct ub_packed_rrset_key**)
&(cp->ref[from->rrset_count]);
/* zero the arrays to assist cleanup in case of malloc failure */
memset( cp->rrsets, 0,
sizeof(struct ub_packed_rrset_key*) * from->rrset_count);
memset( &cp->ref[0], 0,
sizeof(struct rrset_ref) * from->rrset_count);
return cp;
size_t i, s;
struct packed_rrset_data* fd, *dd;
struct ub_packed_rrset_key* fk, *dk;
for(i=0; i<dest->rrset_count; i++) {
fk = from->rrsets[i];
dk = dest->rrsets[i];
fd = (struct packed_rrset_data*)fk->entry.data;
dk->id = fk->id;
dk->entry.hash = fk->entry.hash;
dk->rk = fk->rk;
if(region)
dk->rk.dname = (uint8_t*)region_alloc_init(region,
fk->rk.dname, fk->rk.dname_len);
else
dk->rk.dname = (uint8_t*)memdup(fk->rk.dname,
fk->rk.dname_len);
if(!dk->rk.dname)
return 0;
s = packed_rrset_sizeof(fd);
if(region)
dd = (struct packed_rrset_data*)region_alloc_init(
region, fd, s);
else dd = (struct packed_rrset_data*)memdup(fd, s);
if(!dd)
return 0;
packed_rrset_ptr_fixup(dd);
dk->entry.data = (void*)dd;
}
return 1;
}
struct reply_info*
reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc)
reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc,
struct region* region)
{
struct reply_info* cp;
if(!(cp = copy_repinfo(rep)))
cp = construct_reply_info_base(region, rep->flags, rep->qdcount,
rep->ttl, rep->an_numrrsets, rep->ns_numrrsets,
rep->ar_numrrsets, rep->rrset_count);
if(!cp)
return NULL;
/* TODO copy rrsets */
/* allocate ub_key structures special or not */
if(!repinfo_alloc_rrset_keys(cp, alloc, region)) {
if(!region)
reply_info_parsedelete(cp, alloc);
return NULL;
}
if(!repinfo_copy_rrsets(cp, rep, region)) {
if(!region)
reply_info_parsedelete(cp, alloc);
return NULL;
}
return cp;
}

View file

@ -280,9 +280,14 @@ struct msgreply_entry* query_info_entrysetup(struct query_info* q,
* Copy reply_info and all rrsets in it and allocate.
* @param rep: what to copy, probably inside region, no ref[] array in it.
* @param alloc: how to allocate rrset keys.
* Not used if region!=NULL, it can be NULL in that case.
* @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 new reply info or NULL on memory error.
*/
struct reply_info* reply_info_copy(struct reply_info* rep,
struct alloc_cache* alloc);
struct alloc_cache* alloc, struct region* region);
#endif /* UTIL_DATA_MSGREPLY_H */