]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- ttl-zero-cacherep, Responses in the last second of their cache TTL,
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 11 Nov 2024 14:43:10 +0000 (15:43 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 11 Nov 2024 14:43:10 +0000 (15:43 +0100)
  get an extra second. That makes the TTL not 0, since they are from
  cache and can be cached by the client.

cachedb/cachedb.c
daemon/worker.c
services/authzone.c
services/localzone.c
services/mesh.c
services/rpz.c
testcode/unitmain.c
testdata/serve_expired_client_timeout_no_prefetch.rpl
util/data/msgencode.c
util/data/msgencode.h

index eca3b7cb75cd56a39278a035c5bdefd71537e2a9..24f458e8f54e4d9abd22c9c93052eb01cd08d185 100644 (file)
@@ -419,7 +419,7 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
                        qstate->return_msg->rep);
        if(!reply_info_answer_encode(&qstate->return_msg->qinfo,
                qstate->return_msg->rep, 0, qstate->query_flags,
-               buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0))
+               buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0, 1))
                return 0;
 
        /* TTLs in the return_msg are relative to time(0) so we have to
index 713de316373aedd018fae774d474cd6a32a28a74..7bce4d5a1b26ed653ad7da17e8180aaa6f93206d 100644 (file)
@@ -564,7 +564,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
        }
        if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
                repinfo->c->buffer, 0, 1, worker->scratchpad,
-               udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
+               udpsize, edns, (int)(edns->bits & EDNS_DO), secure, 1)) {
                if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
                        LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
                        worker->env.now_tv))
@@ -802,7 +802,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
                if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
                        repinfo->c->buffer, timenow, 1, worker->scratchpad,
                        udpsize, edns, (int)(edns->bits & EDNS_DO),
-                       *is_secure_answer)) {
+                       *is_secure_answer, 1)) {
                        if(!inplace_cb_reply_servfail_call(&worker->env, qinfo,
                                NULL, NULL, LDNS_RCODE_SERVFAIL, edns, repinfo,
                                worker->scratchpad, worker->env.now_tv))
index 6f6c55d4397dedbc6d1ccb8c916275d62a88945b..90a1e4cb2f2a648413322eb5818f7b35bc78cb7d 100644 (file)
@@ -3542,7 +3542,7 @@ auth_answer_encode(struct query_info* qinfo, struct module_env* env,
                *(uint16_t*)sldns_buffer_begin(buf),
                sldns_buffer_read_u16_at(buf, 2),
                buf, 0, 0, temp, udpsize, edns,
-               (int)(edns->bits&EDNS_DO), 0)) {
+               (int)(edns->bits&EDNS_DO), 0, 0)) {
                error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
                        *(uint16_t*)sldns_buffer_begin(buf),
                        sldns_buffer_read_u16_at(buf, 2), edns);
index d21e0c48aedb8a72793487787de6ec3a42df51fb..5314319aaff4bd0247f2c52aab3dbfa15f0374d6 100644 (file)
@@ -1322,7 +1322,7 @@ local_encode(struct query_info* qinfo, struct module_env* env,
        if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
                repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep,
                *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
-               buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
+               buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0, 0)) {
                error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
                        *(uint16_t*)sldns_buffer_begin(buf),
                        sldns_buffer_read_u16_at(buf, 2), edns);
index 156cde79198d5ba57eae7b67c4dc574d7d54f8f2..f864437b2d21dfd361cf02b18a3ee97fb1316bdd 100644 (file)
@@ -1263,7 +1263,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
                        !reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
                        r->qflags, r->buf, 0, 1,
                        m->s.env->scratch, udp_size, &r->edns,
-                       (int)(r->edns.bits & EDNS_DO), secure))
+                       (int)(r->edns.bits & EDNS_DO), secure, 0))
                {
                        fptr_ok(fptr_whitelist_mesh_cb(r->cb));
                        (*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
@@ -1451,7 +1451,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                        !reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
                        r->qflags, r_buffer, 0, 1, m->s.env->scratch,
                        udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
-                       secure))
+                       secure, 0))
                {
                        if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
                        rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
index 3b92ee53837e4a307d41480e22962054af8a5e21..162881c2face02d276facbcea840f7277705181c 100644 (file)
@@ -1807,7 +1807,7 @@ rpz_local_encode(struct module_env* env, struct query_info* qinfo,
                repinfo, temp, env->now_tv) ||
          !reply_info_answer_encode(qinfo, &rep,
                *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
-               buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
+               buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0, 0)) {
                error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
                        *(uint16_t*)sldns_buffer_begin(buf),
                        sldns_buffer_read_u16_at(buf, 2), edns);
index 653d3efbe9040745d54bc000b87943755e244156..763c9385f72e22c901f22a4169b82a8db4f3e203 100644 (file)
@@ -1110,7 +1110,7 @@ static void edns_ede_encode_encodedecode(struct query_info* qinfo,
        /* encode */
        unit_assert(
                reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt,
-               0, 0, region, 65535, edns, 0, 0));
+               0, 0, region, 65535, edns, 0, 0, 0));
        /* buffer ready for reading; skip after the question section */
        sldns_buffer_skip(pkt, LDNS_HEADER_SIZE);
        (void)query_dname_len(pkt);
