Handle zero-timeout RRs in subqueries correctly.

This commit is contained in:
Tony Garnock-Jones 2012-12-06 16:00:58 -05:00
parent 392d9d4091
commit d1e130961f
3 changed files with 22 additions and 54 deletions

47
TODO
View File

@ -34,50 +34,3 @@ doesn't make sense to apply there.
It probably shouldn't cache SOA records at all. Djbdns doesn't.
("dnscache does not cache SOA records", from http://cr.yp.to/djbdns/dnscache.html)
### Zero-timeout RRs in subqueries
Currently they make it appear that there are no available answers!
E.g. this IN A query for maps.bpl.org. Note the zero-timeout A records
that come back from dns-lproof2.
1348086228 DNS: '#s(udp-address "127.0.0.1" 41127) asks '#s(udp-listener 5555) 44280
1348086228 : (list (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f))
1348086228 dns-vm PID 114447 ((packet-relay #s(active-request #s(udp-address 127.0.0.1 41127) 44280))) started
1348086228 DNS: (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f)
1348086228 dns-vm PID 114448 ((question-handler #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))) started
1348086228 dns-vm PID 114449 ((network-query #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))) started
1348086228 DNS: (question (domain '(#"dns-lproof1" #"bpl" #"org") '(#"dns-lproof1" #"bpl" #"org")) 'a 'in (ns-subq (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f)))
1348086228 dns-vm PID 114450 ((question-handler #s(question #(struct:domain (dns-lproof1 bpl org) (dns-lproof1 bpl org)) a in #s((ns-subq subquestion 1) #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))))) started
1348086228 DNS: (answered-question (question (domain '(#"dns-lproof1" #"bpl" #"org") '(#"dns-lproof1" #"bpl" #"org")) 'a 'in (ns-subq (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f))) (complete-answer (set (rr (domain '(#"dns-lproof1" #"bpl" #"org") '(#"dns-lproof1" #"bpl" #"org")) 'a 'in 9484 '#(192 80 65 2))) (set) (set)))
1348086228 dns-vm PID 114450 ((question-handler #s(question #(struct:domain (dns-lproof1 bpl org) (dns-lproof1 bpl org)) a in #s((ns-subq subquestion 1) #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))))) garbage-collected
1348086228 DNS: '(request network-query/allocate-query-id441781 allocate-query-id)
1348086228 DNS: '(reply network-query/allocate-query-id441781 11080)
1348086228 DNS: '#s(udp-handle dns-client) asks '#s(udp-address "192.80.65.2" 53) 11080
1348086228 : (list (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f))
1348086228 DNS: '#s(set-timer (#s(udp-handle dns-client) 11080) 3000 relative)
1348086231 DNS: '#s(timer-expired (#s(udp-handle dns-client) 11080) 1348086231475.239)
1348086231 DNS: (question (domain '(#"dns-lproof2" #"bpl" #"org") '(#"dns-lproof2" #"bpl" #"org")) 'a 'in (ns-subq (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f)))
1348086231 DNS: '(release-query-id 11080)
1348086231 dns-vm PID 114451 ((question-handler #s(question #(struct:domain (dns-lproof2 bpl org) (dns-lproof2 bpl org)) a in #s((ns-subq subquestion 1) #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))))) started
1348086231 DNS: (answered-question (question (domain '(#"dns-lproof2" #"bpl" #"org") '(#"dns-lproof2" #"bpl" #"org")) 'a 'in (ns-subq (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f))) (complete-answer (set (rr (domain '(#"dns-lproof2" #"bpl" #"org") '(#"dns-lproof2" #"bpl" #"org")) 'a 'in 9481 '#(216 236 248 2))) (set) (set)))
1348086231 dns-vm PID 114451 ((question-handler #s(question #(struct:domain (dns-lproof2 bpl org) (dns-lproof2 bpl org)) a in #s((ns-subq subquestion 1) #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))))) garbage-collected
1348086231 DNS: '(request network-query/allocate-query-id441790 allocate-query-id)
1348086231 DNS: '(reply network-query/allocate-query-id441790 8847)
1348086231 DNS: '#s(udp-handle dns-client) asks '#s(udp-address "216.236.248.2" 53) 8847
1348086231 : (list (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f))
1348086231 DNS: '#s(set-timer (#s(udp-handle dns-client) 8847) 3000 relative)
1348086231 DNS: '#s(udp-address "216.236.248.2" 53) answers '#s(udp-handle dns-client)
1348086231 : (dns-message 8847 'response 'query 'authoritative 'not-truncated 'no-recursion-desired 'no-recursion-available 'no-error (list (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f)) (list (rr (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in 0 '#(216 236 252 42)) (rr (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in 0 '#(192 80 65 42))) '() '())
1348086231 DNS: (network-reply 'referral441777 (complete-answer (set (rr (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in 0 '#(192 80 65 42)) (rr (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in 0 '#(216 236 252 42))) (set) (set)))
1348086231 DNS: '(release-query-id 8847)
1348086231 dns-vm PID 114449 ((network-query #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))) garbage-collected
1348086231 DNS: (answered-question (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f) (complete-answer (set) (set) (set)))
1348086231 DNS: (set-timer (list 'check-dns-expiry (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org"))) 0 'relative)
1348086231 dns-vm PID 114448 ((question-handler #s(question #(struct:domain (maps bpl org) (maps bpl org)) a in #f))) garbage-collected
1348086231 DNS: '#s(udp-listener 5555) answers '#s(udp-address "127.0.0.1" 41127)
1348086231 : (dns-message 44280 'response 'query 'non-authoritative 'not-truncated 'recursion-desired 'recursion-available 'no-error (list (question (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org")) 'a 'in #f)) '() '() '())
1348086231 dns-vm PID 114447 ((packet-relay #s(active-request #s(udp-address 127.0.0.1 41127) 44280))) garbage-collected
1348086231 DNS: (timer-expired (list 'check-dns-expiry (domain '(#"maps" #"bpl" #"org") '(#"maps" #"bpl" #"org"))) 1348086231532.27)

View File

@ -207,7 +207,7 @@
(endpoint #:subscriber (network-reply (wild) (wild))
#:state zone
[(network-reply _ answer)
(let-values (((new-zone timers) (incorporate-complete-answer answer zone)))
(let-values (((new-zone timers) (incorporate-complete-answer answer zone #t)))
(transition-and-set-timers new-zone timers))])
(endpoint #:subscriber (timer-expired (list 'check-dns-expiry (wild)) (wild))
#:state zone
@ -255,7 +255,7 @@
(delete-endpoint referral-id)
(send-message (answered-question q #f)))]
[(network-reply (== referral-id) ans)
(let-values (((new-zone ignored-timers) (incorporate-complete-answer ans zone)))
(let-values (((new-zone ignored-timers) (incorporate-complete-answer ans zone #f)))
(when (log-level? (current-logger) 'debug)
(log-debug (format "Referral ~v results in origin ~v:~n"
referral-id zone-origin))

View File

@ -75,7 +75,20 @@
;; being non-expiring with an InfiniteLifetime.
(define ((incorporate-rr base-time) resource0 db)
(define expiry (if base-time
(+ base-time (rr-ttl resource0))
(if (zero? (rr-ttl resource0))
;; We are definitely not caching this
;; resource then, because we are not even
;; called by incorporate-complete-answer in
;; case of 0-TTL and the cache. This record
;; is transient and used just for the current
;; resolution. Storing it with a real 0-TTL
;; would mean it immediately is ignored,
;; which is silly, so store it with an
;; infinite-lifetime instead.
(infinite-lifetime 0)
;; Otherwise it has a normal TTL, which we
;; honour.
(+ base-time (rr-ttl resource0)))
(infinite-lifetime (rr-ttl resource0))))
(define resource (struct-copy rr resource0 [ttl 0]))
(define name (rr-name resource))
@ -89,8 +102,8 @@
[else ;; old record finite-lifetime but expiring after the new expiry: leave it alone
db]))
;; Maybe<CompleteAnswer> CompiledZone -> (values CompiledZone Timers)
(define (incorporate-complete-answer ans db)
;; Maybe<CompleteAnswer> CompiledZone Boolean -> (values CompiledZone Timers)
(define (incorporate-complete-answer ans db is-cache?)
(match ans
[#f
(values db (set))]
@ -98,8 +111,10 @@
(define now (current-inexact-seconds))
(for/fold ([db db] [timers (set)])
([rr (in-sequences ns us ds)])
(values ((incorporate-rr now) rr db)
(set-add timers (cons (rr-name rr) (rr-ttl rr)))))]))
(if (and is-cache? (zero? (rr-ttl rr))) ;; Do not *cache* 0-TTL RRs (RFC 1034 3.6)
(values db timers)
(values ((incorporate-rr now) rr db)
(set-add timers (cons (rr-name rr) (rr-ttl rr))))))]))
;; CompiledZone DomainName -> CompiledZone
;; Checks the given name to see if there are any expiring records, and