redis cache?

Hi,

Will unbound _only_ serve hits from redis cache for keys with expired
TTL if the configuration option "serve-expired: yes" is set?

I've just tested redis cache very briefly, and it looks like keys with
an expired TTL didn't get updated then I asked for the same name again.
(If recursion happened, why not update the TTL in cachedb too?)

(I can't find much documentation about how it's expected to work)

Re,

/P

I’m not sure if I understand your question correctly, but IIRC the
intended behavior for the mixture of cachedb (regardless of the type
of the backend, redis or not) and serve-expired is as follows:

  • when unbound finds an expired answer for a received query in
    in-memory cache, it will still return it to the client if
    sever-expired is yes. it will also initiate a “prefetch” of the
    answer to possibly update the expired answer.
  • in a prefetch, any cache including cachedb is ignored and it should
    always cause recursive DNS resolution
  • If the recursive resolution succeeds, unbound updates its in-memory
    cache and cachedb backend with the updated answer

I’ve not played with this feature for some time, so something may have
changed since then. But I believe it worked as described above last
time I tested the feature. A quick read of the latest code also
seems to suggest it’s still working that way.

Does this explanation answer your question? Or are you saying that
this is your expected behavior but unbound doesn’t work this way for
you?

Hi Jinmei,

Ah, my test was very brief and simple, and I didn’t have prefetch enabled.
But getting the full picture it makes sense on how it all fits together.

Thanks for the explanation, I tested it again with all options enabled,
and yes now it works better.

Good to know it now works, but if you had to explicitly enable
prefetch, that actually doesn’t sound right. In my
understanding, a prefetch should be attempted when you enable
serve-expired and use expired answer even if prefetch itself is
disabled in the configuration. The most relevant part of the source
code suggests that’s the case:

if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
&& worker->env.now >=
((struct reply_info
)e->data)->prefetch_ttl) {
[…]
reply_and_prefetch(worker, lookup_qinfo,
sldns_buffer_read_u16_at(c->buffer, 2),
repinfo, leeway);

So if it really required to enable prefetch, that may actually be some
kind of bug. But in any case…

(perhaps that should be added to the man page under cachedb)

…it’s more about how serve-expired works in general, rather than
how it should interact with cachedb.

No, your right, it works the way your describing it (even without
serve-expired and/or prefetch enabled).

There must have been something incomplete/wrongly configured then I did
the first brief test, because now I observe the expected behavior with
regards to redis updates.

However, there's a problem with cachedb then you restart unbound
(serve-expired enabled or not).

Even though there's non-expired data in redis, for example this
wikipedia.org RR :

~$ python ./unbound-1.8.3/contrib/unbound-querycachedb.py wikipedia.org
;; query=wikipedia.org/IN/A
;; key=6E5D4AD1B127B12236AD9834A75C85B4BFE0BD0D536378E93D6778EA44DFA1D8
;; Now=1548575380, TimeStamp=1548574948, Expire=1548575548, TTL=168
id 0
opcode QUERY
rcode NOERROR
flags QR RD RA
edns 0
eflags DO
payload 4096
;QUESTION
wikipedia.org. IN A
;ANSWER
wikipedia.org. 600 IN A 91.198.174.192
;AUTHORITY
;ADDITIONAL

Unbound returns SERVFAIL, and will continue to do so until the TTL in
redis expires.

~$ dig wikipedia.org

; <<>> DiG 9.8.3-P1 <<>> wikipedia.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 3738
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;wikipedia.org. IN A

;; Query time: 3 msec
;; SERVER: 100.64.1.10#53(100.64.1.10)
;; WHEN: Sun Jan 27 08:49:38 2019
;; MSG SIZE rcvd: 31

After the TTL has expired in redis, and if serve-expired is enabled, the
first query will still get a SERVFAIL (but now prefetch goes out in the
background and updates cachedb) and after that's done, the next query
will be given a correct answer. and after this no more SERVFAILs happens
for that RR even then the TTL expires in redis.

/P