/* * Create a new reply_info based on 'rep'. The new info is based on * the passed 'rep', but ignores any rrsets except for the first 'an_numrrsets' * RRsets in the answer section. These answer rrsets are copied to the * new info, up to 'copy_rrsets' rrsets (which must not be larger than * 'an_numrrsets'). If an_numrrsets > copy_rrsets, the remaining rrsets array * entries will be kept empty so the caller can fill them later. When rrsets * are copied, they are shallow copied. The caller must ensure that the * copied rrsets are valid throughout its lifetime and must provide appropriate * mutex if it can be shared by multiple threads. */ static struct reply_info * make_new_reply_info(const struct reply_info* rep, struct regional* region, size_t an_numrrsets, size_t copy_rrsets) { struct reply_info* new_rep; size_t i; /* create a base struct. we specify 'insecure' security status as * the modified response won't be DNSSEC-valid. In our faked response * the authority and additional sections will be empty (except possible * EDNS0 OPT RR in the additional section appended on sending it out), * so the total number of RRsets is an_numrrsets. */ new_rep = construct_reply_info_base(region, rep->flags, rep->qdcount, rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets, sec_status_insecure); if(!new_rep) return NULL; if(!reply_info_alloc_rrset_keys(new_rep, NULL, region)) return NULL; for(i=0; i<copy_rrsets; i++) new_rep->rrsets[i] = rep->rrsets[i]; return new_rep; }
/** allocate replyinfo, return 0 on error */ static int parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep, struct regional* region) { *rep = construct_reply_info_base(region, msg->flags, msg->qdcount, 0, 0, msg->an_rrsets, msg->ns_rrsets, msg->ar_rrsets, msg->rrset_count, sec_status_unchecked); if(!*rep) return 0; return 1; }
struct reply_info* reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc, struct regional* region) { struct reply_info* cp; cp = construct_reply_info_base(region, rep->flags, rep->qdcount, rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets, rep->rrset_count, rep->security); if(!cp) return NULL; /* 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; }