index aed397d9e9ae35d42862480d351ac5b8e499dd09..0177dd14af6a5e0d03f82b4da484f28ef3f7e434 100644 (file)
@@ -98,11 +98,11 @@ ENTRY_BEGIN
        SECTION QUESTION
                example.com. IN A
        SECTION ANSWER
-               example.com.  0 IN A 5.6.7.8
+               example.com.  1 IN A 5.6.7.8
        SECTION AUTHORITY
-               example.com. 3590 IN NS ns.example.com.
+               example.com. 3591 IN NS ns.example.com.
        SECTION ADDITIONAL
-               ns.example.com. 3590 IN A 1.2.3.4
+               ns.example.com. 3591 IN A 1.2.3.4
 ENTRY_END
 
 ; If a prefetch triggers the test will fail with 'messages pending'.
index 6d116fb52d6d29204fd9cdb553faa05d666ec5a0..3129018db90f0cf46fd155563f2cf671c46f4ba5 100644 (file)
@@ -997,7 +997,7 @@ int
 reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, 
        uint16_t id, uint16_t qflags, sldns_buffer* pkt, time_t timenow,
        int cached, struct regional* region, uint16_t udpsize, 
-       struct edns_data* edns, int dnssec, int secure)
+       struct edns_data* edns, int dnssec, int secure, int cached_ttl)
 {
        uint16_t flags;
        unsigned int attach_edns = 0;
@@ -1022,6 +1022,17 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
                flags &= ~BIT_AD;
        }
        log_assert(flags & BIT_QR); /* QR bit must be on in our replies */
+       if(cached_ttl && rep->ttl - timenow == 0) {
+               /* The last remaining second of the TTL for a cached response
+                * is replied. This makes a 0 in the protocol message. The
+                * response is valid for the cache, but the DNS TTL 0 item
+                * causes the received to drop the contents. Even though the
+                * contents are cachable, so the time used is decremented
+                * to change that into 1 second, and it can be cached, and
+                * used for expired response generation, and does not give
+                * repeated queries during that last second. */
+               timenow --;
+       }
        if(udpsize < LDNS_HEADER_SIZE)
                return 0;
        /* currently edns does not change during calculations;
index 6aff06099ee97f9b950c0f77ab472ce24f9327ac..bff6f7a40bbf75fd12f2b821c011c440b9b23009 100644 (file)
@@ -64,12 +64,16 @@ struct edns_data;
  *     or if edns_present = 0, it is not included.
  * @param dnssec: if 0 DNSSEC records are omitted from the answer.
  * @param secure: if 1, the AD bit is set in the reply.
+ * @param cached_ttl: the ttl is from a cache response. So that means it
+ *     was some value minus the current time, and not an authoritative
+ *     response with an autoritative TTL or a direct upstream response,
+ *     that could have upstream TTL 0 items.
  * @return: 0 on error (server failure).
  */
 int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, 
        uint16_t id, uint16_t qflags, struct sldns_buffer* dest, time_t timenow,
        int cached, struct regional* region, uint16_t udpsize, 
-       struct edns_data* edns, int dnssec, int secure);
+       struct edns_data* edns, int dnssec, int secure, int cached_ttl);
 
 /**
  * Regenerate the wireformat from the stored msg reply.