diff options
Diffstat (limited to 'util/data/msgreply.c')
| -rw-r--r-- | util/data/msgreply.c | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 02e1230e96e7..e0c4768a6127 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -178,9 +178,9 @@ reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc, int reply_info_can_answer_expired(struct reply_info* rep, time_t timenow) { - log_assert(rep->ttl < timenow); + log_assert(TTL_IS_EXPIRED(rep->ttl, timenow)); /* Really expired */ - if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow) return 0; + if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow)) return 0; /* Ignore expired failure answers */ if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR && FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN && @@ -188,12 +188,13 @@ reply_info_can_answer_expired(struct reply_info* rep, time_t timenow) return 1; } -int reply_info_could_use_expired(struct reply_info* rep, time_t timenow) +int +reply_info_could_use_expired(struct reply_info* rep, time_t timenow) { - log_assert(rep->ttl < timenow); + log_assert(TTL_IS_EXPIRED(rep->ttl, timenow)); /* Really expired */ - if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow && - !SERVE_EXPIRED_TTL_RESET) return 0; + if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow) + && !SERVE_EXPIRED_TTL_RESET) return 0; /* Ignore expired failure answers */ if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR && FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN && @@ -229,7 +230,7 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region, } /** find the minimumttl in the rdata of SOA record */ -static time_t +static uint32_t soa_find_minttl(struct rr_parse* rr) { uint16_t rlen = sldns_read_uint16(rr->ttl_data+4); @@ -237,7 +238,7 @@ soa_find_minttl(struct rr_parse* rr) return 0; /* rdata too small for SOA (dname, dname, 5*32bit) */ /* minimum TTL is the last 32bit value in the rdata of the record */ /* at position ttl_data + 4(ttl) + 2(rdatalen) + rdatalen - 4(timeval)*/ - return (time_t)sldns_read_uint32(rr->ttl_data+6+rlen-4); + return sldns_read_uint32(rr->ttl_data+6+rlen-4); } /** do the rdata copy */ @@ -247,37 +248,40 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, sldns_pkt_section section) { uint16_t pkt_len; + uint32_t ttl; const sldns_rr_descriptor* desc; - *rr_ttl = sldns_read_uint32(rr->ttl_data); + ttl = sldns_read_uint32(rr->ttl_data); /* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */ - if((*rr_ttl & 0x80000000U)) - *rr_ttl = 0; + /* RFC 8767 Section 4. values with high-order bit as positive, not 0. ++ * As such, it will be capped by MAX_TTL below. */ if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) { /* negative response. see if TTL of SOA record larger than the * minimum-ttl in the rdata of the SOA record */ - if(*rr_ttl > soa_find_minttl(rr)) *rr_ttl = soa_find_minttl(rr); + if(ttl > soa_find_minttl(rr)) ttl = soa_find_minttl(rr); if(!SERVE_ORIGINAL_TTL) { /* If MIN_NEG_TTL is configured skip setting MIN_TTL */ - if(MIN_NEG_TTL <= 0 && *rr_ttl < MIN_TTL) { - *rr_ttl = MIN_TTL; + if(MIN_NEG_TTL <= 0 && ttl < (uint32_t)MIN_TTL) { + ttl = (uint32_t)MIN_TTL; } - if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL; + if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL; } /* 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(ttl > (uint32_t)MAX_NEG_TTL) ttl = (uint32_t)MAX_NEG_TTL; /* MIN_NEG_TTL overrides the min and max ttl of everything * else if configured; it is for a more specific record */ - if(MIN_NEG_TTL > 0 && *rr_ttl < MIN_NEG_TTL) { - *rr_ttl = MIN_NEG_TTL; + if(MIN_NEG_TTL > 0 && ttl < (uint32_t)MIN_NEG_TTL) { + ttl = (uint32_t)MIN_NEG_TTL; } } else if(!SERVE_ORIGINAL_TTL) { - if(*rr_ttl < MIN_TTL) *rr_ttl = MIN_TTL; - if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL; + if(ttl < (uint32_t)MIN_TTL) ttl = (uint32_t)MIN_TTL; + if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL; } - if(*rr_ttl < data->ttl) - data->ttl = *rr_ttl; + if((time_t)ttl < data->ttl) + data->ttl = (time_t)ttl; + /* We have concluded the TTL checks */ + *rr_ttl = (time_t)ttl; if(rr->outside_packet) { /* uncompressed already, only needs copy */ @@ -481,6 +485,7 @@ parse_copy_decompress_rrset(sldns_buffer* pkt, struct msg_parse* msg, pk->entry.key = (void*)pk; pk->entry.hash = pset->hash; data->trust = get_rrset_trust(msg, pset); + pk->rk.flags |= (data->ttl == 0) ? PACKED_RRSET_UPSTREAM_0TTL : 0; return 1; } @@ -617,6 +622,29 @@ reply_info_set_ttls(struct reply_info* rep, time_t timenow) } } +void +reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add) +{ + size_t i, j; + rep->ttl = ttl; + rep->prefetch_ttl = PREFETCH_TTL_CALC(ttl); + rep->serve_expired_ttl = ttl + SERVE_EXPIRED_TTL; + /* Don't set rep->serve_expired_norec_ttl; this should only be set + * on cached records when encountering an error */ + log_assert(rep->serve_expired_norec_ttl == 0); + for(i=0; i<rep->rrset_count; i++) { + struct packed_rrset_data* data = (struct packed_rrset_data*) + rep->ref[i].key->entry.data; + if(i>0 && rep->ref[i].key == rep->ref[i-1].key) + continue; + data->ttl = ttl; + for(j=0; j<data->count + data->rrsig_count; j++) { + data->rr_ttl[j] = ttl; + } + data->ttl_add = ttl_add; + } +} + void reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc) { |
