1b7579f77SDag-Erling Smørgrav /*
2b7579f77SDag-Erling Smørgrav * daemon/cachedump.c - dump the cache to text format.
3b7579f77SDag-Erling Smørgrav *
4b7579f77SDag-Erling Smørgrav * Copyright (c) 2008, NLnet Labs. All rights reserved.
5b7579f77SDag-Erling Smørgrav *
6b7579f77SDag-Erling Smørgrav * This software is open source.
7b7579f77SDag-Erling Smørgrav *
8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without
9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions
10b7579f77SDag-Erling Smørgrav * are met:
11b7579f77SDag-Erling Smørgrav *
12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice,
13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer.
14b7579f77SDag-Erling Smørgrav *
15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice,
16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation
17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution.
18b7579f77SDag-Erling Smørgrav *
19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may
20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without
21b7579f77SDag-Erling Smørgrav * specific prior written permission.
22b7579f77SDag-Erling Smørgrav *
23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34b7579f77SDag-Erling Smørgrav */
35b7579f77SDag-Erling Smørgrav
36b7579f77SDag-Erling Smørgrav /**
37b7579f77SDag-Erling Smørgrav * \file
38b7579f77SDag-Erling Smørgrav *
39b7579f77SDag-Erling Smørgrav * This file contains functions to read and write the cache(s)
40b7579f77SDag-Erling Smørgrav * to text format.
41b7579f77SDag-Erling Smørgrav */
42b7579f77SDag-Erling Smørgrav #include "config.h"
4317d15b25SDag-Erling Smørgrav #include <openssl/ssl.h>
44b7579f77SDag-Erling Smørgrav #include "daemon/cachedump.h"
45b7579f77SDag-Erling Smørgrav #include "daemon/remote.h"
46b7579f77SDag-Erling Smørgrav #include "daemon/worker.h"
47b7579f77SDag-Erling Smørgrav #include "services/cache/rrset.h"
48b7579f77SDag-Erling Smørgrav #include "services/cache/dns.h"
49b7579f77SDag-Erling Smørgrav #include "services/cache/infra.h"
50a39a5a69SCy Schubert #include "services/outside_network.h"
51b7579f77SDag-Erling Smørgrav #include "util/data/msgreply.h"
52b7579f77SDag-Erling Smørgrav #include "util/regional.h"
53b7579f77SDag-Erling Smørgrav #include "util/net_help.h"
54b7579f77SDag-Erling Smørgrav #include "util/data/dname.h"
55a39a5a69SCy Schubert #include "util/config_file.h"
56b7579f77SDag-Erling Smørgrav #include "iterator/iterator.h"
57b7579f77SDag-Erling Smørgrav #include "iterator/iter_delegpt.h"
58b7579f77SDag-Erling Smørgrav #include "iterator/iter_utils.h"
59b7579f77SDag-Erling Smørgrav #include "iterator/iter_fwd.h"
60b7579f77SDag-Erling Smørgrav #include "iterator/iter_hints.h"
6109a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h"
6209a3aaf3SDag-Erling Smørgrav #include "sldns/wire2str.h"
6309a3aaf3SDag-Erling Smørgrav #include "sldns/str2wire.h"
64b7579f77SDag-Erling Smørgrav
65b7579f77SDag-Erling Smørgrav /** dump one rrset zonefile line */
66b7579f77SDag-Erling Smørgrav static int
dump_rrset_line(RES * ssl,struct ub_packed_rrset_key * k,time_t now,size_t i)677da0adf7SDag-Erling Smørgrav dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
68b7579f77SDag-Erling Smørgrav {
6917d15b25SDag-Erling Smørgrav char s[65535];
7017d15b25SDag-Erling Smørgrav if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
71b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "BADRR\n");
72b7579f77SDag-Erling Smørgrav }
7317d15b25SDag-Erling Smørgrav return ssl_printf(ssl, "%s", s);
74b7579f77SDag-Erling Smørgrav }
75b7579f77SDag-Erling Smørgrav
76b7579f77SDag-Erling Smørgrav /** dump rrset key and data info */
77b7579f77SDag-Erling Smørgrav static int
dump_rrset(RES * ssl,struct ub_packed_rrset_key * k,struct packed_rrset_data * d,time_t now)787da0adf7SDag-Erling Smørgrav dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
7917d15b25SDag-Erling Smørgrav struct packed_rrset_data* d, time_t now)
80b7579f77SDag-Erling Smørgrav {
81b7579f77SDag-Erling Smørgrav size_t i;
82b7579f77SDag-Erling Smørgrav /* rd lock held by caller */
83b7579f77SDag-Erling Smørgrav if(!k || !d) return 1;
8457bddd21SDag-Erling Smørgrav if(k->id == 0) return 1; /* deleted */
85b7579f77SDag-Erling Smørgrav if(d->ttl < now) return 1; /* expired */
86b7579f77SDag-Erling Smørgrav
87b7579f77SDag-Erling Smørgrav /* meta line */
8817d15b25SDag-Erling Smørgrav if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n",
89b7579f77SDag-Erling Smørgrav (k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"",
9017d15b25SDag-Erling Smørgrav (long long)(d->ttl - now),
91b7579f77SDag-Erling Smørgrav (unsigned)d->count, (unsigned)d->rrsig_count,
92b7579f77SDag-Erling Smørgrav (int)d->trust, (int)d->security
93b7579f77SDag-Erling Smørgrav ))
94b7579f77SDag-Erling Smørgrav return 0;
9517d15b25SDag-Erling Smørgrav for(i=0; i<d->count + d->rrsig_count; i++) {
9617d15b25SDag-Erling Smørgrav if(!dump_rrset_line(ssl, k, now, i))
97b7579f77SDag-Erling Smørgrav return 0;
98b7579f77SDag-Erling Smørgrav }
99b7579f77SDag-Erling Smørgrav return 1;
100b7579f77SDag-Erling Smørgrav }
101b7579f77SDag-Erling Smørgrav
102b7579f77SDag-Erling Smørgrav /** dump lruhash rrset cache */
103b7579f77SDag-Erling Smørgrav static int
dump_rrset_lruhash(RES * ssl,struct lruhash * h,time_t now)1047da0adf7SDag-Erling Smørgrav dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
105b7579f77SDag-Erling Smørgrav {
106b7579f77SDag-Erling Smørgrav struct lruhash_entry* e;
107b7579f77SDag-Erling Smørgrav /* lruhash already locked by caller */
108b7579f77SDag-Erling Smørgrav /* walk in order of lru; best first */
109b7579f77SDag-Erling Smørgrav for(e=h->lru_start; e; e = e->lru_next) {
110b7579f77SDag-Erling Smørgrav lock_rw_rdlock(&e->lock);
111b7579f77SDag-Erling Smørgrav if(!dump_rrset(ssl, (struct ub_packed_rrset_key*)e->key,
112b7579f77SDag-Erling Smørgrav (struct packed_rrset_data*)e->data, now)) {
113b7579f77SDag-Erling Smørgrav lock_rw_unlock(&e->lock);
114b7579f77SDag-Erling Smørgrav return 0;
115b7579f77SDag-Erling Smørgrav }
116b7579f77SDag-Erling Smørgrav lock_rw_unlock(&e->lock);
117b7579f77SDag-Erling Smørgrav }
118b7579f77SDag-Erling Smørgrav return 1;
119b7579f77SDag-Erling Smørgrav }
120b7579f77SDag-Erling Smørgrav
121b7579f77SDag-Erling Smørgrav /** dump rrset cache */
122b7579f77SDag-Erling Smørgrav static int
dump_rrset_cache(RES * ssl,struct worker * worker)1237da0adf7SDag-Erling Smørgrav dump_rrset_cache(RES* ssl, struct worker* worker)
124b7579f77SDag-Erling Smørgrav {
125b7579f77SDag-Erling Smørgrav struct rrset_cache* r = worker->env.rrset_cache;
126b7579f77SDag-Erling Smørgrav size_t slab;
127b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "START_RRSET_CACHE\n")) return 0;
128b7579f77SDag-Erling Smørgrav for(slab=0; slab<r->table.size; slab++) {
129b7579f77SDag-Erling Smørgrav lock_quick_lock(&r->table.array[slab]->lock);
130b7579f77SDag-Erling Smørgrav if(!dump_rrset_lruhash(ssl, r->table.array[slab],
131b7579f77SDag-Erling Smørgrav *worker->env.now)) {
132b7579f77SDag-Erling Smørgrav lock_quick_unlock(&r->table.array[slab]->lock);
133b7579f77SDag-Erling Smørgrav return 0;
134b7579f77SDag-Erling Smørgrav }
135b7579f77SDag-Erling Smørgrav lock_quick_unlock(&r->table.array[slab]->lock);
136b7579f77SDag-Erling Smørgrav }
137b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "END_RRSET_CACHE\n");
138b7579f77SDag-Erling Smørgrav }
139b7579f77SDag-Erling Smørgrav
140b7579f77SDag-Erling Smørgrav /** dump message to rrset reference */
141b7579f77SDag-Erling Smørgrav static int
dump_msg_ref(RES * ssl,struct ub_packed_rrset_key * k)1427da0adf7SDag-Erling Smørgrav dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
143b7579f77SDag-Erling Smørgrav {
144b7579f77SDag-Erling Smørgrav char* nm, *tp, *cl;
14517d15b25SDag-Erling Smørgrav nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
14617d15b25SDag-Erling Smørgrav tp = sldns_wire2str_type(ntohs(k->rk.type));
14717d15b25SDag-Erling Smørgrav cl = sldns_wire2str_class(ntohs(k->rk.rrset_class));
148b7579f77SDag-Erling Smørgrav if(!nm || !cl || !tp) {
149b7579f77SDag-Erling Smørgrav free(nm);
150b7579f77SDag-Erling Smørgrav free(tp);
151b7579f77SDag-Erling Smørgrav free(cl);
152b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "BADREF\n");
153b7579f77SDag-Erling Smørgrav }
154b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags)) {
155b7579f77SDag-Erling Smørgrav free(nm);
156b7579f77SDag-Erling Smørgrav free(tp);
157b7579f77SDag-Erling Smørgrav free(cl);
158b7579f77SDag-Erling Smørgrav return 0;
159b7579f77SDag-Erling Smørgrav }
160b7579f77SDag-Erling Smørgrav free(nm);
161b7579f77SDag-Erling Smørgrav free(tp);
162b7579f77SDag-Erling Smørgrav free(cl);
163b7579f77SDag-Erling Smørgrav
164b7579f77SDag-Erling Smørgrav return 1;
165b7579f77SDag-Erling Smørgrav }
166b7579f77SDag-Erling Smørgrav
167b7579f77SDag-Erling Smørgrav /** dump message entry */
168b7579f77SDag-Erling Smørgrav static int
dump_msg(RES * ssl,struct query_info * k,struct reply_info * d,time_t now)1698f76bb7dSCy Schubert dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
170b7579f77SDag-Erling Smørgrav {
171b7579f77SDag-Erling Smørgrav size_t i;
172b7579f77SDag-Erling Smørgrav char* nm, *tp, *cl;
173b7579f77SDag-Erling Smørgrav if(!k || !d) return 1;
174b7579f77SDag-Erling Smørgrav if(d->ttl < now) return 1; /* expired */
175b7579f77SDag-Erling Smørgrav
17617d15b25SDag-Erling Smørgrav nm = sldns_wire2str_dname(k->qname, k->qname_len);
17717d15b25SDag-Erling Smørgrav tp = sldns_wire2str_type(k->qtype);
17817d15b25SDag-Erling Smørgrav cl = sldns_wire2str_class(k->qclass);
179b7579f77SDag-Erling Smørgrav if(!nm || !tp || !cl) {
180b7579f77SDag-Erling Smørgrav free(nm);
181b7579f77SDag-Erling Smørgrav free(tp);
182b7579f77SDag-Erling Smørgrav free(cl);
183b7579f77SDag-Erling Smørgrav return 1; /* skip this entry */
184b7579f77SDag-Erling Smørgrav }
185b7579f77SDag-Erling Smørgrav if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
186b7579f77SDag-Erling Smørgrav /* rrsets have timed out or do not exist */
187b7579f77SDag-Erling Smørgrav free(nm);
188b7579f77SDag-Erling Smørgrav free(tp);
189b7579f77SDag-Erling Smørgrav free(cl);
190b7579f77SDag-Erling Smørgrav return 1; /* skip this entry */
191b7579f77SDag-Erling Smørgrav }
192b7579f77SDag-Erling Smørgrav
193b7579f77SDag-Erling Smørgrav /* meta line */
1948f76bb7dSCy Schubert if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
195b7579f77SDag-Erling Smørgrav nm, cl, tp,
196b7579f77SDag-Erling Smørgrav (int)d->flags, (int)d->qdcount,
19717d15b25SDag-Erling Smørgrav (long long)(d->ttl-now), (int)d->security,
198b7579f77SDag-Erling Smørgrav (unsigned)d->an_numrrsets,
199b7579f77SDag-Erling Smørgrav (unsigned)d->ns_numrrsets,
2008f76bb7dSCy Schubert (unsigned)d->ar_numrrsets,
2018f76bb7dSCy Schubert (int)d->reason_bogus,
2028f76bb7dSCy Schubert d->reason_bogus_str?d->reason_bogus_str:"")) {
203b7579f77SDag-Erling Smørgrav free(nm);
204b7579f77SDag-Erling Smørgrav free(tp);
205b7579f77SDag-Erling Smørgrav free(cl);
206b7579f77SDag-Erling Smørgrav rrset_array_unlock(d->ref, d->rrset_count);
207b7579f77SDag-Erling Smørgrav return 0;
208b7579f77SDag-Erling Smørgrav }
209b7579f77SDag-Erling Smørgrav free(nm);
210b7579f77SDag-Erling Smørgrav free(tp);
211b7579f77SDag-Erling Smørgrav free(cl);
212b7579f77SDag-Erling Smørgrav
213b7579f77SDag-Erling Smørgrav for(i=0; i<d->rrset_count; i++) {
214b7579f77SDag-Erling Smørgrav if(!dump_msg_ref(ssl, d->rrsets[i])) {
215b7579f77SDag-Erling Smørgrav rrset_array_unlock(d->ref, d->rrset_count);
216b7579f77SDag-Erling Smørgrav return 0;
217b7579f77SDag-Erling Smørgrav }
218b7579f77SDag-Erling Smørgrav }
219b7579f77SDag-Erling Smørgrav rrset_array_unlock(d->ref, d->rrset_count);
220b7579f77SDag-Erling Smørgrav
221b7579f77SDag-Erling Smørgrav return 1;
222b7579f77SDag-Erling Smørgrav }
223b7579f77SDag-Erling Smørgrav
224b7579f77SDag-Erling Smørgrav /** copy msg to worker pad */
225b7579f77SDag-Erling Smørgrav static int
copy_msg(struct regional * region,struct lruhash_entry * e,struct query_info ** k,struct reply_info ** d)226b7579f77SDag-Erling Smørgrav copy_msg(struct regional* region, struct lruhash_entry* e,
227b7579f77SDag-Erling Smørgrav struct query_info** k, struct reply_info** d)
228b7579f77SDag-Erling Smørgrav {
229b7579f77SDag-Erling Smørgrav struct reply_info* rep = (struct reply_info*)e->data;
23009a3aaf3SDag-Erling Smørgrav if(rep->rrset_count > RR_COUNT_MAX)
23109a3aaf3SDag-Erling Smørgrav return 0; /* to protect against integer overflow */
232b7579f77SDag-Erling Smørgrav *d = (struct reply_info*)regional_alloc_init(region, e->data,
233b7579f77SDag-Erling Smørgrav sizeof(struct reply_info) +
234b7579f77SDag-Erling Smørgrav sizeof(struct rrset_ref) * (rep->rrset_count-1) +
235b7579f77SDag-Erling Smørgrav sizeof(struct ub_packed_rrset_key*) * rep->rrset_count);
236b7579f77SDag-Erling Smørgrav if(!*d)
237b7579f77SDag-Erling Smørgrav return 0;
23804b59eacSDag-Erling Smørgrav (*d)->rrsets = (struct ub_packed_rrset_key**)(void *)(
239b7579f77SDag-Erling Smørgrav (uint8_t*)(&((*d)->ref[0])) +
240b7579f77SDag-Erling Smørgrav sizeof(struct rrset_ref) * rep->rrset_count);
241b7579f77SDag-Erling Smørgrav *k = (struct query_info*)regional_alloc_init(region,
242b7579f77SDag-Erling Smørgrav e->key, sizeof(struct query_info));
243b7579f77SDag-Erling Smørgrav if(!*k)
244b7579f77SDag-Erling Smørgrav return 0;
245b7579f77SDag-Erling Smørgrav (*k)->qname = regional_alloc_init(region,
246b7579f77SDag-Erling Smørgrav (*k)->qname, (*k)->qname_len);
247b7579f77SDag-Erling Smørgrav return (*k)->qname != NULL;
248b7579f77SDag-Erling Smørgrav }
249b7579f77SDag-Erling Smørgrav
250b7579f77SDag-Erling Smørgrav /** dump lruhash msg cache */
251b7579f77SDag-Erling Smørgrav static int
dump_msg_lruhash(RES * ssl,struct worker * worker,struct lruhash * h)2527da0adf7SDag-Erling Smørgrav dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
253b7579f77SDag-Erling Smørgrav {
254b7579f77SDag-Erling Smørgrav struct lruhash_entry* e;
255b7579f77SDag-Erling Smørgrav struct query_info* k;
256b7579f77SDag-Erling Smørgrav struct reply_info* d;
257b7579f77SDag-Erling Smørgrav
258b7579f77SDag-Erling Smørgrav /* lruhash already locked by caller */
259b7579f77SDag-Erling Smørgrav /* walk in order of lru; best first */
260b7579f77SDag-Erling Smørgrav for(e=h->lru_start; e; e = e->lru_next) {
261b7579f77SDag-Erling Smørgrav regional_free_all(worker->scratchpad);
262b7579f77SDag-Erling Smørgrav lock_rw_rdlock(&e->lock);
263b7579f77SDag-Erling Smørgrav /* make copy of rrset in worker buffer */
264b7579f77SDag-Erling Smørgrav if(!copy_msg(worker->scratchpad, e, &k, &d)) {
265b7579f77SDag-Erling Smørgrav lock_rw_unlock(&e->lock);
266b7579f77SDag-Erling Smørgrav return 0;
267b7579f77SDag-Erling Smørgrav }
268b7579f77SDag-Erling Smørgrav lock_rw_unlock(&e->lock);
269b7579f77SDag-Erling Smørgrav /* release lock so we can lookup the rrset references
270b7579f77SDag-Erling Smørgrav * in the rrset cache */
271b7579f77SDag-Erling Smørgrav if(!dump_msg(ssl, k, d, *worker->env.now)) {
272b7579f77SDag-Erling Smørgrav return 0;
273b7579f77SDag-Erling Smørgrav }
274b7579f77SDag-Erling Smørgrav }
275b7579f77SDag-Erling Smørgrav return 1;
276b7579f77SDag-Erling Smørgrav }
277b7579f77SDag-Erling Smørgrav
278b7579f77SDag-Erling Smørgrav /** dump msg cache */
279b7579f77SDag-Erling Smørgrav static int
dump_msg_cache(RES * ssl,struct worker * worker)2807da0adf7SDag-Erling Smørgrav dump_msg_cache(RES* ssl, struct worker* worker)
281b7579f77SDag-Erling Smørgrav {
282b7579f77SDag-Erling Smørgrav struct slabhash* sh = worker->env.msg_cache;
283b7579f77SDag-Erling Smørgrav size_t slab;
284b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "START_MSG_CACHE\n")) return 0;
285b7579f77SDag-Erling Smørgrav for(slab=0; slab<sh->size; slab++) {
286b7579f77SDag-Erling Smørgrav lock_quick_lock(&sh->array[slab]->lock);
287b7579f77SDag-Erling Smørgrav if(!dump_msg_lruhash(ssl, worker, sh->array[slab])) {
288b7579f77SDag-Erling Smørgrav lock_quick_unlock(&sh->array[slab]->lock);
289b7579f77SDag-Erling Smørgrav return 0;
290b7579f77SDag-Erling Smørgrav }
291b7579f77SDag-Erling Smørgrav lock_quick_unlock(&sh->array[slab]->lock);
292b7579f77SDag-Erling Smørgrav }
293b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "END_MSG_CACHE\n");
294b7579f77SDag-Erling Smørgrav }
295b7579f77SDag-Erling Smørgrav
296b7579f77SDag-Erling Smørgrav int
dump_cache(RES * ssl,struct worker * worker)2977da0adf7SDag-Erling Smørgrav dump_cache(RES* ssl, struct worker* worker)
298b7579f77SDag-Erling Smørgrav {
299b7579f77SDag-Erling Smørgrav if(!dump_rrset_cache(ssl, worker))
300b7579f77SDag-Erling Smørgrav return 0;
301b7579f77SDag-Erling Smørgrav if(!dump_msg_cache(ssl, worker))
302b7579f77SDag-Erling Smørgrav return 0;
303b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "EOF\n");
304b7579f77SDag-Erling Smørgrav }
305b7579f77SDag-Erling Smørgrav
306b7579f77SDag-Erling Smørgrav /** read a line from ssl into buffer */
307b7579f77SDag-Erling Smørgrav static int
ssl_read_buf(RES * ssl,sldns_buffer * buf)3087da0adf7SDag-Erling Smørgrav ssl_read_buf(RES* ssl, sldns_buffer* buf)
309b7579f77SDag-Erling Smørgrav {
31017d15b25SDag-Erling Smørgrav return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
31117d15b25SDag-Erling Smørgrav sldns_buffer_capacity(buf));
312b7579f77SDag-Erling Smørgrav }
313b7579f77SDag-Erling Smørgrav
314b7579f77SDag-Erling Smørgrav /** check fixed text on line */
315b7579f77SDag-Erling Smørgrav static int
read_fixed(RES * ssl,sldns_buffer * buf,const char * str)3167da0adf7SDag-Erling Smørgrav read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
317b7579f77SDag-Erling Smørgrav {
318b7579f77SDag-Erling Smørgrav if(!ssl_read_buf(ssl, buf)) return 0;
31917d15b25SDag-Erling Smørgrav return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
320b7579f77SDag-Erling Smørgrav }
321b7579f77SDag-Erling Smørgrav
322b7579f77SDag-Erling Smørgrav /** load an RR into rrset */
323b7579f77SDag-Erling Smørgrav static int
load_rr(RES * ssl,sldns_buffer * buf,struct regional * region,struct ub_packed_rrset_key * rk,struct packed_rrset_data * d,unsigned int i,int is_rrsig,int * go_on,time_t now)3247da0adf7SDag-Erling Smørgrav load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
325b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
32617d15b25SDag-Erling Smørgrav unsigned int i, int is_rrsig, int* go_on, time_t now)
327b7579f77SDag-Erling Smørgrav {
32817d15b25SDag-Erling Smørgrav uint8_t rr[LDNS_RR_BUF_SIZE];
32917d15b25SDag-Erling Smørgrav size_t rr_len = sizeof(rr), dname_len = 0;
33017d15b25SDag-Erling Smørgrav int status;
331b7579f77SDag-Erling Smørgrav
332b7579f77SDag-Erling Smørgrav /* read the line */
333b7579f77SDag-Erling Smørgrav if(!ssl_read_buf(ssl, buf))
334b7579f77SDag-Erling Smørgrav return 0;
33517d15b25SDag-Erling Smørgrav if(strncmp((char*)sldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
336b7579f77SDag-Erling Smørgrav *go_on = 0;
337b7579f77SDag-Erling Smørgrav return 1;
338b7579f77SDag-Erling Smørgrav }
33917d15b25SDag-Erling Smørgrav status = sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr,
34017d15b25SDag-Erling Smørgrav &rr_len, &dname_len, 3600, NULL, 0, NULL, 0);
34117d15b25SDag-Erling Smørgrav if(status != 0) {
342b7579f77SDag-Erling Smørgrav log_warn("error cannot parse rr: %s: %s",
34317d15b25SDag-Erling Smørgrav sldns_get_errorstr_parse(status),
34417d15b25SDag-Erling Smørgrav (char*)sldns_buffer_begin(buf));
345b7579f77SDag-Erling Smørgrav return 0;
346b7579f77SDag-Erling Smørgrav }
34717d15b25SDag-Erling Smørgrav if(is_rrsig && sldns_wirerr_get_type(rr, rr_len, dname_len)
34817d15b25SDag-Erling Smørgrav != LDNS_RR_TYPE_RRSIG) {
349b7579f77SDag-Erling Smørgrav log_warn("error expected rrsig but got %s",
35017d15b25SDag-Erling Smørgrav (char*)sldns_buffer_begin(buf));
351b7579f77SDag-Erling Smørgrav return 0;
352b7579f77SDag-Erling Smørgrav }
353b7579f77SDag-Erling Smørgrav
354b7579f77SDag-Erling Smørgrav /* convert ldns rr into packed_rr */
35517d15b25SDag-Erling Smørgrav d->rr_ttl[i] = (time_t)sldns_wirerr_get_ttl(rr, rr_len, dname_len) + now;
35617d15b25SDag-Erling Smørgrav sldns_buffer_clear(buf);
35717d15b25SDag-Erling Smørgrav d->rr_len[i] = sldns_wirerr_get_rdatalen(rr, rr_len, dname_len)+2;
358b7579f77SDag-Erling Smørgrav d->rr_data[i] = (uint8_t*)regional_alloc_init(region,
35917d15b25SDag-Erling Smørgrav sldns_wirerr_get_rdatawl(rr, rr_len, dname_len), d->rr_len[i]);
360b7579f77SDag-Erling Smørgrav if(!d->rr_data[i]) {
361b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
362b7579f77SDag-Erling Smørgrav return 0;
363b7579f77SDag-Erling Smørgrav }
364b7579f77SDag-Erling Smørgrav
365b7579f77SDag-Erling Smørgrav /* if first entry, fill the key structure */
366b7579f77SDag-Erling Smørgrav if(i==0) {
36717d15b25SDag-Erling Smørgrav rk->rk.type = htons(sldns_wirerr_get_type(rr, rr_len, dname_len));
36817d15b25SDag-Erling Smørgrav rk->rk.rrset_class = htons(sldns_wirerr_get_class(rr, rr_len, dname_len));
36917d15b25SDag-Erling Smørgrav rk->rk.dname_len = dname_len;
37017d15b25SDag-Erling Smørgrav rk->rk.dname = regional_alloc_init(region, rr, dname_len);
371b7579f77SDag-Erling Smørgrav if(!rk->rk.dname) {
372b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
373b7579f77SDag-Erling Smørgrav return 0;
374b7579f77SDag-Erling Smørgrav }
375b7579f77SDag-Erling Smørgrav }
376b7579f77SDag-Erling Smørgrav
377b7579f77SDag-Erling Smørgrav return 1;
378b7579f77SDag-Erling Smørgrav }
379b7579f77SDag-Erling Smørgrav
380b7579f77SDag-Erling Smørgrav /** move entry into cache */
381b7579f77SDag-Erling Smørgrav static int
move_into_cache(struct ub_packed_rrset_key * k,struct packed_rrset_data * d,struct worker * worker)382b7579f77SDag-Erling Smørgrav move_into_cache(struct ub_packed_rrset_key* k,
383b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d, struct worker* worker)
384b7579f77SDag-Erling Smørgrav {
385b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* ak;
386b7579f77SDag-Erling Smørgrav struct packed_rrset_data* ad;
387b7579f77SDag-Erling Smørgrav size_t s, i, num = d->count + d->rrsig_count;
388b7579f77SDag-Erling Smørgrav struct rrset_ref ref;
389b7579f77SDag-Erling Smørgrav uint8_t* p;
390b7579f77SDag-Erling Smørgrav
3911838dec3SCy Schubert ak = alloc_special_obtain(worker->alloc);
392b7579f77SDag-Erling Smørgrav if(!ak) {
393b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
394b7579f77SDag-Erling Smørgrav return 0;
395b7579f77SDag-Erling Smørgrav }
396b7579f77SDag-Erling Smørgrav ak->entry.data = NULL;
397b7579f77SDag-Erling Smørgrav ak->rk = k->rk;
398b7579f77SDag-Erling Smørgrav ak->entry.hash = rrset_key_hash(&k->rk);
399b7579f77SDag-Erling Smørgrav ak->rk.dname = (uint8_t*)memdup(k->rk.dname, k->rk.dname_len);
400b7579f77SDag-Erling Smørgrav if(!ak->rk.dname) {
401b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
4021838dec3SCy Schubert ub_packed_rrset_parsedelete(ak, worker->alloc);
403b7579f77SDag-Erling Smørgrav return 0;
404b7579f77SDag-Erling Smørgrav }
405b7579f77SDag-Erling Smørgrav s = sizeof(*ad) + (sizeof(size_t) + sizeof(uint8_t*) +
40617d15b25SDag-Erling Smørgrav sizeof(time_t))* num;
407b7579f77SDag-Erling Smørgrav for(i=0; i<num; i++)
408b7579f77SDag-Erling Smørgrav s += d->rr_len[i];
409b7579f77SDag-Erling Smørgrav ad = (struct packed_rrset_data*)malloc(s);
410b7579f77SDag-Erling Smørgrav if(!ad) {
411b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
4121838dec3SCy Schubert ub_packed_rrset_parsedelete(ak, worker->alloc);
413b7579f77SDag-Erling Smørgrav return 0;
414b7579f77SDag-Erling Smørgrav }
415b7579f77SDag-Erling Smørgrav p = (uint8_t*)ad;
416b7579f77SDag-Erling Smørgrav memmove(p, d, sizeof(*ad));
417b7579f77SDag-Erling Smørgrav p += sizeof(*ad);
418b7579f77SDag-Erling Smørgrav memmove(p, &d->rr_len[0], sizeof(size_t)*num);
419b7579f77SDag-Erling Smørgrav p += sizeof(size_t)*num;
420b7579f77SDag-Erling Smørgrav memmove(p, &d->rr_data[0], sizeof(uint8_t*)*num);
421b7579f77SDag-Erling Smørgrav p += sizeof(uint8_t*)*num;
42217d15b25SDag-Erling Smørgrav memmove(p, &d->rr_ttl[0], sizeof(time_t)*num);
42317d15b25SDag-Erling Smørgrav p += sizeof(time_t)*num;
424b7579f77SDag-Erling Smørgrav for(i=0; i<num; i++) {
425b7579f77SDag-Erling Smørgrav memmove(p, d->rr_data[i], d->rr_len[i]);
426b7579f77SDag-Erling Smørgrav p += d->rr_len[i];
427b7579f77SDag-Erling Smørgrav }
428b7579f77SDag-Erling Smørgrav packed_rrset_ptr_fixup(ad);
429b7579f77SDag-Erling Smørgrav
430b7579f77SDag-Erling Smørgrav ak->entry.data = ad;
431b7579f77SDag-Erling Smørgrav
432b7579f77SDag-Erling Smørgrav ref.key = ak;
433b7579f77SDag-Erling Smørgrav ref.id = ak->id;
434b7579f77SDag-Erling Smørgrav (void)rrset_cache_update(worker->env.rrset_cache, &ref,
4351838dec3SCy Schubert worker->alloc, *worker->env.now);
4361838dec3SCy Schubert
437b7579f77SDag-Erling Smørgrav return 1;
438b7579f77SDag-Erling Smørgrav }
439b7579f77SDag-Erling Smørgrav
440b7579f77SDag-Erling Smørgrav /** load an rrset entry */
441b7579f77SDag-Erling Smørgrav static int
load_rrset(RES * ssl,sldns_buffer * buf,struct worker * worker)4427da0adf7SDag-Erling Smørgrav load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
443b7579f77SDag-Erling Smørgrav {
44417d15b25SDag-Erling Smørgrav char* s = (char*)sldns_buffer_begin(buf);
445b7579f77SDag-Erling Smørgrav struct regional* region = worker->scratchpad;
446b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* rk;
447b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d;
44817d15b25SDag-Erling Smørgrav unsigned int rr_count, rrsig_count, trust, security;
44917d15b25SDag-Erling Smørgrav long long ttl;
450b7579f77SDag-Erling Smørgrav unsigned int i;
451b7579f77SDag-Erling Smørgrav int go_on = 1;
452b7579f77SDag-Erling Smørgrav regional_free_all(region);
453b7579f77SDag-Erling Smørgrav
454b7579f77SDag-Erling Smørgrav rk = (struct ub_packed_rrset_key*)regional_alloc_zero(region,
455b7579f77SDag-Erling Smørgrav sizeof(*rk));
456b7579f77SDag-Erling Smørgrav d = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*d));
457b7579f77SDag-Erling Smørgrav if(!rk || !d) {
458b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
459b7579f77SDag-Erling Smørgrav return 0;
460b7579f77SDag-Erling Smørgrav }
461b7579f77SDag-Erling Smørgrav
462b7579f77SDag-Erling Smørgrav if(strncmp(s, ";rrset", 6) != 0) {
463b7579f77SDag-Erling Smørgrav log_warn("error expected ';rrset' but got %s", s);
464b7579f77SDag-Erling Smørgrav return 0;
465b7579f77SDag-Erling Smørgrav }
466b7579f77SDag-Erling Smørgrav s += 6;
467b7579f77SDag-Erling Smørgrav if(strncmp(s, " nsec_apex", 10) == 0) {
468b7579f77SDag-Erling Smørgrav s += 10;
469b7579f77SDag-Erling Smørgrav rk->rk.flags |= PACKED_RRSET_NSEC_AT_APEX;
470b7579f77SDag-Erling Smørgrav }
47117d15b25SDag-Erling Smørgrav if(sscanf(s, " " ARG_LL "d %u %u %u %u", &ttl, &rr_count, &rrsig_count,
472b7579f77SDag-Erling Smørgrav &trust, &security) != 5) {
473b7579f77SDag-Erling Smørgrav log_warn("error bad rrset spec %s", s);
474b7579f77SDag-Erling Smørgrav return 0;
475b7579f77SDag-Erling Smørgrav }
476b7579f77SDag-Erling Smørgrav if(rr_count == 0 && rrsig_count == 0) {
477b7579f77SDag-Erling Smørgrav log_warn("bad rrset without contents");
478b7579f77SDag-Erling Smørgrav return 0;
479b7579f77SDag-Erling Smørgrav }
48009a3aaf3SDag-Erling Smørgrav if(rr_count > RR_COUNT_MAX || rrsig_count > RR_COUNT_MAX) {
48109a3aaf3SDag-Erling Smørgrav log_warn("bad rrset with too many rrs");
48209a3aaf3SDag-Erling Smørgrav return 0;
48309a3aaf3SDag-Erling Smørgrav }
484b7579f77SDag-Erling Smørgrav d->count = (size_t)rr_count;
485b7579f77SDag-Erling Smørgrav d->rrsig_count = (size_t)rrsig_count;
486b7579f77SDag-Erling Smørgrav d->security = (enum sec_status)security;
487b7579f77SDag-Erling Smørgrav d->trust = (enum rrset_trust)trust;
48817d15b25SDag-Erling Smørgrav d->ttl = (time_t)ttl + *worker->env.now;
489b7579f77SDag-Erling Smørgrav
490b7579f77SDag-Erling Smørgrav d->rr_len = regional_alloc_zero(region,
491b7579f77SDag-Erling Smørgrav sizeof(size_t)*(d->count+d->rrsig_count));
492b7579f77SDag-Erling Smørgrav d->rr_ttl = regional_alloc_zero(region,
49317d15b25SDag-Erling Smørgrav sizeof(time_t)*(d->count+d->rrsig_count));
494b7579f77SDag-Erling Smørgrav d->rr_data = regional_alloc_zero(region,
495b7579f77SDag-Erling Smørgrav sizeof(uint8_t*)*(d->count+d->rrsig_count));
496b7579f77SDag-Erling Smørgrav if(!d->rr_len || !d->rr_ttl || !d->rr_data) {
497b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
498b7579f77SDag-Erling Smørgrav return 0;
499b7579f77SDag-Erling Smørgrav }
500b7579f77SDag-Erling Smørgrav
501b7579f77SDag-Erling Smørgrav /* read the rr's themselves */
502b7579f77SDag-Erling Smørgrav for(i=0; i<rr_count; i++) {
503b7579f77SDag-Erling Smørgrav if(!load_rr(ssl, buf, region, rk, d, i, 0,
504b7579f77SDag-Erling Smørgrav &go_on, *worker->env.now)) {
505b7579f77SDag-Erling Smørgrav log_warn("could not read rr %u", i);
506b7579f77SDag-Erling Smørgrav return 0;
507b7579f77SDag-Erling Smørgrav }
508b7579f77SDag-Erling Smørgrav }
509b7579f77SDag-Erling Smørgrav for(i=0; i<rrsig_count; i++) {
510b7579f77SDag-Erling Smørgrav if(!load_rr(ssl, buf, region, rk, d, i+rr_count, 1,
511b7579f77SDag-Erling Smørgrav &go_on, *worker->env.now)) {
512b7579f77SDag-Erling Smørgrav log_warn("could not read rrsig %u", i);
513b7579f77SDag-Erling Smørgrav return 0;
514b7579f77SDag-Erling Smørgrav }
515b7579f77SDag-Erling Smørgrav }
516b7579f77SDag-Erling Smørgrav if(!go_on) {
517b7579f77SDag-Erling Smørgrav /* skip this entry */
518b7579f77SDag-Erling Smørgrav return 1;
519b7579f77SDag-Erling Smørgrav }
520b7579f77SDag-Erling Smørgrav
521b7579f77SDag-Erling Smørgrav return move_into_cache(rk, d, worker);
522b7579f77SDag-Erling Smørgrav }
523b7579f77SDag-Erling Smørgrav
524b7579f77SDag-Erling Smørgrav /** load rrset cache */
525b7579f77SDag-Erling Smørgrav static int
load_rrset_cache(RES * ssl,struct worker * worker)5267da0adf7SDag-Erling Smørgrav load_rrset_cache(RES* ssl, struct worker* worker)
527b7579f77SDag-Erling Smørgrav {
52817d15b25SDag-Erling Smørgrav sldns_buffer* buf = worker->env.scratch_buffer;
529b7579f77SDag-Erling Smørgrav if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
530b7579f77SDag-Erling Smørgrav while(ssl_read_buf(ssl, buf) &&
53117d15b25SDag-Erling Smørgrav strcmp((char*)sldns_buffer_begin(buf), "END_RRSET_CACHE")!=0) {
532b7579f77SDag-Erling Smørgrav if(!load_rrset(ssl, buf, worker))
533b7579f77SDag-Erling Smørgrav return 0;
534b7579f77SDag-Erling Smørgrav }
535b7579f77SDag-Erling Smørgrav return 1;
536b7579f77SDag-Erling Smørgrav }
537b7579f77SDag-Erling Smørgrav
538b7579f77SDag-Erling Smørgrav /** read qinfo from next three words */
539b7579f77SDag-Erling Smørgrav static char*
load_qinfo(char * str,struct query_info * qinfo,struct regional * region)54017d15b25SDag-Erling Smørgrav load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
541b7579f77SDag-Erling Smørgrav {
542b7579f77SDag-Erling Smørgrav /* s is part of the buf */
543b7579f77SDag-Erling Smørgrav char* s = str;
54417d15b25SDag-Erling Smørgrav uint8_t rr[LDNS_RR_BUF_SIZE];
54517d15b25SDag-Erling Smørgrav size_t rr_len = sizeof(rr), dname_len = 0;
54617d15b25SDag-Erling Smørgrav int status;
547b7579f77SDag-Erling Smørgrav
548b7579f77SDag-Erling Smørgrav /* skip three words */
549b7579f77SDag-Erling Smørgrav s = strchr(str, ' ');
550b7579f77SDag-Erling Smørgrav if(s) s = strchr(s+1, ' ');
551b7579f77SDag-Erling Smørgrav if(s) s = strchr(s+1, ' ');
552b7579f77SDag-Erling Smørgrav if(!s) {
553b7579f77SDag-Erling Smørgrav log_warn("error line too short, %s", str);
554b7579f77SDag-Erling Smørgrav return NULL;
555b7579f77SDag-Erling Smørgrav }
556b7579f77SDag-Erling Smørgrav s[0] = 0;
557b7579f77SDag-Erling Smørgrav s++;
558b7579f77SDag-Erling Smørgrav
559b7579f77SDag-Erling Smørgrav /* parse them */
56017d15b25SDag-Erling Smørgrav status = sldns_str2wire_rr_question_buf(str, rr, &rr_len, &dname_len,
56117d15b25SDag-Erling Smørgrav NULL, 0, NULL, 0);
56217d15b25SDag-Erling Smørgrav if(status != 0) {
563b7579f77SDag-Erling Smørgrav log_warn("error cannot parse: %s %s",
56417d15b25SDag-Erling Smørgrav sldns_get_errorstr_parse(status), str);
565b7579f77SDag-Erling Smørgrav return NULL;
566b7579f77SDag-Erling Smørgrav }
56717d15b25SDag-Erling Smørgrav qinfo->qtype = sldns_wirerr_get_type(rr, rr_len, dname_len);
56817d15b25SDag-Erling Smørgrav qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len);
56917d15b25SDag-Erling Smørgrav qinfo->qname_len = dname_len;
57017d15b25SDag-Erling Smørgrav qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
571bc892140SDag-Erling Smørgrav qinfo->local_alias = NULL;
572b7579f77SDag-Erling Smørgrav if(!qinfo->qname) {
573b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
574b7579f77SDag-Erling Smørgrav return NULL;
575b7579f77SDag-Erling Smørgrav }
576b7579f77SDag-Erling Smørgrav
577b7579f77SDag-Erling Smørgrav return s;
578b7579f77SDag-Erling Smørgrav }
579b7579f77SDag-Erling Smørgrav
580b7579f77SDag-Erling Smørgrav /** load a msg rrset reference */
581b7579f77SDag-Erling Smørgrav static int
load_ref(RES * ssl,sldns_buffer * buf,struct worker * worker,struct regional * region,struct ub_packed_rrset_key ** rrset,int * go_on)5827da0adf7SDag-Erling Smørgrav load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
583b7579f77SDag-Erling Smørgrav struct regional *region, struct ub_packed_rrset_key** rrset,
584b7579f77SDag-Erling Smørgrav int* go_on)
585b7579f77SDag-Erling Smørgrav {
58617d15b25SDag-Erling Smørgrav char* s = (char*)sldns_buffer_begin(buf);
587b7579f77SDag-Erling Smørgrav struct query_info qinfo;
588b7579f77SDag-Erling Smørgrav unsigned int flags;
589b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* k;
590b7579f77SDag-Erling Smørgrav
591b7579f77SDag-Erling Smørgrav /* read line */
592b7579f77SDag-Erling Smørgrav if(!ssl_read_buf(ssl, buf))
593b7579f77SDag-Erling Smørgrav return 0;
594b7579f77SDag-Erling Smørgrav if(strncmp(s, "BADREF", 6) == 0) {
595b7579f77SDag-Erling Smørgrav *go_on = 0; /* its bad, skip it and skip message */
596b7579f77SDag-Erling Smørgrav return 1;
597b7579f77SDag-Erling Smørgrav }
598b7579f77SDag-Erling Smørgrav
59917d15b25SDag-Erling Smørgrav s = load_qinfo(s, &qinfo, region);
600b7579f77SDag-Erling Smørgrav if(!s) {
601b7579f77SDag-Erling Smørgrav return 0;
602b7579f77SDag-Erling Smørgrav }
603b7579f77SDag-Erling Smørgrav if(sscanf(s, " %u", &flags) != 1) {
604b7579f77SDag-Erling Smørgrav log_warn("error cannot parse flags: %s", s);
605b7579f77SDag-Erling Smørgrav return 0;
606b7579f77SDag-Erling Smørgrav }
607b7579f77SDag-Erling Smørgrav
608b7579f77SDag-Erling Smørgrav /* lookup in cache */
609b7579f77SDag-Erling Smørgrav k = rrset_cache_lookup(worker->env.rrset_cache, qinfo.qname,
610b7579f77SDag-Erling Smørgrav qinfo.qname_len, qinfo.qtype, qinfo.qclass,
611b7579f77SDag-Erling Smørgrav (uint32_t)flags, *worker->env.now, 0);
612b7579f77SDag-Erling Smørgrav if(!k) {
613b7579f77SDag-Erling Smørgrav /* not found or expired */
614b7579f77SDag-Erling Smørgrav *go_on = 0;
615b7579f77SDag-Erling Smørgrav return 1;
616b7579f77SDag-Erling Smørgrav }
617b7579f77SDag-Erling Smørgrav
618b7579f77SDag-Erling Smørgrav /* store in result */
619b7579f77SDag-Erling Smørgrav *rrset = packed_rrset_copy_region(k, region, *worker->env.now);
620b7579f77SDag-Erling Smørgrav lock_rw_unlock(&k->entry.lock);
621b7579f77SDag-Erling Smørgrav
622b7579f77SDag-Erling Smørgrav return (*rrset != NULL);
623b7579f77SDag-Erling Smørgrav }
624b7579f77SDag-Erling Smørgrav
625b7579f77SDag-Erling Smørgrav /** load a msg entry */
626b7579f77SDag-Erling Smørgrav static int
load_msg(RES * ssl,sldns_buffer * buf,struct worker * worker)6277da0adf7SDag-Erling Smørgrav load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
628b7579f77SDag-Erling Smørgrav {
629b7579f77SDag-Erling Smørgrav struct regional* region = worker->scratchpad;
630b7579f77SDag-Erling Smørgrav struct query_info qinf;
631b7579f77SDag-Erling Smørgrav struct reply_info rep;
63217d15b25SDag-Erling Smørgrav char* s = (char*)sldns_buffer_begin(buf);
63317d15b25SDag-Erling Smørgrav unsigned int flags, qdcount, security, an, ns, ar;
63417d15b25SDag-Erling Smørgrav long long ttl;
635b7579f77SDag-Erling Smørgrav size_t i;
636b7579f77SDag-Erling Smørgrav int go_on = 1;
6378f76bb7dSCy Schubert int ede;
6388f76bb7dSCy Schubert int consumed = 0;
6398f76bb7dSCy Schubert char* ede_str = NULL;
640b7579f77SDag-Erling Smørgrav
641b7579f77SDag-Erling Smørgrav regional_free_all(region);
642b7579f77SDag-Erling Smørgrav
643b7579f77SDag-Erling Smørgrav if(strncmp(s, "msg ", 4) != 0) {
644b7579f77SDag-Erling Smørgrav log_warn("error expected msg but got %s", s);
645b7579f77SDag-Erling Smørgrav return 0;
646b7579f77SDag-Erling Smørgrav }
647b7579f77SDag-Erling Smørgrav s += 4;
64817d15b25SDag-Erling Smørgrav s = load_qinfo(s, &qinf, region);
649b7579f77SDag-Erling Smørgrav if(!s) {
650b7579f77SDag-Erling Smørgrav return 0;
651b7579f77SDag-Erling Smørgrav }
652b7579f77SDag-Erling Smørgrav
653b7579f77SDag-Erling Smørgrav /* read remainder of line */
6548f76bb7dSCy Schubert /* note the last space before any possible EDE text */
6558f76bb7dSCy Schubert if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u %d %n", &flags, &qdcount, &ttl,
6568f76bb7dSCy Schubert &security, &an, &ns, &ar, &ede, &consumed) != 8) {
657b7579f77SDag-Erling Smørgrav log_warn("error cannot parse numbers: %s", s);
658b7579f77SDag-Erling Smørgrav return 0;
659b7579f77SDag-Erling Smørgrav }
6608f76bb7dSCy Schubert /* there may be EDE text after the numbers */
6618f76bb7dSCy Schubert if(consumed > 0 && (size_t)consumed < strlen(s))
6628f76bb7dSCy Schubert ede_str = s + consumed;
6638f76bb7dSCy Schubert memset(&rep, 0, sizeof(rep));
664b7579f77SDag-Erling Smørgrav rep.flags = (uint16_t)flags;
665b7579f77SDag-Erling Smørgrav rep.qdcount = (uint16_t)qdcount;
66617d15b25SDag-Erling Smørgrav rep.ttl = (time_t)ttl;
667b7579f77SDag-Erling Smørgrav rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
6684c75e3aaSDag-Erling Smørgrav rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL;
669b7579f77SDag-Erling Smørgrav rep.security = (enum sec_status)security;
67009a3aaf3SDag-Erling Smørgrav if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) {
67109a3aaf3SDag-Erling Smørgrav log_warn("error too many rrsets");
67209a3aaf3SDag-Erling Smørgrav return 0; /* protect against integer overflow in alloc */
67309a3aaf3SDag-Erling Smørgrav }
674b7579f77SDag-Erling Smørgrav rep.an_numrrsets = (size_t)an;
675b7579f77SDag-Erling Smørgrav rep.ns_numrrsets = (size_t)ns;
676b7579f77SDag-Erling Smørgrav rep.ar_numrrsets = (size_t)ar;
677b7579f77SDag-Erling Smørgrav rep.rrset_count = (size_t)an+(size_t)ns+(size_t)ar;
6788f76bb7dSCy Schubert rep.reason_bogus = (sldns_ede_code)ede;
6798f76bb7dSCy Schubert rep.reason_bogus_str = ede_str?(char*)regional_strdup(region, ede_str):NULL;
680b7579f77SDag-Erling Smørgrav rep.rrsets = (struct ub_packed_rrset_key**)regional_alloc_zero(
681b7579f77SDag-Erling Smørgrav region, sizeof(struct ub_packed_rrset_key*)*rep.rrset_count);
682b7579f77SDag-Erling Smørgrav
683b7579f77SDag-Erling Smørgrav /* fill repinfo with references */
684b7579f77SDag-Erling Smørgrav for(i=0; i<rep.rrset_count; i++) {
685b7579f77SDag-Erling Smørgrav if(!load_ref(ssl, buf, worker, region, &rep.rrsets[i],
686b7579f77SDag-Erling Smørgrav &go_on)) {
687b7579f77SDag-Erling Smørgrav return 0;
688b7579f77SDag-Erling Smørgrav }
689b7579f77SDag-Erling Smørgrav }
690b7579f77SDag-Erling Smørgrav
691b7579f77SDag-Erling Smørgrav if(!go_on)
692b7579f77SDag-Erling Smørgrav return 1; /* skip this one, not all references satisfied */
693b7579f77SDag-Erling Smørgrav
694790c6b24SCy Schubert if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags,
695790c6b24SCy Schubert *worker->env.now)) {
696b7579f77SDag-Erling Smørgrav log_warn("error out of memory");
697b7579f77SDag-Erling Smørgrav return 0;
698b7579f77SDag-Erling Smørgrav }
699b7579f77SDag-Erling Smørgrav return 1;
700b7579f77SDag-Erling Smørgrav }
701b7579f77SDag-Erling Smørgrav
702b7579f77SDag-Erling Smørgrav /** load msg cache */
703b7579f77SDag-Erling Smørgrav static int
load_msg_cache(RES * ssl,struct worker * worker)7047da0adf7SDag-Erling Smørgrav load_msg_cache(RES* ssl, struct worker* worker)
705b7579f77SDag-Erling Smørgrav {
70617d15b25SDag-Erling Smørgrav sldns_buffer* buf = worker->env.scratch_buffer;
707b7579f77SDag-Erling Smørgrav if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
708b7579f77SDag-Erling Smørgrav while(ssl_read_buf(ssl, buf) &&
70917d15b25SDag-Erling Smørgrav strcmp((char*)sldns_buffer_begin(buf), "END_MSG_CACHE")!=0) {
710b7579f77SDag-Erling Smørgrav if(!load_msg(ssl, buf, worker))
711b7579f77SDag-Erling Smørgrav return 0;
712b7579f77SDag-Erling Smørgrav }
713b7579f77SDag-Erling Smørgrav return 1;
714b7579f77SDag-Erling Smørgrav }
715b7579f77SDag-Erling Smørgrav
716b7579f77SDag-Erling Smørgrav int
load_cache(RES * ssl,struct worker * worker)7177da0adf7SDag-Erling Smørgrav load_cache(RES* ssl, struct worker* worker)
718b7579f77SDag-Erling Smørgrav {
719b7579f77SDag-Erling Smørgrav if(!load_rrset_cache(ssl, worker))
720b7579f77SDag-Erling Smørgrav return 0;
721b7579f77SDag-Erling Smørgrav if(!load_msg_cache(ssl, worker))
722b7579f77SDag-Erling Smørgrav return 0;
723b7579f77SDag-Erling Smørgrav return read_fixed(ssl, worker->env.scratch_buffer, "EOF");
724b7579f77SDag-Erling Smørgrav }
725b7579f77SDag-Erling Smørgrav
726b7579f77SDag-Erling Smørgrav /** print details on a delegation point */
727b7579f77SDag-Erling Smørgrav static void
print_dp_details(RES * ssl,struct worker * worker,struct delegpt * dp)7287da0adf7SDag-Erling Smørgrav print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
729b7579f77SDag-Erling Smørgrav {
730b7579f77SDag-Erling Smørgrav char buf[257];
731b7579f77SDag-Erling Smørgrav struct delegpt_addr* a;
73217d15b25SDag-Erling Smørgrav int lame, dlame, rlame, rto, edns_vs, to, delay,
733b7579f77SDag-Erling Smørgrav tA = 0, tAAAA = 0, tother = 0;
73417d15b25SDag-Erling Smørgrav long long entry_ttl;
735b7579f77SDag-Erling Smørgrav struct rtt_info ri;
736b7579f77SDag-Erling Smørgrav uint8_t edns_lame_known;
737b7579f77SDag-Erling Smørgrav for(a = dp->target_list; a; a = a->next_target) {
738b7579f77SDag-Erling Smørgrav addr_to_str(&a->addr, a->addrlen, buf, sizeof(buf));
739b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "%-16s\t", buf))
740b7579f77SDag-Erling Smørgrav return;
741b7579f77SDag-Erling Smørgrav if(a->bogus) {
742b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "Address is BOGUS. "))
743b7579f77SDag-Erling Smørgrav return;
744b7579f77SDag-Erling Smørgrav }
745b7579f77SDag-Erling Smørgrav /* lookup in infra cache */
746b7579f77SDag-Erling Smørgrav delay=0;
747b7579f77SDag-Erling Smørgrav entry_ttl = infra_get_host_rto(worker->env.infra_cache,
748b7579f77SDag-Erling Smørgrav &a->addr, a->addrlen, dp->name, dp->namelen,
749b7579f77SDag-Erling Smørgrav &ri, &delay, *worker->env.now, &tA, &tAAAA, &tother);
750b7579f77SDag-Erling Smørgrav if(entry_ttl == -2 && ri.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
751b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "expired, rto %d msec, tA %d "
752b7579f77SDag-Erling Smørgrav "tAAAA %d tother %d.\n", ri.rto, tA, tAAAA,
753b7579f77SDag-Erling Smørgrav tother))
754b7579f77SDag-Erling Smørgrav return;
755b7579f77SDag-Erling Smørgrav continue;
756b7579f77SDag-Erling Smørgrav }
757b7579f77SDag-Erling Smørgrav if(entry_ttl == -1 || entry_ttl == -2) {
758b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "not in infra cache.\n"))
759b7579f77SDag-Erling Smørgrav return;
760b7579f77SDag-Erling Smørgrav continue; /* skip stuff not in infra cache */
761b7579f77SDag-Erling Smørgrav }
762b7579f77SDag-Erling Smørgrav
763b7579f77SDag-Erling Smørgrav /* uses type_A because most often looked up, but other
764b7579f77SDag-Erling Smørgrav * lameness won't be reported then */
765b7579f77SDag-Erling Smørgrav if(!infra_get_lame_rtt(worker->env.infra_cache,
766b7579f77SDag-Erling Smørgrav &a->addr, a->addrlen, dp->name, dp->namelen,
767b7579f77SDag-Erling Smørgrav LDNS_RR_TYPE_A, &lame, &dlame, &rlame, &rto,
768b7579f77SDag-Erling Smørgrav *worker->env.now)) {
769b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "not in infra cache.\n"))
770b7579f77SDag-Erling Smørgrav return;
771b7579f77SDag-Erling Smørgrav continue; /* skip stuff not in infra cache */
772b7579f77SDag-Erling Smørgrav }
77317d15b25SDag-Erling Smørgrav if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl " ARG_LL "d, "
77417d15b25SDag-Erling Smørgrav "ping %d var %d rtt %d, tA %d, tAAAA %d, tother %d",
775b7579f77SDag-Erling Smørgrav lame?"LAME ":"", dlame?"NoDNSSEC ":"",
776b7579f77SDag-Erling Smørgrav a->lame?"AddrWasParentSide ":"",
777b7579f77SDag-Erling Smørgrav rlame?"NoAuthButRecursive ":"", rto, entry_ttl,
778b7579f77SDag-Erling Smørgrav ri.srtt, ri.rttvar, rtt_notimeout(&ri),
779b7579f77SDag-Erling Smørgrav tA, tAAAA, tother))
780b7579f77SDag-Erling Smørgrav return;
781b7579f77SDag-Erling Smørgrav if(delay)
782b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, ", probedelay %d", delay))
783b7579f77SDag-Erling Smørgrav return;
784b7579f77SDag-Erling Smørgrav if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
785b7579f77SDag-Erling Smørgrav dp->name, dp->namelen, *worker->env.now, &edns_vs,
786b7579f77SDag-Erling Smørgrav &edns_lame_known, &to)) {
787b7579f77SDag-Erling Smørgrav if(edns_vs == -1) {
788b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, ", noEDNS%s.",
789b7579f77SDag-Erling Smørgrav edns_lame_known?" probed":" assumed"))
790b7579f77SDag-Erling Smørgrav return;
791b7579f77SDag-Erling Smørgrav } else {
792b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, ", EDNS %d%s.", edns_vs,
793b7579f77SDag-Erling Smørgrav edns_lame_known?" probed":" assumed"))
794b7579f77SDag-Erling Smørgrav return;
795b7579f77SDag-Erling Smørgrav }
796b7579f77SDag-Erling Smørgrav }
797b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "\n"))
798b7579f77SDag-Erling Smørgrav return;
799b7579f77SDag-Erling Smørgrav }
800b7579f77SDag-Erling Smørgrav }
801b7579f77SDag-Erling Smørgrav
802b7579f77SDag-Erling Smørgrav /** print main dp info */
803b7579f77SDag-Erling Smørgrav static void
print_dp_main(RES * ssl,struct delegpt * dp,struct dns_msg * msg)8047da0adf7SDag-Erling Smørgrav print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
805b7579f77SDag-Erling Smørgrav {
806b7579f77SDag-Erling Smørgrav size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
807b7579f77SDag-Erling Smørgrav
808b7579f77SDag-Erling Smørgrav /* print the dp */
809b7579f77SDag-Erling Smørgrav if(msg)
810b7579f77SDag-Erling Smørgrav for(i=0; i<msg->rep->rrset_count; i++) {
811b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
812b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d =
813b7579f77SDag-Erling Smørgrav (struct packed_rrset_data*)k->entry.data;
814b7579f77SDag-Erling Smørgrav if(d->security == sec_status_bogus) {
815b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "Address is BOGUS:\n"))
816b7579f77SDag-Erling Smørgrav return;
817b7579f77SDag-Erling Smørgrav }
818b7579f77SDag-Erling Smørgrav if(!dump_rrset(ssl, k, d, 0))
819b7579f77SDag-Erling Smørgrav return;
820b7579f77SDag-Erling Smørgrav }
821b7579f77SDag-Erling Smørgrav delegpt_count_ns(dp, &n_ns, &n_miss);
822b7579f77SDag-Erling Smørgrav delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
823b7579f77SDag-Erling Smørgrav /* since dp has not been used by iterator, all are available*/
824b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
825b7579f77SDag-Erling Smørgrav "can be examined to query further addresses.\n"
826b7579f77SDag-Erling Smørgrav "%sIt provides %d IP addresses.\n",
827b7579f77SDag-Erling Smørgrav (int)n_ns, (int)n_miss, (dp->bogus?"It is BOGUS. ":""),
828b7579f77SDag-Erling Smørgrav (int)n_addr))
829b7579f77SDag-Erling Smørgrav return;
830b7579f77SDag-Erling Smørgrav }
831b7579f77SDag-Erling Smørgrav
print_deleg_lookup(RES * ssl,struct worker * worker,uint8_t * nm,size_t nmlen,int ATTR_UNUSED (nmlabs))8327da0adf7SDag-Erling Smørgrav int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
833b7579f77SDag-Erling Smørgrav size_t nmlen, int ATTR_UNUSED(nmlabs))
834b7579f77SDag-Erling Smørgrav {
835b7579f77SDag-Erling Smørgrav /* deep links into the iterator module */
836b7579f77SDag-Erling Smørgrav struct delegpt* dp;
837b7579f77SDag-Erling Smørgrav struct dns_msg* msg;
838b7579f77SDag-Erling Smørgrav struct regional* region = worker->scratchpad;
839b7579f77SDag-Erling Smørgrav char b[260];
840b7579f77SDag-Erling Smørgrav struct query_info qinfo;
841b7579f77SDag-Erling Smørgrav struct iter_hints_stub* stub;
842*335c7cdaSCy Schubert int nolock = 0;
843b7579f77SDag-Erling Smørgrav regional_free_all(region);
844b7579f77SDag-Erling Smørgrav qinfo.qname = nm;
845b7579f77SDag-Erling Smørgrav qinfo.qname_len = nmlen;
846b7579f77SDag-Erling Smørgrav qinfo.qtype = LDNS_RR_TYPE_A;
847b7579f77SDag-Erling Smørgrav qinfo.qclass = LDNS_RR_CLASS_IN;
848bc892140SDag-Erling Smørgrav qinfo.local_alias = NULL;
849b7579f77SDag-Erling Smørgrav
850b7579f77SDag-Erling Smørgrav dname_str(nm, b);
851b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "The following name servers are used for lookup "
852b7579f77SDag-Erling Smørgrav "of %s\n", b))
853b7579f77SDag-Erling Smørgrav return 0;
854b7579f77SDag-Erling Smørgrav
855*335c7cdaSCy Schubert dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass, nolock);
856b7579f77SDag-Erling Smørgrav if(dp) {
857*335c7cdaSCy Schubert if(!ssl_printf(ssl, "forwarding request:\n")) {
858*335c7cdaSCy Schubert lock_rw_unlock(&worker->env.fwds->lock);
859b7579f77SDag-Erling Smørgrav return 0;
860*335c7cdaSCy Schubert }
861b7579f77SDag-Erling Smørgrav print_dp_main(ssl, dp, NULL);
862b7579f77SDag-Erling Smørgrav print_dp_details(ssl, worker, dp);
863*335c7cdaSCy Schubert lock_rw_unlock(&worker->env.fwds->lock);
864b7579f77SDag-Erling Smørgrav return 1;
865b7579f77SDag-Erling Smørgrav }
866b7579f77SDag-Erling Smørgrav
867b7579f77SDag-Erling Smørgrav while(1) {
868b7579f77SDag-Erling Smørgrav dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
869b7579f77SDag-Erling Smørgrav qinfo.qtype, qinfo.qclass, region, &msg,
870790c6b24SCy Schubert *worker->env.now, 0, NULL, 0);
871b7579f77SDag-Erling Smørgrav if(!dp) {
872b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "no delegation from "
873b7579f77SDag-Erling Smørgrav "cache; goes to configured roots\n");
874b7579f77SDag-Erling Smørgrav }
875b7579f77SDag-Erling Smørgrav /* go up? */
876a39a5a69SCy Schubert if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
877a39a5a69SCy Schubert (worker->env.cfg->do_ip4 && worker->back->num_ip4 != 0),
8788f76bb7dSCy Schubert (worker->env.cfg->do_ip6 && worker->back->num_ip6 != 0),
8798f76bb7dSCy Schubert worker->env.cfg->do_nat64)) {
880b7579f77SDag-Erling Smørgrav print_dp_main(ssl, dp, msg);
881b7579f77SDag-Erling Smørgrav print_dp_details(ssl, worker, dp);
882b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "cache delegation was "
883b7579f77SDag-Erling Smørgrav "useless (no IP addresses)\n"))
884b7579f77SDag-Erling Smørgrav return 0;
885b7579f77SDag-Erling Smørgrav if(dname_is_root(nm)) {
886b7579f77SDag-Erling Smørgrav /* goes to root config */
887b7579f77SDag-Erling Smørgrav return ssl_printf(ssl, "no delegation from "
888b7579f77SDag-Erling Smørgrav "cache; goes to configured roots\n");
889b7579f77SDag-Erling Smørgrav } else {
890b7579f77SDag-Erling Smørgrav /* useless, goes up */
891b7579f77SDag-Erling Smørgrav nm = dp->name;
892b7579f77SDag-Erling Smørgrav nmlen = dp->namelen;
893b7579f77SDag-Erling Smørgrav dname_remove_label(&nm, &nmlen);
894b7579f77SDag-Erling Smørgrav dname_str(nm, b);
895b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "going up, lookup %s\n", b))
896b7579f77SDag-Erling Smørgrav return 0;
897b7579f77SDag-Erling Smørgrav continue;
898b7579f77SDag-Erling Smørgrav }
899b7579f77SDag-Erling Smørgrav }
900b7579f77SDag-Erling Smørgrav stub = hints_lookup_stub(worker->env.hints, nm, qinfo.qclass,
901*335c7cdaSCy Schubert dp, nolock);
902b7579f77SDag-Erling Smørgrav if(stub) {
903b7579f77SDag-Erling Smørgrav if(stub->noprime) {
904b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "The noprime stub servers "
905*335c7cdaSCy Schubert "are used:\n")) {
906*335c7cdaSCy Schubert lock_rw_unlock(&worker->env.hints->lock);
907b7579f77SDag-Erling Smørgrav return 0;
908*335c7cdaSCy Schubert }
909b7579f77SDag-Erling Smørgrav } else {
910b7579f77SDag-Erling Smørgrav if(!ssl_printf(ssl, "The stub is primed "
911*335c7cdaSCy Schubert "with servers:\n")) {
912*335c7cdaSCy Schubert lock_rw_unlock(&worker->env.hints->lock);
913b7579f77SDag-Erling Smørgrav return 0;
914b7579f77SDag-Erling Smørgrav }
915*335c7cdaSCy Schubert }
916b7579f77SDag-Erling Smørgrav print_dp_main(ssl, stub->dp, NULL);
917b7579f77SDag-Erling Smørgrav print_dp_details(ssl, worker, stub->dp);
918*335c7cdaSCy Schubert lock_rw_unlock(&worker->env.hints->lock);
919b7579f77SDag-Erling Smørgrav } else {
920b7579f77SDag-Erling Smørgrav print_dp_main(ssl, dp, msg);
921b7579f77SDag-Erling Smørgrav print_dp_details(ssl, worker, dp);
922b7579f77SDag-Erling Smørgrav }
923b7579f77SDag-Erling Smørgrav break;
924b7579f77SDag-Erling Smørgrav }
925b7579f77SDag-Erling Smørgrav
926b7579f77SDag-Erling Smørgrav return 1;
927b7579f77SDag-Erling Smørgrav }
928