diff options
Diffstat (limited to 'util/data/msgreply.c')
| -rw-r--r-- | util/data/msgreply.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 00272fd1c64e..ec46e4724780 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -166,6 +166,32 @@ reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc, return 1; } +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; +} + /** find the minimumttl in the rdata of SOA record */ static time_t soa_find_minttl(struct rr_parse* rr) @@ -196,13 +222,17 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, * minimum-ttl in the rdata of the SOA record */ if(*rr_ttl > soa_find_minttl(rr)) *rr_ttl = soa_find_minttl(rr); - if(*rr_ttl > MAX_NEG_TTL) - *rr_ttl = MAX_NEG_TTL; } if(!SERVE_ORIGINAL_TTL && (*rr_ttl < MIN_TTL)) *rr_ttl = MIN_TTL; if(!SERVE_ORIGINAL_TTL && (*rr_ttl > MAX_TTL)) *rr_ttl = MAX_TTL; + if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) { + /* max neg ttl overrides the min and max ttl of everything + * else, it is for a more specific record */ + if(*rr_ttl > MAX_NEG_TTL) + *rr_ttl = MAX_NEG_TTL; + } if(*rr_ttl < data->ttl) data->ttl = *rr_ttl; @@ -488,14 +518,13 @@ int reply_info_parse(sldns_buffer* pkt, struct alloc_cache* alloc, if((ret = parse_packet(pkt, msg, region)) != 0) { return ret; } - if((ret = parse_extract_edns(msg, edns, region)) != 0) + if((ret = parse_extract_edns_from_response_msg(msg, edns, region)) != 0) return ret; /* parse OK, allocate return structures */ /* this also performs dname decompression */ if(!parse_create_msg(pkt, msg, alloc, qinf, rep, NULL)) { query_info_clear(qinf); - reply_info_parsedelete(*rep, alloc); *rep = NULL; return LDNS_RCODE_SERVFAIL; } @@ -960,34 +989,6 @@ parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region, return rep; } -int edns_opt_append(struct edns_data* edns, struct regional* region, - uint16_t code, size_t len, uint8_t* data) -{ - struct edns_option** prevp; - struct edns_option* opt; - - /* allocate new element */ - opt = (struct edns_option*)regional_alloc(region, sizeof(*opt)); - if(!opt) - return 0; - opt->next = NULL; - opt->opt_code = code; - opt->opt_len = len; - opt->opt_data = NULL; - if(len > 0) { - opt->opt_data = regional_alloc_init(region, data, len); - if(!opt->opt_data) - return 0; - } - - /* append at end of list */ - prevp = &edns->opt_list; - while(*prevp != NULL) - prevp = &((*prevp)->next); - *prevp = opt; - return 1; -} - int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len, uint8_t* data, struct regional* region) { @@ -1068,7 +1069,7 @@ static int inplace_cb_reply_call_generic( (void)(*(inplace_cb_reply_func_type*)cb->cb)(qinfo, qstate, rep, rcode, edns, &opt_list_out, repinfo, region, start_time, cb->id, cb->cb_arg); } - edns->opt_list = opt_list_out; + edns->opt_list_inplace_cb_out = opt_list_out; return 1; } |
