2 * daemon/cachedump.c - dump the cache to text format.
4 * Copyright (c) 2008, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * This file contains functions to read and write the cache(s)
43 #include <openssl/ssl.h>
44 #include "daemon/cachedump.h"
45 #include "daemon/remote.h"
46 #include "daemon/worker.h"
47 #include "services/cache/rrset.h"
48 #include "services/cache/dns.h"
49 #include "services/cache/infra.h"
50 #include "util/data/msgreply.h"
51 #include "util/regional.h"
52 #include "util/net_help.h"
53 #include "util/data/dname.h"
54 #include "iterator/iterator.h"
55 #include "iterator/iter_delegpt.h"
56 #include "iterator/iter_utils.h"
57 #include "iterator/iter_fwd.h"
58 #include "iterator/iter_hints.h"
59 #include "ldns/sbuffer.h"
60 #include "ldns/wire2str.h"
61 #include "ldns/str2wire.h"
63 /** dump one rrset zonefile line */
65 dump_rrset_line(SSL
* ssl
, struct ub_packed_rrset_key
* k
, time_t now
, size_t i
)
68 if(!packed_rr_to_string(k
, i
, now
, s
, sizeof(s
))) {
69 return ssl_printf(ssl
, "BADRR\n");
71 return ssl_printf(ssl
, "%s", s
);
74 /** dump rrset key and data info */
76 dump_rrset(SSL
* ssl
, struct ub_packed_rrset_key
* k
,
77 struct packed_rrset_data
* d
, time_t now
)
80 /* rd lock held by caller */
81 if(!k
|| !d
) return 1;
82 if(d
->ttl
< now
) return 1; /* expired */
85 if(!ssl_printf(ssl
, ";rrset%s " ARG_LL
"d %u %u %d %d\n",
86 (k
->rk
.flags
& PACKED_RRSET_NSEC_AT_APEX
)?" nsec_apex":"",
87 (long long)(d
->ttl
- now
),
88 (unsigned)d
->count
, (unsigned)d
->rrsig_count
,
89 (int)d
->trust
, (int)d
->security
92 for(i
=0; i
<d
->count
+ d
->rrsig_count
; i
++) {
93 if(!dump_rrset_line(ssl
, k
, now
, i
))
99 /** dump lruhash rrset cache */
101 dump_rrset_lruhash(SSL
* ssl
, struct lruhash
* h
, time_t now
)
103 struct lruhash_entry
* e
;
104 /* lruhash already locked by caller */
105 /* walk in order of lru; best first */
106 for(e
=h
->lru_start
; e
; e
= e
->lru_next
) {
107 lock_rw_rdlock(&e
->lock
);
108 if(!dump_rrset(ssl
, (struct ub_packed_rrset_key
*)e
->key
,
109 (struct packed_rrset_data
*)e
->data
, now
)) {
110 lock_rw_unlock(&e
->lock
);
113 lock_rw_unlock(&e
->lock
);
118 /** dump rrset cache */
120 dump_rrset_cache(SSL
* ssl
, struct worker
* worker
)
122 struct rrset_cache
* r
= worker
->env
.rrset_cache
;
124 if(!ssl_printf(ssl
, "START_RRSET_CACHE\n")) return 0;
125 for(slab
=0; slab
<r
->table
.size
; slab
++) {
126 lock_quick_lock(&r
->table
.array
[slab
]->lock
);
127 if(!dump_rrset_lruhash(ssl
, r
->table
.array
[slab
],
129 lock_quick_unlock(&r
->table
.array
[slab
]->lock
);
132 lock_quick_unlock(&r
->table
.array
[slab
]->lock
);
134 return ssl_printf(ssl
, "END_RRSET_CACHE\n");
137 /** dump message to rrset reference */
139 dump_msg_ref(SSL
* ssl
, struct ub_packed_rrset_key
* k
)
142 nm
= sldns_wire2str_dname(k
->rk
.dname
, k
->rk
.dname_len
);
143 tp
= sldns_wire2str_type(ntohs(k
->rk
.type
));
144 cl
= sldns_wire2str_class(ntohs(k
->rk
.rrset_class
));
145 if(!nm
|| !cl
|| !tp
) {
149 return ssl_printf(ssl
, "BADREF\n");
151 if(!ssl_printf(ssl
, "%s %s %s %d\n", nm
, cl
, tp
, (int)k
->rk
.flags
)) {
164 /** dump message entry */
166 dump_msg(SSL
* ssl
, struct query_info
* k
, struct reply_info
* d
,
171 if(!k
|| !d
) return 1;
172 if(d
->ttl
< now
) return 1; /* expired */
174 nm
= sldns_wire2str_dname(k
->qname
, k
->qname_len
);
175 tp
= sldns_wire2str_type(k
->qtype
);
176 cl
= sldns_wire2str_class(k
->qclass
);
177 if(!nm
|| !tp
|| !cl
) {
181 return 1; /* skip this entry */
183 if(!rrset_array_lock(d
->ref
, d
->rrset_count
, now
)) {
184 /* rrsets have timed out or do not exist */
188 return 1; /* skip this entry */
192 if(!ssl_printf(ssl
, "msg %s %s %s %d %d " ARG_LL
"d %d %u %u %u\n",
194 (int)d
->flags
, (int)d
->qdcount
,
195 (long long)(d
->ttl
-now
), (int)d
->security
,
196 (unsigned)d
->an_numrrsets
,
197 (unsigned)d
->ns_numrrsets
,
198 (unsigned)d
->ar_numrrsets
)) {
202 rrset_array_unlock(d
->ref
, d
->rrset_count
);
209 for(i
=0; i
<d
->rrset_count
; i
++) {
210 if(!dump_msg_ref(ssl
, d
->rrsets
[i
])) {
211 rrset_array_unlock(d
->ref
, d
->rrset_count
);
215 rrset_array_unlock(d
->ref
, d
->rrset_count
);
220 /** copy msg to worker pad */
222 copy_msg(struct regional
* region
, struct lruhash_entry
* e
,
223 struct query_info
** k
, struct reply_info
** d
)
225 struct reply_info
* rep
= (struct reply_info
*)e
->data
;
226 *d
= (struct reply_info
*)regional_alloc_init(region
, e
->data
,
227 sizeof(struct reply_info
) +
228 sizeof(struct rrset_ref
) * (rep
->rrset_count
-1) +
229 sizeof(struct ub_packed_rrset_key
*) * rep
->rrset_count
);
232 (*d
)->rrsets
= (struct ub_packed_rrset_key
**)(void *)(
233 (uint8_t*)(&((*d
)->ref
[0])) +
234 sizeof(struct rrset_ref
) * rep
->rrset_count
);
235 *k
= (struct query_info
*)regional_alloc_init(region
,
236 e
->key
, sizeof(struct query_info
));
239 (*k
)->qname
= regional_alloc_init(region
,
240 (*k
)->qname
, (*k
)->qname_len
);
241 return (*k
)->qname
!= NULL
;
244 /** dump lruhash msg cache */
246 dump_msg_lruhash(SSL
* ssl
, struct worker
* worker
, struct lruhash
* h
)
248 struct lruhash_entry
* e
;
249 struct query_info
* k
;
250 struct reply_info
* d
;
252 /* lruhash already locked by caller */
253 /* walk in order of lru; best first */
254 for(e
=h
->lru_start
; e
; e
= e
->lru_next
) {
255 regional_free_all(worker
->scratchpad
);
256 lock_rw_rdlock(&e
->lock
);
257 /* make copy of rrset in worker buffer */
258 if(!copy_msg(worker
->scratchpad
, e
, &k
, &d
)) {
259 lock_rw_unlock(&e
->lock
);
262 lock_rw_unlock(&e
->lock
);
263 /* release lock so we can lookup the rrset references
264 * in the rrset cache */
265 if(!dump_msg(ssl
, k
, d
, *worker
->env
.now
)) {
272 /** dump msg cache */
274 dump_msg_cache(SSL
* ssl
, struct worker
* worker
)
276 struct slabhash
* sh
= worker
->env
.msg_cache
;
278 if(!ssl_printf(ssl
, "START_MSG_CACHE\n")) return 0;
279 for(slab
=0; slab
<sh
->size
; slab
++) {
280 lock_quick_lock(&sh
->array
[slab
]->lock
);
281 if(!dump_msg_lruhash(ssl
, worker
, sh
->array
[slab
])) {
282 lock_quick_unlock(&sh
->array
[slab
]->lock
);
285 lock_quick_unlock(&sh
->array
[slab
]->lock
);
287 return ssl_printf(ssl
, "END_MSG_CACHE\n");
291 dump_cache(SSL
* ssl
, struct worker
* worker
)
293 if(!dump_rrset_cache(ssl
, worker
))
295 if(!dump_msg_cache(ssl
, worker
))
297 return ssl_printf(ssl
, "EOF\n");
300 /** read a line from ssl into buffer */
302 ssl_read_buf(SSL
* ssl
, sldns_buffer
* buf
)
304 return ssl_read_line(ssl
, (char*)sldns_buffer_begin(buf
),
305 sldns_buffer_capacity(buf
));
308 /** check fixed text on line */
310 read_fixed(SSL
* ssl
, sldns_buffer
* buf
, const char* str
)
312 if(!ssl_read_buf(ssl
, buf
)) return 0;
313 return (strcmp((char*)sldns_buffer_begin(buf
), str
) == 0);
316 /** load an RR into rrset */
318 load_rr(SSL
* ssl
, sldns_buffer
* buf
, struct regional
* region
,
319 struct ub_packed_rrset_key
* rk
, struct packed_rrset_data
* d
,
320 unsigned int i
, int is_rrsig
, int* go_on
, time_t now
)
322 uint8_t rr
[LDNS_RR_BUF_SIZE
];
323 size_t rr_len
= sizeof(rr
), dname_len
= 0;
327 if(!ssl_read_buf(ssl
, buf
))
329 if(strncmp((char*)sldns_buffer_begin(buf
), "BADRR\n", 6) == 0) {
333 status
= sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf
), rr
,
334 &rr_len
, &dname_len
, 3600, NULL
, 0, NULL
, 0);
336 log_warn("error cannot parse rr: %s: %s",
337 sldns_get_errorstr_parse(status
),
338 (char*)sldns_buffer_begin(buf
));
341 if(is_rrsig
&& sldns_wirerr_get_type(rr
, rr_len
, dname_len
)
342 != LDNS_RR_TYPE_RRSIG
) {
343 log_warn("error expected rrsig but got %s",
344 (char*)sldns_buffer_begin(buf
));
348 /* convert ldns rr into packed_rr */
349 d
->rr_ttl
[i
] = (time_t)sldns_wirerr_get_ttl(rr
, rr_len
, dname_len
) + now
;
350 sldns_buffer_clear(buf
);
351 d
->rr_len
[i
] = sldns_wirerr_get_rdatalen(rr
, rr_len
, dname_len
)+2;
352 d
->rr_data
[i
] = (uint8_t*)regional_alloc_init(region
,
353 sldns_wirerr_get_rdatawl(rr
, rr_len
, dname_len
), d
->rr_len
[i
]);
355 log_warn("error out of memory");
359 /* if first entry, fill the key structure */
361 rk
->rk
.type
= htons(sldns_wirerr_get_type(rr
, rr_len
, dname_len
));
362 rk
->rk
.rrset_class
= htons(sldns_wirerr_get_class(rr
, rr_len
, dname_len
));
363 rk
->rk
.dname_len
= dname_len
;
364 rk
->rk
.dname
= regional_alloc_init(region
, rr
, dname_len
);
366 log_warn("error out of memory");
374 /** move entry into cache */
376 move_into_cache(struct ub_packed_rrset_key
* k
,
377 struct packed_rrset_data
* d
, struct worker
* worker
)
379 struct ub_packed_rrset_key
* ak
;
380 struct packed_rrset_data
* ad
;
381 size_t s
, i
, num
= d
->count
+ d
->rrsig_count
;
382 struct rrset_ref ref
;
385 ak
= alloc_special_obtain(&worker
->alloc
);
387 log_warn("error out of memory");
390 ak
->entry
.data
= NULL
;
392 ak
->entry
.hash
= rrset_key_hash(&k
->rk
);
393 ak
->rk
.dname
= (uint8_t*)memdup(k
->rk
.dname
, k
->rk
.dname_len
);
395 log_warn("error out of memory");
396 ub_packed_rrset_parsedelete(ak
, &worker
->alloc
);
399 s
= sizeof(*ad
) + (sizeof(size_t) + sizeof(uint8_t*) +
400 sizeof(time_t))* num
;
403 ad
= (struct packed_rrset_data
*)malloc(s
);
405 log_warn("error out of memory");
406 ub_packed_rrset_parsedelete(ak
, &worker
->alloc
);
410 memmove(p
, d
, sizeof(*ad
));
412 memmove(p
, &d
->rr_len
[0], sizeof(size_t)*num
);
413 p
+= sizeof(size_t)*num
;
414 memmove(p
, &d
->rr_data
[0], sizeof(uint8_t*)*num
);
415 p
+= sizeof(uint8_t*)*num
;
416 memmove(p
, &d
->rr_ttl
[0], sizeof(time_t)*num
);
417 p
+= sizeof(time_t)*num
;
418 for(i
=0; i
<num
; i
++) {
419 memmove(p
, d
->rr_data
[i
], d
->rr_len
[i
]);
422 packed_rrset_ptr_fixup(ad
);
428 (void)rrset_cache_update(worker
->env
.rrset_cache
, &ref
,
429 &worker
->alloc
, *worker
->env
.now
);
433 /** load an rrset entry */
435 load_rrset(SSL
* ssl
, sldns_buffer
* buf
, struct worker
* worker
)
437 char* s
= (char*)sldns_buffer_begin(buf
);
438 struct regional
* region
= worker
->scratchpad
;
439 struct ub_packed_rrset_key
* rk
;
440 struct packed_rrset_data
* d
;
441 unsigned int rr_count
, rrsig_count
, trust
, security
;
445 regional_free_all(region
);
447 rk
= (struct ub_packed_rrset_key
*)regional_alloc_zero(region
,
449 d
= (struct packed_rrset_data
*)regional_alloc_zero(region
, sizeof(*d
));
451 log_warn("error out of memory");
455 if(strncmp(s
, ";rrset", 6) != 0) {
456 log_warn("error expected ';rrset' but got %s", s
);
460 if(strncmp(s
, " nsec_apex", 10) == 0) {
462 rk
->rk
.flags
|= PACKED_RRSET_NSEC_AT_APEX
;
464 if(sscanf(s
, " " ARG_LL
"d %u %u %u %u", &ttl
, &rr_count
, &rrsig_count
,
465 &trust
, &security
) != 5) {
466 log_warn("error bad rrset spec %s", s
);
469 if(rr_count
== 0 && rrsig_count
== 0) {
470 log_warn("bad rrset without contents");
473 d
->count
= (size_t)rr_count
;
474 d
->rrsig_count
= (size_t)rrsig_count
;
475 d
->security
= (enum sec_status
)security
;
476 d
->trust
= (enum rrset_trust
)trust
;
477 d
->ttl
= (time_t)ttl
+ *worker
->env
.now
;
479 d
->rr_len
= regional_alloc_zero(region
,
480 sizeof(size_t)*(d
->count
+d
->rrsig_count
));
481 d
->rr_ttl
= regional_alloc_zero(region
,
482 sizeof(time_t)*(d
->count
+d
->rrsig_count
));
483 d
->rr_data
= regional_alloc_zero(region
,
484 sizeof(uint8_t*)*(d
->count
+d
->rrsig_count
));
485 if(!d
->rr_len
|| !d
->rr_ttl
|| !d
->rr_data
) {
486 log_warn("error out of memory");
490 /* read the rr's themselves */
491 for(i
=0; i
<rr_count
; i
++) {
492 if(!load_rr(ssl
, buf
, region
, rk
, d
, i
, 0,
493 &go_on
, *worker
->env
.now
)) {
494 log_warn("could not read rr %u", i
);
498 for(i
=0; i
<rrsig_count
; i
++) {
499 if(!load_rr(ssl
, buf
, region
, rk
, d
, i
+rr_count
, 1,
500 &go_on
, *worker
->env
.now
)) {
501 log_warn("could not read rrsig %u", i
);
506 /* skip this entry */
510 return move_into_cache(rk
, d
, worker
);
513 /** load rrset cache */
515 load_rrset_cache(SSL
* ssl
, struct worker
* worker
)
517 sldns_buffer
* buf
= worker
->env
.scratch_buffer
;
518 if(!read_fixed(ssl
, buf
, "START_RRSET_CACHE")) return 0;
519 while(ssl_read_buf(ssl
, buf
) &&
520 strcmp((char*)sldns_buffer_begin(buf
), "END_RRSET_CACHE")!=0) {
521 if(!load_rrset(ssl
, buf
, worker
))
527 /** read qinfo from next three words */
529 load_qinfo(char* str
, struct query_info
* qinfo
, struct regional
* region
)
531 /* s is part of the buf */
533 uint8_t rr
[LDNS_RR_BUF_SIZE
];
534 size_t rr_len
= sizeof(rr
), dname_len
= 0;
537 /* skip three words */
538 s
= strchr(str
, ' ');
539 if(s
) s
= strchr(s
+1, ' ');
540 if(s
) s
= strchr(s
+1, ' ');
542 log_warn("error line too short, %s", str
);
549 status
= sldns_str2wire_rr_question_buf(str
, rr
, &rr_len
, &dname_len
,
552 log_warn("error cannot parse: %s %s",
553 sldns_get_errorstr_parse(status
), str
);
556 qinfo
->qtype
= sldns_wirerr_get_type(rr
, rr_len
, dname_len
);
557 qinfo
->qclass
= sldns_wirerr_get_class(rr
, rr_len
, dname_len
);
558 qinfo
->qname_len
= dname_len
;
559 qinfo
->qname
= (uint8_t*)regional_alloc_init(region
, rr
, dname_len
);
561 log_warn("error out of memory");
568 /** load a msg rrset reference */
570 load_ref(SSL
* ssl
, sldns_buffer
* buf
, struct worker
* worker
,
571 struct regional
*region
, struct ub_packed_rrset_key
** rrset
,
574 char* s
= (char*)sldns_buffer_begin(buf
);
575 struct query_info qinfo
;
577 struct ub_packed_rrset_key
* k
;
580 if(!ssl_read_buf(ssl
, buf
))
582 if(strncmp(s
, "BADREF", 6) == 0) {
583 *go_on
= 0; /* its bad, skip it and skip message */
587 s
= load_qinfo(s
, &qinfo
, region
);
591 if(sscanf(s
, " %u", &flags
) != 1) {
592 log_warn("error cannot parse flags: %s", s
);
596 /* lookup in cache */
597 k
= rrset_cache_lookup(worker
->env
.rrset_cache
, qinfo
.qname
,
598 qinfo
.qname_len
, qinfo
.qtype
, qinfo
.qclass
,
599 (uint32_t)flags
, *worker
->env
.now
, 0);
601 /* not found or expired */
606 /* store in result */
607 *rrset
= packed_rrset_copy_region(k
, region
, *worker
->env
.now
);
608 lock_rw_unlock(&k
->entry
.lock
);
610 return (*rrset
!= NULL
);
613 /** load a msg entry */
615 load_msg(SSL
* ssl
, sldns_buffer
* buf
, struct worker
* worker
)
617 struct regional
* region
= worker
->scratchpad
;
618 struct query_info qinf
;
619 struct reply_info rep
;
620 char* s
= (char*)sldns_buffer_begin(buf
);
621 unsigned int flags
, qdcount
, security
, an
, ns
, ar
;
626 regional_free_all(region
);
628 if(strncmp(s
, "msg ", 4) != 0) {
629 log_warn("error expected msg but got %s", s
);
633 s
= load_qinfo(s
, &qinf
, region
);
638 /* read remainder of line */
639 if(sscanf(s
, " %u %u " ARG_LL
"d %u %u %u %u", &flags
, &qdcount
, &ttl
,
640 &security
, &an
, &ns
, &ar
) != 7) {
641 log_warn("error cannot parse numbers: %s", s
);
644 rep
.flags
= (uint16_t)flags
;
645 rep
.qdcount
= (uint16_t)qdcount
;
646 rep
.ttl
= (time_t)ttl
;
647 rep
.prefetch_ttl
= PREFETCH_TTL_CALC(rep
.ttl
);
648 rep
.security
= (enum sec_status
)security
;
649 rep
.an_numrrsets
= (size_t)an
;
650 rep
.ns_numrrsets
= (size_t)ns
;
651 rep
.ar_numrrsets
= (size_t)ar
;
652 rep
.rrset_count
= (size_t)an
+(size_t)ns
+(size_t)ar
;
653 rep
.rrsets
= (struct ub_packed_rrset_key
**)regional_alloc_zero(
654 region
, sizeof(struct ub_packed_rrset_key
*)*rep
.rrset_count
);
656 /* fill repinfo with references */
657 for(i
=0; i
<rep
.rrset_count
; i
++) {
658 if(!load_ref(ssl
, buf
, worker
, region
, &rep
.rrsets
[i
],
665 return 1; /* skip this one, not all references satisfied */
667 if(!dns_cache_store(&worker
->env
, &qinf
, &rep
, 0, 0, 0, NULL
, flags
)) {
668 log_warn("error out of memory");
674 /** load msg cache */
676 load_msg_cache(SSL
* ssl
, struct worker
* worker
)
678 sldns_buffer
* buf
= worker
->env
.scratch_buffer
;
679 if(!read_fixed(ssl
, buf
, "START_MSG_CACHE")) return 0;
680 while(ssl_read_buf(ssl
, buf
) &&
681 strcmp((char*)sldns_buffer_begin(buf
), "END_MSG_CACHE")!=0) {
682 if(!load_msg(ssl
, buf
, worker
))
689 load_cache(SSL
* ssl
, struct worker
* worker
)
691 if(!load_rrset_cache(ssl
, worker
))
693 if(!load_msg_cache(ssl
, worker
))
695 return read_fixed(ssl
, worker
->env
.scratch_buffer
, "EOF");
698 /** print details on a delegation point */
700 print_dp_details(SSL
* ssl
, struct worker
* worker
, struct delegpt
* dp
)
703 struct delegpt_addr
* a
;
704 int lame
, dlame
, rlame
, rto
, edns_vs
, to
, delay
,
705 tA
= 0, tAAAA
= 0, tother
= 0;
708 uint8_t edns_lame_known
;
709 for(a
= dp
->target_list
; a
; a
= a
->next_target
) {
710 addr_to_str(&a
->addr
, a
->addrlen
, buf
, sizeof(buf
));
711 if(!ssl_printf(ssl
, "%-16s\t", buf
))
714 if(!ssl_printf(ssl
, "Address is BOGUS. "))
717 /* lookup in infra cache */
719 entry_ttl
= infra_get_host_rto(worker
->env
.infra_cache
,
720 &a
->addr
, a
->addrlen
, dp
->name
, dp
->namelen
,
721 &ri
, &delay
, *worker
->env
.now
, &tA
, &tAAAA
, &tother
);
722 if(entry_ttl
== -2 && ri
.rto
>= USEFUL_SERVER_TOP_TIMEOUT
) {
723 if(!ssl_printf(ssl
, "expired, rto %d msec, tA %d "
724 "tAAAA %d tother %d.\n", ri
.rto
, tA
, tAAAA
,
729 if(entry_ttl
== -1 || entry_ttl
== -2) {
730 if(!ssl_printf(ssl
, "not in infra cache.\n"))
732 continue; /* skip stuff not in infra cache */
735 /* uses type_A because most often looked up, but other
736 * lameness won't be reported then */
737 if(!infra_get_lame_rtt(worker
->env
.infra_cache
,
738 &a
->addr
, a
->addrlen
, dp
->name
, dp
->namelen
,
739 LDNS_RR_TYPE_A
, &lame
, &dlame
, &rlame
, &rto
,
741 if(!ssl_printf(ssl
, "not in infra cache.\n"))
743 continue; /* skip stuff not in infra cache */
745 if(!ssl_printf(ssl
, "%s%s%s%srto %d msec, ttl " ARG_LL
"d, "
746 "ping %d var %d rtt %d, tA %d, tAAAA %d, tother %d",
747 lame
?"LAME ":"", dlame
?"NoDNSSEC ":"",
748 a
->lame
?"AddrWasParentSide ":"",
749 rlame
?"NoAuthButRecursive ":"", rto
, entry_ttl
,
750 ri
.srtt
, ri
.rttvar
, rtt_notimeout(&ri
),
754 if(!ssl_printf(ssl
, ", probedelay %d", delay
))
756 if(infra_host(worker
->env
.infra_cache
, &a
->addr
, a
->addrlen
,
757 dp
->name
, dp
->namelen
, *worker
->env
.now
, &edns_vs
,
758 &edns_lame_known
, &to
)) {
760 if(!ssl_printf(ssl
, ", noEDNS%s.",
761 edns_lame_known
?" probed":" assumed"))
764 if(!ssl_printf(ssl
, ", EDNS %d%s.", edns_vs
,
765 edns_lame_known
?" probed":" assumed"))
769 if(!ssl_printf(ssl
, "\n"))
774 /** print main dp info */
776 print_dp_main(SSL
* ssl
, struct delegpt
* dp
, struct dns_msg
* msg
)
778 size_t i
, n_ns
, n_miss
, n_addr
, n_res
, n_avail
;
782 for(i
=0; i
<msg
->rep
->rrset_count
; i
++) {
783 struct ub_packed_rrset_key
* k
= msg
->rep
->rrsets
[i
];
784 struct packed_rrset_data
* d
=
785 (struct packed_rrset_data
*)k
->entry
.data
;
786 if(d
->security
== sec_status_bogus
) {
787 if(!ssl_printf(ssl
, "Address is BOGUS:\n"))
790 if(!dump_rrset(ssl
, k
, d
, 0))
793 delegpt_count_ns(dp
, &n_ns
, &n_miss
);
794 delegpt_count_addr(dp
, &n_addr
, &n_res
, &n_avail
);
795 /* since dp has not been used by iterator, all are available*/
796 if(!ssl_printf(ssl
, "Delegation with %d names, of which %d "
797 "can be examined to query further addresses.\n"
798 "%sIt provides %d IP addresses.\n",
799 (int)n_ns
, (int)n_miss
, (dp
->bogus
?"It is BOGUS. ":""),
804 int print_deleg_lookup(SSL
* ssl
, struct worker
* worker
, uint8_t* nm
,
805 size_t nmlen
, int ATTR_UNUSED(nmlabs
))
807 /* deep links into the iterator module */
810 struct regional
* region
= worker
->scratchpad
;
812 struct query_info qinfo
;
813 struct iter_hints_stub
* stub
;
814 regional_free_all(region
);
816 qinfo
.qname_len
= nmlen
;
817 qinfo
.qtype
= LDNS_RR_TYPE_A
;
818 qinfo
.qclass
= LDNS_RR_CLASS_IN
;
821 if(!ssl_printf(ssl
, "The following name servers are used for lookup "
825 dp
= forwards_lookup(worker
->env
.fwds
, nm
, qinfo
.qclass
);
827 if(!ssl_printf(ssl
, "forwarding request:\n"))
829 print_dp_main(ssl
, dp
, NULL
);
830 print_dp_details(ssl
, worker
, dp
);
835 dp
= dns_cache_find_delegation(&worker
->env
, nm
, nmlen
,
836 qinfo
.qtype
, qinfo
.qclass
, region
, &msg
,
839 return ssl_printf(ssl
, "no delegation from "
840 "cache; goes to configured roots\n");
843 if(iter_dp_is_useless(&qinfo
, BIT_RD
, dp
)) {
844 print_dp_main(ssl
, dp
, msg
);
845 print_dp_details(ssl
, worker
, dp
);
846 if(!ssl_printf(ssl
, "cache delegation was "
847 "useless (no IP addresses)\n"))
849 if(dname_is_root(nm
)) {
850 /* goes to root config */
851 return ssl_printf(ssl
, "no delegation from "
852 "cache; goes to configured roots\n");
854 /* useless, goes up */
857 dname_remove_label(&nm
, &nmlen
);
859 if(!ssl_printf(ssl
, "going up, lookup %s\n", b
))
864 stub
= hints_lookup_stub(worker
->env
.hints
, nm
, qinfo
.qclass
,
868 if(!ssl_printf(ssl
, "The noprime stub servers "
872 if(!ssl_printf(ssl
, "The stub is primed "
876 print_dp_main(ssl
, stub
->dp
, NULL
);
877 print_dp_details(ssl
, worker
, stub
->dp
);
879 print_dp_main(ssl
, dp
, msg
);
880 print_dp_details(ssl
, worker
, dp
);