aboutsummaryrefslogtreecommitdiff
path: root/util/data/msgreply.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/data/msgreply.c')
-rw-r--r--util/data/msgreply.c67
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;
}