Coverage Report

Created: 2025-08-26 06:59

/src/bind9/lib/dns/resolver.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
/*! \file */
15
16
#include <ctype.h>
17
#include <inttypes.h>
18
#include <stdbool.h>
19
#include <stdint.h>
20
21
#include <isc/ascii.h>
22
#include <isc/async.h>
23
#include <isc/atomic.h>
24
#include <isc/counter.h>
25
#include <isc/hash.h>
26
#include <isc/hashmap.h>
27
#include <isc/hex.h>
28
#include <isc/log.h>
29
#include <isc/loop.h>
30
#include <isc/mutex.h>
31
#include <isc/random.h>
32
#include <isc/refcount.h>
33
#include <isc/result.h>
34
#include <isc/rwlock.h>
35
#include <isc/siphash.h>
36
#include <isc/stats.h>
37
#include <isc/string.h>
38
#include <isc/tid.h>
39
#include <isc/time.h>
40
#include <isc/timer.h>
41
#include <isc/util.h>
42
43
#include <dns/acl.h>
44
#include <dns/adb.h>
45
#include <dns/cache.h>
46
#include <dns/db.h>
47
#include <dns/dispatch.h>
48
#include <dns/dns64.h>
49
#include <dns/dnstap.h>
50
#include <dns/ds.h>
51
#include <dns/ede.h>
52
#include <dns/edns.h>
53
#include <dns/forward.h>
54
#include <dns/keytable.h>
55
#include <dns/message.h>
56
#include <dns/name.h>
57
#include <dns/nametree.h>
58
#include <dns/ncache.h>
59
#include <dns/nsec.h>
60
#include <dns/nsec3.h>
61
#include <dns/opcode.h>
62
#include <dns/peer.h>
63
#include <dns/rcode.h>
64
#include <dns/rdata.h>
65
#include <dns/rdataclass.h>
66
#include <dns/rdatalist.h>
67
#include <dns/rdataset.h>
68
#include <dns/rdatastruct.h>
69
#include <dns/rdatatype.h>
70
#include <dns/resolver.h>
71
#include <dns/rootns.h>
72
#include <dns/stats.h>
73
#include <dns/tsig.h>
74
#include <dns/validator.h>
75
#include <dns/zone.h>
76
77
#ifdef WANT_QUERYTRACE
78
#define RTRACE(m)                                                       \
79
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, \
80
          ISC_LOG_DEBUG(3), "res %p: %s", res, (m))
81
#define RRTRACE(r, m)                                                   \
82
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, \
83
          ISC_LOG_DEBUG(3), "res %p: %s", (r), (m))
84
#define FCTXTRACE(m)                                                         \
85
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,      \
86
          ISC_LOG_DEBUG(3), "fctx %p(%s): %s", fctx, fctx->info, \
87
          (m))
88
#define FCTXTRACE2(m1, m2)                                              \
89
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, \
90
          ISC_LOG_DEBUG(3), "fctx %p(%s): %s %s", fctx,     \
91
          fctx->info, (m1), (m2))
92
#define FCTXTRACE3(m, res)                                                    \
93
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,       \
94
          ISC_LOG_DEBUG(3), "fctx %p(%s): [result: %s] %s", fctx, \
95
          fctx->info, isc_result_totext(res), (m))
96
#define FCTXTRACE4(m1, m2, res)                                            \
97
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,    \
98
          ISC_LOG_DEBUG(3), "fctx %p(%s): [result: %s] %s %s", \
99
          fctx, fctx->info, isc_result_totext(res), (m1), (m2))
100
#define FCTXTRACE5(m1, m2, v)                                           \
101
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, \
102
          ISC_LOG_DEBUG(3), "fctx %p(%s): %s %s%u", fctx,   \
103
          fctx->info, (m1), (m2), (v))
104
#define FCTXTRACEN(m1, name, res)                                    \
105
  do {                                                         \
106
    if (isc_log_wouldlog(ISC_LOG_DEBUG(3))) {            \
107
      char dbuf[DNS_NAME_FORMATSIZE];              \
108
      dns_name_format((name), dbuf, sizeof(dbuf)); \
109
      FCTXTRACE4((m1), dbuf, (res));               \
110
    }                                                    \
111
  } while (0)
112
#define FTRACE(m)                                                            \
113
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,      \
114
          ISC_LOG_DEBUG(3), "fetch %p (fctx %p(%s)): %s", fetch, \
115
          fetch->private, fetch->private->info, (m))
116
#define QTRACE(m)                                                        \
117
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,  \
118
          ISC_LOG_DEBUG(3), "resquery %p (fctx %p(%s)): %s", \
119
          query, query->fctx, query->fctx->info, (m))
120
#else /* ifdef WANT_QUERYTRACE */
121
#define RTRACE(m)          \
122
0
  do {               \
123
0
    UNUSED(m); \
124
0
  } while (0)
125
#define RRTRACE(r, m)      \
126
  do {               \
127
    UNUSED(r); \
128
    UNUSED(m); \
129
  } while (0)
130
#define FCTXTRACE(m)          \
131
0
  do {                  \
132
0
    UNUSED(fctx); \
133
0
    UNUSED(m);    \
134
0
  } while (0)
135
#define FCTXTRACE2(m1, m2)    \
136
0
  do {                  \
137
0
    UNUSED(fctx); \
138
0
    UNUSED(m1);   \
139
0
    UNUSED(m2);   \
140
0
  } while (0)
141
#define FCTXTRACE3(m1, res)   \
142
0
  do {                  \
143
0
    UNUSED(fctx); \
144
0
    UNUSED(m1);   \
145
0
    UNUSED(res);  \
146
0
  } while (0)
147
#define FCTXTRACE4(m1, m2, res) \
148
0
  do {                    \
149
0
    UNUSED(fctx);   \
150
0
    UNUSED(m1);     \
151
0
    UNUSED(m2);     \
152
0
    UNUSED(res);    \
153
0
  } while (0)
154
#define FCTXTRACE5(m1, m2, v) \
155
0
  do {                  \
156
0
    UNUSED(fctx); \
157
0
    UNUSED(m1);   \
158
0
    UNUSED(m2);   \
159
0
    UNUSED(v);    \
160
0
  } while (0)
161
0
#define FCTXTRACEN(m1, name, res) FCTXTRACE4(m1, name, res)
162
#define FTRACE(m)          \
163
0
  do {               \
164
0
    UNUSED(m); \
165
0
  } while (0)
166
#define QTRACE(m)          \
167
0
  do {               \
168
0
    UNUSED(m); \
169
0
  } while (0)
170
#endif /* WANT_QUERYTRACE */
171
172
/*
173
 * The maximum time we will wait for a single query.
174
 */
175
0
#define MAX_SINGLE_QUERY_TIMEOUT    9000U
176
0
#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT * US_PER_MS)
177
178
/*
179
 * The default maximum number of validations and validation failures per-fetch
180
 */
181
#ifndef DEFAULT_MAX_VALIDATIONS
182
0
#define DEFAULT_MAX_VALIDATIONS 16
183
#endif
184
#ifndef DEFAULT_MAX_VALIDATION_FAILURES
185
0
#define DEFAULT_MAX_VALIDATION_FAILURES 1
186
#endif
187
188
/*
189
 * A minumum sane timeout value for the whole query to live when e.g. talking to
190
 * a backend server and a quick timeout is preferred by the user.
191
 *
192
 * IMPORTANT: if changing this value, note there is a documented behavior when
193
 * values of 'resolver-query-timeout' less than or equal to 300 are treated as
194
 * seconds and converted to milliseconds before applying the limits, that's
195
 * why the value of 301 was chosen as the absolute minimum in order to not break
196
 * backward compatibility.
197
 */
198
0
#define MINIMUM_QUERY_TIMEOUT 301U
199
200
/*
201
 * The default time in seconds for the whole query to live.
202
 * We want to allow an individual query time to complete / timeout.
203
 */
204
#ifndef DEFAULT_QUERY_TIMEOUT
205
0
#define DEFAULT_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1000U)
206
#endif /* ifndef DEFAULT_QUERY_TIMEOUT */
207
208
/* The maximum time in seconds for the whole query to live. */
209
#ifndef MAXIMUM_QUERY_TIMEOUT
210
0
#define MAXIMUM_QUERY_TIMEOUT 30000
211
#endif /* ifndef MAXIMUM_QUERY_TIMEOUT */
212
213
/* The default maximum number of recursions to follow before giving up. */
214
#ifndef DEFAULT_RECURSION_DEPTH
215
0
#define DEFAULT_RECURSION_DEPTH 7
216
#endif /* ifndef DEFAULT_RECURSION_DEPTH */
217
218
/* The default maximum number of iterative queries to allow before giving up. */
219
#ifndef DEFAULT_MAX_QUERIES
220
0
#define DEFAULT_MAX_QUERIES 50
221
#endif /* ifndef DEFAULT_MAX_QUERIES */
222
223
/*
224
 * After NS_FAIL_LIMIT attempts to fetch a name server address,
225
 * if the number of addresses in the NS RRset exceeds NS_RR_LIMIT,
226
 * stop trying to fetch, in order to avoid wasting resources.
227
 */
228
0
#define NS_FAIL_LIMIT 4
229
0
#define NS_RR_LIMIT   5
230
/*
231
 * IP address lookups are performed for at most NS_PROCESSING_LIMIT NS RRs in
232
 * any NS RRset encountered, to avoid excessive resource use while processing
233
 * large delegations.
234
 */
235
0
#define NS_PROCESSING_LIMIT 20
236
237
STATIC_ASSERT(NS_PROCESSING_LIMIT > NS_RR_LIMIT,
238
        "The maximum number of NS RRs processed for each "
239
        "delegation "
240
        "(NS_PROCESSING_LIMIT) must be larger than the large "
241
        "delegation "
242
        "threshold (NS_RR_LIMIT).");
243
244
/* Hash table for zone counters */
245
#ifndef RES_DOMAIN_HASH_BITS
246
0
#define RES_DOMAIN_HASH_BITS 12
247
#endif /* ifndef RES_DOMAIN_HASH_BITS */
248
249
/*%
250
 * Maximum EDNS0 input packet size.
251
 */
252
#define RECV_BUFFER_SIZE 4096 /* XXXRTH  Constant. */
253
254
/*%
255
 * This defines the maximum number of timeouts we will permit before we
256
 * disable EDNS0 on the query.
257
 */
258
#define MAX_EDNS0_TIMEOUTS 3
259
260
typedef struct fetchctx fetchctx_t;
261
262
typedef struct query {
263
  /* Locked by loop event serialization. */
264
  unsigned int magic;
265
  isc_refcount_t references;
266
  fetchctx_t *fctx;
267
  dns_message_t *rmessage;
268
  dns_dispatchmgr_t *dispatchmgr;
269
  dns_dispatch_t *dispatch;
270
  dns_adbaddrinfo_t *addrinfo;
271
  isc_time_t start;
272
  dns_messageid_t id;
273
  dns_dispentry_t *dispentry;
274
  ISC_LINK(struct query) link;
275
  isc_buffer_t buffer;
276
  isc_buffer_t *tsig;
277
  dns_tsigkey_t *tsigkey;
278
  int ednsversion;
279
  unsigned int options;
280
  unsigned int attributes;
281
  unsigned int udpsize;
282
  unsigned char data[512];
283
} resquery_t;
284
285
#if DNS_RESOLVER_TRACE
286
#define resquery_ref(ptr)   resquery__ref(ptr, __func__, __FILE__, __LINE__)
287
#define resquery_unref(ptr) resquery__unref(ptr, __func__, __FILE__, __LINE__)
288
#define resquery_attach(ptr, ptrp) \
289
  resquery__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
290
#define resquery_detach(ptrp) \
291
  resquery__detach(ptrp, __func__, __FILE__, __LINE__)
292
ISC_REFCOUNT_TRACE_DECL(resquery);
293
#else
294
ISC_REFCOUNT_DECL(resquery);
295
#endif
296
297
struct tried {
298
  isc_sockaddr_t addr;
299
  unsigned int count;
300
  ISC_LINK(struct tried) link;
301
};
302
303
0
#define QUERY_MAGIC    ISC_MAGIC('Q', '!', '!', '!')
304
#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
305
306
0
#define RESQUERY_ATTR_CANCELED 0x02
307
308
#define RESQUERY_CONNECTING(q) ((q)->connects > 0)
309
0
#define RESQUERY_CANCELED(q)   (((q)->attributes & RESQUERY_ATTR_CANCELED) != 0)
310
#define RESQUERY_SENDING(q)    ((q)->sends > 0)
311
312
typedef enum {
313
  fetchstate_active,
314
  fetchstate_done /*%< Fetch completion events posted. */
315
} fetchstate_t;
316
317
typedef enum {
318
  badns_unreachable = 0,
319
  badns_response,
320
  badns_validation,
321
  badns_forwarder,
322
} badnstype_t;
323
324
0
#define FCTXCOUNT_MAGIC    ISC_MAGIC('F', 'C', 'n', 't')
325
#define VALID_FCTXCOUNT(counter) ISC_MAGIC_VALID(counter, FCTXCOUNT_MAGIC)
326
327
typedef struct fctxcount fctxcount_t;
328
struct fctxcount {
329
  unsigned int magic;
330
  isc_mem_t *mctx;
331
  isc_mutex_t lock;
332
  dns_fixedname_t dfname;
333
  dns_name_t *domain;
334
  uint_fast32_t count;
335
  uint_fast32_t allowed;
336
  uint_fast32_t dropped;
337
  isc_stdtime_t logged;
338
};
339
340
struct fetchctx {
341
  /*% Not locked. */
342
  unsigned int magic;
343
  dns_resolver_t *res;
344
  dns_fixedname_t fname;
345
  dns_name_t *name;
346
  dns_rdatatype_t type;
347
  unsigned int options;
348
  fctxcount_t *counter;
349
  char *info;
350
  isc_mem_t *mctx;
351
  isc_stdtime_t now;
352
353
  isc_loop_t *loop;
354
  isc_tid_t tid;
355
356
  dns_edectx_t edectx;
357
358
  /* Atomic */
359
  isc_refcount_t references;
360
361
  /*% Locked by lock. */
362
  isc_mutex_t lock;
363
  fetchstate_t state;
364
  bool cloned;
365
  bool spilled;
366
  uint_fast32_t allowed;
367
  uint_fast32_t dropped;
368
  ISC_LIST(dns_fetchresponse_t) resps;
369
370
  /*% Locked by loop event serialization. */
371
  dns_fixedname_t dfname;
372
  dns_name_t *domain;
373
  dns_rdataset_t nameservers;
374
  atomic_uint_fast32_t attributes;
375
  isc_timer_t *timer;
376
  isc_time_t expires;
377
  isc_interval_t interval;
378
  dns_message_t *qmessage;
379
  ISC_LIST(resquery_t) queries;
380
  dns_adbfindlist_t finds;
381
  dns_adbfind_t *find;
382
  /*
383
   * altfinds are names and/or addresses of dual stack servers that
384
   * should be used when iterative resolution to a server is not
385
   * possible because the address family of that server is not usable.
386
   */
387
  dns_adbfindlist_t altfinds;
388
  dns_adbfind_t *altfind;
389
  dns_adbaddrinfolist_t forwaddrs;
390
  dns_adbaddrinfolist_t altaddrs;
391
  dns_forwarderlist_t forwarders;
392
  dns_fwdpolicy_t fwdpolicy;
393
  isc_sockaddrlist_t bad;
394
  ISC_LIST(struct tried) edns;
395
  ISC_LIST(dns_validator_t) validators;
396
  dns_db_t *cache;
397
  dns_adb_t *adb;
398
  bool ns_ttl_ok;
399
  uint32_t ns_ttl;
400
  isc_counter_t *qc;
401
  isc_counter_t *gqc;
402
  bool minimized;
403
  unsigned int qmin_labels;
404
  isc_result_t qmin_warning;
405
  bool force_qmin_warning;
406
  bool ip6arpaskip;
407
  bool forwarding;
408
  dns_fixedname_t qminfname;
409
  dns_name_t *qminname;
410
  dns_rdatatype_t qmintype;
411
  dns_fetch_t *qminfetch;
412
  dns_rdataset_t qminrrset;
413
  dns_rdataset_t qminsigrrset;
414
  dns_fixedname_t qmindcfname;
415
  dns_name_t *qmindcname;
416
  dns_fixedname_t fwdfname;
417
  dns_name_t *fwdname;
418
419
  /*%
420
   * The number of events we're waiting for.
421
   */
422
  atomic_uint_fast32_t pending;
423
424
  /*%
425
   * The number of times we've "restarted" the current
426
   * nameserver set.  This acts as a failsafe to prevent
427
   * us from pounding constantly on a particular set of
428
   * servers that, for whatever reason, are not giving
429
   * us useful responses, but are responding in such a
430
   * way that they are not marked "bad".
431
   */
432
  unsigned int restarts;
433
434
  /*%
435
   * The number of timeouts that have occurred since we
436
   * last successfully received a response packet.  This
437
   * is used for EDNS0 black hole detection.
438
   */
439
  unsigned int timeouts;
440
441
  /*%
442
   * Look aside state for DS lookups.
443
   */
444
  dns_fixedname_t nsfname;
445
  dns_name_t *nsname;
446
447
  dns_fetch_t *nsfetch;
448
  dns_rdataset_t nsrrset;
449
450
  /*%
451
   * Number of queries that reference this context.
452
   */
453
  atomic_uint_fast32_t nqueries; /* Bucket lock. */
454
455
  /*%
456
   * Random numbers to use for mixing up server addresses.
457
   */
458
  uint32_t rand_buf;
459
  uint32_t rand_bits;
460
461
  /*%
462
   * Fetch-local statistics for detailed logging.
463
   */
464
  isc_result_t result;  /*%< fetch result */
465
  isc_result_t vresult; /*%< validation result */
466
  isc_time_t start;
467
  uint64_t duration;
468
  bool logged;
469
  unsigned int querysent;
470
  unsigned int referrals;
471
  unsigned int lamecount;
472
  unsigned int quotacount;
473
  unsigned int neterr;
474
  unsigned int badresp;
475
  unsigned int adberr;
476
  unsigned int findfail;
477
  unsigned int valfail;
478
  bool timeout;
479
  dns_adbaddrinfo_t *addrinfo;
480
  unsigned int depth;
481
  char clientstr[ISC_SOCKADDR_FORMATSIZE];
482
483
  isc_counter_t *nvalidations;
484
  isc_counter_t *nfails;
485
};
486
487
0
#define FCTX_MAGIC   ISC_MAGIC('F', '!', '!', '!')
488
0
#define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC)
489
490
0
#define FCTX_ATTR_HAVEANSWER 0x0001
491
0
#define FCTX_ATTR_GLUING     0x0002
492
0
#define FCTX_ATTR_ADDRWAIT   0x0004
493
0
#define FCTX_ATTR_WANTCACHE  0x0010
494
0
#define FCTX_ATTR_WANTNCACHE 0x0020
495
0
#define FCTX_ATTR_NEEDEDNS0  0x0040
496
0
#define FCTX_ATTR_TRIEDFIND  0x0080
497
0
#define FCTX_ATTR_TRIEDALT   0x0100
498
499
#define HAVE_ANSWER(f) \
500
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_HAVEANSWER) != 0)
501
#define GLUING(f) \
502
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_GLUING) != 0)
503
#define ADDRWAIT(f) \
504
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_ADDRWAIT) != 0)
505
0
#define SHUTTINGDOWN(f) ((f)->state == fetchstate_done)
506
#define WANTCACHE(f) \
507
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_WANTCACHE) != 0)
508
#define WANTNCACHE(f) \
509
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_WANTNCACHE) != 0)
510
#define NEEDEDNS0(f) \
511
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_NEEDEDNS0) != 0)
512
#define TRIEDFIND(f) \
513
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_TRIEDFIND) != 0)
514
#define TRIEDALT(f) \
515
0
  ((atomic_load_acquire(&(f)->attributes) & FCTX_ATTR_TRIEDALT) != 0)
516
517
0
#define FCTX_ATTR_SET(f, a) atomic_fetch_or_release(&(f)->attributes, (a))
518
0
#define FCTX_ATTR_CLR(f, a) atomic_fetch_and_release(&(f)->attributes, ~(a))
519
520
0
#define CHECKNTA(f) (((f)->options & DNS_FETCHOPT_NONTA) == 0)
521
522
typedef struct {
523
  dns_adbaddrinfo_t *addrinfo;
524
  fetchctx_t *fctx;
525
} dns_valarg_t;
526
527
struct dns_fetch {
528
  unsigned int magic;
529
  isc_mem_t *mctx;
530
  dns_resolver_t *res;
531
  fetchctx_t *private;
532
};
533
534
0
#define DNS_FETCH_MAGIC        ISC_MAGIC('F', 't', 'c', 'h')
535
0
#define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)
536
537
typedef struct alternate {
538
  bool isaddress;
539
  union {
540
    isc_sockaddr_t addr;
541
    struct {
542
      dns_name_t name;
543
      in_port_t port;
544
    } _n;
545
  } _u;
546
  ISC_LINK(struct alternate) link;
547
} alternate_t;
548
549
struct dns_resolver {
550
  /* Unlocked. */
551
  unsigned int magic;
552
  isc_mem_t *mctx;
553
  isc_mutex_t lock;
554
  isc_mutex_t primelock;
555
  dns_rdataclass_t rdclass;
556
  dns_view_t *view;
557
  bool frozen;
558
  unsigned int options;
559
  isc_tlsctx_cache_t *tlsctx_cache;
560
  dns_dispatchset_t *dispatches4;
561
  dns_dispatchset_t *dispatches6;
562
563
  isc_hashmap_t *fctxs;
564
  isc_rwlock_t fctxs_lock;
565
566
  isc_hashmap_t *counters;
567
  isc_rwlock_t counters_lock;
568
569
  uint32_t lame_ttl;
570
  ISC_LIST(alternate_t) alternates;
571
  dns_nametree_t *algorithms;
572
  dns_nametree_t *digests;
573
  unsigned int spillatmax;
574
  unsigned int spillatmin;
575
  isc_timer_t *spillattimer;
576
  bool zero_no_soa_ttl;
577
  unsigned int query_timeout;
578
  unsigned int maxdepth;
579
  unsigned int maxqueries;
580
  isc_result_t quotaresp[2];
581
  isc_stats_t *stats;
582
  dns_stats_t *querystats;
583
584
  /* Additions for serve-stale feature. */
585
  unsigned int retryinterval; /* in milliseconds */
586
  unsigned int nonbackofftries;
587
588
  /* Atomic */
589
  isc_refcount_t references;
590
  atomic_uint_fast32_t zspill; /* fetches-per-zone */
591
  atomic_bool exiting;
592
  atomic_bool priming;
593
594
  atomic_uint_fast32_t maxvalidations;
595
  atomic_uint_fast32_t maxvalidationfails;
596
597
  /* Locked by lock. */
598
  unsigned int spillat; /* clients-per-query */
599
600
  /* Locked by primelock. */
601
  dns_fetch_t *primefetch;
602
603
  uint32_t nloops;
604
605
  isc_mempool_t **namepools;
606
  isc_mempool_t **rdspools;
607
};
608
609
0
#define RES_MAGIC     ISC_MAGIC('R', 'e', 's', '!')
610
#define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC)
611
612
/*%
613
 * Private addrinfo flags.
614
 */
615
enum {
616
  FCTX_ADDRINFO_MARK = 1 << 0,
617
  FCTX_ADDRINFO_FORWARDER = 1 << 1,
618
  FCTX_ADDRINFO_EDNSOK = 1 << 2,
619
  FCTX_ADDRINFO_NOCOOKIE = 1 << 3,
620
  FCTX_ADDRINFO_BADCOOKIE = 1 << 4,
621
  FCTX_ADDRINFO_DUALSTACK = 1 << 5,
622
  FCTX_ADDRINFO_NOEDNS0 = 1 << 6,
623
};
624
625
0
#define UNMARKED(a)    (((a)->flags & FCTX_ADDRINFO_MARK) == 0)
626
0
#define ISFORWARDER(a) (((a)->flags & FCTX_ADDRINFO_FORWARDER) != 0)
627
0
#define NOCOOKIE(a)    (((a)->flags & FCTX_ADDRINFO_NOCOOKIE) != 0)
628
0
#define EDNSOK(a)      (((a)->flags & FCTX_ADDRINFO_EDNSOK) != 0)
629
0
#define BADCOOKIE(a)   (((a)->flags & FCTX_ADDRINFO_BADCOOKIE) != 0)
630
0
#define ISDUALSTACK(a) (((a)->flags & FCTX_ADDRINFO_DUALSTACK) != 0)
631
632
0
#define NXDOMAIN(r)   (((r)->attributes.nxdomain))
633
0
#define NEGATIVE(r)   (((r)->attributes.negative))
634
0
#define STATICSTUB(r) (((r)->attributes.staticstub))
635
636
#ifdef ENABLE_AFL
637
bool dns_fuzzing_resolver = false;
638
void
639
dns_resolver_setfuzzing(void) {
640
  dns_fuzzing_resolver = true;
641
}
642
#endif /* ifdef ENABLE_AFL */
643
644
static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA";
645
static const dns_name_t ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data);
646
647
static void
648
dns_resolver__destroy(dns_resolver_t *res);
649
static isc_result_t
650
resquery_send(resquery_t *query);
651
static void
652
resquery_response(isc_result_t eresult, isc_region_t *region, void *arg);
653
static void
654
resquery_response_continue(void *arg, isc_result_t result);
655
static void
656
resquery_connected(isc_result_t eresult, isc_region_t *region, void *arg);
657
static void
658
fctx_try(fetchctx_t *fctx, bool retrying);
659
static void
660
fctx_shutdown(void *arg);
661
static void
662
fctx_minimize_qname(fetchctx_t *fctx);
663
static void
664
fctx_destroy(fetchctx_t *fctx);
665
static isc_result_t
666
negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name,
667
   isc_stdtime_t now, bool optout, bool secure, dns_rdataset_t *added,
668
   dns_dbnode_t **nodep);
669
static void
670
validated(void *arg);
671
static void
672
maybe_cancel_validators(fetchctx_t *fctx);
673
static void
674
add_bad(fetchctx_t *fctx, dns_message_t *rmessage, dns_adbaddrinfo_t *addrinfo,
675
  isc_result_t reason, badnstype_t badtype);
676
static void
677
findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name,
678
      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
679
680
#define fctx_done_detach(fctxp, result)                                 \
681
0
  if (fctx__done(*fctxp, result, __func__, __FILE__, __LINE__)) { \
682
0
    fetchctx_detach(fctxp);                                 \
683
0
  }
684
685
#define fctx_done_unref(fctx, result)                                 \
686
0
  if (fctx__done(fctx, result, __func__, __FILE__, __LINE__)) { \
687
0
    fetchctx_unref(fctx);                                 \
688
0
  }
689
690
#if DNS_RESOLVER_TRACE
691
#define fetchctx_ref(ptr)   fetchctx__ref(ptr, __func__, __FILE__, __LINE__)
692
#define fetchctx_unref(ptr) fetchctx__unref(ptr, __func__, __FILE__, __LINE__)
693
#define fetchctx_attach(ptr, ptrp) \
694
  fetchctx__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
695
#define fetchctx_detach(ptrp) \
696
  fetchctx__detach(ptrp, __func__, __FILE__, __LINE__)
697
ISC_REFCOUNT_TRACE_DECL(fetchctx);
698
#else
699
ISC_REFCOUNT_DECL(fetchctx);
700
#endif
701
702
static bool
703
fctx__done(fetchctx_t *fctx, isc_result_t result, const char *func,
704
     const char *file, unsigned int line);
705
706
static void
707
resume_qmin(void *arg);
708
709
static void
710
clone_results(fetchctx_t *fctx);
711
712
static isc_result_t
713
get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
714
      dns_rdatatype_t type, const dns_name_t *domain,
715
      dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
716
      unsigned int options, unsigned int depth, isc_counter_t *qc,
717
      isc_counter_t *gqc, fetchctx_t **fctxp, bool *new_fctx);
718
719
/*%
720
 * The structure and functions defined below implement the resolver
721
 * query (resquery) response handling logic.
722
 *
723
 * When a resolver query is sent and a response is received, the
724
 * resquery_response() event handler is run, which calls the rctx_*()
725
 * functions.  The respctx_t structure maintains state from function
726
 * to function.
727
 *
728
 * The call flow is described below:
729
 *
730
 * 1. resquery_response():
731
 *    - Initialize a respctx_t structure (rctx_respinit()).
732
 *    - Check for dispatcher failure (rctx_dispfail()).
733
 *    - Parse the response (rctx_parse()).
734
 *    - Log the response (rctx_logpacket()).
735
 *    - Check the parsed response for an OPT record and handle
736
 *      EDNS (rctx_opt(), rctx_edns()).
737
 *    - Check for a bad or lame server (rctx_badserver(), rctx_lameserver()).
738
 *    - If RCODE and ANCOUNT suggest this is a positive answer, and
739
 *      if so, call rctx_answer(): go to step 2.
740
 *    - If RCODE and NSCOUNT suggest this is a negative answer or a
741
 *      referral, call rctx_answer_none(): go to step 4.
742
 *    - Check the additional section for data that should be cached
743
 *      (rctx_additional()).
744
 *    - Clean up and finish by calling rctx_done(): go to step 5.
745
 *
746
 * 2. rctx_answer():
747
 *    - If the answer appears to be positive, call rctx_answer_positive():
748
 *      go to step 3.
749
 *    - If the response is a malformed delegation (with glue or NS records
750
 *      in the answer section), call rctx_answer_none(): go to step 4.
751
 *
752
 * 3. rctx_answer_positive():
753
 *    - Initialize the portions of respctx_t needed for processing an answer
754
 *      (rctx_answer_init()).
755
 *    - Scan the answer section to find records that are responsive to the
756
 *      query (rctx_answer_scan()).
757
 *    - For whichever type of response was found, call a separate routine
758
 *      to handle it: matching QNAME/QTYPE (rctx_answer_match()),
759
 *      CNAME (rctx_answer_cname()), covering DNAME (rctx_answer_dname()),
760
 *      or any records returned in response to a query of type ANY
761
 *      (rctx_answer_any()).
762
 *    - Scan the authority section for NS or other records that may be
763
 *      included with a positive answer (rctx_authority_scan()).
764
 *
765
 * 4. rctx_answer_none():
766
 *    - Determine whether this is an NXDOMAIN, NXRRSET, or referral.
767
 *    - If referral, set up the resolver to follow the delegation
768
 *      (rctx_referral()).
769
 *    - If NXDOMAIN/NXRRSET, scan the authority section for NS and SOA
770
 *      records included with a negative response (rctx_authority_negative()),
771
 *      then for DNSSEC proof of nonexistence (rctx_authority_dnssec()).
772
 *
773
 * 5. rctx_done():
774
 *    - Set up chasing of DS records if needed (rctx_chaseds()).
775
 *    - If the response wasn't intended for us, wait for another response
776
 *      from the dispatcher (rctx_next()).
777
 *    - If there is a problem with the responding server, set up another
778
 *      query to a different server (rctx_nextserver()).
779
 *    - If there is a problem that might be temporary or dependent on
780
 *      EDNS options, set up another query to the same server with changed
781
 *      options (rctx_resend()).
782
 *    - Shut down the fetch context.
783
 */
784
785
typedef struct respctx {
786
  resquery_t *query;
787
  fetchctx_t *fctx;
788
  isc_mem_t *mctx;
789
  isc_result_t result;
790
  isc_buffer_t buffer;
791
  unsigned int retryopts; /* updated options to pass to
792
         * fctx_query() when resending */
793
794
  dns_rdatatype_t type; /* type being sought (set to
795
             * ANY if qtype was SIG or RRSIG) */
796
  bool aa;        /* authoritative answer? */
797
  dns_trust_t trust;    /* answer trust level */
798
  bool chaining;        /* CNAME/DNAME processing? */
799
  bool next_server;     /* give up, try the next server
800
             * */
801
802
  badnstype_t broken_type; /* type of name server problem
803
          * */
804
  isc_result_t broken_server;
805
806
  bool get_nameservers; /* get a new NS rrset at
807
             * zone cut? */
808
  bool resend;        /* resend this query? */
809
  bool nextitem;        /* invalid response; keep
810
             * listening for the correct one */
811
  bool truncated;       /* response was truncated */
812
  bool no_response;     /* no response was received */
813
  bool negative;        /* is this a negative response? */
814
815
  isc_stdtime_t now; /* time info */
816
  isc_time_t tnow;
817
  isc_time_t *finish;
818
819
  unsigned int dname_labels;
820
  unsigned int domain_labels; /* range of permissible number
821
             * of
822
             * labels in a DNAME */
823
824
  dns_name_t *aname;     /* answer name */
825
  dns_rdataset_t *ardataset; /* answer rdataset */
826
827
  dns_name_t *cname;     /* CNAME name */
828
  dns_rdataset_t *crdataset; /* CNAME rdataset */
829
830
  dns_name_t *dname;     /* DNAME name */
831
  dns_rdataset_t *drdataset; /* DNAME rdataset */
832
833
  dns_name_t *ns_name;       /* NS name */
834
  dns_rdataset_t *ns_rdataset; /* NS rdataset */
835
836
  dns_name_t *soa_name; /* SOA name in a negative answer */
837
  dns_name_t *ds_name;  /* DS name in a negative answer */
838
839
  dns_name_t *found_name;     /* invalid name in negative
840
             * response */
841
  dns_rdatatype_t found_type; /* invalid type in negative
842
             * response */
843
844
  dns_rdataset_t *opt; /* OPT rdataset */
845
846
  dns_rdataset_t *vrdataset;
847
  dns_rdataset_t *vsigrdataset;
848
} respctx_t;
849
850
static void
851
rctx_respinit(resquery_t *query, fetchctx_t *fctx, isc_result_t result,
852
        isc_region_t *region, respctx_t *rctx);
853
854
static void
855
rctx_answer_init(respctx_t *rctx);
856
857
static void
858
rctx_answer_scan(respctx_t *rctx);
859
860
static void
861
rctx_authority_positive(respctx_t *rctx);
862
863
static isc_result_t
864
rctx_answer_any(respctx_t *rctx);
865
866
static isc_result_t
867
rctx_answer_match(respctx_t *rctx);
868
869
static isc_result_t
870
rctx_answer_cname(respctx_t *rctx);
871
872
static isc_result_t
873
rctx_answer_dname(respctx_t *rctx);
874
875
static isc_result_t
876
rctx_answer_positive(respctx_t *rctx);
877
878
static isc_result_t
879
rctx_authority_negative(respctx_t *rctx);
880
881
static isc_result_t
882
rctx_authority_dnssec(respctx_t *rctx);
883
884
static void
885
rctx_additional(respctx_t *rctx);
886
887
static isc_result_t
888
rctx_referral(respctx_t *rctx);
889
890
static isc_result_t
891
rctx_answer_none(respctx_t *rctx);
892
893
static void
894
rctx_nextserver(respctx_t *rctx, dns_message_t *message,
895
    dns_adbaddrinfo_t *addrinfo, isc_result_t result);
896
897
static void
898
rctx_resend(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo);
899
900
static isc_result_t
901
rctx_next(respctx_t *rctx);
902
903
static void
904
rctx_chaseds(respctx_t *rctx, dns_message_t *message,
905
       dns_adbaddrinfo_t *addrinfo, isc_result_t result);
906
907
static void
908
rctx_done(respctx_t *rctx, isc_result_t result);
909
910
static void
911
rctx_logpacket(respctx_t *rctx);
912
913
static void
914
rctx_opt(respctx_t *rctx);
915
916
static void
917
rctx_edns(respctx_t *rctx);
918
919
static isc_result_t
920
rctx_parse(respctx_t *rctx);
921
922
static isc_result_t
923
rctx_badserver(respctx_t *rctx, isc_result_t result);
924
925
static isc_result_t
926
rctx_answer(respctx_t *rctx);
927
928
static isc_result_t
929
rctx_lameserver(respctx_t *rctx);
930
931
static isc_result_t
932
rctx_dispfail(respctx_t *rctx);
933
934
static isc_result_t
935
rctx_timedout(respctx_t *rctx);
936
937
static void
938
rctx_ncache(respctx_t *rctx);
939
940
/*%
941
 * Increment resolver-related statistics counters.
942
 */
943
static void
944
0
inc_stats(dns_resolver_t *res, isc_statscounter_t counter) {
945
0
  if (res->stats != NULL) {
946
0
    isc_stats_increment(res->stats, counter);
947
0
  }
948
0
}
949
950
static void
951
0
dec_stats(dns_resolver_t *res, isc_statscounter_t counter) {
952
0
  if (res->stats != NULL) {
953
0
    isc_stats_decrement(res->stats, counter);
954
0
  }
955
0
}
956
957
static void
958
0
set_stats(dns_resolver_t *res, isc_statscounter_t counter, uint64_t val) {
959
0
  if (res->stats != NULL) {
960
0
    isc_stats_set(res->stats, val, counter);
961
0
  }
962
0
}
963
964
static void
965
valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo,
966
    dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset,
967
0
    dns_rdataset_t *sigrdataset) {
968
0
  dns_validator_t *validator = NULL;
969
0
  dns_valarg_t *valarg = NULL;
970
0
  unsigned int valoptions = 0;
971
0
  isc_result_t result;
972
973
0
  valarg = isc_mem_get(fctx->mctx, sizeof(*valarg));
974
0
  *valarg = (dns_valarg_t){
975
0
    .addrinfo = addrinfo,
976
0
  };
977
978
0
  fetchctx_attach(fctx, &valarg->fctx);
979
980
  /* Set up validator options */
981
0
  if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) {
982
0
    valoptions |= DNS_VALIDATOR_NOCDFLAG;
983
0
  }
984
985
0
  if ((fctx->options & DNS_FETCHOPT_NONTA) != 0) {
986
0
    valoptions |= DNS_VALIDATOR_NONTA;
987
0
  }
988
989
0
  if (!ISC_LIST_EMPTY(fctx->validators)) {
990
0
    valoptions |= DNS_VALIDATOR_DEFER;
991
0
  }
992
993
0
  result = dns_validator_create(
994
0
    fctx->res->view, name, type, rdataset, sigrdataset, message,
995
0
    valoptions, fctx->loop, validated, valarg, fctx->nvalidations,
996
0
    fctx->nfails, fctx->qc, fctx->gqc, &fctx->edectx, &validator);
997
0
  RUNTIME_CHECK(result == ISC_R_SUCCESS);
998
0
  inc_stats(fctx->res, dns_resstatscounter_val);
999
0
  ISC_LIST_APPEND(fctx->validators, validator, link);
1000
0
}
1001
1002
static void
1003
0
resquery_destroy(resquery_t *query) {
1004
0
  fetchctx_t *fctx = query->fctx;
1005
1006
0
  query->magic = 0;
1007
1008
0
  if (ISC_LINK_LINKED(query, link)) {
1009
0
    ISC_LIST_UNLINK(fctx->queries, query, link);
1010
0
  }
1011
1012
0
  if (query->tsig != NULL) {
1013
0
    isc_buffer_free(&query->tsig);
1014
0
  }
1015
1016
0
  if (query->tsigkey != NULL) {
1017
0
    dns_tsigkey_detach(&query->tsigkey);
1018
0
  }
1019
1020
0
  if (query->dispentry != NULL) {
1021
0
    dns_dispatch_done(&query->dispentry);
1022
0
  }
1023
1024
0
  if (query->dispatch != NULL) {
1025
0
    dns_dispatch_detach(&query->dispatch);
1026
0
  }
1027
1028
0
  LOCK(&fctx->lock);
1029
0
  atomic_fetch_sub_release(&fctx->nqueries, 1);
1030
0
  UNLOCK(&fctx->lock);
1031
1032
0
  if (query->rmessage != NULL) {
1033
0
    dns_message_detach(&query->rmessage);
1034
0
  }
1035
1036
0
  isc_mem_put(fctx->mctx, query, sizeof(*query));
1037
1038
0
  fetchctx_detach(&fctx);
1039
0
}
1040
1041
#if DNS_RESOLVER_TRACE
1042
ISC_REFCOUNT_TRACE_IMPL(resquery, resquery_destroy);
1043
#else
1044
ISC_REFCOUNT_IMPL(resquery, resquery_destroy);
1045
#endif
1046
1047
/*%
1048
 * Update EDNS statistics for a server after not getting a response to a UDP
1049
 * query sent to it.
1050
 */
1051
static void
1052
0
update_edns_stats(resquery_t *query) {
1053
0
  fetchctx_t *fctx = query->fctx;
1054
1055
0
  if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1056
0
    return;
1057
0
  }
1058
1059
0
  if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1060
0
    dns_adb_ednsto(fctx->adb, query->addrinfo);
1061
0
  } else {
1062
0
    dns_adb_timeout(fctx->adb, query->addrinfo);
1063
0
  }
1064
0
}
1065
1066
static void
1067
fctx_expired(void *arg);
1068
1069
/*
1070
 * Start the maximum lifetime timer for the fetch. This will
1071
 * trigger if, for example, some ADB or validator dependency
1072
 * loop occurs and causes a fetch to hang.
1073
 */
1074
static void
1075
0
fctx_starttimer(fetchctx_t *fctx) {
1076
0
  isc_interval_t interval;
1077
0
  isc_time_t now;
1078
0
  isc_time_t expires;
1079
1080
0
  isc_interval_set(&interval, 2, 0);
1081
0
  isc_time_add(&fctx->expires, &interval, &expires);
1082
1083
0
  now = isc_time_now();
1084
0
  if (isc_time_compare(&expires, &now) <= 0) {
1085
0
    isc_interval_set(&interval, 0, 1);
1086
0
  } else {
1087
0
    isc_time_subtract(&expires, &now, &interval);
1088
0
  }
1089
1090
0
  isc_timer_start(fctx->timer, isc_timertype_once, &interval);
1091
0
}
1092
1093
static void
1094
0
fctx_stoptimer(fetchctx_t *fctx) {
1095
0
  isc_timer_stop(fctx->timer);
1096
0
}
1097
1098
static void
1099
fctx_cancelquery(resquery_t **queryp, isc_time_t *finish, bool no_response,
1100
0
     bool age_untried) {
1101
0
  resquery_t *query = NULL;
1102
0
  fetchctx_t *fctx = NULL;
1103
0
  isc_stdtime_t now = isc_stdtime_now();
1104
1105
0
  REQUIRE(queryp != NULL);
1106
1107
0
  query = *queryp;
1108
0
  fctx = query->fctx;
1109
1110
0
  if (RESQUERY_CANCELED(query)) {
1111
0
    return;
1112
0
  }
1113
1114
0
  FCTXTRACE("cancelquery");
1115
1116
0
  query->attributes |= RESQUERY_ATTR_CANCELED;
1117
1118
  /*
1119
   * Should we update the RTT?
1120
   */
1121
0
  if (finish != NULL || no_response) {
1122
0
    unsigned int rtt, factor;
1123
0
    if (finish != NULL) {
1124
      /*
1125
       * We have both the start and finish times for this
1126
       * packet, so we can compute a real RTT.
1127
       */
1128
0
      unsigned int rttms;
1129
1130
0
      rtt = (unsigned int)isc_time_microdiff(finish,
1131
0
                     &query->start);
1132
0
      rttms = rtt / US_PER_MS;
1133
0
      factor = DNS_ADB_RTTADJDEFAULT;
1134
1135
0
      if (rttms < DNS_RESOLVER_QRYRTTCLASS0) {
1136
0
        inc_stats(fctx->res,
1137
0
            dns_resstatscounter_queryrtt0);
1138
0
      } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) {
1139
0
        inc_stats(fctx->res,
1140
0
            dns_resstatscounter_queryrtt1);
1141
0
      } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) {
1142
0
        inc_stats(fctx->res,
1143
0
            dns_resstatscounter_queryrtt2);
1144
0
      } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) {
1145
0
        inc_stats(fctx->res,
1146
0
            dns_resstatscounter_queryrtt3);
1147
0
      } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) {
1148
0
        inc_stats(fctx->res,
1149
0
            dns_resstatscounter_queryrtt4);
1150
0
      } else {
1151
0
        inc_stats(fctx->res,
1152
0
            dns_resstatscounter_queryrtt5);
1153
0
      }
1154
0
    } else {
1155
0
      uint32_t value;
1156
0
      uint32_t mask;
1157
1158
0
      update_edns_stats(query);
1159
1160
      /*
1161
       * If "forward first;" is used and a forwarder timed
1162
       * out, do not attempt to query it again in this fetch
1163
       * context.
1164
       */
1165
0
      if (fctx->fwdpolicy == dns_fwdpolicy_first &&
1166
0
          ISFORWARDER(query->addrinfo))
1167
0
      {
1168
0
        add_bad(fctx, query->rmessage, query->addrinfo,
1169
0
          ISC_R_TIMEDOUT, badns_forwarder);
1170
0
      }
1171
1172
      /*
1173
       * We don't have an RTT for this query.  Maybe the
1174
       * packet was lost, or maybe this server is very
1175
       * slow.  We don't know.  Increase the RTT.
1176
       */
1177
0
      INSIST(no_response);
1178
0
      value = isc_random32();
1179
0
      if (query->addrinfo->srtt > 800000) {
1180
0
        mask = 0x3fff;
1181
0
      } else if (query->addrinfo->srtt > 400000) {
1182
0
        mask = 0x7fff;
1183
0
      } else if (query->addrinfo->srtt > 200000) {
1184
0
        mask = 0xffff;
1185
0
      } else if (query->addrinfo->srtt > 100000) {
1186
0
        mask = 0x1ffff;
1187
0
      } else if (query->addrinfo->srtt > 50000) {
1188
0
        mask = 0x3ffff;
1189
0
      } else if (query->addrinfo->srtt > 25000) {
1190
0
        mask = 0x7ffff;
1191
0
      } else {
1192
0
        mask = 0xfffff;
1193
0
      }
1194
1195
      /*
1196
       * Don't adjust timeout on EDNS queries unless we have
1197
       * seen a EDNS response.
1198
       */
1199
0
      if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
1200
0
          !EDNSOK(query->addrinfo))
1201
0
      {
1202
0
        mask >>= 2;
1203
0
      }
1204
1205
0
      rtt = query->addrinfo->srtt + (value & mask);
1206
0
      if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US) {
1207
0
        rtt = MAX_SINGLE_QUERY_TIMEOUT_US;
1208
0
      }
1209
0
      if (rtt > fctx->res->query_timeout * US_PER_MS) {
1210
0
        rtt = fctx->res->query_timeout * US_PER_MS;
1211
0
      }
1212
1213
      /*
1214
       * Replace the current RTT with our value.
1215
       */
1216
0
      factor = DNS_ADB_RTTADJREPLACE;
1217
0
    }
1218
1219
0
    dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
1220
0
  }
1221
1222
0
  if ((query->options & DNS_FETCHOPT_TCP) == 0) {
1223
    /* Inform the ADB that we're ending a UDP fetch */
1224
0
    dns_adb_endudpfetch(fctx->adb, query->addrinfo);
1225
0
  }
1226
1227
  /*
1228
   * Age RTTs of servers not tried.
1229
   */
1230
0
  if (finish != NULL || age_untried) {
1231
0
    ISC_LIST_FOREACH(fctx->forwaddrs, addrinfo, publink) {
1232
0
      if (UNMARKED(addrinfo)) {
1233
0
        dns_adb_agesrtt(fctx->adb, addrinfo, now);
1234
0
      }
1235
0
    }
1236
0
  }
1237
1238
0
  if ((finish != NULL || age_untried) && TRIEDFIND(fctx)) {
1239
0
    ISC_LIST_FOREACH(fctx->finds, find, publink) {
1240
0
      ISC_LIST_FOREACH(find->list, addrinfo, publink) {
1241
0
        if (UNMARKED(addrinfo)) {
1242
0
          dns_adb_agesrtt(fctx->adb, addrinfo,
1243
0
              now);
1244
0
        }
1245
0
      }
1246
0
    }
1247
0
  }
1248
1249
0
  if ((finish != NULL || age_untried) && TRIEDALT(fctx)) {
1250
0
    ISC_LIST_FOREACH(fctx->altaddrs, addrinfo, publink) {
1251
0
      if (UNMARKED(addrinfo)) {
1252
0
        dns_adb_agesrtt(fctx->adb, addrinfo, now);
1253
0
      }
1254
0
    }
1255
0
    ISC_LIST_FOREACH(fctx->altfinds, find, publink) {
1256
0
      ISC_LIST_FOREACH(find->list, addrinfo, publink) {
1257
0
        if (UNMARKED(addrinfo)) {
1258
0
          dns_adb_agesrtt(fctx->adb, addrinfo,
1259
0
              now);
1260
0
        }
1261
0
      }
1262
0
    }
1263
0
  }
1264
1265
  /*
1266
   * Check for any outstanding dispatch responses and if they
1267
   * exist, cancel them.
1268
   */
1269
0
  if (query->dispentry != NULL) {
1270
0
    dns_dispatch_done(&query->dispentry);
1271
0
  }
1272
1273
0
  LOCK(&fctx->lock);
1274
0
  if (ISC_LINK_LINKED(query, link)) {
1275
0
    ISC_LIST_UNLINK(fctx->queries, query, link);
1276
0
  }
1277
0
  UNLOCK(&fctx->lock);
1278
1279
0
  resquery_detach(queryp);
1280
0
}
1281
1282
static void
1283
0
fctx_cleanup(fetchctx_t *fctx) {
1284
0
  REQUIRE(ISC_LIST_EMPTY(fctx->queries));
1285
1286
0
  ISC_LIST_FOREACH(fctx->finds, find, publink) {
1287
0
    ISC_LIST_UNLINK(fctx->finds, find, publink);
1288
0
    dns_adb_destroyfind(&find);
1289
0
    fetchctx_unref(fctx);
1290
0
  }
1291
0
  fctx->find = NULL;
1292
1293
0
  ISC_LIST_FOREACH(fctx->altfinds, find, publink) {
1294
0
    ISC_LIST_UNLINK(fctx->altfinds, find, publink);
1295
0
    dns_adb_destroyfind(&find);
1296
0
    fetchctx_unref(fctx);
1297
0
  }
1298
0
  fctx->altfind = NULL;
1299
1300
0
  ISC_LIST_FOREACH(fctx->forwaddrs, addr, publink) {
1301
0
    ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
1302
0
    dns_adb_freeaddrinfo(fctx->adb, &addr);
1303
0
  }
1304
1305
0
  ISC_LIST_FOREACH(fctx->altaddrs, addr, publink) {
1306
0
    ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);
1307
0
    dns_adb_freeaddrinfo(fctx->adb, &addr);
1308
0
  }
1309
0
}
1310
1311
static void
1312
0
fctx_cancelqueries(fetchctx_t *fctx, bool no_response, bool age_untried) {
1313
0
  ISC_LIST(resquery_t) queries;
1314
1315
0
  FCTXTRACE("cancelqueries");
1316
1317
0
  ISC_LIST_INIT(queries);
1318
1319
  /*
1320
   * Move the queries to a local list so we can cancel
1321
   * them without holding the lock.
1322
   */
1323
0
  LOCK(&fctx->lock);
1324
0
  ISC_LIST_MOVE(queries, fctx->queries);
1325
0
  UNLOCK(&fctx->lock);
1326
1327
0
  ISC_LIST_FOREACH(queries, query, link) {
1328
    /*
1329
     * Note that we have to unlink the query here,
1330
     * because if it's still linked in fctx_cancelquery(),
1331
     * then it will try to unlink it from fctx->queries.
1332
     */
1333
0
    ISC_LIST_UNLINK(queries, query, link);
1334
0
    fctx_cancelquery(&query, NULL, no_response, age_untried);
1335
0
  }
1336
0
}
1337
1338
static void
1339
0
fcount_logspill(fetchctx_t *fctx, fctxcount_t *counter, bool final) {
1340
0
  char dbuf[DNS_NAME_FORMATSIZE];
1341
0
  isc_stdtime_t now;
1342
1343
0
  if (!isc_log_wouldlog(ISC_LOG_INFO)) {
1344
0
    return;
1345
0
  }
1346
1347
  /* Do not log a message if there were no dropped fetches. */
1348
0
  if (counter->dropped == 0) {
1349
0
    return;
1350
0
  }
1351
1352
  /* Do not log the cumulative message if the previous log is recent. */
1353
0
  now = isc_stdtime_now();
1354
0
  if (!final && counter->logged > now - 60) {
1355
0
    return;
1356
0
  }
1357
1358
0
  dns_name_format(fctx->domain, dbuf, sizeof(dbuf));
1359
1360
0
  if (!final) {
1361
0
    isc_log_write(DNS_LOGCATEGORY_SPILL, DNS_LOGMODULE_RESOLVER,
1362
0
            ISC_LOG_INFO,
1363
0
            "too many simultaneous fetches for %s "
1364
0
            "(allowed %" PRIuFAST32 " spilled %" PRIuFAST32
1365
0
            "; %s)",
1366
0
            dbuf, counter->allowed, counter->dropped,
1367
0
            counter->dropped == 1 ? "initial trigger event"
1368
0
                : "cumulative since "
1369
0
                  "initial trigger event");
1370
0
  } else {
1371
0
    isc_log_write(DNS_LOGCATEGORY_SPILL, DNS_LOGMODULE_RESOLVER,
1372
0
            ISC_LOG_INFO,
1373
0
            "fetch counters for %s now being discarded "
1374
0
            "(allowed %" PRIuFAST32 " spilled %" PRIuFAST32
1375
0
            "; cumulative since initial trigger event)",
1376
0
            dbuf, counter->allowed, counter->dropped);
1377
0
  }
1378
1379
0
  counter->logged = now;
1380
0
}
1381
1382
static bool
1383
0
fcount_match(void *node, const void *key) {
1384
0
  const fctxcount_t *counter = node;
1385
0
  const dns_name_t *domain = key;
1386
1387
0
  return dns_name_equal(counter->domain, domain);
1388
0
}
1389
1390
static isc_result_t
1391
0
fcount_incr(fetchctx_t *fctx, bool force) {
1392
0
  isc_result_t result = ISC_R_SUCCESS;
1393
0
  dns_resolver_t *res = NULL;
1394
0
  fctxcount_t *counter = NULL;
1395
0
  uint32_t hashval;
1396
0
  uint_fast32_t spill;
1397
0
  isc_rwlocktype_t locktype = isc_rwlocktype_read;
1398
1399
0
  REQUIRE(fctx != NULL);
1400
0
  res = fctx->res;
1401
0
  REQUIRE(res != NULL);
1402
0
  INSIST(fctx->counter == NULL);
1403
1404
  /* Skip any counting if fetches-per-zone is disabled */
1405
0
  spill = atomic_load_acquire(&res->zspill);
1406
0
  if (spill == 0) {
1407
0
    return ISC_R_SUCCESS;
1408
0
  }
1409
1410
0
  hashval = dns_name_hash(fctx->domain);
1411
1412
0
  RWLOCK(&res->counters_lock, locktype);
1413
0
  result = isc_hashmap_find(res->counters, hashval, fcount_match,
1414
0
          fctx->domain, (void **)&counter);
1415
0
  switch (result) {
1416
0
  case ISC_R_SUCCESS:
1417
0
    break;
1418
0
  case ISC_R_NOTFOUND:
1419
0
    counter = isc_mem_get(fctx->mctx, sizeof(*counter));
1420
0
    *counter = (fctxcount_t){
1421
0
      .magic = FCTXCOUNT_MAGIC,
1422
0
    };
1423
0
    isc_mem_attach(fctx->mctx, &counter->mctx);
1424
0
    isc_mutex_init(&counter->lock);
1425
0
    counter->domain = dns_fixedname_initname(&counter->dfname);
1426
0
    dns_name_copy(fctx->domain, counter->domain);
1427
1428
0
    UPGRADELOCK(&res->counters_lock, locktype);
1429
1430
0
    void *found = NULL;
1431
0
    result = isc_hashmap_add(res->counters, hashval, fcount_match,
1432
0
           counter->domain, counter, &found);
1433
0
    if (result == ISC_R_EXISTS) {
1434
0
      isc_mutex_destroy(&counter->lock);
1435
0
      isc_mem_putanddetach(&counter->mctx, counter,
1436
0
               sizeof(*counter));
1437
0
      counter = found;
1438
0
      result = ISC_R_SUCCESS;
1439
0
    }
1440
1441
0
    INSIST(result == ISC_R_SUCCESS);
1442
0
    break;
1443
0
  default:
1444
0
    UNREACHABLE();
1445
0
  }
1446
0
  INSIST(VALID_FCTXCOUNT(counter));
1447
1448
0
  INSIST(spill > 0);
1449
0
  LOCK(&counter->lock);
1450
0
  if (++counter->count > spill && !force) {
1451
0
    counter->count--;
1452
0
    INSIST(counter->count > 0);
1453
0
    counter->dropped++;
1454
0
    fcount_logspill(fctx, counter, false);
1455
0
    result = ISC_R_QUOTA;
1456
0
  } else {
1457
0
    counter->allowed++;
1458
0
    fctx->counter = counter;
1459
0
  }
1460
0
  UNLOCK(&counter->lock);
1461
0
  RWUNLOCK(&res->counters_lock, locktype);
1462
1463
0
  return result;
1464
0
}
1465
1466
static bool
1467
0
match_ptr(void *node, const void *key) {
1468
0
  return node == key;
1469
0
}
1470
1471
static void
1472
0
fcount_decr(fetchctx_t *fctx) {
1473
0
  REQUIRE(fctx != NULL);
1474
1475
0
  fctxcount_t *counter = fctx->counter;
1476
0
  if (counter == NULL) {
1477
0
    return;
1478
0
  }
1479
0
  fctx->counter = NULL;
1480
1481
  /*
1482
   * FIXME: This should not require a write lock, but should be
1483
   * implemented using reference counting later, otherwise we would could
1484
   * encounter ABA problem here - the count could go up and down when we
1485
   * switch from read to write lock.
1486
   */
1487
0
  RWLOCK(&fctx->res->counters_lock, isc_rwlocktype_write);
1488
1489
0
  LOCK(&counter->lock);
1490
0
  INSIST(VALID_FCTXCOUNT(counter));
1491
0
  INSIST(counter->count > 0);
1492
0
  if (--counter->count > 0) {
1493
0
    UNLOCK(&counter->lock);
1494
0
    RWUNLOCK(&fctx->res->counters_lock, isc_rwlocktype_write);
1495
0
    return;
1496
0
  }
1497
1498
0
  isc_result_t result = isc_hashmap_delete(fctx->res->counters,
1499
0
             dns_name_hash(counter->domain),
1500
0
             match_ptr, counter);
1501
0
  INSIST(result == ISC_R_SUCCESS);
1502
1503
0
  fcount_logspill(fctx, counter, true);
1504
0
  UNLOCK(&counter->lock);
1505
1506
0
  isc_mutex_destroy(&counter->lock);
1507
0
  isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter));
1508
1509
0
  RWUNLOCK(&fctx->res->counters_lock, isc_rwlocktype_write);
1510
0
}
1511
1512
static void
1513
spillattimer_countdown(void *arg);
1514
1515
static void
1516
0
fctx_sendevents(fetchctx_t *fctx, isc_result_t result) {
1517
0
  unsigned int count = 0;
1518
0
  bool logit = false;
1519
0
  isc_time_t now;
1520
0
  unsigned int old_spillat;
1521
0
  unsigned int new_spillat = 0; /* initialized to silence
1522
               * compiler warnings */
1523
1524
0
  LOCK(&fctx->lock);
1525
1526
0
  REQUIRE(fctx->state == fetchstate_done);
1527
1528
0
  FCTXTRACE("sendevents");
1529
1530
  /*
1531
   * Keep some record of fetch result for logging later (if required).
1532
   */
1533
0
  fctx->result = result;
1534
0
  now = isc_time_now();
1535
0
  fctx->duration = isc_time_microdiff(&now, &fctx->start);
1536
1537
0
  ISC_LIST_FOREACH(fctx->resps, resp, link) {
1538
0
    ISC_LIST_UNLINK(fctx->resps, resp, link);
1539
1540
0
    count++;
1541
1542
0
    resp->vresult = fctx->vresult;
1543
0
    if (!HAVE_ANSWER(fctx)) {
1544
0
      resp->result = result;
1545
0
    }
1546
1547
0
    INSIST(resp->result != ISC_R_SUCCESS ||
1548
0
           dns_rdataset_isassociated(resp->rdataset) ||
1549
0
           dns_rdatatype_ismulti(fctx->type));
1550
1551
    /*
1552
     * Negative results must be indicated in resp->result.
1553
     */
1554
0
    if (dns_rdataset_isassociated(resp->rdataset) &&
1555
0
        NEGATIVE(resp->rdataset))
1556
0
    {
1557
0
      INSIST(resp->result == DNS_R_NCACHENXDOMAIN ||
1558
0
             resp->result == DNS_R_NCACHENXRRSET);
1559
0
    }
1560
1561
    /*
1562
     * Finalize the EDE context so it becomes "constant", and
1563
     * assign it to all clients.
1564
     */
1565
0
    if (resp->edectx != NULL) {
1566
0
      dns_ede_copy(resp->edectx, &fctx->edectx);
1567
0
    }
1568
1569
0
    FCTXTRACE("post response event");
1570
0
    isc_async_run(resp->loop, resp->cb, resp);
1571
0
  }
1572
0
  UNLOCK(&fctx->lock);
1573
1574
0
  if (HAVE_ANSWER(fctx) && fctx->spilled &&
1575
0
      (count < fctx->res->spillatmax || fctx->res->spillatmax == 0))
1576
0
  {
1577
0
    LOCK(&fctx->res->lock);
1578
0
    if (count == fctx->res->spillat &&
1579
0
        !atomic_load_acquire(&fctx->res->exiting))
1580
0
    {
1581
0
      old_spillat = fctx->res->spillat;
1582
0
      fctx->res->spillat += 5;
1583
0
      if (fctx->res->spillat > fctx->res->spillatmax &&
1584
0
          fctx->res->spillatmax != 0)
1585
0
      {
1586
0
        fctx->res->spillat = fctx->res->spillatmax;
1587
0
      }
1588
0
      new_spillat = fctx->res->spillat;
1589
0
      if (new_spillat != old_spillat) {
1590
0
        logit = true;
1591
0
      }
1592
1593
      /* Timer not running */
1594
0
      if (fctx->res->spillattimer == NULL) {
1595
0
        isc_interval_t i;
1596
1597
0
        isc_timer_create(
1598
0
          isc_loop(), spillattimer_countdown,
1599
0
          fctx->res, &fctx->res->spillattimer);
1600
1601
0
        isc_interval_set(&i, 20 * 60, 0);
1602
0
        isc_timer_start(fctx->res->spillattimer,
1603
0
            isc_timertype_ticker, &i);
1604
0
      }
1605
0
    }
1606
0
    UNLOCK(&fctx->res->lock);
1607
0
    if (logit) {
1608
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
1609
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
1610
0
              "clients-per-query increased to %u",
1611
0
              new_spillat);
1612
0
    }
1613
0
  }
1614
0
}
1615
1616
static uint32_t
1617
0
fctx_hash(fetchctx_t *fctx) {
1618
0
  isc_hash32_t hash32;
1619
0
  isc_hash32_init(&hash32);
1620
0
  isc_hash32_hash(&hash32, fctx->name->ndata, fctx->name->length, false);
1621
0
  isc_hash32_hash(&hash32, &fctx->options, sizeof(fctx->options), true);
1622
0
  isc_hash32_hash(&hash32, &fctx->type, sizeof(fctx->type), true);
1623
0
  return isc_hash32_finalize(&hash32);
1624
0
}
1625
1626
static bool
1627
0
fctx_match(void *node, const void *key) {
1628
0
  const fetchctx_t *fctx0 = node;
1629
0
  const fetchctx_t *fctx1 = key;
1630
1631
0
  return fctx0->options == fctx1->options && fctx0->type == fctx1->type &&
1632
0
         dns_name_equal(fctx0->name, fctx1->name);
1633
0
}
1634
1635
static bool
1636
fctx__done(fetchctx_t *fctx, isc_result_t result, const char *func,
1637
0
     const char *file, unsigned int line) {
1638
0
  bool no_response = false;
1639
0
  bool age_untried = false;
1640
1641
0
  REQUIRE(fctx != NULL);
1642
0
  REQUIRE(fctx->tid == isc_tid());
1643
1644
0
  FCTXTRACE("done");
1645
1646
#ifdef DNS_RESOLVER_TRACE
1647
  fprintf(stderr, "%s:%s:%s:%u:(%p): %s\n", __func__, func, file, line,
1648
    fctx, isc_result_totext(result));
1649
#else
1650
0
  UNUSED(file);
1651
0
  UNUSED(line);
1652
0
  UNUSED(func);
1653
0
#endif
1654
1655
0
  LOCK(&fctx->lock);
1656
  /* We need to do this under the lock for intra-thread synchronization */
1657
0
  if (fctx->state == fetchstate_done) {
1658
0
    UNLOCK(&fctx->lock);
1659
0
    return false;
1660
0
  }
1661
0
  fctx->state = fetchstate_done;
1662
0
  FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
1663
0
  UNLOCK(&fctx->lock);
1664
1665
  /* The fctx will get deleted either here or in get_attached_fctx() */
1666
0
  RWLOCK(&fctx->res->fctxs_lock, isc_rwlocktype_write);
1667
0
  (void)isc_hashmap_delete(fctx->res->fctxs, fctx_hash(fctx), match_ptr,
1668
0
         fctx);
1669
0
  RWUNLOCK(&fctx->res->fctxs_lock, isc_rwlocktype_write);
1670
1671
0
  if (result == ISC_R_SUCCESS) {
1672
0
    if (fctx->qmin_warning != ISC_R_SUCCESS) {
1673
0
      isc_log_write(DNS_LOGCATEGORY_LAME_SERVERS,
1674
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
1675
0
              "success resolving '%s' after disabling "
1676
0
              "qname minimization due to '%s'",
1677
0
              fctx->info,
1678
0
              isc_result_totext(fctx->qmin_warning));
1679
0
    }
1680
1681
    /*
1682
     * A success result indicates we got a response to a
1683
     * query. That query should be canceled already. If
1684
     * there still are any outstanding queries attached to the
1685
     * same fctx, then those have *not* gotten a response,
1686
     * so we set 'no_response' to true here: that way, when
1687
     * we run fctx_cancelqueries() below, the SRTTs will
1688
     * be adjusted.
1689
     */
1690
0
    no_response = true;
1691
0
  } else if (result == ISC_R_TIMEDOUT) {
1692
0
    age_untried = true;
1693
0
  }
1694
1695
0
  fctx->qmin_warning = ISC_R_SUCCESS;
1696
1697
0
  fctx_cancelqueries(fctx, no_response, age_untried);
1698
0
  fctx_stoptimer(fctx);
1699
1700
  /*
1701
   * Cancel all pending validators.  Note that this must be done
1702
   * without the fctx lock held, since that could cause
1703
   * deadlock.
1704
   */
1705
0
  maybe_cancel_validators(fctx);
1706
1707
0
  if (fctx->nsfetch != NULL) {
1708
0
    dns_resolver_cancelfetch(fctx->nsfetch);
1709
0
  }
1710
1711
0
  if (fctx->qminfetch != NULL) {
1712
0
    dns_resolver_cancelfetch(fctx->qminfetch);
1713
0
  }
1714
1715
  /*
1716
   * Shut down anything still running on behalf of this
1717
   * fetch, and clean up finds and addresses.
1718
   */
1719
0
  fctx_sendevents(fctx, result);
1720
0
  fctx_cleanup(fctx);
1721
1722
0
  isc_timer_destroy(&fctx->timer);
1723
1724
0
  return true;
1725
0
}
1726
1727
static void
1728
0
resquery_senddone(isc_result_t eresult, isc_region_t *region, void *arg) {
1729
0
  resquery_t *query = (resquery_t *)arg;
1730
0
  resquery_t *copy = query;
1731
0
  fetchctx_t *fctx = NULL;
1732
1733
0
  QTRACE("senddone");
1734
1735
0
  UNUSED(region);
1736
1737
0
  REQUIRE(VALID_QUERY(query));
1738
0
  fctx = query->fctx;
1739
0
  REQUIRE(VALID_FCTX(fctx));
1740
0
  REQUIRE(fctx->tid == isc_tid());
1741
1742
0
  if (RESQUERY_CANCELED(query)) {
1743
0
    goto detach;
1744
0
  }
1745
1746
  /*
1747
   * See the note in resquery_connected() about reference
1748
   * counting on error conditions.
1749
   */
1750
0
  switch (eresult) {
1751
0
  case ISC_R_SUCCESS:
1752
0
  case ISC_R_CANCELED:
1753
0
  case ISC_R_SHUTTINGDOWN:
1754
0
    break;
1755
1756
0
  case ISC_R_HOSTDOWN:
1757
0
  case ISC_R_HOSTUNREACH:
1758
0
  case ISC_R_NETDOWN:
1759
0
  case ISC_R_NETUNREACH:
1760
0
  case ISC_R_NOPERM:
1761
0
  case ISC_R_ADDRNOTAVAIL:
1762
0
  case ISC_R_CONNREFUSED:
1763
0
  case ISC_R_CONNECTIONRESET:
1764
0
  case ISC_R_TIMEDOUT:
1765
    /* No route to remote. */
1766
0
    FCTXTRACE3("query canceled in resquery_senddone(): "
1767
0
         "no route to host; no response",
1768
0
         eresult);
1769
0
    add_bad(fctx, query->rmessage, query->addrinfo, eresult,
1770
0
      badns_unreachable);
1771
0
    fctx_cancelquery(&copy, NULL, true, false);
1772
0
    FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
1773
0
    fctx_try(fctx, true);
1774
0
    break;
1775
1776
0
  default:
1777
0
    FCTXTRACE3("query canceled in resquery_senddone() "
1778
0
         "due to unexpected result; responding",
1779
0
         eresult);
1780
0
    fctx_cancelquery(&copy, NULL, false, false);
1781
0
    fctx_done_detach(&fctx, eresult);
1782
0
    break;
1783
0
  }
1784
1785
0
detach:
1786
0
  resquery_detach(&query);
1787
0
}
1788
1789
static isc_result_t
1790
fctx_addopt(dns_message_t *message, unsigned int version, uint16_t udpsize,
1791
0
      dns_ednsopt_t *ednsopts, size_t count) {
1792
0
  dns_rdataset_t *rdataset = NULL;
1793
0
  isc_result_t result;
1794
1795
0
  result = dns_message_buildopt(message, &rdataset, version, udpsize,
1796
0
              DNS_MESSAGEEXTFLAG_DO, ednsopts, count);
1797
0
  if (result != ISC_R_SUCCESS) {
1798
0
    return result;
1799
0
  }
1800
0
  return dns_message_setopt(message, rdataset);
1801
0
}
1802
1803
static void
1804
0
fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
1805
0
  unsigned int seconds, us;
1806
0
  uint64_t limit;
1807
0
  isc_time_t now;
1808
1809
  /*
1810
   * Has this fetch already expired?
1811
   */
1812
0
  now = isc_time_now();
1813
0
  limit = isc_time_microdiff(&fctx->expires, &now);
1814
0
  if (limit < US_PER_MS) {
1815
0
    FCTXTRACE("fetch already expired");
1816
0
    isc_interval_set(&fctx->interval, 0, 0);
1817
0
    return;
1818
0
  }
1819
1820
0
  us = fctx->res->retryinterval * US_PER_MS;
1821
1822
  /*
1823
   * Exponential backoff after the first few tries.
1824
   */
1825
0
  if (fctx->restarts > fctx->res->nonbackofftries) {
1826
0
    int shift = fctx->restarts - fctx->res->nonbackofftries;
1827
0
    if (shift > 6) {
1828
0
      shift = 6;
1829
0
    }
1830
0
    us <<= shift;
1831
0
  }
1832
1833
  /*
1834
   * Add a fudge factor to the expected rtt based on the current
1835
   * estimate.
1836
   */
1837
0
  if (rtt < 50000) {
1838
0
    rtt += 50000;
1839
0
  } else if (rtt < 100000) {
1840
0
    rtt += 100000;
1841
0
  } else {
1842
0
    rtt += 200000;
1843
0
  }
1844
1845
  /*
1846
   * Always wait for at least the expected rtt.
1847
   */
1848
0
  if (us < rtt) {
1849
0
    us = rtt;
1850
0
  }
1851
1852
  /*
1853
   * But don't wait past the the final expiration of the fetch,
1854
   * or for more than 10 seconds total.
1855
   */
1856
0
  if (us > limit) {
1857
0
    us = limit;
1858
0
  }
1859
0
  if (us > MAX_SINGLE_QUERY_TIMEOUT_US) {
1860
0
    us = MAX_SINGLE_QUERY_TIMEOUT_US;
1861
0
  }
1862
0
  if (us > fctx->res->query_timeout * US_PER_MS) {
1863
0
    us = fctx->res->query_timeout * US_PER_MS;
1864
0
  }
1865
1866
0
  seconds = us / US_PER_SEC;
1867
0
  us -= seconds * US_PER_SEC;
1868
0
  isc_interval_set(&fctx->interval, seconds, us * NS_PER_US);
1869
0
}
1870
1871
static isc_result_t
1872
fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
1873
0
     unsigned int options) {
1874
0
  isc_result_t result;
1875
0
  dns_resolver_t *res = NULL;
1876
0
  dns_dns64_t *dns64 = NULL;
1877
0
  resquery_t *query = NULL;
1878
0
  isc_sockaddr_t addr, sockaddr;
1879
0
  bool have_addr = false;
1880
0
  unsigned int srtt;
1881
0
  isc_tlsctx_cache_t *tlsctx_cache = NULL;
1882
1883
0
  FCTXTRACE("query");
1884
1885
0
  res = fctx->res;
1886
1887
0
  srtt = addrinfo->srtt;
1888
1889
0
  if (addrinfo->transport != NULL) {
1890
0
    switch (dns_transport_get_type(addrinfo->transport)) {
1891
0
    case DNS_TRANSPORT_TLS:
1892
0
      options |= DNS_FETCHOPT_TCP;
1893
0
      tlsctx_cache = res->tlsctx_cache;
1894
0
      break;
1895
0
    case DNS_TRANSPORT_TCP:
1896
0
    case DNS_TRANSPORT_HTTP:
1897
0
      options |= DNS_FETCHOPT_TCP;
1898
0
      break;
1899
0
    default:
1900
0
      break;
1901
0
    }
1902
0
  }
1903
1904
  /*
1905
   * Maybe apply DNS64 mappings to IPv4 addresses.
1906
   */
1907
0
  sockaddr = addrinfo->sockaddr;
1908
0
  dns64 = ISC_LIST_HEAD(fctx->res->view->dns64);
1909
0
  if (isc_sockaddr_pf(&sockaddr) == AF_INET &&
1910
0
      fctx->res->view->usedns64 && dns64 != NULL)
1911
0
  {
1912
0
    struct in6_addr aaaa;
1913
1914
0
    result = dns_dns64_aaaafroma(
1915
0
      dns64, NULL, NULL, fctx->res->view->aclenv, 0,
1916
0
      (unsigned char *)&sockaddr.type.sin.sin_addr.s_addr,
1917
0
      aaaa.s6_addr);
1918
0
    if (result == ISC_R_SUCCESS) {
1919
0
      char sockaddrbuf1[ISC_SOCKADDR_FORMATSIZE];
1920
0
      char sockaddrbuf2[ISC_SOCKADDR_FORMATSIZE];
1921
1922
      /* format old address */
1923
0
      isc_sockaddr_format(&sockaddr, sockaddrbuf1,
1924
0
              sizeof(sockaddrbuf1));
1925
1926
      /* replace address */
1927
0
      isc_sockaddr_fromin6(&sockaddr, &aaaa,
1928
0
               ntohs(sockaddr.type.sin.sin_port));
1929
0
      addrinfo->sockaddr = sockaddr;
1930
1931
      /* format new address */
1932
0
      isc_sockaddr_format(&sockaddr, sockaddrbuf2,
1933
0
              sizeof(sockaddrbuf2));
1934
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
1935
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
1936
0
              "Using DNS64 address %s to talk to %s\n",
1937
0
              sockaddrbuf2, sockaddrbuf1);
1938
0
    }
1939
0
  }
1940
1941
  /*
1942
   * Check if the address is in the peers list and has a special
1943
   * confguration.
1944
   */
1945
0
  if (res->view->peers != NULL) {
1946
0
    dns_peer_t *peer = NULL;
1947
0
    isc_netaddr_t dstip;
1948
0
    bool usetcp = false;
1949
0
    isc_netaddr_fromsockaddr(&dstip, &sockaddr);
1950
0
    result = dns_peerlist_peerbyaddr(res->view->peers, &dstip,
1951
0
             &peer);
1952
0
    if (result == ISC_R_SUCCESS) {
1953
0
      result = dns_peer_getquerysource(peer, &addr);
1954
0
      if (result == ISC_R_SUCCESS) {
1955
0
        have_addr = true;
1956
0
      }
1957
0
      result = dns_peer_getforcetcp(peer, &usetcp);
1958
0
      if (result == ISC_R_SUCCESS && usetcp) {
1959
0
        options |= DNS_FETCHOPT_TCP;
1960
0
      }
1961
0
    }
1962
0
  }
1963
1964
  /*
1965
   * Allow an additional second for the kernel to resend the SYN
1966
   * (or SYN without ECN in the case of stupid firewalls blocking
1967
   * ECN negotiation) over the current RTT estimate.
1968
   */
1969
0
  if ((options & DNS_FETCHOPT_TCP) != 0) {
1970
0
    srtt += US_PER_SEC;
1971
0
  }
1972
1973
  /*
1974
   * A forwarder needs to make multiple queries. Give it at least
1975
   * a second to do these in.
1976
   */
1977
0
  if (ISFORWARDER(addrinfo) && srtt < US_PER_SEC) {
1978
0
    srtt = US_PER_SEC;
1979
0
  }
1980
1981
0
  fctx_setretryinterval(fctx, srtt);
1982
0
  if (isc_interval_iszero(&fctx->interval)) {
1983
0
    FCTXTRACE("fetch expired");
1984
0
    dns_ede_add(&fctx->edectx, DNS_EDE_NOREACHABLEAUTH, NULL);
1985
0
    return ISC_R_TIMEDOUT;
1986
0
  }
1987
1988
0
  INSIST(ISC_LIST_EMPTY(fctx->validators));
1989
1990
0
  query = isc_mem_get(fctx->mctx, sizeof(*query));
1991
0
  *query = (resquery_t){
1992
0
    .options = options,
1993
0
    .addrinfo = addrinfo,
1994
0
    .dispatchmgr = res->view->dispatchmgr,
1995
0
    .link = ISC_LINK_INITIALIZER,
1996
0
  };
1997
1998
#if DNS_RESOLVER_TRACE
1999
  fprintf(stderr, "rctx_init:%s:%s:%d:%p->references = 1\n", __func__,
2000
    __FILE__, __LINE__, query);
2001
#endif
2002
0
  isc_refcount_init(&query->references, 1);
2003
2004
  /*
2005
   * Note that the caller MUST guarantee that 'addrinfo' will
2006
   * remain valid until this query is canceled.
2007
   */
2008
2009
0
  dns_message_create(fctx->mctx, fctx->res->namepools[fctx->tid],
2010
0
         fctx->res->rdspools[fctx->tid],
2011
0
         DNS_MESSAGE_INTENTPARSE, &query->rmessage);
2012
0
  query->start = isc_time_now();
2013
2014
  /*
2015
   * If this is a TCP query, then we need to make a socket and
2016
   * a dispatch for it here.  Otherwise we use the resolver's
2017
   * shared dispatch.
2018
   */
2019
0
  if ((query->options & DNS_FETCHOPT_TCP) != 0) {
2020
0
    int pf;
2021
2022
0
    pf = isc_sockaddr_pf(&sockaddr);
2023
0
    if (!have_addr) {
2024
0
      switch (pf) {
2025
0
      case PF_INET:
2026
0
        result = dns_dispatch_getlocaladdress(
2027
0
          res->dispatches4->dispatches[0], &addr);
2028
0
        break;
2029
0
      case PF_INET6:
2030
0
        result = dns_dispatch_getlocaladdress(
2031
0
          res->dispatches6->dispatches[0], &addr);
2032
0
        break;
2033
0
      default:
2034
0
        result = ISC_R_NOTIMPLEMENTED;
2035
0
        break;
2036
0
      }
2037
0
      if (result != ISC_R_SUCCESS) {
2038
0
        goto cleanup_query;
2039
0
      }
2040
0
    }
2041
0
    isc_sockaddr_setport(&addr, 0);
2042
2043
0
    result = dns_dispatch_createtcp(res->view->dispatchmgr, &addr,
2044
0
            &sockaddr, addrinfo->transport,
2045
0
            DNS_DISPATCHOPT_UNSHARED,
2046
0
            &query->dispatch);
2047
0
    if (result != ISC_R_SUCCESS) {
2048
0
      goto cleanup_query;
2049
0
    }
2050
2051
0
    FCTXTRACE("connecting via TCP");
2052
0
  } else {
2053
0
    if (have_addr) {
2054
0
      result = dns_dispatch_createudp(res->view->dispatchmgr,
2055
0
              &addr,
2056
0
              &query->dispatch);
2057
0
      if (result != ISC_R_SUCCESS) {
2058
0
        goto cleanup_query;
2059
0
      }
2060
0
    } else {
2061
0
      switch (isc_sockaddr_pf(&sockaddr)) {
2062
0
      case PF_INET:
2063
0
        dns_dispatch_attach(
2064
0
          dns_resolver_dispatchv4(res),
2065
0
          &query->dispatch);
2066
0
        break;
2067
0
      case PF_INET6:
2068
0
        dns_dispatch_attach(
2069
0
          dns_resolver_dispatchv6(res),
2070
0
          &query->dispatch);
2071
0
        break;
2072
0
      default:
2073
0
        result = ISC_R_NOTIMPLEMENTED;
2074
0
        goto cleanup_query;
2075
0
      }
2076
0
    }
2077
2078
    /*
2079
     * We should always have a valid dispatcher here.  If we
2080
     * don't support a protocol family, then its dispatcher
2081
     * will be NULL, but we shouldn't be finding addresses
2082
     * for protocol types we don't support, so the
2083
     * dispatcher we found should never be NULL.
2084
     */
2085
0
    INSIST(query->dispatch != NULL);
2086
0
  }
2087
2088
0
  LOCK(&fctx->lock);
2089
0
  INSIST(!SHUTTINGDOWN(fctx));
2090
0
  fetchctx_attach(fctx, &query->fctx);
2091
0
  query->magic = QUERY_MAGIC;
2092
2093
0
  if ((query->options & DNS_FETCHOPT_TCP) == 0) {
2094
0
    if (dns_adb_overquota(fctx->adb, addrinfo)) {
2095
0
      UNLOCK(&fctx->lock);
2096
0
      result = ISC_R_QUOTA;
2097
0
      goto cleanup_dispatch;
2098
0
    }
2099
2100
    /* Inform the ADB that we're starting a UDP fetch */
2101
0
    dns_adb_beginudpfetch(fctx->adb, addrinfo);
2102
0
  }
2103
2104
0
  ISC_LIST_APPEND(fctx->queries, query, link);
2105
0
  atomic_fetch_add_relaxed(&fctx->nqueries, 1);
2106
0
  UNLOCK(&fctx->lock);
2107
2108
  /* Set up the dispatch and set the query ID */
2109
0
  const unsigned int timeout_ms = isc_interval_ms(&fctx->interval);
2110
0
  result = dns_dispatch_add(query->dispatch, fctx->loop, 0, timeout_ms,
2111
0
          timeout_ms, &sockaddr, addrinfo->transport,
2112
0
          tlsctx_cache, resquery_connected,
2113
0
          resquery_senddone, resquery_response, query,
2114
0
          &query->id, &query->dispentry);
2115
0
  if (result != ISC_R_SUCCESS) {
2116
0
    goto cleanup_udpfetch;
2117
0
  }
2118
2119
  /* Connect the socket */
2120
0
  resquery_ref(query);
2121
0
  result = dns_dispatch_connect(query->dispentry);
2122
2123
0
  if (result != ISC_R_SUCCESS && (query->options & DNS_FETCHOPT_TCP) != 0)
2124
0
  {
2125
0
    int log_level = ISC_LOG_NOTICE;
2126
0
    if (isc_log_wouldlog(log_level)) {
2127
0
      char peerbuf[ISC_SOCKADDR_FORMATSIZE];
2128
2129
0
      isc_sockaddr_format(&sockaddr, peerbuf,
2130
0
              ISC_SOCKADDR_FORMATSIZE);
2131
2132
0
      isc_log_write(
2133
0
        DNS_LOGCATEGORY_RESOLVER,
2134
0
        DNS_LOGMODULE_RESOLVER, log_level,
2135
0
        "Unable to establish a connection to %s: %s\n",
2136
0
        peerbuf, isc_result_totext(result));
2137
0
    }
2138
0
    dns_dispatch_done(&query->dispentry);
2139
0
    goto cleanup_fetch;
2140
0
  } else {
2141
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
2142
0
  }
2143
2144
0
  return result;
2145
2146
0
cleanup_udpfetch:
2147
0
  if (!RESQUERY_CANCELED(query)) {
2148
0
    if ((query->options & DNS_FETCHOPT_TCP) == 0) {
2149
      /* Inform the ADB that we're ending a UDP fetch */
2150
0
      dns_adb_endudpfetch(fctx->adb, addrinfo);
2151
0
    }
2152
0
  }
2153
2154
0
cleanup_fetch:
2155
0
  LOCK(&fctx->lock);
2156
0
  if (ISC_LINK_LINKED(query, link)) {
2157
0
    atomic_fetch_sub_release(&fctx->nqueries, 1);
2158
0
    ISC_LIST_UNLINK(fctx->queries, query, link);
2159
0
  }
2160
0
  UNLOCK(&fctx->lock);
2161
2162
0
cleanup_dispatch:
2163
0
  fetchctx_detach(&query->fctx);
2164
2165
0
  if (query->dispatch != NULL) {
2166
0
    dns_dispatch_detach(&query->dispatch);
2167
0
  }
2168
2169
0
cleanup_query:
2170
0
  query->magic = 0;
2171
0
  dns_message_detach(&query->rmessage);
2172
0
  isc_mem_put(fctx->mctx, query, sizeof(*query));
2173
2174
0
  return result;
2175
0
}
2176
2177
static struct tried *
2178
0
triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
2179
0
  ISC_LIST_FOREACH(fctx->edns, tried, link) {
2180
0
    if (isc_sockaddr_equal(&tried->addr, address)) {
2181
0
      return tried;
2182
0
    }
2183
0
  }
2184
2185
0
  return NULL;
2186
0
}
2187
2188
static void
2189
0
add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
2190
0
  struct tried *tried = triededns(fctx, address);
2191
0
  if (tried != NULL) {
2192
0
    tried->count++;
2193
0
    return;
2194
0
  }
2195
2196
0
  tried = isc_mem_get(fctx->mctx, sizeof(*tried));
2197
0
  tried->addr = *address;
2198
0
  tried->count = 1;
2199
0
  ISC_LIST_INITANDAPPEND(fctx->edns, tried, link);
2200
0
}
2201
2202
static size_t
2203
0
addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) {
2204
0
  isc_netaddr_t netaddr;
2205
0
  isc_netaddr_fromsockaddr(&netaddr, sockaddr);
2206
0
  switch (netaddr.family) {
2207
0
  case AF_INET:
2208
0
    INSIST(bufsize >= 4);
2209
0
    memmove(buf, &netaddr.type.in, 4);
2210
0
    return 4;
2211
0
  case AF_INET6:
2212
0
    INSIST(bufsize >= 16);
2213
0
    memmove(buf, &netaddr.type.in6, 16);
2214
0
    return 16;
2215
0
  default:
2216
0
    UNREACHABLE();
2217
0
  }
2218
0
  return 0;
2219
0
}
2220
2221
static size_t
2222
0
add_serveraddr(uint8_t *buf, const size_t bufsize, const resquery_t *query) {
2223
0
  return addr2buf(buf, bufsize, &query->addrinfo->sockaddr);
2224
0
}
2225
2226
/*
2227
 * Client cookie is 8 octets.
2228
 * Server cookie is [8..32] octets.
2229
 */
2230
0
#define CLIENT_COOKIE_SIZE 8U
2231
#define COOKIE_BUFFER_SIZE (8U + 32U)
2232
2233
static void
2234
0
compute_cc(const resquery_t *query, uint8_t *cookie, const size_t len) {
2235
0
  INSIST(len >= CLIENT_COOKIE_SIZE);
2236
0
  STATIC_ASSERT(sizeof(query->fctx->res->view->secret) >=
2237
0
            ISC_SIPHASH24_KEY_LENGTH,
2238
0
          "The view->secret size can't fit SipHash 2-4 key "
2239
0
          "length");
2240
2241
0
  uint8_t buf[16] ISC_NONSTRING = { 0 };
2242
0
  size_t buflen = add_serveraddr(buf, sizeof(buf), query);
2243
2244
0
  uint8_t digest[ISC_SIPHASH24_TAG_LENGTH] ISC_NONSTRING = { 0 };
2245
0
  isc_siphash24(query->fctx->res->view->secret, buf, buflen, true,
2246
0
          digest);
2247
0
  memmove(cookie, digest, CLIENT_COOKIE_SIZE);
2248
0
}
2249
2250
static bool
2251
issecuredomain(fetchctx_t *fctx, const dns_name_t *name, dns_rdatatype_t type,
2252
0
         isc_stdtime_t now, bool *ntap) {
2253
0
  dns_name_t suffix;
2254
0
  unsigned int labels;
2255
2256
  /*
2257
   * For DS variants we need to check fom the parent domain,
2258
   * since there may be a negative trust anchor for the name,
2259
   * while the enclosing domain where the DS record lives is
2260
   * under a secure entry point.
2261
   */
2262
0
  labels = dns_name_countlabels(name);
2263
0
  if (dns_rdatatype_atparent(type) && labels > 1) {
2264
0
    dns_name_init(&suffix);
2265
0
    dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
2266
0
    name = &suffix;
2267
0
  }
2268
2269
0
  return dns_view_issecuredomain(fctx->res->view, name, now,
2270
0
               CHECKNTA(fctx), ntap);
2271
0
}
2272
2273
static isc_result_t
2274
0
resquery_send(resquery_t *query) {
2275
0
  isc_result_t result;
2276
0
  fetchctx_t *fctx = query->fctx;
2277
0
  dns_resolver_t *res = fctx->res;
2278
0
  isc_buffer_t buffer;
2279
0
  dns_name_t *qname = NULL;
2280
0
  dns_rdataset_t *qrdataset = NULL;
2281
0
  isc_region_t r;
2282
0
  isc_netaddr_t ipaddr;
2283
0
  dns_tsigkey_t *tsigkey = NULL;
2284
0
  dns_peer_t *peer = NULL;
2285
0
  dns_compress_t cctx;
2286
0
  bool useedns;
2287
0
  bool tcp = ((query->options & DNS_FETCHOPT_TCP) != 0);
2288
0
  dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
2289
0
  unsigned int ednsopt = 0;
2290
0
  uint16_t hint = 0, udpsize = 0; /* No EDNS */
2291
0
  isc_sockaddr_t localaddr, *la = NULL;
2292
#ifdef HAVE_DNSTAP
2293
  unsigned char zone[DNS_NAME_MAXWIRE];
2294
  dns_transport_type_t transport_type;
2295
  dns_dtmsgtype_t dtmsgtype;
2296
  isc_region_t zr;
2297
  isc_buffer_t zb;
2298
#endif /* HAVE_DNSTAP */
2299
2300
0
  QTRACE("send");
2301
2302
0
  if (atomic_load_acquire(&res->exiting)) {
2303
0
    FCTXTRACE("resquery_send: resolver shutting down");
2304
0
    return ISC_R_SHUTTINGDOWN;
2305
0
  }
2306
2307
0
  dns_message_gettempname(fctx->qmessage, &qname);
2308
0
  dns_message_gettemprdataset(fctx->qmessage, &qrdataset);
2309
2310
0
  fctx->qmessage->opcode = dns_opcode_query;
2311
2312
  /*
2313
   * Set up question.
2314
   */
2315
0
  dns_name_clone(fctx->name, qname);
2316
0
  dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
2317
0
  ISC_LIST_APPEND(qname->list, qrdataset, link);
2318
0
  dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
2319
2320
  /*
2321
   * Set RD if the client has requested that we do a recursive
2322
   * query, or if we're sending to a forwarder.
2323
   */
2324
0
  if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 ||
2325
0
      ISFORWARDER(query->addrinfo))
2326
0
  {
2327
0
    fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
2328
0
  }
2329
2330
  /*
2331
   * Set CD if the client says not to validate, or if the
2332
   * question is under a secure entry point and this is a
2333
   * recursive/forward query -- unless the client said not to.
2334
   */
2335
0
  if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0) {
2336
    /* Do nothing */
2337
0
  } else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0 ||
2338
0
       (query->options & DNS_FETCHOPT_TRYCD) != 0)
2339
0
  {
2340
0
    fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
2341
0
  } else if (res->view->enablevalidation &&
2342
0
       ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0))
2343
0
  {
2344
0
    query->options |= DNS_FETCHOPT_TRYCD;
2345
0
  }
2346
2347
  /*
2348
   * We don't have to set opcode because it defaults to query.
2349
   */
2350
0
  fctx->qmessage->id = query->id;
2351
2352
  /*
2353
   * Convert the question to wire format.
2354
   */
2355
0
  dns_compress_init(&cctx, fctx->mctx, 0);
2356
2357
0
  isc_buffer_init(&buffer, query->data, sizeof(query->data));
2358
0
  result = dns_message_renderbegin(fctx->qmessage, &cctx, &buffer);
2359
0
  if (result != ISC_R_SUCCESS) {
2360
0
    goto cleanup_message;
2361
0
  }
2362
2363
0
  result = dns_message_rendersection(fctx->qmessage, DNS_SECTION_QUESTION,
2364
0
             0);
2365
0
  if (result != ISC_R_SUCCESS) {
2366
0
    goto cleanup_message;
2367
0
  }
2368
2369
0
  isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr);
2370
0
  (void)dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
2371
2372
  /*
2373
   * The ADB does not know about servers with "edns no".  Check
2374
   * this, and then inform the ADB for future use.
2375
   */
2376
0
  if ((query->addrinfo->flags & FCTX_ADDRINFO_NOEDNS0) == 0 &&
2377
0
      peer != NULL &&
2378
0
      dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS &&
2379
0
      !useedns)
2380
0
  {
2381
0
    query->options |= DNS_FETCHOPT_NOEDNS0;
2382
0
    dns_adb_changeflags(fctx->adb, query->addrinfo,
2383
0
            FCTX_ADDRINFO_NOEDNS0,
2384
0
            FCTX_ADDRINFO_NOEDNS0);
2385
0
  }
2386
2387
  /* Sync NOEDNS0 flag in addrinfo->flags and options now. */
2388
0
  if ((query->addrinfo->flags & FCTX_ADDRINFO_NOEDNS0) != 0) {
2389
0
    query->options |= DNS_FETCHOPT_NOEDNS0;
2390
0
  }
2391
2392
0
  if (fctx->timeout && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
2393
0
    isc_sockaddr_t *sockaddr = &query->addrinfo->sockaddr;
2394
0
    struct tried *tried;
2395
2396
    /*
2397
     * If this is the first timeout for this server in this
2398
     * fetch context, try setting EDNS UDP buffer size to
2399
     * the largest UDP response size we have seen from this
2400
     * server so far.
2401
     *
2402
     * If this server has already timed out twice or more in
2403
     * this fetch context, force TCP.
2404
     */
2405
0
    if ((tried = triededns(fctx, sockaddr)) != NULL) {
2406
0
      if (tried->count == 1U) {
2407
0
        hint = dns_adb_getudpsize(fctx->adb,
2408
0
                query->addrinfo);
2409
0
      } else if (tried->count >= 2U) {
2410
0
        if ((query->options & DNS_FETCHOPT_TCP) == 0) {
2411
          /*
2412
           * Inform the ADB that we're ending a
2413
           * UDP fetch, and turn the query into
2414
           * a TCP query.
2415
           */
2416
0
          dns_adb_endudpfetch(fctx->adb,
2417
0
                  query->addrinfo);
2418
0
          query->options |= DNS_FETCHOPT_TCP;
2419
0
        }
2420
0
      }
2421
0
    }
2422
0
  }
2423
0
  fctx->timeout = false;
2424
2425
  /*
2426
   * Use EDNS0, unless the caller doesn't want it, or we know that
2427
   * the remote server doesn't like it.
2428
   */
2429
0
  if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
2430
0
    if ((query->addrinfo->flags & FCTX_ADDRINFO_NOEDNS0) == 0) {
2431
0
      uint16_t peerudpsize = 0;
2432
0
      unsigned int version = DNS_EDNS_VERSION;
2433
0
      unsigned int flags = query->addrinfo->flags;
2434
0
      bool reqnsid = res->view->requestnsid;
2435
0
      bool sendcookie = res->view->sendcookie;
2436
0
      bool reqzoneversion = res->view->requestzoneversion;
2437
0
      bool tcpkeepalive = false;
2438
0
      unsigned char cookie[COOKIE_BUFFER_SIZE];
2439
0
      uint16_t padding = 0;
2440
2441
      /*
2442
       * Set the default UDP size to what was
2443
       * configured as 'edns-buffer-size'
2444
       */
2445
0
      udpsize = res->view->udpsize;
2446
2447
      /*
2448
       * This server timed out for the first time in
2449
       * this fetch context and we received a response
2450
       * from it before (either in this fetch context
2451
       * or in a different one).  Set 'udpsize' to the
2452
       * size of the largest UDP response we have
2453
       * received from this server so far.
2454
       */
2455
0
      if (hint != 0U) {
2456
0
        udpsize = hint;
2457
0
      }
2458
2459
      /*
2460
       * If a fixed EDNS UDP buffer size is configured
2461
       * for this server, make sure we obey that.
2462
       */
2463
0
      if (peer != NULL) {
2464
0
        (void)dns_peer_getudpsize(peer, &peerudpsize);
2465
0
        if (peerudpsize != 0) {
2466
0
          udpsize = peerudpsize;
2467
0
        }
2468
0
      }
2469
2470
0
      if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
2471
0
        version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
2472
0
        version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
2473
0
      }
2474
2475
      /* Request NSID/COOKIE/VERSION for current peer?
2476
       */
2477
0
      if (peer != NULL) {
2478
0
        uint8_t ednsversion;
2479
0
        result = dns_peer_getednsversion(peer,
2480
0
                 &ednsversion);
2481
0
        if (result == ISC_R_SUCCESS &&
2482
0
            ednsversion < version)
2483
0
        {
2484
0
          version = ednsversion;
2485
0
        }
2486
0
        (void)dns_peer_getrequestnsid(peer, &reqnsid);
2487
0
        (void)dns_peer_getrequestzoneversion(
2488
0
          peer, &reqzoneversion);
2489
0
        (void)dns_peer_getsendcookie(peer, &sendcookie);
2490
0
      }
2491
0
      if (NOCOOKIE(query->addrinfo)) {
2492
0
        sendcookie = false;
2493
0
      }
2494
0
      if (reqnsid) {
2495
0
        INSIST(ednsopt < DNS_EDNSOPTIONS);
2496
0
        ednsopts[ednsopt].code = DNS_OPT_NSID;
2497
0
        ednsopts[ednsopt].length = 0;
2498
0
        ednsopts[ednsopt].value = NULL;
2499
0
        ednsopt++;
2500
0
      }
2501
0
      if (reqzoneversion) {
2502
0
        INSIST(ednsopt < DNS_EDNSOPTIONS);
2503
0
        ednsopts[ednsopt].code = DNS_OPT_ZONEVERSION;
2504
0
        ednsopts[ednsopt].length = 0;
2505
0
        ednsopts[ednsopt].value = NULL;
2506
0
        ednsopt++;
2507
0
      }
2508
0
      if (sendcookie) {
2509
0
        INSIST(ednsopt < DNS_EDNSOPTIONS);
2510
0
        ednsopts[ednsopt].code = DNS_OPT_COOKIE;
2511
0
        ednsopts[ednsopt].length =
2512
0
          (uint16_t)dns_adb_getcookie(
2513
0
            query->addrinfo, cookie,
2514
0
            sizeof(cookie));
2515
0
        if (ednsopts[ednsopt].length != 0) {
2516
0
          ednsopts[ednsopt].value = cookie;
2517
0
          inc_stats(
2518
0
            fctx->res,
2519
0
            dns_resstatscounter_cookieout);
2520
0
        } else {
2521
0
          compute_cc(query, cookie,
2522
0
               CLIENT_COOKIE_SIZE);
2523
0
          ednsopts[ednsopt].value = cookie;
2524
0
          ednsopts[ednsopt].length =
2525
0
            CLIENT_COOKIE_SIZE;
2526
0
          inc_stats(
2527
0
            fctx->res,
2528
0
            dns_resstatscounter_cookienew);
2529
0
        }
2530
0
        ednsopt++;
2531
0
      }
2532
2533
      /* Add TCP keepalive option if appropriate */
2534
0
      if ((peer != NULL) && tcp) {
2535
0
        (void)dns_peer_gettcpkeepalive(peer,
2536
0
                     &tcpkeepalive);
2537
0
      }
2538
0
      if (tcpkeepalive) {
2539
0
        INSIST(ednsopt < DNS_EDNSOPTIONS);
2540
0
        ednsopts[ednsopt].code = DNS_OPT_TCP_KEEPALIVE;
2541
0
        ednsopts[ednsopt].length = 0;
2542
0
        ednsopts[ednsopt].value = NULL;
2543
0
        ednsopt++;
2544
0
      }
2545
2546
      /* Add PAD for current peer? Require TCP for now
2547
       */
2548
0
      if ((peer != NULL) && tcp) {
2549
0
        (void)dns_peer_getpadding(peer, &padding);
2550
0
      }
2551
0
      if (padding != 0) {
2552
0
        INSIST(ednsopt < DNS_EDNSOPTIONS);
2553
0
        ednsopts[ednsopt].code = DNS_OPT_PAD;
2554
0
        ednsopts[ednsopt].length = 0;
2555
0
        ednsopt++;
2556
0
        dns_message_setpadding(fctx->qmessage, padding);
2557
0
      }
2558
2559
0
      query->ednsversion = version;
2560
0
      result = fctx_addopt(fctx->qmessage, version, udpsize,
2561
0
               ednsopts, ednsopt);
2562
0
      if (result == ISC_R_SUCCESS) {
2563
0
        if (reqnsid) {
2564
0
          query->options |= DNS_FETCHOPT_WANTNSID;
2565
0
        }
2566
0
        if (reqzoneversion) {
2567
0
          query->options |=
2568
0
            DNS_FETCHOPT_WANTZONEVERSION;
2569
0
        }
2570
0
      } else if (result != ISC_R_SUCCESS) {
2571
        /*
2572
         * We couldn't add the OPT, but we'll
2573
         * press on. We're not using EDNS0, so
2574
         * set the NOEDNS0 bit.
2575
         */
2576
0
        query->options |= DNS_FETCHOPT_NOEDNS0;
2577
0
        query->ednsversion = -1;
2578
0
        udpsize = 0;
2579
0
      }
2580
0
    } else {
2581
      /*
2582
       * We know this server doesn't like EDNS0, so we
2583
       * won't use it.  Set the NOEDNS0 bit since
2584
       * we're not using EDNS0.
2585
       */
2586
0
      query->options |= DNS_FETCHOPT_NOEDNS0;
2587
0
      query->ednsversion = -1;
2588
0
    }
2589
0
  } else {
2590
0
    query->ednsversion = -1;
2591
0
  }
2592
2593
  /*
2594
   * Record the UDP EDNS size chosen.
2595
   */
2596
0
  query->udpsize = udpsize;
2597
2598
  /*
2599
   * If we need EDNS0 to do this query and aren't using it, we
2600
   * lose.
2601
   */
2602
0
  if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
2603
0
    result = DNS_R_SERVFAIL;
2604
0
    goto cleanup_message;
2605
0
  }
2606
2607
0
  add_triededns(fctx, &query->addrinfo->sockaddr);
2608
2609
  /*
2610
   * Clear CD if EDNS is not in use.
2611
   */
2612
0
  if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
2613
0
    fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD;
2614
0
  }
2615
2616
  /*
2617
   * Add TSIG record tailored to the current recipient.
2618
   */
2619
0
  result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey);
2620
0
  if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
2621
0
    goto cleanup_message;
2622
0
  }
2623
2624
0
  if (tsigkey != NULL) {
2625
0
    result = dns_message_settsigkey(fctx->qmessage, tsigkey);
2626
0
    dns_tsigkey_detach(&tsigkey);
2627
0
    if (result != ISC_R_SUCCESS) {
2628
0
      goto cleanup_message;
2629
0
    }
2630
0
  }
2631
2632
0
  result = dns_message_rendersection(fctx->qmessage,
2633
0
             DNS_SECTION_ADDITIONAL, 0);
2634
0
  if (result != ISC_R_SUCCESS) {
2635
0
    goto cleanup_message;
2636
0
  }
2637
2638
0
  result = dns_message_renderend(fctx->qmessage);
2639
0
  if (result != ISC_R_SUCCESS) {
2640
0
    goto cleanup_message;
2641
0
  }
2642
2643
#ifdef HAVE_DNSTAP
2644
  memset(&zr, 0, sizeof(zr));
2645
  isc_buffer_init(&zb, zone, sizeof(zone));
2646
  dns_compress_setpermitted(&cctx, false);
2647
  result = dns_name_towire(fctx->domain, &cctx, &zb);
2648
  if (result == ISC_R_SUCCESS) {
2649
    isc_buffer_usedregion(&zb, &zr);
2650
  }
2651
#endif /* HAVE_DNSTAP */
2652
2653
0
  if (dns_message_gettsigkey(fctx->qmessage) != NULL) {
2654
0
    dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage),
2655
0
           &query->tsigkey);
2656
0
    result = dns_message_getquerytsig(fctx->qmessage, fctx->mctx,
2657
0
              &query->tsig);
2658
0
    if (result != ISC_R_SUCCESS) {
2659
0
      goto cleanup_message;
2660
0
    }
2661
0
  }
2662
2663
  /*
2664
   * Log the outgoing packet.
2665
   */
2666
0
  result = dns_dispentry_getlocaladdress(query->dispentry, &localaddr);
2667
0
  if (result == ISC_R_SUCCESS) {
2668
0
    la = &localaddr;
2669
0
  }
2670
2671
0
  dns_message_logpacketfromto(
2672
0
    fctx->qmessage, "sending packet", la,
2673
0
    &query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER,
2674
0
    DNS_LOGMODULE_PACKETS, ISC_LOG_DEBUG(11), fctx->mctx);
2675
2676
  /*
2677
   * We're now done with the query message.
2678
   */
2679
0
  dns_compress_invalidate(&cctx);
2680
0
  dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
2681
2682
0
  isc_buffer_usedregion(&buffer, &r);
2683
2684
0
  resquery_ref(query);
2685
0
  dns_dispatch_send(query->dispentry, &r);
2686
2687
0
  QTRACE("sent");
2688
2689
#ifdef HAVE_DNSTAP
2690
  /*
2691
   * Log the outgoing query via dnstap.
2692
   */
2693
  if ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0) {
2694
    dtmsgtype = DNS_DTTYPE_FQ;
2695
  } else {
2696
    dtmsgtype = DNS_DTTYPE_RQ;
2697
  }
2698
2699
  if (query->addrinfo->transport != NULL) {
2700
    transport_type =
2701
      dns_transport_get_type(query->addrinfo->transport);
2702
  } else if ((query->options & DNS_FETCHOPT_TCP) != 0) {
2703
    transport_type = DNS_TRANSPORT_TCP;
2704
  } else {
2705
    transport_type = DNS_TRANSPORT_UDP;
2706
  }
2707
2708
  dns_dt_send(fctx->res->view, dtmsgtype, la, &query->addrinfo->sockaddr,
2709
        transport_type, &zr, &query->start, NULL, &buffer);
2710
#endif /* HAVE_DNSTAP */
2711
2712
0
  return ISC_R_SUCCESS;
2713
2714
0
cleanup_message:
2715
0
  dns_compress_invalidate(&cctx);
2716
2717
0
  dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
2718
2719
  /*
2720
   * Stop the dispatcher from listening.
2721
   */
2722
0
  dns_dispatch_done(&query->dispentry);
2723
2724
0
  return result;
2725
0
}
2726
2727
static void
2728
0
resquery_connected(isc_result_t eresult, isc_region_t *region, void *arg) {
2729
0
  resquery_t *query = (resquery_t *)arg;
2730
0
  resquery_t *copy = query;
2731
0
  isc_result_t result;
2732
0
  fetchctx_t *fctx = NULL;
2733
0
  dns_resolver_t *res = NULL;
2734
0
  int pf;
2735
2736
0
  REQUIRE(VALID_QUERY(query));
2737
2738
0
  QTRACE("connected");
2739
2740
0
  UNUSED(region);
2741
2742
0
  fctx = query->fctx;
2743
2744
0
  REQUIRE(VALID_FCTX(fctx));
2745
0
  REQUIRE(fctx->tid == isc_tid());
2746
2747
0
  res = fctx->res;
2748
2749
0
  if (RESQUERY_CANCELED(query)) {
2750
0
    goto detach;
2751
0
  }
2752
2753
0
  if (atomic_load_acquire(&fctx->res->exiting)) {
2754
0
    eresult = ISC_R_SHUTTINGDOWN;
2755
0
  }
2756
2757
  /*
2758
   * The reference counting of resquery objects is complex:
2759
   *
2760
   * 1. attached in fctx_query()
2761
   * 2. attached prior to dns_dispatch_connect(), detached in
2762
   *    resquery_connected()
2763
   * 3. attached prior to dns_dispatch_send(), detached in
2764
   *    resquery_senddone()
2765
   * 4. finally detached in fctx_cancelquery()
2766
   *
2767
   * On error conditions, it's necessary to call fctx_cancelquery()
2768
   * from resquery_connected() or _senddone(), detaching twice
2769
   * within the same function. To make it clear that's what's
2770
   * happening, we cancel-and-detach 'copy' and detach 'query',
2771
   * which are both pointing to the same object.
2772
   */
2773
0
  switch (eresult) {
2774
0
  case ISC_R_SUCCESS:
2775
    /*
2776
     * We are connected. Send the query.
2777
     */
2778
2779
0
    result = resquery_send(query);
2780
0
    if (result != ISC_R_SUCCESS) {
2781
0
      FCTXTRACE("query canceled: resquery_send() failed; "
2782
0
          "responding");
2783
2784
0
      fctx_cancelquery(&copy, NULL, false, false);
2785
0
      fctx_done_detach(&fctx, result);
2786
0
      break;
2787
0
    }
2788
2789
0
    fctx->querysent++;
2790
2791
0
    pf = isc_sockaddr_pf(&query->addrinfo->sockaddr);
2792
0
    if (pf == PF_INET) {
2793
0
      inc_stats(res, dns_resstatscounter_queryv4);
2794
0
    } else {
2795
0
      inc_stats(res, dns_resstatscounter_queryv6);
2796
0
    }
2797
0
    if (res->querystats != NULL) {
2798
0
      dns_rdatatypestats_increment(res->querystats,
2799
0
                 fctx->type);
2800
0
    }
2801
0
    break;
2802
2803
0
  case ISC_R_CANCELED:
2804
0
  case ISC_R_SHUTTINGDOWN:
2805
0
    FCTXTRACE3("shutdown in resquery_connected()", eresult);
2806
0
    fctx_cancelquery(&copy, NULL, true, false);
2807
0
    fctx_done_detach(&fctx, eresult);
2808
0
    break;
2809
2810
0
  case ISC_R_HOSTDOWN:
2811
0
  case ISC_R_HOSTUNREACH:
2812
0
  case ISC_R_NETDOWN:
2813
0
  case ISC_R_NETUNREACH:
2814
0
  case ISC_R_CONNREFUSED:
2815
0
  case ISC_R_NOPERM:
2816
0
  case ISC_R_ADDRNOTAVAIL:
2817
0
  case ISC_R_CONNECTIONRESET:
2818
0
  case ISC_R_TIMEDOUT:
2819
    /*
2820
     * Do not query this server again in this fetch context.
2821
     */
2822
0
    FCTXTRACE3("query failed in resquery_connected(): "
2823
0
         "no response",
2824
0
         eresult);
2825
0
    add_bad(fctx, query->rmessage, query->addrinfo, eresult,
2826
0
      badns_unreachable);
2827
0
    fctx_cancelquery(&copy, NULL, true, false);
2828
2829
0
    FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
2830
0
    fctx_try(fctx, true);
2831
0
    break;
2832
2833
0
  default:
2834
0
    FCTXTRACE3("query canceled in resquery_connected() "
2835
0
         "due to unexpected result; responding",
2836
0
         eresult);
2837
2838
0
    fctx_cancelquery(&copy, NULL, false, false);
2839
0
    fctx_done_detach(&fctx, eresult);
2840
0
    break;
2841
0
  }
2842
2843
0
detach:
2844
0
  resquery_detach(&query);
2845
0
}
2846
2847
static void
2848
0
fctx_finddone(void *arg) {
2849
0
  dns_adbfind_t *find = (dns_adbfind_t *)arg;
2850
0
  fetchctx_t *fctx = (fetchctx_t *)find->cbarg;
2851
0
  bool want_try = false;
2852
0
  bool want_done = false;
2853
0
  uint_fast32_t pending;
2854
2855
0
  REQUIRE(VALID_FCTX(fctx));
2856
2857
0
  FCTXTRACE("finddone");
2858
2859
0
  REQUIRE(fctx->tid == isc_tid());
2860
2861
0
  LOCK(&fctx->lock);
2862
0
  pending = atomic_fetch_sub_release(&fctx->pending, 1);
2863
0
  INSIST(pending > 0);
2864
2865
0
  if (ADDRWAIT(fctx)) {
2866
    /*
2867
     * The fetch is waiting for a name to be found.
2868
     */
2869
0
    INSIST(!SHUTTINGDOWN(fctx));
2870
0
    if (dns_adb_findstatus(find) == DNS_ADB_MOREADDRESSES) {
2871
0
      FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
2872
0
      want_try = true;
2873
0
    } else {
2874
0
      fctx->findfail++;
2875
0
      if (atomic_load_acquire(&fctx->pending) == 0) {
2876
0
        FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
2877
0
        if (!ISC_LIST_EMPTY(fctx->res->alternates)) {
2878
0
          want_try = true;
2879
0
        } else {
2880
          /*
2881
           * We've got nothing else to wait for
2882
           * and don't know the answer.  There's
2883
           * nothing to do but fail the fctx.
2884
           */
2885
0
          want_done = true;
2886
0
        }
2887
0
      }
2888
0
    }
2889
0
  }
2890
2891
0
  UNLOCK(&fctx->lock);
2892
2893
0
  dns_adb_destroyfind(&find);
2894
2895
0
  if (want_done) {
2896
0
    FCTXTRACE("fetch failed in finddone(); return "
2897
0
        "ISC_R_FAILURE");
2898
2899
0
    fctx_done_unref(fctx, ISC_R_FAILURE);
2900
0
  } else if (want_try) {
2901
0
    fctx_try(fctx, true);
2902
0
  }
2903
2904
0
  fetchctx_detach(&fctx);
2905
0
}
2906
2907
static bool
2908
0
bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) {
2909
0
  ISC_LIST_FOREACH(fctx->bad, sa, link) {
2910
0
    if (isc_sockaddr_equal(sa, address)) {
2911
0
      return true;
2912
0
    }
2913
0
  }
2914
2915
0
  return false;
2916
0
}
2917
2918
static bool
2919
0
mark_bad(fetchctx_t *fctx) {
2920
0
  bool all_bad = true;
2921
2922
#ifdef ENABLE_AFL
2923
  if (dns_fuzzing_resolver) {
2924
    return false;
2925
  }
2926
#endif /* ifdef ENABLE_AFL */
2927
2928
  /*
2929
   * Mark all known bad servers, so we don't try to talk to them
2930
   * again.
2931
   */
2932
2933
  /*
2934
   * Mark any bad nameservers.
2935
   */
2936
0
  ISC_LIST_FOREACH(fctx->finds, curr, publink) {
2937
0
    ISC_LIST_FOREACH(curr->list, addrinfo, publink) {
2938
0
      if (bad_server(fctx, &addrinfo->sockaddr)) {
2939
0
        addrinfo->flags |= FCTX_ADDRINFO_MARK;
2940
0
      } else {
2941
0
        all_bad = false;
2942
0
      }
2943
0
    }
2944
0
  }
2945
2946
  /*
2947
   * Mark any bad forwarders.
2948
   */
2949
0
  ISC_LIST_FOREACH(fctx->forwaddrs, addrinfo, publink) {
2950
0
    if (bad_server(fctx, &addrinfo->sockaddr)) {
2951
0
      addrinfo->flags |= FCTX_ADDRINFO_MARK;
2952
0
    } else {
2953
0
      all_bad = false;
2954
0
    }
2955
0
  }
2956
2957
  /*
2958
   * Mark any bad alternates.
2959
   */
2960
0
  ISC_LIST_FOREACH(fctx->altfinds, curr, publink) {
2961
0
    ISC_LIST_FOREACH(curr->list, addrinfo, publink) {
2962
0
      if (bad_server(fctx, &addrinfo->sockaddr)) {
2963
0
        addrinfo->flags |= FCTX_ADDRINFO_MARK;
2964
0
      } else {
2965
0
        all_bad = false;
2966
0
      }
2967
0
    }
2968
0
  }
2969
2970
0
  ISC_LIST_FOREACH(fctx->altaddrs, addrinfo, publink) {
2971
0
    if (bad_server(fctx, &addrinfo->sockaddr)) {
2972
0
      addrinfo->flags |= FCTX_ADDRINFO_MARK;
2973
0
    } else {
2974
0
      all_bad = false;
2975
0
    }
2976
0
  }
2977
2978
0
  return all_bad;
2979
0
}
2980
2981
static void
2982
add_bad(fetchctx_t *fctx, dns_message_t *rmessage, dns_adbaddrinfo_t *addrinfo,
2983
0
  isc_result_t reason, badnstype_t badtype) {
2984
0
  char namebuf[DNS_NAME_FORMATSIZE];
2985
0
  char addrbuf[ISC_SOCKADDR_FORMATSIZE];
2986
0
  char classbuf[64];
2987
0
  char typebuf[64];
2988
0
  char code[64];
2989
0
  isc_buffer_t b;
2990
0
  isc_sockaddr_t *sa;
2991
0
  const char *spc = "";
2992
0
  isc_sockaddr_t *address = &addrinfo->sockaddr;
2993
2994
#ifdef ENABLE_AFL
2995
  if (dns_fuzzing_resolver) {
2996
    return;
2997
  }
2998
#endif /* ifdef ENABLE_AFL */
2999
3000
0
  if (reason == DNS_R_LAME) {
3001
0
    fctx->lamecount++;
3002
0
  } else {
3003
0
    switch (badtype) {
3004
0
    case badns_unreachable:
3005
0
      fctx->neterr++;
3006
0
      break;
3007
0
    case badns_response:
3008
0
      fctx->badresp++;
3009
0
      break;
3010
0
    case badns_validation:
3011
0
      break; /* counted as 'valfail' */
3012
0
    case badns_forwarder:
3013
      /*
3014
       * We were called to prevent the given forwarder
3015
       * from being used again for this fetch context.
3016
       */
3017
0
      break;
3018
0
    }
3019
0
  }
3020
3021
0
  if (bad_server(fctx, address)) {
3022
    /*
3023
     * We already know this server is bad.
3024
     */
3025
0
    return;
3026
0
  }
3027
3028
0
  FCTXTRACE("add_bad");
3029
3030
0
  sa = isc_mem_get(fctx->mctx, sizeof(*sa));
3031
0
  *sa = *address;
3032
0
  ISC_LIST_INITANDAPPEND(fctx->bad, sa, link);
3033
3034
0
  if (reason == DNS_R_LAME) { /* already logged */
3035
0
    return;
3036
0
  }
3037
3038
0
  if (reason == DNS_R_UNEXPECTEDRCODE &&
3039
0
      rmessage->rcode == dns_rcode_servfail && ISFORWARDER(addrinfo))
3040
0
  {
3041
0
    return;
3042
0
  }
3043
3044
0
  if (reason == DNS_R_UNEXPECTEDRCODE) {
3045
0
    isc_buffer_init(&b, code, sizeof(code) - 1);
3046
0
    dns_rcode_totext(rmessage->rcode, &b);
3047
0
    code[isc_buffer_usedlength(&b)] = '\0';
3048
0
    spc = " ";
3049
0
  } else if (reason == DNS_R_UNEXPECTEDOPCODE) {
3050
0
    isc_buffer_init(&b, code, sizeof(code) - 1);
3051
0
    dns_opcode_totext((dns_opcode_t)rmessage->opcode, &b);
3052
0
    code[isc_buffer_usedlength(&b)] = '\0';
3053
0
    spc = " ";
3054
0
  } else {
3055
0
    code[0] = '\0';
3056
0
  }
3057
0
  dns_name_format(fctx->name, namebuf, sizeof(namebuf));
3058
0
  dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
3059
0
  dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf));
3060
0
  isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
3061
0
  isc_log_write(DNS_LOGCATEGORY_LAME_SERVERS, DNS_LOGMODULE_RESOLVER,
3062
0
          ISC_LOG_INFO, "%s%s%s resolving '%s/%s/%s': %s", code,
3063
0
          spc, isc_result_totext(reason), namebuf, typebuf,
3064
0
          classbuf, addrbuf);
3065
0
}
3066
3067
/*
3068
 * Sort addrinfo list by RTT.
3069
 */
3070
static void
3071
0
sort_adbfind(dns_adbfind_t *find, unsigned int bias) {
3072
0
  dns_adbaddrinfo_t *best, *curr;
3073
0
  dns_adbaddrinfolist_t sorted;
3074
3075
  /* Lame N^2 bubble sort. */
3076
0
  ISC_LIST_INIT(sorted);
3077
0
  while (!ISC_LIST_EMPTY(find->list)) {
3078
0
    unsigned int best_srtt;
3079
0
    best = ISC_LIST_HEAD(find->list);
3080
0
    best_srtt = best->srtt;
3081
0
    if (isc_sockaddr_pf(&best->sockaddr) != AF_INET6) {
3082
0
      best_srtt += bias;
3083
0
    }
3084
0
    curr = ISC_LIST_NEXT(best, publink);
3085
0
    while (curr != NULL) {
3086
0
      unsigned int curr_srtt = curr->srtt;
3087
0
      if (isc_sockaddr_pf(&curr->sockaddr) != AF_INET6) {
3088
0
        curr_srtt += bias;
3089
0
      }
3090
0
      if (curr_srtt < best_srtt) {
3091
0
        best = curr;
3092
0
        best_srtt = curr_srtt;
3093
0
      }
3094
0
      curr = ISC_LIST_NEXT(curr, publink);
3095
0
    }
3096
0
    ISC_LIST_UNLINK(find->list, best, publink);
3097
0
    ISC_LIST_APPEND(sorted, best, publink);
3098
0
  }
3099
0
  find->list = sorted;
3100
0
}
3101
3102
/*
3103
 * Sort a list of finds by server RTT.
3104
 */
3105
static void
3106
0
sort_finds(dns_adbfindlist_t *findlist, unsigned int bias) {
3107
0
  dns_adbfind_t *best = NULL;
3108
0
  dns_adbfindlist_t sorted;
3109
0
  dns_adbaddrinfo_t *addrinfo, *bestaddrinfo;
3110
3111
  /* Sort each find's addrinfo list by SRTT. */
3112
0
  ISC_LIST_FOREACH(*findlist, curr, publink) {
3113
0
    sort_adbfind(curr, bias);
3114
0
  }
3115
3116
  /* Lame N^2 bubble sort. */
3117
0
  ISC_LIST_INIT(sorted);
3118
0
  while (!ISC_LIST_EMPTY(*findlist)) {
3119
0
    dns_adbfind_t *curr = NULL;
3120
0
    unsigned int best_srtt;
3121
3122
0
    best = ISC_LIST_HEAD(*findlist);
3123
0
    bestaddrinfo = ISC_LIST_HEAD(best->list);
3124
0
    INSIST(bestaddrinfo != NULL);
3125
0
    best_srtt = bestaddrinfo->srtt;
3126
0
    if (isc_sockaddr_pf(&bestaddrinfo->sockaddr) != AF_INET6) {
3127
0
      best_srtt += bias;
3128
0
    }
3129
0
    curr = ISC_LIST_NEXT(best, publink);
3130
0
    while (curr != NULL) {
3131
0
      unsigned int curr_srtt;
3132
0
      addrinfo = ISC_LIST_HEAD(curr->list);
3133
0
      INSIST(addrinfo != NULL);
3134
0
      curr_srtt = addrinfo->srtt;
3135
0
      if (isc_sockaddr_pf(&addrinfo->sockaddr) != AF_INET6) {
3136
0
        curr_srtt += bias;
3137
0
      }
3138
0
      if (curr_srtt < best_srtt) {
3139
0
        best = curr;
3140
0
        best_srtt = curr_srtt;
3141
0
      }
3142
0
      curr = ISC_LIST_NEXT(curr, publink);
3143
0
    }
3144
0
    ISC_LIST_UNLINK(*findlist, best, publink);
3145
0
    ISC_LIST_APPEND(sorted, best, publink);
3146
0
  }
3147
0
  *findlist = sorted;
3148
0
}
3149
3150
/*
3151
 * Return true iff the ADB find has a pending fetch for 'type'.  This is
3152
 * used to find out whether we're in a loop, where a fetch is waiting for a
3153
 * find which is waiting for that same fetch.
3154
 *
3155
 * Note: This could be done with either an equivalence check (e.g.,
3156
 * query_pending == DNS_ADBFIND_INET) or with a bit check, as below.  If
3157
 * we checked for equivalence, that would mean we could only detect a loop
3158
 * when there is exactly one pending fetch, and we're it. If there were
3159
 * pending fetches for *both* address families, then a loop would be
3160
 * undetected.
3161
 *
3162
 * However, using a bit check means that in theory, an ADB find might be
3163
 * aborted that could have succeeded, if the other fetch had returned an
3164
 * answer.
3165
 *
3166
 * Since there's a good chance the server is broken and won't answer either
3167
 * query, and since an ADB find with two pending fetches is a very rare
3168
 * occurrance anyway, we regard this theoretical SERVFAIL as the lesser
3169
 * evil.
3170
 */
3171
static bool
3172
0
waiting_for(dns_adbfind_t *find, dns_rdatatype_t type) {
3173
0
  switch (type) {
3174
0
  case dns_rdatatype_a:
3175
0
    return (find->query_pending & DNS_ADBFIND_INET) != 0;
3176
0
  case dns_rdatatype_aaaa:
3177
0
    return (find->query_pending & DNS_ADBFIND_INET6) != 0;
3178
0
  default:
3179
0
    return false;
3180
0
  }
3181
0
}
3182
3183
static void
3184
findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
3185
   unsigned int options, unsigned int flags, isc_stdtime_t now,
3186
0
   bool *overquota, bool *need_alternate, unsigned int *no_addresses) {
3187
0
  dns_adbfind_t *find = NULL;
3188
0
  dns_resolver_t *res = fctx->res;
3189
0
  bool unshared = ((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
3190
0
  isc_result_t result;
3191
3192
0
  FCTXTRACE("FINDNAME");
3193
3194
  /*
3195
   * If this name is a subdomain of the query domain, tell
3196
   * the ADB to start looking using zone/hint data. This keeps us
3197
   * from getting stuck if the nameserver is beneath the zone cut
3198
   * and we don't know its address (e.g. because the A record has
3199
   * expired).
3200
   */
3201
0
  if (dns_name_issubdomain(name, fctx->domain)) {
3202
0
    options |= DNS_ADBFIND_STARTATZONE;
3203
0
  }
3204
3205
  /*
3206
   * Exempt prefetches from ADB quota.
3207
   */
3208
0
  if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) {
3209
0
    options |= DNS_ADBFIND_QUOTAEXEMPT;
3210
0
  }
3211
3212
  /*
3213
   * Pass through NOVALIDATE to any lookups ADB makes.
3214
   */
3215
0
  if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
3216
0
    options |= DNS_ADBFIND_NOVALIDATE;
3217
0
  }
3218
3219
  /*
3220
   * See what we know about this address.
3221
   */
3222
0
  INSIST(!SHUTTINGDOWN(fctx));
3223
0
  fetchctx_ref(fctx);
3224
0
  result = dns_adb_createfind(fctx->adb, fctx->loop, fctx_finddone, fctx,
3225
0
            name, fctx->name, fctx->type, options, now,
3226
0
            res->view->dstport, fctx->depth + 1,
3227
0
            fctx->qc, fctx->gqc, &find);
3228
3229
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
3230
0
          ISC_LOG_DEBUG(3), "fctx %p(%s): createfind for %s - %s",
3231
0
          fctx, fctx->info, fctx->clientstr,
3232
0
          isc_result_totext(result));
3233
3234
0
  if (result != ISC_R_SUCCESS) {
3235
0
    if (result == DNS_R_ALIAS) {
3236
0
      char namebuf[DNS_NAME_FORMATSIZE];
3237
3238
      /*
3239
       * XXXRTH  Follow the CNAME/DNAME chain?
3240
       */
3241
0
      dns_adb_destroyfind(&find);
3242
0
      fctx->adberr++;
3243
0
      dns_name_format(name, namebuf, sizeof(namebuf));
3244
0
      isc_log_write(DNS_LOGCATEGORY_CNAME,
3245
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
3246
0
              "skipping nameserver '%s' because it "
3247
0
              "is a CNAME, while resolving '%s'",
3248
0
              namebuf, fctx->info);
3249
0
    }
3250
0
    fetchctx_detach(&fctx);
3251
0
    return;
3252
0
  }
3253
3254
0
  if (!ISC_LIST_EMPTY(find->list)) {
3255
    /*
3256
     * We have at least some of the addresses for the
3257
     * name.
3258
     */
3259
0
    INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0);
3260
0
    if (flags != 0 || port != 0) {
3261
0
      ISC_LIST_FOREACH(find->list, ai, publink) {
3262
0
        ai->flags |= flags;
3263
0
        if (port != 0) {
3264
0
          isc_sockaddr_setport(&ai->sockaddr,
3265
0
                   port);
3266
0
        }
3267
0
      }
3268
0
    }
3269
0
    if ((flags & FCTX_ADDRINFO_DUALSTACK) != 0) {
3270
0
      ISC_LIST_APPEND(fctx->altfinds, find, publink);
3271
0
    } else {
3272
0
      ISC_LIST_APPEND(fctx->finds, find, publink);
3273
0
    }
3274
0
    return;
3275
0
  }
3276
3277
  /*
3278
   * We don't know any of the addresses for this name.
3279
   *
3280
   * The find may be waiting on a resolver fetch for a server
3281
   * address. We need to make sure it isn't waiting on *this*
3282
   * fetch, because if it is, we won't be answering it and it
3283
   * won't be answering us.
3284
   */
3285
0
  if (waiting_for(find, fctx->type) && dns_name_equal(name, fctx->name)) {
3286
0
    fctx->adberr++;
3287
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
3288
0
            ISC_LOG_INFO, "loop detected resolving '%s'",
3289
0
            fctx->info);
3290
3291
0
    if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) {
3292
0
      atomic_fetch_add_relaxed(&fctx->pending, 1);
3293
0
      dns_adb_cancelfind(find);
3294
0
    } else {
3295
0
      dns_adb_destroyfind(&find);
3296
0
      fetchctx_detach(&fctx);
3297
0
    }
3298
0
    return;
3299
0
  }
3300
3301
  /*
3302
   * We may be waiting for another fetch to complete, and
3303
   * we'll get an event later when the find has what it needs.
3304
   */
3305
0
  if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) {
3306
0
    atomic_fetch_add_relaxed(&fctx->pending, 1);
3307
3308
    /*
3309
     * Bootstrap.
3310
     */
3311
0
    if (need_alternate != NULL && !*need_alternate && unshared &&
3312
0
        ((res->dispatches4 == NULL &&
3313
0
          find->result_v6 != DNS_R_NXDOMAIN) ||
3314
0
         (res->dispatches6 == NULL &&
3315
0
          find->result_v4 != DNS_R_NXDOMAIN)))
3316
0
    {
3317
0
      *need_alternate = true;
3318
0
    }
3319
0
    if (no_addresses != NULL) {
3320
0
      (*no_addresses)++;
3321
0
    }
3322
0
    return;
3323
0
  }
3324
3325
  /*
3326
   * No addresses and no pending events: the find failed.
3327
   */
3328
0
  if ((find->options & DNS_ADBFIND_OVERQUOTA) != 0) {
3329
0
    if (overquota != NULL) {
3330
0
      *overquota = true;
3331
0
    }
3332
0
    fctx->quotacount++; /* quota exceeded */
3333
0
  } else {
3334
0
    fctx->adberr++; /* unreachable server, etc. */
3335
0
  }
3336
3337
  /*
3338
   * If we know there are no addresses for the family we are using then
3339
   * try to add an alternative server.
3340
   */
3341
0
  if (need_alternate != NULL && !*need_alternate &&
3342
0
      ((res->dispatches4 == NULL && find->result_v6 == DNS_R_NXRRSET) ||
3343
0
       (res->dispatches6 == NULL && find->result_v4 == DNS_R_NXRRSET)))
3344
0
  {
3345
0
    *need_alternate = true;
3346
0
  }
3347
0
  dns_adb_destroyfind(&find);
3348
0
  fetchctx_detach(&fctx);
3349
0
}
3350
3351
static bool
3352
0
isstrictsubdomain(const dns_name_t *name1, const dns_name_t *name2) {
3353
0
  int order;
3354
0
  unsigned int nlabels;
3355
0
  dns_namereln_t namereln;
3356
3357
0
  namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
3358
0
  return namereln == dns_namereln_subdomain;
3359
0
}
3360
3361
static isc_result_t
3362
0
fctx_getaddresses(fetchctx_t *fctx) {
3363
0
  isc_result_t result;
3364
0
  dns_resolver_t *res;
3365
0
  isc_stdtime_t now;
3366
0
  unsigned int stdoptions = 0;
3367
0
  dns_forwarder_t *fwd;
3368
0
  dns_adbaddrinfo_t *ai;
3369
0
  bool all_bad;
3370
0
  dns_rdata_ns_t ns;
3371
0
  bool need_alternate = false;
3372
0
  bool all_spilled = false;
3373
0
  unsigned int no_addresses = 0;
3374
0
  unsigned int ns_processed = 0;
3375
3376
0
  FCTXTRACE5("getaddresses", "fctx->depth=", fctx->depth);
3377
3378
  /*
3379
   * Don't pound on remote servers.  (Failsafe!)
3380
   */
3381
0
  fctx->restarts++;
3382
0
  if (fctx->restarts > 100) {
3383
0
    FCTXTRACE("too many restarts");
3384
0
    return DNS_R_SERVFAIL;
3385
0
  }
3386
3387
0
  res = fctx->res;
3388
3389
0
  if (fctx->depth > res->maxdepth) {
3390
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
3391
0
            ISC_LOG_DEBUG(3),
3392
0
            "too much NS indirection resolving '%s' "
3393
0
            "(depth=%u, maxdepth=%u)",
3394
0
            fctx->info, fctx->depth, res->maxdepth);
3395
0
    return DNS_R_SERVFAIL;
3396
0
  }
3397
3398
  /*
3399
   * Forwarders.
3400
   */
3401
3402
0
  INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
3403
0
  INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
3404
3405
  /*
3406
   * If we have DNS_FETCHOPT_NOFORWARD set and forwarding policy
3407
   * allows us to not forward - skip forwarders and go straight
3408
   * to NSes. This is currently used to make sure that priming
3409
   * query gets root servers' IP addresses in ADDITIONAL section.
3410
   */
3411
0
  if ((fctx->options & DNS_FETCHOPT_NOFORWARD) != 0 &&
3412
0
      (fctx->fwdpolicy != dns_fwdpolicy_only))
3413
0
  {
3414
0
    goto normal_nses;
3415
0
  }
3416
3417
  /*
3418
   * If this fctx has forwarders, use them; otherwise use any
3419
   * selective forwarders specified in the view; otherwise use the
3420
   * resolver's forwarders (if any).
3421
   */
3422
0
  fwd = ISC_LIST_HEAD(fctx->forwarders);
3423
0
  if (fwd == NULL) {
3424
0
    dns_forwarders_t *forwarders = NULL;
3425
0
    dns_name_t *name = fctx->name;
3426
0
    dns_name_t suffix;
3427
3428
    /*
3429
     * DS records are found in the parent server.
3430
     * Strip label to get the correct forwarder (if any).
3431
     */
3432
0
    if (dns_rdatatype_atparent(fctx->type) &&
3433
0
        dns_name_countlabels(name) > 1)
3434
0
    {
3435
0
      unsigned int labels;
3436
0
      dns_name_init(&suffix);
3437
0
      labels = dns_name_countlabels(name);
3438
0
      dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
3439
0
      name = &suffix;
3440
0
    }
3441
3442
0
    result = dns_fwdtable_find(res->view->fwdtable, name,
3443
0
             &forwarders);
3444
0
    if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
3445
0
      fwd = ISC_LIST_HEAD(forwarders->fwdrs);
3446
0
      fctx->fwdpolicy = forwarders->fwdpolicy;
3447
0
      dns_name_copy(&forwarders->name, fctx->fwdname);
3448
0
      if (fctx->fwdpolicy == dns_fwdpolicy_only &&
3449
0
          isstrictsubdomain(&forwarders->name, fctx->domain))
3450
0
      {
3451
0
        fcount_decr(fctx);
3452
0
        dns_name_copy(&forwarders->name, fctx->domain);
3453
0
        result = fcount_incr(fctx, true);
3454
0
        if (result != ISC_R_SUCCESS) {
3455
0
          dns_forwarders_detach(&forwarders);
3456
0
          return result;
3457
0
        }
3458
0
      }
3459
0
      dns_forwarders_detach(&forwarders);
3460
0
    }
3461
0
  }
3462
3463
0
  while (fwd != NULL) {
3464
0
    if ((isc_sockaddr_pf(&fwd->addr) == AF_INET &&
3465
0
         res->dispatches4 == NULL) ||
3466
0
        (isc_sockaddr_pf(&fwd->addr) == AF_INET6 &&
3467
0
         res->dispatches6 == NULL))
3468
0
    {
3469
0
      fwd = ISC_LIST_NEXT(fwd, link);
3470
0
      continue;
3471
0
    }
3472
0
    ai = NULL;
3473
0
    result = dns_adb_findaddrinfo(fctx->adb, &fwd->addr, &ai, 0);
3474
0
    if (result == ISC_R_SUCCESS) {
3475
0
      dns_adbaddrinfo_t *cur;
3476
0
      ai->flags |= FCTX_ADDRINFO_FORWARDER;
3477
0
      if (fwd->tlsname != NULL) {
3478
0
        result = dns_view_gettransport(
3479
0
          res->view, DNS_TRANSPORT_TLS,
3480
0
          fwd->tlsname, &ai->transport);
3481
0
        if (result != ISC_R_SUCCESS) {
3482
0
          dns_adb_freeaddrinfo(fctx->adb, &ai);
3483
0
          goto next;
3484
0
        }
3485
0
      }
3486
0
      cur = ISC_LIST_HEAD(fctx->forwaddrs);
3487
0
      while (cur != NULL && cur->srtt < ai->srtt) {
3488
0
        cur = ISC_LIST_NEXT(cur, publink);
3489
0
      }
3490
0
      if (cur != NULL) {
3491
0
        ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur, ai,
3492
0
                  publink);
3493
0
      } else {
3494
0
        ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
3495
0
      }
3496
0
    }
3497
0
  next:
3498
0
    fwd = ISC_LIST_NEXT(fwd, link);
3499
0
  }
3500
3501
  /*
3502
   * If the forwarding policy is "only", we don't need the
3503
   * addresses of the nameservers.
3504
   */
3505
0
  if (fctx->fwdpolicy == dns_fwdpolicy_only) {
3506
0
    goto out;
3507
0
  }
3508
3509
  /*
3510
   * Normal nameservers.
3511
   */
3512
0
normal_nses:
3513
0
  stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;
3514
0
  if (fctx->restarts == 1) {
3515
    /*
3516
     * To avoid sending out a flood of queries likely to
3517
     * result in NXRRSET, we suppress fetches for address
3518
     * families we don't have the first time through,
3519
     * provided that we have addresses in some family we
3520
     * can use.
3521
     *
3522
     * We don't want to set this option all the time, since
3523
     * if fctx->restarts > 1, we've clearly been having
3524
     * trouble with the addresses we had, so getting more
3525
     * could help.
3526
     */
3527
0
    stdoptions |= DNS_ADBFIND_AVOIDFETCHES;
3528
0
  }
3529
0
  if (res->dispatches4 != NULL) {
3530
0
    stdoptions |= DNS_ADBFIND_INET;
3531
0
  }
3532
0
  if (res->dispatches6 != NULL) {
3533
0
    stdoptions |= DNS_ADBFIND_INET6;
3534
0
  }
3535
3536
0
  if ((stdoptions & DNS_ADBFIND_ADDRESSMASK) == 0) {
3537
0
    return DNS_R_SERVFAIL;
3538
0
  }
3539
3540
0
  now = isc_stdtime_now();
3541
0
  all_spilled = true; /* resets to false below after the first success */
3542
3543
0
  INSIST(ISC_LIST_EMPTY(fctx->finds));
3544
0
  INSIST(ISC_LIST_EMPTY(fctx->altfinds));
3545
3546
0
  DNS_RDATASET_FOREACH(&fctx->nameservers) {
3547
0
    dns_rdata_t rdata = DNS_RDATA_INIT;
3548
0
    bool overquota = false;
3549
0
    unsigned int static_stub = 0;
3550
3551
0
    dns_rdataset_current(&fctx->nameservers, &rdata);
3552
    /*
3553
     * Extract the name from the NS record.
3554
     */
3555
0
    result = dns_rdata_tostruct(&rdata, &ns, NULL);
3556
0
    if (result != ISC_R_SUCCESS) {
3557
0
      continue;
3558
0
    }
3559
3560
0
    if (STATICSTUB(&fctx->nameservers) &&
3561
0
        dns_name_equal(&ns.name, fctx->domain))
3562
0
    {
3563
0
      static_stub = DNS_ADBFIND_STATICSTUB;
3564
0
    }
3565
3566
0
    if (no_addresses > NS_FAIL_LIMIT &&
3567
0
        dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
3568
0
    {
3569
0
      stdoptions |= DNS_ADBFIND_NOFETCH;
3570
0
    }
3571
0
    findname(fctx, &ns.name, 0, stdoptions | static_stub, 0, now,
3572
0
       &overquota, &need_alternate, &no_addresses);
3573
3574
0
    if (!overquota) {
3575
0
      all_spilled = false;
3576
0
    }
3577
3578
0
    dns_rdata_reset(&rdata);
3579
0
    dns_rdata_freestruct(&ns);
3580
3581
0
    if (++ns_processed >= NS_PROCESSING_LIMIT) {
3582
0
      break;
3583
0
    }
3584
0
  }
3585
3586
  /*
3587
   * Do we need to use 6 to 4?
3588
   */
3589
0
  if (need_alternate) {
3590
0
    int family;
3591
0
    family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET;
3592
0
    ISC_LIST_FOREACH(res->alternates, a, link) {
3593
0
      if (!a->isaddress) {
3594
0
        findname(fctx, &a->_u._n.name, a->_u._n.port,
3595
0
           stdoptions, FCTX_ADDRINFO_DUALSTACK,
3596
0
           now, NULL, NULL, NULL);
3597
0
        continue;
3598
0
      }
3599
0
      if (isc_sockaddr_pf(&a->_u.addr) != family) {
3600
0
        continue;
3601
0
      }
3602
0
      ai = NULL;
3603
0
      result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr,
3604
0
                  &ai, 0);
3605
0
      if (result == ISC_R_SUCCESS) {
3606
0
        dns_adbaddrinfo_t *cur;
3607
0
        ai->flags |= FCTX_ADDRINFO_FORWARDER;
3608
0
        ai->flags |= FCTX_ADDRINFO_DUALSTACK;
3609
0
        cur = ISC_LIST_HEAD(fctx->altaddrs);
3610
0
        while (cur != NULL && cur->srtt < ai->srtt) {
3611
0
          cur = ISC_LIST_NEXT(cur, publink);
3612
0
        }
3613
0
        if (cur != NULL) {
3614
0
          ISC_LIST_INSERTBEFORE(fctx->altaddrs,
3615
0
                    cur, ai, publink);
3616
0
        } else {
3617
0
          ISC_LIST_APPEND(fctx->altaddrs, ai,
3618
0
              publink);
3619
0
        }
3620
0
      }
3621
0
    }
3622
0
  }
3623
3624
0
out:
3625
  /*
3626
   * Mark all known bad servers.
3627
   */
3628
0
  all_bad = mark_bad(fctx);
3629
3630
  /*
3631
   * How are we doing?
3632
   */
3633
0
  if (all_bad) {
3634
    /*
3635
     * We've got no addresses.
3636
     */
3637
0
    if (atomic_load_acquire(&fctx->pending) > 0) {
3638
      /*
3639
       * We're fetching the addresses, but don't have
3640
       * any yet.   Tell the caller to wait for an
3641
       * answer.
3642
       */
3643
0
      result = DNS_R_WAIT;
3644
0
    } else {
3645
      /*
3646
       * We've lost completely.  We don't know any
3647
       * addresses, and the ADB has told us it can't
3648
       * get them.
3649
       */
3650
0
      FCTXTRACE("no addresses");
3651
3652
0
      result = ISC_R_FAILURE;
3653
3654
      /*
3655
       * If all of the addresses found were over the
3656
       * fetches-per-server quota, increase the ServerQuota
3657
       * counter and return the configured response.
3658
       */
3659
0
      if (all_spilled) {
3660
0
        result = res->quotaresp[dns_quotatype_server];
3661
0
        inc_stats(res, dns_resstatscounter_serverquota);
3662
0
      }
3663
3664
      /*
3665
       * If we are using a 'forward only' policy, and all
3666
       * the forwarders are bad, increase the ForwardOnlyFail
3667
       * counter.
3668
       */
3669
0
      if (fctx->fwdpolicy == dns_fwdpolicy_only) {
3670
0
        inc_stats(res,
3671
0
            dns_resstatscounter_forwardonlyfail);
3672
0
      }
3673
0
    }
3674
0
  } else {
3675
    /*
3676
     * We've found some addresses.  We might still be
3677
     * looking for more addresses.
3678
     */
3679
0
    sort_finds(&fctx->finds, res->view->v6bias);
3680
0
    sort_finds(&fctx->altfinds, 0);
3681
0
    result = ISC_R_SUCCESS;
3682
0
  }
3683
3684
0
  return result;
3685
0
}
3686
3687
static void
3688
0
possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) {
3689
0
  isc_netaddr_t na;
3690
0
  isc_sockaddr_t *sa = &addr->sockaddr;
3691
0
  bool aborted = false;
3692
0
  bool bogus;
3693
0
  dns_acl_t *blackhole;
3694
0
  isc_netaddr_t ipaddr;
3695
0
  dns_peer_t *peer = NULL;
3696
0
  dns_resolver_t *res = fctx->res;
3697
0
  const char *msg = NULL;
3698
3699
0
  isc_netaddr_fromsockaddr(&ipaddr, sa);
3700
0
  blackhole = dns_dispatchmgr_getblackhole(res->view->dispatchmgr);
3701
0
  (void)dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer);
3702
3703
0
  if (blackhole != NULL) {
3704
0
    int match;
3705
3706
0
    if ((dns_acl_match(&ipaddr, NULL, blackhole, res->view->aclenv,
3707
0
           &match, NULL) == ISC_R_SUCCESS) &&
3708
0
        match > 0)
3709
0
    {
3710
0
      aborted = true;
3711
0
    }
3712
0
  }
3713
3714
0
  if (peer != NULL && dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS &&
3715
0
      bogus)
3716
0
  {
3717
0
    aborted = true;
3718
0
  }
3719
3720
0
  if (aborted) {
3721
0
    addr->flags |= FCTX_ADDRINFO_MARK;
3722
0
    msg = "ignoring blackholed / bogus server: ";
3723
0
  } else if (isc_sockaddr_isnetzero(sa)) {
3724
0
    addr->flags |= FCTX_ADDRINFO_MARK;
3725
0
    msg = "ignoring net zero address: ";
3726
0
  } else if (isc_sockaddr_ismulticast(sa)) {
3727
0
    addr->flags |= FCTX_ADDRINFO_MARK;
3728
0
    msg = "ignoring multicast address: ";
3729
0
  } else if (isc_sockaddr_isexperimental(sa)) {
3730
0
    addr->flags |= FCTX_ADDRINFO_MARK;
3731
0
    msg = "ignoring experimental address: ";
3732
0
  } else if (sa->type.sa.sa_family != AF_INET6) {
3733
0
    return;
3734
0
  } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) {
3735
0
    addr->flags |= FCTX_ADDRINFO_MARK;
3736
0
    msg = "ignoring IPv6 mapped IPV4 address: ";
3737
0
  } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) {
3738
0
    addr->flags |= FCTX_ADDRINFO_MARK;
3739
0
    msg = "ignoring IPv6 compatibility IPV4 address: ";
3740
0
  } else {
3741
0
    return;
3742
0
  }
3743
3744
0
  if (isc_log_wouldlog(ISC_LOG_DEBUG(3))) {
3745
0
    char buf[ISC_NETADDR_FORMATSIZE];
3746
0
    isc_netaddr_fromsockaddr(&na, sa);
3747
0
    isc_netaddr_format(&na, buf, sizeof(buf));
3748
0
    FCTXTRACE2(msg, buf);
3749
0
  }
3750
0
}
3751
3752
static dns_adbaddrinfo_t *
3753
0
fctx_nextaddress(fetchctx_t *fctx) {
3754
0
  dns_adbfind_t *find = NULL, *start = NULL;
3755
0
  dns_adbaddrinfo_t *addrinfo = NULL, *faddrinfo = NULL;
3756
3757
  /*
3758
   * Return the next untried address, if any.
3759
   */
3760
3761
  /*
3762
   * Find the first unmarked forwarder (if any).
3763
   */
3764
0
  ISC_LIST_FOREACH(fctx->forwaddrs, ai, publink) {
3765
0
    if (!UNMARKED(ai)) {
3766
0
      continue;
3767
0
    }
3768
0
    possibly_mark(fctx, ai);
3769
0
    if (UNMARKED(ai)) {
3770
0
      ai->flags |= FCTX_ADDRINFO_MARK;
3771
0
      fctx->find = NULL;
3772
0
      fctx->forwarding = true;
3773
3774
      /*
3775
       * QNAME minimization is disabled when
3776
       * forwarding, and has to remain disabled if
3777
       * we switch back to normal recursion; otherwise
3778
       * forwarding could leave us in an inconsistent
3779
       * state.
3780
       */
3781
0
      fctx->minimized = false;
3782
0
      return ai;
3783
0
    }
3784
0
  }
3785
3786
  /*
3787
   * No forwarders.  Move to the next find.
3788
   */
3789
0
  fctx->forwarding = false;
3790
0
  FCTX_ATTR_SET(fctx, FCTX_ATTR_TRIEDFIND);
3791
3792
0
  find = fctx->find;
3793
0
  if (find == NULL) {
3794
0
    find = ISC_LIST_HEAD(fctx->finds);
3795
0
  } else {
3796
0
    find = ISC_LIST_NEXT(find, publink);
3797
0
    if (find == NULL) {
3798
0
      find = ISC_LIST_HEAD(fctx->finds);
3799
0
    }
3800
0
  }
3801
3802
  /*
3803
   * Find the first unmarked addrinfo.
3804
   */
3805
0
  if (find != NULL) {
3806
0
    start = find;
3807
0
    do {
3808
0
      ISC_LIST_FOREACH(find->list, ai, publink) {
3809
0
        if (!UNMARKED(ai)) {
3810
0
          continue;
3811
0
        }
3812
0
        possibly_mark(fctx, ai);
3813
0
        if (UNMARKED(ai)) {
3814
0
          ai->flags |= FCTX_ADDRINFO_MARK;
3815
0
          faddrinfo = ai;
3816
0
          break;
3817
0
        }
3818
0
      }
3819
0
      if (faddrinfo != NULL) {
3820
0
        break;
3821
0
      }
3822
0
      find = ISC_LIST_NEXT(find, publink);
3823
0
      if (find == NULL) {
3824
0
        find = ISC_LIST_HEAD(fctx->finds);
3825
0
      }
3826
0
    } while (find != start);
3827
0
  }
3828
3829
0
  fctx->find = find;
3830
0
  if (faddrinfo != NULL) {
3831
0
    return faddrinfo;
3832
0
  }
3833
3834
  /*
3835
   * No nameservers left.  Try alternates.
3836
   */
3837
3838
0
  FCTX_ATTR_SET(fctx, FCTX_ATTR_TRIEDALT);
3839
3840
0
  find = fctx->altfind;
3841
0
  if (find == NULL) {
3842
0
    find = ISC_LIST_HEAD(fctx->altfinds);
3843
0
  } else {
3844
0
    find = ISC_LIST_NEXT(find, publink);
3845
0
    if (find == NULL) {
3846
0
      find = ISC_LIST_HEAD(fctx->altfinds);
3847
0
    }
3848
0
  }
3849
3850
  /*
3851
   * Find the first unmarked addrinfo.
3852
   */
3853
0
  if (find != NULL) {
3854
0
    start = find;
3855
0
    do {
3856
0
      ISC_LIST_FOREACH(find->list, ai, publink) {
3857
0
        if (!UNMARKED(ai)) {
3858
0
          continue;
3859
0
        }
3860
0
        possibly_mark(fctx, ai);
3861
0
        if (UNMARKED(ai)) {
3862
0
          ai->flags |= FCTX_ADDRINFO_MARK;
3863
0
          faddrinfo = ai;
3864
0
          break;
3865
0
        }
3866
0
      }
3867
0
      if (faddrinfo != NULL) {
3868
0
        break;
3869
0
      }
3870
0
      find = ISC_LIST_NEXT(find, publink);
3871
0
      if (find == NULL) {
3872
0
        find = ISC_LIST_HEAD(fctx->altfinds);
3873
0
      }
3874
0
    } while (find != start);
3875
0
  }
3876
3877
  /*
3878
   * See if we have a better alternate server by address.
3879
   */
3880
0
  ISC_LIST_FOREACH(fctx->altaddrs, ai, publink) {
3881
0
    if (!UNMARKED(ai)) {
3882
0
      continue;
3883
0
    }
3884
0
    possibly_mark(fctx, ai);
3885
0
    if (UNMARKED(ai) &&
3886
0
        (faddrinfo == NULL || ai->srtt < faddrinfo->srtt))
3887
0
    {
3888
0
      if (faddrinfo != NULL) {
3889
0
        faddrinfo->flags &= ~FCTX_ADDRINFO_MARK;
3890
0
      }
3891
0
      ai->flags |= FCTX_ADDRINFO_MARK;
3892
0
      addrinfo = ai;
3893
0
      break;
3894
0
    }
3895
0
  }
3896
3897
0
  if (addrinfo == NULL) {
3898
0
    addrinfo = faddrinfo;
3899
0
    fctx->altfind = find;
3900
0
  }
3901
3902
0
  return addrinfo;
3903
0
}
3904
3905
static void
3906
0
fctx_try(fetchctx_t *fctx, bool retrying) {
3907
0
  isc_result_t result;
3908
0
  dns_adbaddrinfo_t *addrinfo = NULL;
3909
0
  dns_resolver_t *res = NULL;
3910
3911
0
  FCTXTRACE5("try", "fctx->qc=", isc_counter_used(fctx->qc));
3912
0
  if (fctx->gqc != NULL) {
3913
0
    FCTXTRACE5("try", "fctx->gqc=", isc_counter_used(fctx->gqc));
3914
0
  }
3915
3916
0
  REQUIRE(!ADDRWAIT(fctx));
3917
0
  REQUIRE(fctx->tid == isc_tid());
3918
3919
0
  res = fctx->res;
3920
3921
  /* We've already exceeded maximum query count */
3922
0
  if (isc_counter_used(fctx->qc) > isc_counter_getlimit(fctx->qc)) {
3923
0
    isc_log_write(
3924
0
      DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
3925
0
      ISC_LOG_DEBUG(3),
3926
0
      "exceeded max queries resolving '%s' "
3927
0
      "(max-recursion-queries, querycount=%u, maxqueries=%u)",
3928
0
      fctx->info, isc_counter_used(fctx->qc),
3929
0
      isc_counter_getlimit(fctx->qc));
3930
0
    result = DNS_R_SERVFAIL;
3931
0
    goto done;
3932
0
  }
3933
3934
0
  if (fctx->gqc != NULL &&
3935
0
      isc_counter_used(fctx->gqc) > isc_counter_getlimit(fctx->gqc))
3936
0
  {
3937
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
3938
0
            ISC_LOG_DEBUG(3),
3939
0
            "exceeded global max queries resolving '%s' "
3940
0
            "(max-query-count, querycount=%u, maxqueries=%u)",
3941
0
            fctx->info, isc_counter_used(fctx->gqc),
3942
0
            isc_counter_getlimit(fctx->gqc));
3943
0
    result = DNS_R_SERVFAIL;
3944
0
    goto done;
3945
0
  }
3946
3947
0
  addrinfo = fctx_nextaddress(fctx);
3948
3949
  /* Try to find an address that isn't over quota */
3950
0
  while (addrinfo != NULL && dns_adb_overquota(fctx->adb, addrinfo)) {
3951
0
    addrinfo = fctx_nextaddress(fctx);
3952
0
  }
3953
3954
0
  if (addrinfo == NULL) {
3955
    /* We have no more addresses.  Start over. */
3956
0
    fctx_cancelqueries(fctx, true, false);
3957
0
    fctx_cleanup(fctx);
3958
0
    result = fctx_getaddresses(fctx);
3959
0
    switch (result) {
3960
0
    case ISC_R_SUCCESS:
3961
0
      break;
3962
0
    case DNS_R_WAIT:
3963
      /* Sleep waiting for addresses. */
3964
0
      FCTXTRACE("addrwait");
3965
0
      FCTX_ATTR_SET(fctx, FCTX_ATTR_ADDRWAIT);
3966
0
      return;
3967
0
    default:
3968
0
      goto done;
3969
0
    }
3970
3971
0
    addrinfo = fctx_nextaddress(fctx);
3972
3973
0
    while (addrinfo != NULL &&
3974
0
           dns_adb_overquota(fctx->adb, addrinfo))
3975
0
    {
3976
0
      addrinfo = fctx_nextaddress(fctx);
3977
0
    }
3978
3979
    /*
3980
     * While we may have addresses from the ADB, they
3981
     * might be bad ones.  In this case, return SERVFAIL.
3982
     */
3983
0
    if (addrinfo == NULL) {
3984
0
      result = DNS_R_SERVFAIL;
3985
0
      goto done;
3986
0
    }
3987
0
  }
3988
  /*
3989
   * We're minimizing and we're not yet at the final NS -
3990
   * we need to launch a query for NS for 'upper' domain
3991
   */
3992
0
  if (fctx->minimized && !fctx->forwarding) {
3993
0
    unsigned int options = fctx->options;
3994
3995
0
    options &= ~DNS_FETCHOPT_QMINIMIZE;
3996
3997
    /*
3998
     * Is another QNAME minimization fetch still running?
3999
     */
4000
0
    if (fctx->qminfetch != NULL) {
4001
0
      bool validfctx = (DNS_FETCH_VALID(fctx->qminfetch) &&
4002
0
            VALID_FCTX(fctx->qminfetch->private));
4003
0
      char namebuf[DNS_NAME_FORMATSIZE];
4004
0
      char typebuf[DNS_RDATATYPE_FORMATSIZE];
4005
4006
0
      dns_name_format(fctx->qminname, namebuf,
4007
0
          sizeof(namebuf));
4008
0
      dns_rdatatype_format(fctx->qmintype, typebuf,
4009
0
               sizeof(typebuf));
4010
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
4011
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
4012
0
              "fctx %p(%s): attempting QNAME "
4013
0
              "minimization fetch for %s/%s but "
4014
0
              "fetch %p(%s) still running",
4015
0
              fctx, fctx->info, namebuf, typebuf,
4016
0
              fctx->qminfetch,
4017
0
              validfctx ? fctx->qminfetch->private->info
4018
0
            : "<invalid>");
4019
0
      result = DNS_R_SERVFAIL;
4020
0
      goto done;
4021
0
    }
4022
4023
    /*
4024
     * Turn on NOFOLLOW in relaxed mode so that QNAME minimization
4025
     * doesn't cause additional queries to resolve the target of the
4026
     * QNAME minimization request when a referral is returned.  This
4027
     * will also reduce the impact of mis-matched NS RRsets where
4028
     * the child's NS RRset is garbage.  If a delegation is
4029
     * discovered DNS_R_DELEGATION will be returned to resume_qmin.
4030
     */
4031
0
    if ((options & DNS_FETCHOPT_QMIN_STRICT) == 0) {
4032
0
      options |= DNS_FETCHOPT_NOFOLLOW;
4033
0
    }
4034
4035
0
    fetchctx_ref(fctx);
4036
0
    result = dns_resolver_createfetch(
4037
0
      fctx->res, fctx->qminname, fctx->qmintype, fctx->domain,
4038
0
      &fctx->nameservers, NULL, NULL, 0,
4039
0
      options | DNS_FETCHOPT_QMINFETCH, 0, fctx->qc,
4040
0
      fctx->gqc, fctx->loop, resume_qmin, fctx, &fctx->edectx,
4041
0
      &fctx->qminrrset, &fctx->qminsigrrset,
4042
0
      &fctx->qminfetch);
4043
0
    if (result != ISC_R_SUCCESS) {
4044
0
      fetchctx_unref(fctx);
4045
0
      goto done;
4046
0
    }
4047
0
    return;
4048
0
  }
4049
4050
0
  result = isc_counter_increment(fctx->qc);
4051
0
  if (result != ISC_R_SUCCESS) {
4052
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4053
0
            ISC_LOG_DEBUG(3),
4054
0
            "exceeded max queries resolving '%s' "
4055
0
            "(max-recursion-queries, querycount=%u)",
4056
0
            fctx->info, isc_counter_used(fctx->qc));
4057
0
    goto done;
4058
0
  }
4059
4060
0
  if (fctx->gqc != NULL) {
4061
0
    result = isc_counter_increment(fctx->gqc);
4062
0
    if (result != ISC_R_SUCCESS) {
4063
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
4064
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
4065
0
              "exceeded global max queries resolving "
4066
0
              "'%s' (max-query-count, querycount=%u)",
4067
0
              fctx->info, isc_counter_used(fctx->gqc));
4068
0
      goto done;
4069
0
    }
4070
0
  }
4071
4072
0
  result = fctx_query(fctx, addrinfo, fctx->options);
4073
0
  if (result != ISC_R_SUCCESS) {
4074
0
    goto done;
4075
0
  }
4076
0
  if (retrying) {
4077
0
    inc_stats(res, dns_resstatscounter_retry);
4078
0
  }
4079
4080
0
done:
4081
0
  if (result != ISC_R_SUCCESS) {
4082
0
    fctx_done_detach(&fctx, result);
4083
0
  }
4084
0
}
4085
4086
static void
4087
0
resume_qmin(void *arg) {
4088
0
  dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg;
4089
0
  fetchctx_t *fctx = resp->arg;
4090
0
  dns_resolver_t *res = NULL;
4091
0
  isc_result_t result;
4092
0
  unsigned int findoptions = 0;
4093
0
  dns_name_t *fname = NULL, *dcname = NULL;
4094
0
  dns_fixedname_t ffixed, dcfixed;
4095
0
  dns_rdataset_t rdataset;
4096
0
  dns_rdataset_t sigrdataset;
4097
0
  dns_db_t *db = NULL;
4098
0
  dns_dbnode_t *node = NULL;
4099
0
  bool fixup_result = false;
4100
4101
0
  REQUIRE(VALID_FCTX(fctx));
4102
4103
0
  res = fctx->res;
4104
4105
0
  REQUIRE(fctx->tid == isc_tid());
4106
4107
0
  FCTXTRACE("resume_qmin");
4108
4109
0
  fname = dns_fixedname_initname(&ffixed);
4110
0
  dcname = dns_fixedname_initname(&dcfixed);
4111
4112
0
  dns_rdataset_init(&rdataset);
4113
0
  dns_rdataset_init(&sigrdataset);
4114
4115
0
  if (resp->node != NULL) {
4116
0
    dns_db_attachnode(resp->node, &node);
4117
0
    dns_db_detachnode(&resp->node);
4118
0
  }
4119
0
  if (resp->db != NULL) {
4120
0
    dns_db_attach(resp->db, &db);
4121
0
    dns_db_detach(&resp->db);
4122
0
  }
4123
4124
0
  if (dns_rdataset_isassociated(resp->rdataset)) {
4125
0
    dns_rdataset_clone(resp->rdataset, &rdataset);
4126
0
    dns_rdataset_disassociate(resp->rdataset);
4127
0
  }
4128
0
  if (dns_rdataset_isassociated(resp->sigrdataset)) {
4129
0
    dns_rdataset_clone(resp->sigrdataset, &sigrdataset);
4130
0
    dns_rdataset_disassociate(resp->sigrdataset);
4131
0
  }
4132
0
  dns_name_copy(resp->foundname, fname);
4133
4134
0
  result = resp->result;
4135
4136
0
  dns_resolver_freefresp(&resp);
4137
4138
0
  LOCK(&fctx->lock);
4139
0
  if (SHUTTINGDOWN(fctx)) {
4140
0
    result = ISC_R_SHUTTINGDOWN;
4141
0
  }
4142
0
  UNLOCK(&fctx->lock);
4143
4144
0
  dns_resolver_destroyfetch(&fctx->qminfetch);
4145
4146
  /*
4147
   * Beware, the switch() below is little bit tricky - the order of the
4148
   * branches is important.
4149
   */
4150
0
  switch (result) {
4151
0
  case ISC_R_SHUTTINGDOWN:
4152
0
  case ISC_R_CANCELED:
4153
0
    goto cleanup;
4154
4155
0
  case DNS_R_NXDOMAIN:
4156
0
  case DNS_R_NCACHENXDOMAIN:
4157
0
  case DNS_R_FORMERR:
4158
0
  case DNS_R_REMOTEFORMERR:
4159
0
  case ISC_R_FAILURE:
4160
0
  case ISC_R_TIMEDOUT:
4161
0
    if ((fctx->options & DNS_FETCHOPT_QMIN_STRICT) != 0) {
4162
      /* These results cause a hard fail in strict mode */
4163
0
      goto cleanup;
4164
0
    }
4165
4166
0
    if (result == DNS_R_NXDOMAIN &&
4167
0
        fctx->qmin_labels == dns_name_countlabels(fctx->name))
4168
0
    {
4169
0
      LOCK(&fctx->lock);
4170
0
      resp = ISC_LIST_HEAD(fctx->resps);
4171
0
      if (resp != NULL) {
4172
0
        if (dns_rdataset_isassociated(&rdataset)) {
4173
0
          dns_rdataset_clone(&rdataset,
4174
0
                 resp->rdataset);
4175
0
        }
4176
0
        if (dns_rdataset_isassociated(&sigrdataset) &&
4177
0
            resp->sigrdataset != NULL)
4178
0
        {
4179
0
          dns_rdataset_clone(&sigrdataset,
4180
0
                 resp->sigrdataset);
4181
0
        }
4182
0
        if (db != NULL) {
4183
0
          dns_db_attach(db, &resp->db);
4184
0
        }
4185
0
        if (node != NULL) {
4186
0
          dns_db_attachnode(node, &resp->node);
4187
0
        }
4188
0
        dns_name_copy(fname, resp->foundname);
4189
0
        clone_results(fctx);
4190
0
        UNLOCK(&fctx->lock);
4191
0
        goto cleanup;
4192
0
      }
4193
0
      UNLOCK(&fctx->lock);
4194
0
    }
4195
4196
    /* ...or disable minimization in relaxed mode */
4197
0
    fctx->qmin_labels = DNS_NAME_MAXLABELS;
4198
4199
    /*
4200
     * We store the result. If we succeed in the end
4201
     * we'll issue a warning that the server is
4202
     * broken.
4203
     */
4204
0
    fctx->qmin_warning = result;
4205
0
    break;
4206
4207
0
  case ISC_R_SUCCESS:
4208
0
  case DNS_R_DELEGATION:
4209
0
  case DNS_R_NXRRSET:
4210
0
  case DNS_R_NCACHENXRRSET:
4211
0
  case DNS_R_CNAME:
4212
0
  case DNS_R_DNAME:
4213
    /*
4214
     * We have previously detected a possible error of an
4215
     * incorrect NXDOMAIN and now have a response that
4216
     * indicates that it was an actual error.
4217
     */
4218
0
    if (fctx->qmin_warning == DNS_R_NCACHENXDOMAIN ||
4219
0
        fctx->qmin_warning == DNS_R_NXDOMAIN)
4220
0
    {
4221
0
      fctx->force_qmin_warning = true;
4222
0
    }
4223
4224
    /*
4225
     * We have got a CNAME or DNAME respone to the NS query
4226
     * so we are done in almost all cases.
4227
     */
4228
0
    if ((result == DNS_R_CNAME || result == DNS_R_DNAME) &&
4229
0
        fctx->qmin_labels == dns_name_countlabels(fctx->name) &&
4230
0
        fctx->type != dns_rdatatype_key &&
4231
0
        fctx->type != dns_rdatatype_nsec &&
4232
0
        fctx->type != dns_rdatatype_any &&
4233
0
        fctx->type != dns_rdatatype_sig &&
4234
0
        fctx->type != dns_rdatatype_rrsig)
4235
0
    {
4236
0
      LOCK(&fctx->lock);
4237
0
      resp = ISC_LIST_HEAD(fctx->resps);
4238
0
      if (resp != NULL) {
4239
0
        if (dns_rdataset_isassociated(&rdataset)) {
4240
0
          dns_rdataset_clone(&rdataset,
4241
0
                 resp->rdataset);
4242
0
        }
4243
0
        if (dns_rdataset_isassociated(&sigrdataset) &&
4244
0
            resp->sigrdataset != NULL)
4245
0
        {
4246
0
          dns_rdataset_clone(&sigrdataset,
4247
0
                 resp->sigrdataset);
4248
0
        }
4249
0
        if (db != NULL) {
4250
0
          dns_db_attach(db, &resp->db);
4251
0
        }
4252
0
        if (node != NULL) {
4253
0
          dns_db_attachnode(node, &resp->node);
4254
0
        }
4255
0
        dns_name_copy(fname, resp->foundname);
4256
0
        if (result == DNS_R_CNAME &&
4257
0
            dns_rdataset_isassociated(&rdataset) &&
4258
0
            fctx->type == dns_rdatatype_cname)
4259
0
        {
4260
0
          fixup_result = true;
4261
0
        }
4262
0
        clone_results(fctx);
4263
0
        UNLOCK(&fctx->lock);
4264
0
        goto cleanup;
4265
0
      }
4266
0
      UNLOCK(&fctx->lock);
4267
0
    }
4268
4269
    /*
4270
     * Any other result will *not* cause a failure in strict
4271
     * mode, or cause minimization to be disabled in relaxed
4272
     * mode.
4273
     *
4274
     * If DNS_R_DELEGATION is set here, it implies that
4275
     * DNS_FETCHOPT_NOFOLLOW was set, and a delegation was
4276
     * discovered but not followed; we will do so now.
4277
     */
4278
0
    break;
4279
4280
0
  default:
4281
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4282
0
            ISC_LOG_DEBUG(5),
4283
0
            "QNAME minimization: unexpected result %s",
4284
0
            isc_result_totext(result));
4285
0
    break;
4286
0
  }
4287
4288
0
  if (dns_rdataset_isassociated(&fctx->nameservers)) {
4289
0
    dns_rdataset_disassociate(&fctx->nameservers);
4290
0
  }
4291
4292
0
  if (dns_rdatatype_atparent(fctx->type)) {
4293
0
    findoptions |= DNS_DBFIND_NOEXACT;
4294
0
  }
4295
0
  result = dns_view_findzonecut(res->view, fctx->name, fname, dcname,
4296
0
              fctx->now, findoptions, true, true,
4297
0
              &fctx->nameservers, NULL);
4298
0
  FCTXTRACEN("resume_qmin findzonecut", fname, result);
4299
4300
  /*
4301
   * DNS_R_NXDOMAIN here means we have not loaded the root zone
4302
   * mirror yet - but DNS_R_NXDOMAIN is not a valid return value
4303
   * when doing recursion, we need to patch it.
4304
   *
4305
   * CNAME or DNAME means zone were added with that record
4306
   * after the start of a recursion. It means we do not have
4307
   * initialized correct hevent->foundname and have to fail.
4308
   */
4309
0
  if (result == DNS_R_NXDOMAIN || result == DNS_R_CNAME ||
4310
0
      result == DNS_R_DNAME)
4311
0
  {
4312
0
    result = DNS_R_SERVFAIL;
4313
0
  }
4314
4315
0
  if (result != ISC_R_SUCCESS) {
4316
0
    goto cleanup;
4317
0
  }
4318
0
  fcount_decr(fctx);
4319
4320
0
  dns_name_copy(fname, fctx->domain);
4321
4322
0
  result = fcount_incr(fctx, false);
4323
0
  if (result != ISC_R_SUCCESS) {
4324
0
    goto cleanup;
4325
0
  }
4326
4327
0
  dns_name_copy(dcname, fctx->qmindcname);
4328
0
  fctx->ns_ttl = fctx->nameservers.ttl;
4329
0
  fctx->ns_ttl_ok = true;
4330
4331
0
  fctx_minimize_qname(fctx);
4332
4333
0
  if (!fctx->minimized) {
4334
    /*
4335
     * We have finished minimizing, but fctx->finds was
4336
     * filled at the beginning of the run - now we need to
4337
     * clear it before sending the final query to use proper
4338
     * nameservers.
4339
     */
4340
0
    fctx_cancelqueries(fctx, false, false);
4341
0
    fctx_cleanup(fctx);
4342
0
  }
4343
4344
0
  fctx_try(fctx, true);
4345
4346
0
cleanup:
4347
0
  if (node != NULL) {
4348
0
    dns_db_detachnode(&node);
4349
0
  }
4350
0
  if (db != NULL) {
4351
0
    dns_db_detach(&db);
4352
0
  }
4353
0
  if (dns_rdataset_isassociated(&rdataset)) {
4354
0
    dns_rdataset_disassociate(&rdataset);
4355
0
  }
4356
0
  if (dns_rdataset_isassociated(&sigrdataset)) {
4357
0
    dns_rdataset_disassociate(&sigrdataset);
4358
0
  }
4359
0
  if (result != ISC_R_SUCCESS) {
4360
    /* An error occurred, tear down whole fctx */
4361
0
    fctx_done_unref(fctx, fixup_result ? ISC_R_SUCCESS : result);
4362
0
  }
4363
0
  fetchctx_detach(&fctx);
4364
0
}
4365
4366
static void
4367
0
fctx_destroy(fetchctx_t *fctx) {
4368
0
  dns_resolver_t *res = NULL;
4369
4370
0
  REQUIRE(VALID_FCTX(fctx));
4371
0
  REQUIRE(ISC_LIST_EMPTY(fctx->resps));
4372
0
  REQUIRE(ISC_LIST_EMPTY(fctx->queries));
4373
0
  REQUIRE(ISC_LIST_EMPTY(fctx->finds));
4374
0
  REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
4375
0
  REQUIRE(atomic_load_acquire(&fctx->pending) == 0);
4376
0
  REQUIRE(ISC_LIST_EMPTY(fctx->validators));
4377
0
  REQUIRE(fctx->state != fetchstate_active);
4378
4379
0
  FCTXTRACE("destroy");
4380
4381
0
  fctx->magic = 0;
4382
4383
0
  res = fctx->res;
4384
4385
0
  dec_stats(res, dns_resstatscounter_nfetch);
4386
4387
  /* Free bad */
4388
0
  ISC_LIST_FOREACH(fctx->bad, sa, link) {
4389
0
    ISC_LIST_UNLINK(fctx->bad, sa, link);
4390
0
    isc_mem_put(fctx->mctx, sa, sizeof(*sa));
4391
0
  }
4392
4393
0
  ISC_LIST_FOREACH(fctx->edns, tried, link) {
4394
0
    ISC_LIST_UNLINK(fctx->edns, tried, link);
4395
0
    isc_mem_put(fctx->mctx, tried, sizeof(*tried));
4396
0
  }
4397
4398
0
  if (fctx->nfails != NULL) {
4399
0
    isc_counter_detach(&fctx->nfails);
4400
0
  }
4401
0
  if (fctx->nvalidations != NULL) {
4402
0
    isc_counter_detach(&fctx->nvalidations);
4403
0
  }
4404
0
  isc_counter_detach(&fctx->qc);
4405
0
  if (fctx->gqc != NULL) {
4406
0
    isc_counter_detach(&fctx->gqc);
4407
0
  }
4408
0
  fcount_decr(fctx);
4409
0
  dns_message_detach(&fctx->qmessage);
4410
0
  if (dns_rdataset_isassociated(&fctx->nameservers)) {
4411
0
    dns_rdataset_disassociate(&fctx->nameservers);
4412
0
  }
4413
0
  dns_db_detach(&fctx->cache);
4414
0
  dns_adb_detach(&fctx->adb);
4415
4416
0
  dns_resolver_detach(&fctx->res);
4417
4418
0
  dns_ede_invalidate(&fctx->edectx);
4419
4420
0
  isc_mutex_destroy(&fctx->lock);
4421
4422
0
  isc_mem_free(fctx->mctx, fctx->info);
4423
0
  isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
4424
0
}
4425
4426
static void
4427
0
fctx_expired(void *arg) {
4428
0
  fetchctx_t *fctx = (fetchctx_t *)arg;
4429
4430
0
  REQUIRE(VALID_FCTX(fctx));
4431
0
  REQUIRE(fctx->tid == isc_tid());
4432
4433
0
  FCTXTRACE(isc_result_totext(ISC_R_TIMEDOUT));
4434
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4435
0
          ISC_LOG_INFO, "gave up on resolving '%s'", fctx->info);
4436
4437
0
  dns_ede_add(&fctx->edectx, DNS_EDE_NOREACHABLEAUTH, NULL);
4438
4439
0
  fctx_done_detach(&fctx, DNS_R_SERVFAIL);
4440
0
}
4441
4442
static void
4443
0
fctx_shutdown(void *arg) {
4444
0
  fetchctx_t *fctx = arg;
4445
4446
0
  REQUIRE(VALID_FCTX(fctx));
4447
4448
0
  fctx_done_unref(fctx, ISC_R_SHUTTINGDOWN);
4449
0
  fetchctx_detach(&fctx);
4450
0
}
4451
4452
static void
4453
0
fctx_start(void *arg) {
4454
0
  fetchctx_t *fctx = (fetchctx_t *)arg;
4455
4456
0
  REQUIRE(VALID_FCTX(fctx));
4457
4458
0
  FCTXTRACE("start");
4459
4460
0
  LOCK(&fctx->lock);
4461
0
  if (SHUTTINGDOWN(fctx)) {
4462
0
    UNLOCK(&fctx->lock);
4463
0
    goto detach;
4464
0
  }
4465
4466
  /*
4467
   * Normal fctx startup.
4468
   */
4469
0
  fctx->state = fetchstate_active;
4470
0
  UNLOCK(&fctx->lock);
4471
4472
  /*
4473
   * As a backstop, we also set a timer to stop the fetch
4474
   * if in-band netmgr timeouts don't work. It will fire two
4475
   * seconds after the fetch should have finished. (This
4476
   * should be enough of a gap to avoid the timer firing
4477
   * while a response is being processed normally.)
4478
   */
4479
0
  fctx_starttimer(fctx);
4480
0
  fctx_try(fctx, false);
4481
4482
0
detach:
4483
0
  fetchctx_detach(&fctx);
4484
0
}
4485
4486
/*
4487
 * Fetch Creation, Joining, and Cancellation.
4488
 */
4489
4490
static void
4491
fctx_add_event(fetchctx_t *fctx, isc_loop_t *loop, const isc_sockaddr_t *client,
4492
         dns_messageid_t id, isc_job_cb cb, void *arg,
4493
         dns_edectx_t *edectx, dns_rdataset_t *rdataset,
4494
0
         dns_rdataset_t *sigrdataset, dns_fetch_t *fetch) {
4495
0
  dns_fetchresponse_t *resp = NULL;
4496
4497
0
  FCTXTRACE("addevent");
4498
4499
0
  resp = isc_mem_get(fctx->mctx, sizeof(*resp));
4500
0
  *resp = (dns_fetchresponse_t){
4501
0
    .result = DNS_R_SERVFAIL,
4502
0
    .qtype = fctx->type,
4503
0
    .rdataset = rdataset,
4504
0
    .sigrdataset = sigrdataset,
4505
0
    .fetch = fetch,
4506
0
    .client = client,
4507
0
    .id = id,
4508
0
    .loop = loop,
4509
0
    .cb = cb,
4510
0
    .arg = arg,
4511
0
    .link = ISC_LINK_INITIALIZER,
4512
0
    .edectx = edectx,
4513
0
  };
4514
0
  isc_mem_attach(fctx->mctx, &resp->mctx);
4515
4516
0
  resp->foundname = dns_fixedname_initname(&resp->fname);
4517
4518
  /*
4519
   * Store the sigrdataset in the first resp in case it is needed
4520
   * by any of the events.
4521
   */
4522
0
  if (resp->sigrdataset != NULL) {
4523
0
    ISC_LIST_PREPEND(fctx->resps, resp, link);
4524
0
  } else {
4525
0
    ISC_LIST_APPEND(fctx->resps, resp, link);
4526
0
  }
4527
0
}
4528
4529
static void
4530
fctx_join(fetchctx_t *fctx, isc_loop_t *loop, const isc_sockaddr_t *client,
4531
    dns_messageid_t id, isc_job_cb cb, void *arg, dns_edectx_t *edectx,
4532
    dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
4533
0
    dns_fetch_t *fetch) {
4534
0
  FCTXTRACE("join");
4535
4536
0
  REQUIRE(!SHUTTINGDOWN(fctx));
4537
4538
0
  fctx_add_event(fctx, loop, client, id, cb, arg, edectx, rdataset,
4539
0
           sigrdataset, fetch);
4540
4541
0
  fetch->magic = DNS_FETCH_MAGIC;
4542
0
  fetchctx_attach(fctx, &fetch->private);
4543
0
}
4544
4545
static void
4546
0
log_ns_ttl(fetchctx_t *fctx, const char *where) {
4547
0
  char namebuf[DNS_NAME_FORMATSIZE];
4548
0
  char domainbuf[DNS_NAME_FORMATSIZE];
4549
4550
0
  dns_name_format(fctx->name, namebuf, sizeof(namebuf));
4551
0
  dns_name_format(fctx->domain, domainbuf, sizeof(domainbuf));
4552
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4553
0
          ISC_LOG_DEBUG(10),
4554
0
          "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u", fctx,
4555
0
          where, namebuf, domainbuf, fctx->ns_ttl_ok, fctx->ns_ttl);
4556
0
}
4557
4558
static isc_result_t
4559
fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
4560
      dns_rdatatype_t type, const dns_name_t *domain,
4561
      dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
4562
      unsigned int options, unsigned int depth, isc_counter_t *qc,
4563
0
      isc_counter_t *gqc, fetchctx_t **fctxp) {
4564
0
  fetchctx_t *fctx = NULL;
4565
0
  isc_result_t result;
4566
0
  isc_result_t iresult;
4567
0
  isc_interval_t interval;
4568
0
  unsigned int findoptions = 0;
4569
0
  char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 1];
4570
0
  isc_mem_t *mctx = isc_loop_getmctx(loop);
4571
0
  size_t p;
4572
0
  uint32_t nvalidations = atomic_load_relaxed(&res->maxvalidations);
4573
0
  uint32_t nfails = atomic_load_relaxed(&res->maxvalidationfails);
4574
4575
  /*
4576
   * Caller must be holding the lock for 'bucket'
4577
   */
4578
0
  REQUIRE(fctxp != NULL && *fctxp == NULL);
4579
4580
0
  fctx = isc_mem_get(mctx, sizeof(*fctx));
4581
0
  *fctx = (fetchctx_t){
4582
0
    .type = type,
4583
0
    .qmintype = type,
4584
0
    .options = options,
4585
0
    .tid = isc_tid(),
4586
0
    .state = fetchstate_active,
4587
0
    .depth = depth,
4588
0
    .qmin_labels = 1,
4589
0
    .fwdpolicy = dns_fwdpolicy_none,
4590
0
    .result = ISC_R_FAILURE,
4591
0
    .loop = loop,
4592
0
  };
4593
4594
0
  isc_mem_attach(mctx, &fctx->mctx);
4595
0
  dns_resolver_attach(res, &fctx->res);
4596
4597
0
  isc_mutex_init(&fctx->lock);
4598
4599
0
  dns_ede_init(fctx->mctx, &fctx->edectx);
4600
4601
  /*
4602
   * Make fctx->info point to a copy of a formatted string
4603
   * "name/type". FCTXTRACE won't work until this is done.
4604
   */
4605
0
  dns_name_format(name, buf, sizeof(buf));
4606
0
  p = strlcat(buf, "/", sizeof(buf));
4607
0
  INSIST(p + DNS_RDATATYPE_FORMATSIZE < sizeof(buf));
4608
0
  dns_rdatatype_format(type, buf + p, sizeof(buf) - p);
4609
0
  fctx->info = isc_mem_strdup(fctx->mctx, buf);
4610
4611
0
  FCTXTRACE("create");
4612
4613
0
  if (nfails > 0) {
4614
0
    isc_counter_create(mctx, nfails, &fctx->nfails);
4615
0
  }
4616
4617
0
  if (nvalidations > 0) {
4618
0
    isc_counter_create(mctx, nvalidations, &fctx->nvalidations);
4619
0
  }
4620
4621
0
  if (qc != NULL) {
4622
0
    isc_counter_attach(qc, &fctx->qc);
4623
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4624
0
            ISC_LOG_DEBUG(9),
4625
0
            "fctx %p(%s): attached to counter %p (%d)", fctx,
4626
0
            fctx->info, fctx->qc, isc_counter_used(fctx->qc));
4627
0
  } else {
4628
0
    isc_counter_create(fctx->mctx, res->maxqueries, &fctx->qc);
4629
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4630
0
            ISC_LOG_DEBUG(9),
4631
0
            "fctx %p(%s): created counter %p", fctx,
4632
0
            fctx->info, fctx->qc);
4633
0
  }
4634
4635
0
  if (gqc != NULL) {
4636
0
    isc_counter_attach(gqc, &fctx->gqc);
4637
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4638
0
            ISC_LOG_DEBUG(9),
4639
0
            "fctx %p(%s): attached to counter %p (%d)", fctx,
4640
0
            fctx->info, fctx->gqc,
4641
0
            isc_counter_used(fctx->gqc));
4642
0
  }
4643
4644
#if DNS_RESOLVER_TRACE
4645
  fprintf(stderr, "fetchctx__init:%s:%s:%d:%p:%p->references = 1\n",
4646
    __func__, __FILE__, __LINE__, fctx, fctx);
4647
#endif
4648
0
  isc_refcount_init(&fctx->references, 1);
4649
4650
0
  ISC_LIST_INIT(fctx->queries);
4651
0
  ISC_LIST_INIT(fctx->finds);
4652
0
  ISC_LIST_INIT(fctx->altfinds);
4653
0
  ISC_LIST_INIT(fctx->forwaddrs);
4654
0
  ISC_LIST_INIT(fctx->altaddrs);
4655
0
  ISC_LIST_INIT(fctx->forwarders);
4656
0
  ISC_LIST_INIT(fctx->bad);
4657
0
  ISC_LIST_INIT(fctx->edns);
4658
0
  ISC_LIST_INIT(fctx->validators);
4659
4660
0
  atomic_init(&fctx->attributes, 0);
4661
4662
0
  fctx->name = dns_fixedname_initname(&fctx->fname);
4663
0
  fctx->nsname = dns_fixedname_initname(&fctx->nsfname);
4664
0
  fctx->domain = dns_fixedname_initname(&fctx->dfname);
4665
0
  fctx->qminname = dns_fixedname_initname(&fctx->qminfname);
4666
0
  fctx->qmindcname = dns_fixedname_initname(&fctx->qmindcfname);
4667
0
  fctx->fwdname = dns_fixedname_initname(&fctx->fwdfname);
4668
4669
0
  dns_name_copy(name, fctx->name);
4670
0
  dns_name_copy(name, fctx->qminname);
4671
4672
0
  dns_rdataset_init(&fctx->nameservers);
4673
0
  dns_rdataset_init(&fctx->qminrrset);
4674
0
  dns_rdataset_init(&fctx->qminsigrrset);
4675
0
  dns_rdataset_init(&fctx->nsrrset);
4676
4677
0
  fctx->start = isc_time_now();
4678
0
  fctx->now = (isc_stdtime_t)fctx->start.seconds;
4679
4680
0
  if (client != NULL) {
4681
0
    isc_sockaddr_format(client, fctx->clientstr,
4682
0
            sizeof(fctx->clientstr));
4683
0
  } else {
4684
0
    strlcpy(fctx->clientstr, "<unknown>", sizeof(fctx->clientstr));
4685
0
  }
4686
4687
0
  if (domain == NULL) {
4688
0
    dns_forwarders_t *forwarders = NULL;
4689
0
    unsigned int labels;
4690
0
    const dns_name_t *fwdname = name;
4691
0
    dns_name_t suffix;
4692
4693
    /*
4694
     * DS records are found in the parent server. Strip one
4695
     * leading label from the name (to be used in finding
4696
     * the forwarder).
4697
     */
4698
0
    if (dns_rdatatype_atparent(fctx->type) &&
4699
0
        dns_name_countlabels(name) > 1)
4700
0
    {
4701
0
      dns_name_init(&suffix);
4702
0
      labels = dns_name_countlabels(name);
4703
0
      dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
4704
0
      fwdname = &suffix;
4705
0
    }
4706
4707
    /* Find the forwarder for this name. */
4708
0
    result = dns_fwdtable_find(fctx->res->view->fwdtable, fwdname,
4709
0
             &forwarders);
4710
0
    if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
4711
0
      fctx->fwdpolicy = forwarders->fwdpolicy;
4712
0
      dns_name_copy(&forwarders->name, fctx->fwdname);
4713
0
      dns_forwarders_detach(&forwarders);
4714
0
    }
4715
4716
0
    if (fctx->fwdpolicy == dns_fwdpolicy_only) {
4717
      /*
4718
       * We're in forward-only mode.  Set the query
4719
       * domain.
4720
       */
4721
0
      dns_name_copy(fctx->fwdname, fctx->domain);
4722
0
      dns_name_copy(fctx->fwdname, fctx->qmindcname);
4723
      /*
4724
       * Disable query minimization
4725
       */
4726
0
      options &= ~DNS_FETCHOPT_QMINIMIZE;
4727
0
    } else {
4728
0
      dns_fixedname_t dcfixed;
4729
0
      dns_name_t *dcname = dns_fixedname_initname(&dcfixed);
4730
4731
      /*
4732
       * The caller didn't supply a query domain and
4733
       * nameservers, and we're not in forward-only
4734
       * mode, so find the best nameservers to use.
4735
       */
4736
0
      if (dns_rdatatype_atparent(fctx->type)) {
4737
0
        findoptions |= DNS_DBFIND_NOEXACT;
4738
0
      }
4739
0
      result = dns_view_findzonecut(
4740
0
        res->view, name, fctx->fwdname, dcname,
4741
0
        fctx->now, findoptions, true, true,
4742
0
        &fctx->nameservers, NULL);
4743
0
      if (result != ISC_R_SUCCESS) {
4744
0
        goto cleanup_nameservers;
4745
0
      }
4746
4747
0
      dns_name_copy(fctx->fwdname, fctx->domain);
4748
0
      dns_name_copy(dcname, fctx->qmindcname);
4749
0
      fctx->ns_ttl = fctx->nameservers.ttl;
4750
0
      fctx->ns_ttl_ok = true;
4751
0
    }
4752
0
  } else {
4753
0
    dns_name_copy(domain, fctx->domain);
4754
0
    dns_name_copy(domain, fctx->qmindcname);
4755
0
    dns_rdataset_clone(nameservers, &fctx->nameservers);
4756
0
    fctx->ns_ttl = fctx->nameservers.ttl;
4757
0
    fctx->ns_ttl_ok = true;
4758
0
  }
4759
4760
  /*
4761
   * Exempt prefetch queries from the fetches-per-zone quota check
4762
   * also exempt QMIN fetches as the calling fetch has already
4763
   * successfully called fcount_incr for this zone.
4764
   */
4765
0
  if ((fctx->options & DNS_FETCHOPT_PREFETCH) == 0 &&
4766
0
      (fctx->options & DNS_FETCHOPT_QMINFETCH) == 0)
4767
0
  {
4768
    /*
4769
     * Are there too many simultaneous queries for this domain?
4770
     */
4771
0
    result = fcount_incr(fctx, false);
4772
0
    if (result != ISC_R_SUCCESS) {
4773
0
      result = fctx->res->quotaresp[dns_quotatype_zone];
4774
0
      inc_stats(res, dns_resstatscounter_zonequota);
4775
0
      goto cleanup_nameservers;
4776
0
    }
4777
0
  }
4778
4779
0
  log_ns_ttl(fctx, "fctx_create");
4780
4781
0
  if (!dns_name_issubdomain(fctx->name, fctx->domain)) {
4782
0
    dns_name_format(fctx->domain, buf, sizeof(buf));
4783
0
    UNEXPECTED_ERROR("'%s' is not subdomain of '%s'", fctx->info,
4784
0
         buf);
4785
0
    result = ISC_R_UNEXPECTED;
4786
0
    goto cleanup_fcount;
4787
0
  }
4788
4789
0
  dns_message_create(fctx->mctx, fctx->res->namepools[fctx->tid],
4790
0
         fctx->res->rdspools[fctx->tid],
4791
0
         DNS_MESSAGE_INTENTRENDER, &fctx->qmessage);
4792
4793
  /*
4794
   * Compute an expiration time for the entire fetch.
4795
   */
4796
0
  isc_interval_set(&interval, res->query_timeout / 1000,
4797
0
       res->query_timeout % 1000 * 1000000);
4798
0
  iresult = isc_time_nowplusinterval(&fctx->expires, &interval);
4799
0
  if (iresult != ISC_R_SUCCESS) {
4800
0
    UNEXPECTED_ERROR("isc_time_nowplusinterval: %s",
4801
0
         isc_result_totext(iresult));
4802
0
    result = ISC_R_UNEXPECTED;
4803
0
    goto cleanup_qmessage;
4804
0
  }
4805
4806
  /*
4807
   * Default retry interval initialization.  We set the interval
4808
   * now mostly so it won't be uninitialized.  It will be set to
4809
   * the correct value before a query is issued.
4810
   */
4811
0
  isc_interval_set(&fctx->interval, 2, 0);
4812
4813
  /*
4814
   * Attach to the view's cache and adb.
4815
   */
4816
0
  dns_db_attach(res->view->cachedb, &fctx->cache);
4817
0
  dns_view_getadb(res->view, &fctx->adb);
4818
4819
0
  ISC_LIST_INIT(fctx->resps);
4820
0
  fctx->magic = FCTX_MAGIC;
4821
4822
  /*
4823
   * If qname minimization is enabled we need to trim
4824
   * the name in fctx to proper length.
4825
   */
4826
0
  if ((options & DNS_FETCHOPT_QMINIMIZE) != 0) {
4827
0
    fctx->ip6arpaskip = (options & DNS_FETCHOPT_QMIN_SKIP_IP6A) !=
4828
0
              0 &&
4829
0
            dns_name_issubdomain(fctx->name, &ip6_arpa);
4830
0
    fctx_minimize_qname(fctx);
4831
0
  }
4832
4833
0
  inc_stats(res, dns_resstatscounter_nfetch);
4834
4835
0
  isc_timer_create(fctx->loop, fctx_expired, fctx, &fctx->timer);
4836
4837
0
  *fctxp = fctx;
4838
4839
0
  return ISC_R_SUCCESS;
4840
4841
0
cleanup_qmessage:
4842
0
  dns_message_detach(&fctx->qmessage);
4843
4844
0
cleanup_fcount:
4845
0
  fcount_decr(fctx);
4846
4847
0
cleanup_nameservers:
4848
0
  if (dns_rdataset_isassociated(&fctx->nameservers)) {
4849
0
    dns_rdataset_disassociate(&fctx->nameservers);
4850
0
  }
4851
0
  isc_mem_free(fctx->mctx, fctx->info);
4852
0
  if (fctx->nfails != NULL) {
4853
0
    isc_counter_detach(&fctx->nfails);
4854
0
  }
4855
0
  if (fctx->nvalidations != NULL) {
4856
0
    isc_counter_detach(&fctx->nvalidations);
4857
0
  }
4858
0
  isc_counter_detach(&fctx->qc);
4859
0
  if (fctx->gqc != NULL) {
4860
0
    isc_counter_detach(&fctx->gqc);
4861
0
  }
4862
4863
0
  dns_resolver_detach(&fctx->res);
4864
0
  isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
4865
4866
0
  return result;
4867
0
}
4868
4869
/*
4870
 * Handle Responses
4871
 */
4872
static bool
4873
0
is_lame(fetchctx_t *fctx, dns_message_t *message) {
4874
0
  if (message->rcode != dns_rcode_noerror &&
4875
0
      message->rcode != dns_rcode_yxdomain &&
4876
0
      message->rcode != dns_rcode_nxdomain)
4877
0
  {
4878
0
    return false;
4879
0
  }
4880
4881
0
  if (message->counts[DNS_SECTION_ANSWER] != 0) {
4882
0
    return false;
4883
0
  }
4884
4885
0
  if (message->counts[DNS_SECTION_AUTHORITY] == 0) {
4886
0
    return false;
4887
0
  }
4888
4889
0
  MSG_SECTION_FOREACH(message, DNS_SECTION_AUTHORITY, name) {
4890
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
4891
0
      dns_namereln_t namereln;
4892
0
      int order;
4893
0
      unsigned int labels;
4894
0
      if (rdataset->type != dns_rdatatype_ns) {
4895
0
        continue;
4896
0
      }
4897
0
      namereln = dns_name_fullcompare(name, fctx->domain,
4898
0
              &order, &labels);
4899
0
      if (namereln == dns_namereln_equal &&
4900
0
          (message->flags & DNS_MESSAGEFLAG_AA) != 0)
4901
0
      {
4902
0
        return false;
4903
0
      }
4904
0
      if (namereln == dns_namereln_subdomain) {
4905
0
        return false;
4906
0
      }
4907
0
      return true;
4908
0
    }
4909
0
  }
4910
4911
0
  return false;
4912
0
}
4913
4914
static void
4915
0
log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
4916
0
  char namebuf[DNS_NAME_FORMATSIZE];
4917
0
  char domainbuf[DNS_NAME_FORMATSIZE];
4918
0
  char addrbuf[ISC_SOCKADDR_FORMATSIZE];
4919
4920
0
  dns_name_format(fctx->name, namebuf, sizeof(namebuf));
4921
0
  dns_name_format(fctx->domain, domainbuf, sizeof(domainbuf));
4922
0
  isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf));
4923
0
  isc_log_write(DNS_LOGCATEGORY_LAME_SERVERS, DNS_LOGMODULE_RESOLVER,
4924
0
          ISC_LOG_INFO, "lame server resolving '%s' (in '%s'?): %s",
4925
0
          namebuf, domainbuf, addrbuf);
4926
0
}
4927
4928
static void
4929
0
log_formerr(fetchctx_t *fctx, const char *format, ...) {
4930
0
  char nsbuf[ISC_SOCKADDR_FORMATSIZE];
4931
0
  char msgbuf[2048];
4932
0
  va_list args;
4933
4934
0
  va_start(args, format);
4935
0
  vsnprintf(msgbuf, sizeof(msgbuf), format, args);
4936
0
  va_end(args);
4937
4938
0
  isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf));
4939
4940
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
4941
0
          ISC_LOG_NOTICE,
4942
0
          "DNS format error from %s resolving %s for %s: %s", nsbuf,
4943
0
          fctx->info, fctx->clientstr, msgbuf);
4944
0
}
4945
4946
static isc_result_t
4947
0
same_question(fetchctx_t *fctx, dns_message_t *message) {
4948
0
  dns_name_t *name = NULL;
4949
0
  dns_rdataset_t *rdataset = NULL;
4950
4951
  /*
4952
   * Caller must be holding the fctx lock.
4953
   */
4954
4955
  /*
4956
   * XXXRTH  Currently we support only one question.
4957
   */
4958
0
  if (message->counts[DNS_SECTION_QUESTION] == 0) {
4959
0
    if ((message->flags & DNS_MESSAGEFLAG_TC) != 0) {
4960
      /*
4961
       * If TC=1 and the question section is empty, we
4962
       * accept the reply message as a truncated
4963
       * answer, to be retried over TCP.
4964
       *
4965
       * It is really a FORMERR condition, but this is
4966
       * a workaround to accept replies from some
4967
       * implementations.
4968
       *
4969
       * Because the question section matching is not
4970
       * performed, the worst that could happen is
4971
       * that an attacker who gets past the ID and
4972
       * source port checks can force the use of
4973
       * TCP. This is considered an acceptable risk.
4974
       */
4975
0
      log_formerr(fctx, "empty question section, "
4976
0
            "accepting it anyway as TC=1");
4977
0
      return ISC_R_SUCCESS;
4978
0
    } else {
4979
0
      log_formerr(fctx, "empty question section");
4980
0
      return DNS_R_FORMERR;
4981
0
    }
4982
0
  } else if (message->counts[DNS_SECTION_QUESTION] > 1) {
4983
0
    log_formerr(fctx, "too many questions");
4984
0
    return DNS_R_FORMERR;
4985
0
  }
4986
4987
0
  if (ISC_LIST_EMPTY(message->sections[DNS_SECTION_QUESTION])) {
4988
0
    return ISC_R_NOMORE;
4989
0
  }
4990
0
  name = ISC_LIST_HEAD(message->sections[DNS_SECTION_QUESTION]);
4991
0
  rdataset = ISC_LIST_HEAD(name->list);
4992
0
  INSIST(rdataset != NULL);
4993
0
  INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
4994
4995
0
  if (fctx->type != rdataset->type ||
4996
0
      fctx->res->rdclass != rdataset->rdclass ||
4997
0
      !dns_name_equal(fctx->name, name))
4998
0
  {
4999
0
    char namebuf[DNS_NAME_FORMATSIZE];
5000
0
    char classbuf[DNS_RDATACLASS_FORMATSIZE];
5001
0
    char typebuf[DNS_RDATATYPE_FORMATSIZE];
5002
5003
0
    dns_name_format(name, namebuf, sizeof(namebuf));
5004
0
    dns_rdataclass_format(rdataset->rdclass, classbuf,
5005
0
              sizeof(classbuf));
5006
0
    dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
5007
0
    log_formerr(fctx, "question section mismatch: got %s/%s/%s",
5008
0
          namebuf, classbuf, typebuf);
5009
0
    return DNS_R_FORMERR;
5010
0
  }
5011
5012
0
  return ISC_R_SUCCESS;
5013
0
}
5014
5015
static void
5016
0
clone_results(fetchctx_t *fctx) {
5017
0
  dns_fetchresponse_t *hresp = NULL;
5018
5019
0
  REQUIRE(!ISC_LIST_EMPTY(fctx->resps));
5020
5021
  /*
5022
   * Set up any other resps to have the same data as the first.
5023
   * Caller must be holding the appropriate lock.
5024
   */
5025
5026
0
  FCTXTRACE("clone_results");
5027
5028
0
  ISC_LIST_FOREACH(fctx->resps, resp, link) {
5029
    /* This is the head resp; keep a pointer and move on */
5030
0
    if (hresp == NULL) {
5031
0
      hresp = ISC_LIST_HEAD(fctx->resps);
5032
0
      FCTXTRACEN("clone_results", hresp->foundname,
5033
0
           hresp->result);
5034
0
      continue;
5035
0
    }
5036
5037
0
    resp->result = hresp->result;
5038
0
    dns_name_copy(hresp->foundname, resp->foundname);
5039
0
    dns_db_attach(hresp->db, &resp->db);
5040
0
    dns_db_attachnode(hresp->node, &resp->node);
5041
5042
0
    INSIST(hresp->rdataset != NULL && resp->rdataset != NULL);
5043
0
    if (dns_rdataset_isassociated(hresp->rdataset)) {
5044
0
      dns_rdataset_clone(hresp->rdataset, resp->rdataset);
5045
0
    }
5046
5047
0
    INSIST(hresp->sigrdataset != NULL || resp->sigrdataset == NULL);
5048
0
    if (resp->sigrdataset != NULL && hresp->sigrdataset != NULL &&
5049
0
        dns_rdataset_isassociated(hresp->sigrdataset))
5050
0
    {
5051
0
      dns_rdataset_clone(hresp->sigrdataset,
5052
0
             resp->sigrdataset);
5053
0
    }
5054
0
  }
5055
5056
0
  fctx->cloned = true;
5057
0
}
5058
5059
0
#define CACHE(r)      (((r)->attributes.cache))
5060
0
#define ANSWER(r)     (((r)->attributes.answer))
5061
0
#define ANSWERSIG(r)  (((r)->attributes.answersig))
5062
0
#define EXTERNAL(r)   (((r)->attributes.external))
5063
0
#define CHAINING(r)   (((r)->attributes.chaining))
5064
0
#define CHASE(r)      (((r)->attributes.chase))
5065
0
#define CHECKNAMES(r) (((r)->attributes.checknames))
5066
5067
/*
5068
 * Cancel validators associated with '*fctx' if it is ready to be
5069
 * destroyed (i.e., no queries waiting for it and no pending ADB finds).
5070
 * Caller must hold fctx bucket lock.
5071
 *
5072
 * Requires:
5073
 *      '*fctx' is shutting down.
5074
 */
5075
static void
5076
0
maybe_cancel_validators(fetchctx_t *fctx) {
5077
0
  if (atomic_load_acquire(&fctx->pending) != 0 ||
5078
0
      atomic_load_acquire(&fctx->nqueries) != 0)
5079
0
  {
5080
0
    return;
5081
0
  }
5082
5083
0
  REQUIRE(SHUTTINGDOWN(fctx));
5084
0
  ISC_LIST_FOREACH(fctx->validators, validator, link) {
5085
0
    dns_validator_cancel(validator);
5086
0
  }
5087
0
}
5088
5089
/*
5090
 * typemap with just RRSIG(46) and NSEC(47) bits set.
5091
 *
5092
 * Bitmap calculation from dns_nsec_setbit:
5093
 *
5094
 *          46  47
5095
 *  shift = 7 - (type % 8);   0 1
5096
 *  mask = 1 << shift;    0x02  0x01
5097
 *  array[type / 8] |= mask;
5098
 *
5099
 * Window (0), bitmap length (6), and bitmap.
5100
 */
5101
static const unsigned char minimal_typemap[] = { 0, 6, 0, 0, 0, 0, 0, 0x03 };
5102
5103
static bool
5104
0
is_minimal_nsec(dns_rdataset_t *nsecset) {
5105
0
  dns_rdataset_t rdataset = DNS_RDATASET_INIT;
5106
5107
0
  dns_rdataset_clone(nsecset, &rdataset);
5108
5109
0
  DNS_RDATASET_FOREACH(&rdataset) {
5110
0
    isc_result_t result;
5111
0
    dns_rdata_t rdata = DNS_RDATA_INIT;
5112
0
    dns_rdata_nsec_t nsec;
5113
5114
0
    dns_rdataset_current(&rdataset, &rdata);
5115
0
    result = dns_rdata_tostruct(&rdata, &nsec, NULL);
5116
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
5117
5118
0
    if (nsec.len == sizeof(minimal_typemap) &&
5119
0
        memcmp(nsec.typebits, minimal_typemap, nsec.len) == 0)
5120
0
    {
5121
0
      dns_rdataset_disassociate(&rdataset);
5122
0
      return true;
5123
0
    }
5124
0
  }
5125
0
  dns_rdataset_disassociate(&rdataset);
5126
0
  return false;
5127
0
}
5128
5129
/*
5130
 * If there is a SOA record in the type map then there must be a DNSKEY.
5131
 */
5132
static bool
5133
0
check_soa_and_dnskey(dns_rdataset_t *nsecset) {
5134
0
  dns_rdataset_t rdataset = DNS_RDATASET_INIT;
5135
5136
0
  dns_rdataset_clone(nsecset, &rdataset);
5137
5138
0
  DNS_RDATASET_FOREACH(&rdataset) {
5139
0
    dns_rdata_t rdata = DNS_RDATA_INIT;
5140
0
    dns_rdataset_current(&rdataset, &rdata);
5141
0
    if (dns_nsec_typepresent(&rdata, dns_rdatatype_soa) &&
5142
0
        (!dns_nsec_typepresent(&rdata, dns_rdatatype_dnskey) ||
5143
0
         !dns_nsec_typepresent(&rdata, dns_rdatatype_ns)))
5144
0
    {
5145
0
      dns_rdataset_disassociate(&rdataset);
5146
0
      return false;
5147
0
    }
5148
0
  }
5149
0
  dns_rdataset_disassociate(&rdataset);
5150
0
  return true;
5151
0
}
5152
5153
/*
5154
 * Look for NSEC next name that starts with the label '\000'.
5155
 */
5156
static bool
5157
0
has_000_label(dns_rdataset_t *nsecset) {
5158
0
  dns_rdataset_t rdataset = DNS_RDATASET_INIT;
5159
5160
0
  dns_rdataset_clone(nsecset, &rdataset);
5161
5162
0
  DNS_RDATASET_FOREACH(&rdataset) {
5163
0
    dns_rdata_t rdata = DNS_RDATA_INIT;
5164
0
    dns_rdataset_current(&rdataset, &rdata);
5165
0
    if (rdata.length > 1 && rdata.data[0] == 1 &&
5166
0
        rdata.data[1] == 0)
5167
0
    {
5168
0
      dns_rdataset_disassociate(&rdataset);
5169
0
      return true;
5170
0
    }
5171
0
  }
5172
0
  dns_rdataset_disassociate(&rdataset);
5173
0
  return false;
5174
0
}
5175
5176
static isc_result_t
5177
0
fctx_setresult(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
5178
0
  isc_result_t eresult = ISC_R_SUCCESS;
5179
5180
0
  if (NEGATIVE(rdataset)) {
5181
0
    eresult = NXDOMAIN(rdataset) ? DNS_R_NCACHENXDOMAIN
5182
0
               : DNS_R_NCACHENXRRSET;
5183
0
  } else if (eresult == ISC_R_SUCCESS && rdataset->type != fctx->type) {
5184
0
    switch (rdataset->type) {
5185
0
    case dns_rdatatype_cname:
5186
0
      eresult = DNS_R_CNAME;
5187
0
      break;
5188
0
    case dns_rdatatype_dname:
5189
0
      eresult = DNS_R_DNAME;
5190
0
      break;
5191
0
    default:
5192
0
      break;
5193
0
    }
5194
0
  }
5195
5196
0
  return eresult;
5197
0
}
5198
5199
static inline dns_trust_t
5200
0
gettrust(dns_rdataset_t *rdataset) {
5201
0
  if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
5202
0
    return dns_trust_none;
5203
0
  }
5204
5205
0
  return rdataset->trust;
5206
0
}
5207
5208
static inline dns_rdataset_t *
5209
0
getrrsig(dns_name_t *name, dns_rdatatype_t type) {
5210
0
  for (dns_rdataset_t *sig = ISC_LIST_HEAD(name->list); sig != NULL;
5211
0
       sig = ISC_LIST_NEXT(sig, link))
5212
0
  {
5213
0
    if (dns_rdataset_issigtype(sig, type)) {
5214
0
      return sig;
5215
0
    }
5216
0
  }
5217
5218
0
  return NULL;
5219
0
}
5220
5221
static isc_result_t
5222
cache_rrset(fetchctx_t *fctx, isc_stdtime_t now, dns_name_t *name,
5223
      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
5224
      dns_dbnode_t **nodep, dns_rdataset_t *added,
5225
0
      dns_rdataset_t *addedsig, bool need_validation) {
5226
0
  isc_result_t result = ISC_R_SUCCESS;
5227
0
  unsigned int options = 0;
5228
0
  dns_dbnode_t *node = NULL;
5229
5230
0
  if (rdataset == NULL) {
5231
0
    return ISC_R_NOTFOUND;
5232
0
  }
5233
5234
  /*
5235
   * If the trust level is glue, we must be caching a referral.
5236
   * New referral data always takes precedence over the existing
5237
   * cache contents. We also force a cache update if the fctx
5238
   * has the _NOCACHED option.
5239
   */
5240
0
  if ((gettrust(rdataset) == dns_trust_glue &&
5241
0
       dns_rdataset_matchestype(rdataset, dns_rdatatype_ns)) ||
5242
0
      (fctx->options & DNS_FETCHOPT_NOCACHED) != 0)
5243
0
  {
5244
0
    options = DNS_DBADD_FORCE;
5245
0
  } else if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) {
5246
0
    options = DNS_DBADD_PREFETCH;
5247
0
  }
5248
5249
  /*
5250
   * If the node pointer points to a node, attach to it.
5251
   *
5252
   * If it points to NULL, find or create the node and pass
5253
   * it back to the caller.
5254
   *
5255
   * If there's no node pointer at all, find the node, but
5256
   * detach it before returning.
5257
   */
5258
0
  if (nodep != NULL && *nodep != NULL) {
5259
0
    dns_db_attachnode(*nodep, &node);
5260
0
  } else {
5261
0
    result = dns_db_findnode(fctx->cache, name, true, &node);
5262
0
  }
5263
5264
0
  if (result == ISC_R_SUCCESS) {
5265
0
    result = dns_db_addrdataset(fctx->cache, node, NULL, now,
5266
0
              rdataset, options, added);
5267
0
  }
5268
5269
0
  if (result == DNS_R_UNCHANGED) {
5270
    /*
5271
     * The cache wasn't updated because something was
5272
     * already there. If the data was the same as what
5273
     * we were trying to add, then sigrdataset might
5274
     * still be useful.
5275
     */
5276
0
    if (!need_validation && added != NULL &&
5277
0
        !dns_rdataset_equals(rdataset, added))
5278
0
    {
5279
      /* Skip adding the sigrdataset */
5280
0
    } else {
5281
      /* Carry on caching the sigrdataset */
5282
0
      result = ISC_R_SUCCESS;
5283
0
    }
5284
0
  }
5285
5286
0
  if (result == ISC_R_SUCCESS && sigrdataset != NULL) {
5287
0
    result = dns_db_addrdataset(fctx->cache, node, NULL, now,
5288
0
              sigrdataset, options, addedsig);
5289
0
    if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) {
5290
0
      dns__rdataset_disassociate(added);
5291
0
    }
5292
0
  }
5293
5294
0
  if (result == DNS_R_UNCHANGED) {
5295
0
    result = ISC_R_SUCCESS;
5296
0
  }
5297
5298
  /*
5299
   * If we're passing a node that we looked up back to the
5300
   * caller, then we don't detach it.
5301
   */
5302
0
  if (nodep != NULL && *nodep == NULL) {
5303
0
    *nodep = node;
5304
0
  } else if (node != NULL) {
5305
0
    dns_db_detachnode(&node);
5306
0
  }
5307
5308
0
  return result;
5309
0
}
5310
5311
static void
5312
0
delete_rrset(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type) {
5313
0
  isc_result_t result;
5314
0
  dns_dbnode_t *node = NULL;
5315
5316
0
  result = dns_db_findnode(fctx->cache, name, false, &node);
5317
0
  if (result != ISC_R_SUCCESS) {
5318
0
    return;
5319
0
  }
5320
5321
0
  dns_db_deleterdataset(fctx->cache, node, NULL, type, 0);
5322
0
  dns_db_deleterdataset(fctx->cache, node, NULL, dns_rdatatype_rrsig,
5323
0
            type);
5324
0
  dns_db_detachnode(&node);
5325
0
}
5326
5327
static void
5328
fctx_cacheauthority(fetchctx_t *fctx, dns_message_t *message,
5329
0
        isc_stdtime_t now) {
5330
0
  isc_result_t result;
5331
5332
  /*
5333
   * Cache any SOA/NS/NSEC records that happened to be validated.
5334
   */
5335
0
  MSG_SECTION_FOREACH(message, DNS_SECTION_AUTHORITY, name) {
5336
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
5337
0
      dns_rdataset_t *sigrdataset = NULL;
5338
5339
0
      if ((rdataset->type != dns_rdatatype_ns &&
5340
0
           rdataset->type != dns_rdatatype_soa &&
5341
0
           rdataset->type != dns_rdatatype_nsec) ||
5342
0
          gettrust(rdataset) != dns_trust_secure)
5343
0
      {
5344
0
        continue;
5345
0
      }
5346
5347
0
      sigrdataset = getrrsig(name, rdataset->type);
5348
0
      if (gettrust(sigrdataset) != dns_trust_secure) {
5349
0
        continue;
5350
0
      }
5351
5352
      /*
5353
       * Don't cache NSEC if missing NSEC or RRSIG types.
5354
       */
5355
0
      if (rdataset->type == dns_rdatatype_nsec &&
5356
0
          !dns_nsec_requiredtypespresent(rdataset))
5357
0
      {
5358
0
        continue;
5359
0
      }
5360
5361
      /*
5362
       * Don't cache "white lies" but do cache
5363
       * "black lies".
5364
       */
5365
0
      if (rdataset->type == dns_rdatatype_nsec &&
5366
0
          !dns_name_equal(fctx->name, name) &&
5367
0
          is_minimal_nsec(rdataset))
5368
0
      {
5369
0
        continue;
5370
0
      }
5371
5372
      /*
5373
       * Check SOA and DNSKEY consistency.
5374
       */
5375
0
      if (rdataset->type == dns_rdatatype_nsec &&
5376
0
          !check_soa_and_dnskey(rdataset))
5377
0
      {
5378
0
        continue;
5379
0
      }
5380
5381
      /*
5382
       * Look for \000 label in next name.
5383
       */
5384
0
      if (rdataset->type == dns_rdatatype_nsec &&
5385
0
          has_000_label(rdataset))
5386
0
      {
5387
0
        continue;
5388
0
      }
5389
5390
0
      result = cache_rrset(fctx, now, name, rdataset,
5391
0
               sigrdataset, NULL, NULL, NULL,
5392
0
               false);
5393
0
      if (result != ISC_R_SUCCESS) {
5394
0
        continue;
5395
0
      }
5396
0
    }
5397
0
  }
5398
0
}
5399
5400
/*
5401
 * The validator has finished.
5402
 */
5403
static void
5404
0
validated(void *arg) {
5405
0
  isc_result_t result = ISC_R_SUCCESS;
5406
0
  dns_validator_t *val = (dns_validator_t *)arg;
5407
0
  dns_valarg_t *valarg = val->arg;
5408
0
  dns_validator_t *nextval = NULL;
5409
0
  dns_adbaddrinfo_t *addrinfo = NULL;
5410
0
  dns_dbnode_t *node = NULL;
5411
0
  dns_fetchresponse_t *resp = NULL;
5412
0
  dns_rdataset_t *ardataset = NULL, *asigrdataset = NULL;
5413
0
  dns_message_t *message = NULL;
5414
0
  fetchctx_t *fctx = NULL;
5415
0
  dns_resolver_t *res = NULL;
5416
0
  isc_stdtime_t now;
5417
0
  bool done = false;
5418
0
  bool negative = (val->rdataset == NULL);
5419
0
  bool chaining = (val->result == ISC_R_SUCCESS) && !negative &&
5420
0
      CHAINING(val->rdataset);
5421
5422
0
  fctx = valarg->fctx;
5423
0
  valarg->fctx = NULL;
5424
5425
0
  REQUIRE(VALID_FCTX(fctx));
5426
0
  REQUIRE(fctx->tid == isc_tid());
5427
5428
0
  res = fctx->res;
5429
0
  addrinfo = valarg->addrinfo;
5430
5431
0
  message = val->message;
5432
0
  fctx->vresult = val->result;
5433
5434
0
  FCTXTRACE("received validation completion event");
5435
5436
0
  isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
5437
5438
0
  LOCK(&fctx->lock);
5439
5440
0
  ISC_LIST_UNLINK(fctx->validators, val, link);
5441
5442
0
  if (SHUTTINGDOWN(fctx)) {
5443
0
    goto cleanup;
5444
0
  }
5445
5446
0
  now = isc_stdtime_now();
5447
5448
  /* Validation failed. */
5449
0
  if (val->result != ISC_R_SUCCESS) {
5450
0
    FCTXTRACE("validation failed");
5451
0
    inc_stats(res, dns_resstatscounter_valfail);
5452
0
    fctx->valfail++;
5453
0
    result = fctx->vresult = val->result;
5454
0
    if (result != DNS_R_BROKENCHAIN) {
5455
0
      delete_rrset(fctx, val->name, val->type);
5456
0
    } else if (!negative) {
5457
      /*
5458
       * Cache the data as pending for later validation.
5459
       */
5460
0
      cache_rrset(fctx, now, val->name, val->rdataset,
5461
0
            val->sigrdataset, NULL, NULL, NULL, false);
5462
0
    }
5463
5464
0
    add_bad(fctx, message, addrinfo, result, badns_validation);
5465
5466
    /* Start the next validator if there is one. */
5467
0
    nextval = ISC_LIST_HEAD(fctx->validators);
5468
0
    if (nextval != NULL) {
5469
0
      goto cleanup;
5470
0
    }
5471
5472
    /* A broken trust chain isn't recoverable. */
5473
0
    if (result == DNS_R_BROKENCHAIN) {
5474
0
      done = true;
5475
0
      goto cleanup;
5476
0
    }
5477
5478
    /*
5479
     * Some other error, we can try again. We have to
5480
     * unlock the fctx before calling fctx_try().
5481
     */
5482
0
    UNLOCK(&fctx->lock);
5483
0
    fctx_try(fctx, true);
5484
0
    goto cleanup_unlocked;
5485
0
  }
5486
5487
  /*
5488
   * For non-ANY responses, and all negative and chaining responses,
5489
   * we pass an rdataset back to the caller. Otherwise the caller
5490
   * iterates the node.
5491
   */
5492
0
  resp = ISC_LIST_HEAD(fctx->resps);
5493
0
  if (resp != NULL &&
5494
0
      (negative || chaining || !dns_rdatatype_ismulti(fctx->type)))
5495
0
  {
5496
0
    ardataset = resp->rdataset;
5497
0
    asigrdataset = resp->sigrdataset;
5498
0
  }
5499
5500
  /*
5501
   * Validator proved nonexistence.
5502
   */
5503
0
  if (negative) {
5504
0
    FCTXTRACE("nonexistence validation OK");
5505
0
    inc_stats(res, dns_resstatscounter_valnegsuccess);
5506
5507
0
    result = negcache(message, fctx, val->name, now, val->optout,
5508
0
          val->secure, ardataset, &node);
5509
0
    if (result != ISC_R_SUCCESS) {
5510
0
      done = true;
5511
0
      goto cleanup;
5512
0
    }
5513
0
    goto answer_response;
5514
0
  }
5515
5516
  /*
5517
   * Validator proved a positive answer.
5518
   */
5519
0
  FCTXTRACE("validation OK");
5520
0
  inc_stats(res, dns_resstatscounter_valsuccess);
5521
5522
0
  if (val->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
5523
0
    result = dns_rdataset_addnoqname(
5524
0
      val->rdataset, val->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
5525
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
5526
0
    INSIST(val->sigrdataset != NULL);
5527
0
    val->sigrdataset->ttl = val->rdataset->ttl;
5528
0
    if (val->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
5529
0
      result = dns_rdataset_addclosest(
5530
0
        val->rdataset,
5531
0
        val->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
5532
0
      RUNTIME_CHECK(result == ISC_R_SUCCESS);
5533
0
    }
5534
0
  } else if (gettrust(val->rdataset) == dns_trust_answer) {
5535
0
    findnoqname(fctx, message, val->name, val->rdataset,
5536
0
          val->sigrdataset);
5537
0
  }
5538
5539
  /*
5540
   * The data was already cached as pending. Re-cache it as secure.
5541
   */
5542
0
  result = cache_rrset(fctx, now, val->name, val->rdataset,
5543
0
           val->sigrdataset, &node, ardataset, asigrdataset,
5544
0
           true);
5545
0
  if (result != ISC_R_SUCCESS) {
5546
0
    done = true;
5547
0
    goto cleanup;
5548
0
  }
5549
5550
  /*
5551
   * If this was an ANY query, we might have more rdatasets
5552
   * needing to be validated before we can respond.
5553
   */
5554
0
  if (!ISC_LIST_EMPTY(fctx->validators)) {
5555
0
    INSIST(!negative);
5556
0
    INSIST(dns_rdatatype_ismulti(fctx->type));
5557
5558
0
    nextval = ISC_LIST_HEAD(fctx->validators);
5559
0
    goto cleanup;
5560
0
  }
5561
5562
0
answer_response:
5563
0
  fctx_cacheauthority(fctx, message, now);
5564
5565
  /*
5566
   * Cache the wild card entry.
5567
   */
5568
0
  if (val->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL &&
5569
0
      gettrust(val->rdataset) == dns_trust_secure &&
5570
0
      gettrust(val->sigrdataset) == dns_trust_secure)
5571
0
  {
5572
0
    cache_rrset(fctx, now, dns_fixedname_name(&val->wild),
5573
0
          val->rdataset, val->sigrdataset, NULL, NULL, NULL,
5574
0
          true);
5575
0
  }
5576
5577
  /*
5578
   * We're responding with an answer, positive or negative,
5579
   * not an error.
5580
   */
5581
0
  if (resp != NULL) {
5582
0
    FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);
5583
5584
0
    resp->result = fctx_setresult(fctx, resp->rdataset);
5585
0
    dns_name_copy(val->name, resp->foundname);
5586
0
    dns_db_attach(fctx->cache, &resp->db);
5587
0
    dns_db_transfernode(fctx->cache, &node, &resp->node);
5588
0
    clone_results(fctx);
5589
0
  }
5590
5591
0
  done = true;
5592
5593
0
cleanup:
5594
0
  UNLOCK(&fctx->lock);
5595
0
cleanup_unlocked:
5596
5597
0
  if (node != NULL) {
5598
0
    dns_db_detachnode(&node);
5599
0
  }
5600
5601
0
  if (nextval != NULL) {
5602
0
    dns_validator_send(nextval);
5603
0
  }
5604
5605
0
  if (done) {
5606
0
    fctx_done_unref(fctx, result);
5607
0
  }
5608
5609
  /*
5610
   * val->name points to name on a message on one of the
5611
   * queries on the fetch context so the name has to be
5612
   * released first with a dns_validator_shutdown() call.
5613
   */
5614
0
  dns_validator_shutdown(val);
5615
0
  dns_validator_detach(&val);
5616
0
  fetchctx_detach(&fctx);
5617
0
  INSIST(node == NULL);
5618
0
}
5619
5620
static void
5621
0
fctx_log(void *arg, int level, const char *fmt, ...) {
5622
0
  char msgbuf[2048];
5623
0
  va_list args;
5624
0
  fetchctx_t *fctx = arg;
5625
5626
0
  va_start(args, fmt);
5627
0
  vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
5628
0
  va_end(args);
5629
5630
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, level,
5631
0
          "fctx %p(%s): %s", fctx, fctx->info, msgbuf);
5632
0
}
5633
5634
static void
5635
findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name,
5636
0
      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
5637
0
  isc_result_t result;
5638
0
  dns_rdata_rrsig_t rrsig;
5639
0
  unsigned int labels;
5640
0
  dns_name_t *zonename = NULL;
5641
0
  dns_fixedname_t fzonename;
5642
0
  dns_name_t *closest = NULL;
5643
0
  dns_fixedname_t fclosest;
5644
0
  dns_name_t *nearest = NULL;
5645
0
  dns_fixedname_t fnearest;
5646
0
  dns_rdatatype_t found = dns_rdatatype_none;
5647
0
  dns_name_t *noqname = NULL;
5648
0
  dns_rdatatype_t type = rdataset->type;
5649
5650
0
  FCTXTRACE("findnoqname");
5651
5652
0
  if (dns_rdatatype_issig(rdataset->type) || sigrdataset == NULL) {
5653
0
    return;
5654
0
  }
5655
5656
0
  labels = dns_name_countlabels(name);
5657
5658
0
  result = ISC_R_NOTFOUND;
5659
0
  DNS_RDATASET_FOREACH(sigrdataset) {
5660
0
    dns_rdata_t rdata = DNS_RDATA_INIT;
5661
0
    dns_rdataset_current(sigrdataset, &rdata);
5662
0
    result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5663
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
5664
    /* Wildcard has rrsig.labels < labels - 1. */
5665
0
    if (rrsig.labels + 1U >= labels) {
5666
0
      continue;
5667
0
    }
5668
0
    result = ISC_R_SUCCESS;
5669
0
    break;
5670
0
  }
5671
5672
0
  if (result != ISC_R_SUCCESS) {
5673
0
    return;
5674
0
  }
5675
5676
0
  zonename = dns_fixedname_initname(&fzonename);
5677
0
  closest = dns_fixedname_initname(&fclosest);
5678
0
  nearest = dns_fixedname_initname(&fnearest);
5679
5680
0
#define NXND(x) ((x) == ISC_R_SUCCESS)
5681
5682
0
  MSG_SECTION_FOREACH(message, DNS_SECTION_AUTHORITY, nsec) {
5683
0
    ISC_LIST_FOREACH(nsec->list, nrdataset, link) {
5684
0
      bool data = false, exists = false;
5685
0
      bool optout = false, unknown = false;
5686
0
      bool setclosest = false;
5687
0
      bool setnearest = false;
5688
5689
0
      if (!dns_rdatatype_isnsec(nrdataset->type)) {
5690
0
        continue;
5691
0
      }
5692
5693
0
      if (nrdataset->type == dns_rdatatype_nsec &&
5694
0
          NXND(dns_nsec_noexistnodata(
5695
0
            type, name, nsec, nrdataset, &exists, &data,
5696
0
            NULL, fctx_log, fctx)))
5697
0
      {
5698
0
        if (!exists) {
5699
0
          noqname = nsec;
5700
0
          found = dns_rdatatype_nsec;
5701
0
        }
5702
0
      }
5703
5704
0
      if (nrdataset->type == dns_rdatatype_nsec3 &&
5705
0
          NXND(dns_nsec3_noexistnodata(
5706
0
            type, name, nsec, nrdataset, zonename,
5707
0
            &exists, &data, &optout, &unknown,
5708
0
            &setclosest, &setnearest, closest, nearest,
5709
0
            fctx_log, fctx)))
5710
0
      {
5711
0
        if (!exists && setnearest) {
5712
0
          noqname = nsec;
5713
0
          found = dns_rdatatype_nsec3;
5714
0
        }
5715
0
      }
5716
0
    }
5717
0
  }
5718
5719
0
  if (noqname != NULL) {
5720
0
    sigrdataset = getrrsig(noqname, found);
5721
0
    if (sigrdataset == NULL) {
5722
0
      noqname = NULL;
5723
0
    }
5724
0
  }
5725
5726
0
  if (result == ISC_R_SUCCESS && noqname != NULL) {
5727
0
    (void)dns_rdataset_addnoqname(rdataset, noqname);
5728
0
  }
5729
5730
0
  return;
5731
0
}
5732
5733
static isc_result_t
5734
0
check_cacheable(dns_name_t *name, dns_rdataset_t *rdataset, bool fail) {
5735
  /* This rdataset isn't marked for caching */
5736
0
  if (!CACHE(rdataset)) {
5737
0
    return DNS_R_CONTINUE;
5738
0
  }
5739
5740
  /* See if there are any name errors */
5741
0
  if (CHECKNAMES(rdataset)) {
5742
0
    char namebuf[DNS_NAME_FORMATSIZE];
5743
0
    char typebuf[DNS_RDATATYPE_FORMATSIZE];
5744
0
    char classbuf[DNS_RDATATYPE_FORMATSIZE];
5745
5746
0
    dns_name_format(name, namebuf, sizeof(namebuf));
5747
0
    dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
5748
0
    dns_rdataclass_format(rdataset->rdclass, classbuf,
5749
0
              sizeof(classbuf));
5750
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
5751
0
            ISC_LOG_NOTICE, "check-names %s %s/%s/%s",
5752
0
            fail ? "failure" : "warning", namebuf, typebuf,
5753
0
            classbuf);
5754
0
    if (fail) {
5755
0
      if (ANSWER(rdataset)) {
5756
0
        return DNS_R_BADNAME;
5757
0
      }
5758
5759
0
      return DNS_R_CONTINUE;
5760
0
    }
5761
0
  }
5762
5763
  /*
5764
   * We do not attempt to cache or validate glue or out-of-bailiwick
5765
   * data - even if there might be some performance benefit to doing
5766
   * so - because it makes it simpler and safer.
5767
   */
5768
0
  if (EXTERNAL(rdataset)) {
5769
0
    return DNS_R_CONTINUE;
5770
0
  }
5771
5772
0
  return ISC_R_SUCCESS;
5773
0
}
5774
5775
static void
5776
fixttls(dns_view_t *view, dns_rdataset_t *rdataset,
5777
0
  dns_rdataset_t *sigrdataset) {
5778
  /*
5779
   * Enforce the configured maximum and minimum cache TTL.
5780
   */
5781
0
  if (rdataset->ttl > view->maxcachettl) {
5782
0
    rdataset->ttl = view->maxcachettl;
5783
0
  }
5784
5785
0
  if (rdataset->ttl < view->mincachettl) {
5786
0
    rdataset->ttl = view->mincachettl;
5787
0
  }
5788
5789
  /*
5790
   * Mark the rdataset as being prefetch eligible.
5791
   */
5792
0
  if (rdataset->ttl >= view->prefetch_eligible) {
5793
0
    rdataset->attributes.prefetch = true;
5794
0
  }
5795
5796
  /* Normalize the rdataset and sigrdataset TTLs */
5797
0
  if (sigrdataset != NULL) {
5798
0
    rdataset->ttl = ISC_MIN(rdataset->ttl, sigrdataset->ttl);
5799
0
    sigrdataset->ttl = rdataset->ttl;
5800
0
  }
5801
0
}
5802
5803
static isc_result_t
5804
rctx_cache_secure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
5805
      dns_dbnode_t *node, dns_rdataset_t *rdataset,
5806
0
      dns_rdataset_t *sigrdataset, bool need_validation) {
5807
0
  isc_result_t result;
5808
0
  fetchctx_t *fctx = rctx->fctx;
5809
0
  resquery_t *query = rctx->query;
5810
0
  dns_rdataset_t *ardataset = NULL, *asigset = NULL;
5811
0
  dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps);
5812
5813
  /*
5814
   * RRSIGs are validated as part of validating the type they cover.
5815
   */
5816
0
  if (dns_rdatatype_issig(rdataset->type)) {
5817
0
    return ISC_R_SUCCESS;
5818
0
  }
5819
5820
  /*
5821
   * Ignore unrelated non-answer rdatasets that are missing
5822
   * signatures.
5823
   */
5824
0
  if (sigrdataset == NULL && need_validation && !ANSWER(rdataset)) {
5825
0
    return ISC_R_SUCCESS;
5826
0
  }
5827
5828
  /*
5829
   * Mark this rdataset/sigrdataset pair as "pending".
5830
   */
5831
0
  if (rdataset->trust == dns_trust_additional) {
5832
0
    rdataset->trust = dns_trust_pending_additional;
5833
0
  } else {
5834
0
    rdataset->trust = dns_trust_pending_answer;
5835
0
  }
5836
5837
0
  if (sigrdataset != NULL) {
5838
0
    sigrdataset->trust = rdataset->trust;
5839
0
  }
5840
5841
0
  if (ANSWER(rdataset) && need_validation) {
5842
0
    if (!dns_rdatatype_ismulti(fctx->type)) {
5843
      /*
5844
       * This is The Answer.  We will validate it,
5845
       * but first we finish caching the rest of the
5846
       * response; it may contain useful keys.
5847
       */
5848
0
      INSIST(rctx->vrdataset == NULL &&
5849
0
             rctx->vsigrdataset == NULL);
5850
0
      rctx->vrdataset = rdataset;
5851
0
      rctx->vsigrdataset = sigrdataset;
5852
0
    } else {
5853
      /*
5854
       * This is one of (potentially) multiple answers to
5855
       * an ANY query.  To keep things simple, we just
5856
       * start the validator right away rather than
5857
       * caching first and having to remember which
5858
       * rdatasets needed validation.
5859
       */
5860
0
      valcreate(fctx, message, query->addrinfo, name,
5861
0
          rdataset->type, rdataset, sigrdataset);
5862
0
    }
5863
0
  } else {
5864
0
    if (ANSWER(rdataset)) {
5865
      /*
5866
       * We're not validating, but the client might
5867
       * be, so look for the NOQNAME proof.
5868
       */
5869
0
      findnoqname(fctx, message, name, rdataset, sigrdataset);
5870
5871
      /*
5872
       * If this was not an ANY query - or if it was,
5873
       * but we got a CNAME/DNAME - then we need to
5874
       * set up rdatasets to send back to the caller.
5875
       */
5876
0
      if (resp != NULL &&
5877
0
          (!dns_rdatatype_ismulti(fctx->type) ||
5878
0
           CHAINING(rdataset)))
5879
0
      {
5880
0
        ardataset = resp->rdataset;
5881
0
        asigset = resp->sigrdataset;
5882
0
      }
5883
0
    }
5884
5885
    /*
5886
     * In this case we cache the rdataset and sigrdataset
5887
     * (if any) in two steps, so we can do an extra check
5888
     * in-between.
5889
     */
5890
5891
0
    result = cache_rrset(fctx, rctx->now, name, rdataset,
5892
0
             sigrdataset, &node, ardataset, asigset,
5893
0
             need_validation);
5894
0
    if (result != ISC_R_SUCCESS) {
5895
0
      return result;
5896
0
    }
5897
0
  }
5898
5899
0
  return ISC_R_SUCCESS;
5900
0
}
5901
5902
static isc_result_t
5903
rctx_cache_insecure(respctx_t *rctx, dns_message_t *message, dns_name_t *name,
5904
        dns_dbnode_t *node, dns_rdataset_t *rdataset,
5905
0
        dns_rdataset_t *sigrdataset) {
5906
0
  isc_result_t result;
5907
0
  fetchctx_t *fctx = rctx->fctx;
5908
0
  dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps);
5909
0
  dns_rdataset_t *added = NULL;
5910
5911
  /*
5912
   * If this was not an ANY query - or if it was, but we got a
5913
   * CNAME/DNAME - then we need to set up an rdataset to send
5914
   * back to the caller.
5915
   */
5916
0
  if (resp != NULL &&
5917
0
      (!dns_rdatatype_ismulti(fctx->type) || CHAINING(rdataset)))
5918
0
  {
5919
0
    if (ANSWER(rdataset)) {
5920
0
      added = resp->rdataset;
5921
0
    } else if (ANSWERSIG(rdataset)) {
5922
0
      added = resp->sigrdataset;
5923
0
    }
5924
0
  }
5925
5926
  /*
5927
   * Look for the NOQNAME proof.
5928
   */
5929
0
  if (ANSWER(rdataset)) {
5930
0
    findnoqname(fctx, message, name, rdataset, sigrdataset);
5931
0
  }
5932
5933
  /*
5934
   * Cache the rdataset.
5935
   */
5936
0
  result = cache_rrset(fctx, rctx->now, name, rdataset, NULL, &node,
5937
0
           added, NULL, NULL);
5938
5939
0
  return result;
5940
0
}
5941
5942
static isc_result_t
5943
0
rctx_cachename(respctx_t *rctx, dns_message_t *message, dns_name_t *name) {
5944
0
  isc_result_t result;
5945
0
  fetchctx_t *fctx = rctx->fctx;
5946
0
  resquery_t *query = rctx->query;
5947
0
  dns_resolver_t *res = fctx->res;
5948
0
  dns_rdataset_t *sigrdataset = NULL;
5949
0
  dns_dbnode_t *node = NULL;
5950
5951
0
  FCTXTRACE("rctx_cachename");
5952
5953
  /*
5954
   * The appropriate bucket lock must be held.
5955
   */
5956
5957
  /*
5958
   * Is DNSSEC validation required for this name?
5959
   */
5960
0
  bool secure_domain = issecuredomain(fctx, name, fctx->type, rctx->now,
5961
0
              NULL);
5962
0
  bool need_validation = secure_domain &&
5963
0
             ((fctx->options & DNS_FETCHOPT_NOVALIDATE) == 0);
5964
5965
  /*
5966
   * Find or create the cache node.
5967
   */
5968
0
  result = dns_db_findnode(fctx->cache, name, true, &node);
5969
0
  if (result != ISC_R_SUCCESS) {
5970
0
    return result;
5971
0
  }
5972
5973
  /*
5974
   * Cache or validate each cacheable rdataset.
5975
   */
5976
0
  bool fail = ((res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
5977
0
  ISC_LIST_FOREACH(name->list, rdataset, link) {
5978
0
    result = check_cacheable(name, rdataset, fail);
5979
0
    if (result == DNS_R_CONTINUE) {
5980
0
      result = ISC_R_SUCCESS;
5981
0
      continue;
5982
0
    } else if (result != ISC_R_SUCCESS) {
5983
0
      goto cleanup;
5984
0
    }
5985
5986
    /* Find the signature for this rdataset */
5987
0
    sigrdataset = getrrsig(name, rdataset->type);
5988
5989
    /*
5990
     * Make the TTL consistent with the configured
5991
     * maximum and minimum
5992
     */
5993
0
    fixttls(res->view, rdataset, sigrdataset);
5994
5995
0
    if (secure_domain && gettrust(rdataset) != dns_trust_glue) {
5996
      /*
5997
       * If this is a secure domain and the rdataset
5998
       * isn't glue, start a validator. The data will
5999
       * be cached when the validator finishes.
6000
       */
6001
0
      result = rctx_cache_secure(rctx, message, name, node,
6002
0
               rdataset, sigrdataset,
6003
0
               need_validation);
6004
0
    } else {
6005
      /* Insecure domain or glue: cache the data now. */
6006
0
      result = rctx_cache_insecure(rctx, message, name, node,
6007
0
                 rdataset, sigrdataset);
6008
0
    }
6009
0
    if (result != ISC_R_SUCCESS) {
6010
0
      goto cleanup;
6011
0
    }
6012
0
  }
6013
6014
  /*
6015
   * If there was a delayed validation set up in
6016
   * rctx_cache_secure(), run it now.
6017
   */
6018
0
  if (rctx->vrdataset != NULL) {
6019
0
    dns_rdatatype_t vtype = fctx->type;
6020
0
    if (CHAINING(rctx->vrdataset)) {
6021
0
      vtype = rctx->vrdataset->type;
6022
0
      INSIST(dns_rdatatype_isalias(vtype));
6023
0
    }
6024
6025
0
    valcreate(fctx, message, query->addrinfo, name, vtype,
6026
0
        rctx->vrdataset, rctx->vsigrdataset);
6027
0
    rctx->vrdataset = NULL;
6028
0
    rctx->vsigrdataset = NULL;
6029
0
    goto cleanup;
6030
0
  }
6031
6032
  /*
6033
   * We're not validating and have an answer ready; pass
6034
   * it back to the caller.
6035
   */
6036
0
  if (!need_validation && name->attributes.answer && !HAVE_ANSWER(fctx)) {
6037
0
    dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps);
6038
0
    if (resp != NULL) {
6039
0
      isc_result_t eresult = ISC_R_SUCCESS;
6040
6041
0
      if (dns_rdataset_isassociated(resp->rdataset)) {
6042
0
        eresult = fctx_setresult(fctx, resp->rdataset);
6043
0
      }
6044
6045
0
      resp->result = eresult;
6046
0
      dns_name_copy(name, resp->foundname);
6047
0
      dns_db_attach(fctx->cache, &resp->db);
6048
0
      dns_db_transfernode(fctx->cache, &node, &resp->node);
6049
0
      clone_results(fctx);
6050
6051
0
      FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);
6052
0
    }
6053
0
  }
6054
6055
0
cleanup:
6056
0
  if (node != NULL) {
6057
0
    dns_db_detachnode(&node);
6058
0
  }
6059
6060
0
  return result;
6061
0
}
6062
6063
static isc_result_t
6064
0
rctx_cachemessage(respctx_t *rctx) {
6065
0
  isc_result_t result;
6066
0
  fetchctx_t *fctx = rctx->fctx;
6067
0
  resquery_t *query = rctx->query;
6068
0
  dns_message_t *message = query->rmessage;
6069
6070
0
  FCTXTRACE("rctx_cachemessage");
6071
6072
0
  FCTX_ATTR_CLR(fctx, FCTX_ATTR_WANTCACHE);
6073
6074
0
  LOCK(&fctx->lock);
6075
6076
0
  for (dns_section_t section = DNS_SECTION_ANSWER;
6077
0
       section <= DNS_SECTION_ADDITIONAL; section++)
6078
0
  {
6079
0
    MSG_SECTION_FOREACH(message, section, name) {
6080
0
      if (name->attributes.cache) {
6081
0
        result = rctx_cachename(rctx, message, name);
6082
0
        if (result != ISC_R_SUCCESS) {
6083
0
          goto cleanup;
6084
0
        }
6085
0
      }
6086
0
    }
6087
0
  }
6088
6089
0
cleanup:
6090
0
  UNLOCK(&fctx->lock);
6091
0
  return result;
6092
0
}
6093
6094
/*
6095
 * Call dns_ncache_add() and then compute an appropriate eresult.
6096
 */
6097
static isc_result_t
6098
negcache(dns_message_t *message, fetchctx_t *fctx, const dns_name_t *name,
6099
   isc_stdtime_t now, bool optout, bool secure, dns_rdataset_t *added,
6100
0
   dns_dbnode_t **nodep) {
6101
0
  isc_result_t result;
6102
0
  dns_ttl_t minttl = fctx->res->view->minncachettl;
6103
0
  dns_ttl_t maxttl = fctx->res->view->maxncachettl;
6104
0
  dns_rdatatype_t covers = fctx->type;
6105
0
  dns_db_t *cache = fctx->cache;
6106
0
  dns_dbnode_t *node = NULL;
6107
0
  dns_rdataset_t rdataset = DNS_RDATASET_INIT;
6108
6109
  /* Set up a placeholder in case added was NULL */
6110
0
  if (added == NULL) {
6111
0
    added = &rdataset;
6112
0
  }
6113
6114
  /*
6115
   * Cache DS NXDOMAIN separately to other types.
6116
   */
6117
0
  if (message->rcode == dns_rcode_nxdomain &&
6118
0
      fctx->type != dns_rdatatype_ds)
6119
0
  {
6120
0
    covers = dns_rdatatype_any;
6121
0
  }
6122
6123
  /*
6124
   * If the request was for an SOA record, set the cache time
6125
   * to zero to facilitate locating the containing zone of
6126
   * an arbitrary zone.
6127
   */
6128
0
  if (fctx->type == dns_rdatatype_soa && covers == dns_rdatatype_any &&
6129
0
      fctx->res->zero_no_soa_ttl)
6130
0
  {
6131
0
    maxttl = 0;
6132
0
  }
6133
6134
  /*
6135
   * Don't warn about QNAME minimization NXDOMAIN errors
6136
   * if the final result is NXDOMAIN anyway.
6137
   */
6138
0
  if (!fctx->force_qmin_warning && message->rcode == dns_rcode_nxdomain &&
6139
0
      (fctx->qmin_warning == DNS_R_NXDOMAIN ||
6140
0
       fctx->qmin_warning == DNS_R_NCACHENXDOMAIN))
6141
0
  {
6142
0
    fctx->qmin_warning = ISC_R_SUCCESS;
6143
0
  }
6144
6145
  /*
6146
   * Cache the negative entry.
6147
   */
6148
0
  result = dns_db_findnode(fctx->cache, name, true, &node);
6149
0
  if (result != ISC_R_SUCCESS) {
6150
0
    return result;
6151
0
  }
6152
6153
0
  result = dns_ncache_add(message, cache, node, covers, now, minttl,
6154
0
        maxttl, optout, secure, added);
6155
6156
0
  if (added == &rdataset && dns_rdataset_isassociated(added)) {
6157
0
    dns_rdataset_disassociate(added);
6158
0
  }
6159
6160
0
  *nodep = node;
6161
0
  return result;
6162
0
}
6163
6164
/*
6165
 * rctx_ncache():
6166
 * Cache the negatively cacheable parts of the message.  This may
6167
 * also cause work to be queued to the DNSSEC validator.
6168
 */
6169
static void
6170
0
rctx_ncache(respctx_t *rctx) {
6171
0
  isc_result_t result = ISC_R_SUCCESS;
6172
0
  fetchctx_t *fctx = rctx->fctx;
6173
0
  dns_name_t *name = fctx->name;
6174
0
  dns_message_t *message = rctx->query->rmessage;
6175
0
  dns_adbaddrinfo_t *addrinfo = rctx->query->addrinfo;
6176
0
  dns_dbnode_t *node = NULL;
6177
0
  dns_fetchresponse_t *resp = NULL;
6178
0
  dns_rdataset_t *added = NULL;
6179
6180
0
  FCTXTRACE("rctx_ncache");
6181
6182
0
  if (!WANTNCACHE(fctx)) {
6183
0
    goto done;
6184
0
  }
6185
6186
0
  FCTX_ATTR_CLR(fctx, FCTX_ATTR_WANTNCACHE);
6187
6188
  /*
6189
   * XXXMPA remove when we follow cnames and adjust the setting
6190
   * of FCTX_ATTR_WANTNCACHE in rctx_answer_none().
6191
   */
6192
0
  INSIST(message->counts[DNS_SECTION_ANSWER] == 0);
6193
6194
  /*
6195
   * Is DNSSEC validation required for this name?
6196
   */
6197
0
  bool secure_domain = issecuredomain(fctx, name, fctx->type, rctx->now,
6198
0
              NULL);
6199
0
  bool need_validation = secure_domain &&
6200
0
             ((fctx->options & DNS_FETCHOPT_NOVALIDATE) == 0);
6201
6202
0
  if (secure_domain) {
6203
    /*
6204
     * Mark all rdatasets as pending. (We do this for
6205
     * any domain under a trust anchor, regardless
6206
     * of whether we're actually validating.)
6207
     */
6208
0
    MSG_SECTION_FOREACH(message, DNS_SECTION_AUTHORITY, tname) {
6209
0
      ISC_LIST_FOREACH(tname->list, trdataset, link) {
6210
0
        trdataset->trust = dns_trust_pending_answer;
6211
0
      }
6212
0
    }
6213
0
  }
6214
6215
0
  if (need_validation) {
6216
    /*
6217
     * Start the validator for the negative response. It
6218
     * will call validated() on completion; the caching of
6219
     * negative answers will be done then.
6220
     */
6221
0
    valcreate(fctx, message, addrinfo, name, fctx->type, NULL,
6222
0
        NULL);
6223
0
    goto done;
6224
0
  }
6225
6226
  /*
6227
   * Cache the negative answer, and copy it into the fetch response.
6228
   */
6229
0
  LOCK(&fctx->lock);
6230
0
  resp = ISC_LIST_HEAD(fctx->resps);
6231
0
  if (!HAVE_ANSWER(fctx) && resp != NULL) {
6232
0
    added = resp->rdataset;
6233
0
  }
6234
6235
0
  result = negcache(message, fctx, name, rctx->now, false, false, added,
6236
0
        &node);
6237
0
  if (result != ISC_R_SUCCESS || HAVE_ANSWER(fctx)) {
6238
0
    goto unlock;
6239
0
  }
6240
6241
0
  FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);
6242
0
  if (resp != NULL) {
6243
0
    resp->result = fctx_setresult(fctx, resp->rdataset);
6244
0
    dns_name_copy(name, resp->foundname);
6245
0
    dns_db_attach(fctx->cache, &resp->db);
6246
0
    dns_db_transfernode(fctx->cache, &node, &resp->node);
6247
0
    clone_results(fctx);
6248
0
  }
6249
6250
0
unlock:
6251
0
  UNLOCK(&fctx->lock);
6252
6253
0
  if (node != NULL) {
6254
0
    dns_db_detachnode(&node);
6255
0
  }
6256
6257
0
done:
6258
0
  if (result != ISC_R_SUCCESS) {
6259
0
    FCTXTRACE3("rctx_ncache complete", result);
6260
0
  }
6261
0
}
6262
6263
static void
6264
mark_related(dns_name_t *name, dns_rdataset_t *rdataset, bool external,
6265
0
       bool gluing) {
6266
0
  name->attributes.cache = true;
6267
0
  if (gluing) {
6268
0
    rdataset->trust = dns_trust_glue;
6269
    /*
6270
     * Glue with 0 TTL causes problems.  We force the TTL to
6271
     * 1 second to prevent this.
6272
     */
6273
0
    if (rdataset->ttl == 0) {
6274
0
      rdataset->ttl = 1;
6275
0
    }
6276
0
  } else {
6277
0
    rdataset->trust = dns_trust_additional;
6278
0
  }
6279
6280
  /*
6281
   * Avoid infinite loops by only marking new rdatasets.
6282
   */
6283
0
  if (!CACHE(rdataset)) {
6284
0
    name->attributes.chase = true;
6285
0
    rdataset->attributes.chase = true;
6286
0
  }
6287
0
  rdataset->attributes.cache = true;
6288
0
  if (external) {
6289
0
    rdataset->attributes.external = true;
6290
0
  }
6291
0
}
6292
6293
/*
6294
 * Returns true if 'name' is external to the namespace for which
6295
 * the server being queried can answer, either because it's not a
6296
 * subdomain or because it's below a forward declaration or a
6297
 * locally served zone.
6298
 */
6299
static inline bool
6300
0
name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
6301
0
  isc_result_t result;
6302
0
  dns_forwarders_t *forwarders = NULL;
6303
0
  dns_name_t *apex = NULL;
6304
0
  dns_name_t suffix;
6305
0
  dns_zone_t *zone = NULL;
6306
0
  unsigned int labels;
6307
0
  dns_namereln_t rel;
6308
6309
0
  apex = (ISDUALSTACK(fctx->addrinfo) || !ISFORWARDER(fctx->addrinfo))
6310
0
           ? fctx->domain
6311
0
           : fctx->fwdname;
6312
6313
  /*
6314
   * The name is outside the queried namespace.
6315
   */
6316
0
  rel = dns_name_fullcompare(name, apex, &(int){ 0 },
6317
0
           &(unsigned int){ 0U });
6318
0
  if (rel != dns_namereln_subdomain && rel != dns_namereln_equal) {
6319
0
    return true;
6320
0
  }
6321
6322
  /*
6323
   * If the record lives in the parent zone, adjust the name so we
6324
   * look for the correct zone or forward clause.
6325
   */
6326
0
  labels = dns_name_countlabels(name);
6327
0
  if (dns_rdatatype_atparent(type) && labels > 1U) {
6328
0
    dns_name_init(&suffix);
6329
0
    dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
6330
0
    name = &suffix;
6331
0
  } else if (rel == dns_namereln_equal) {
6332
    /* If 'name' is 'apex', no further checking is needed. */
6333
0
    return false;
6334
0
  }
6335
6336
  /*
6337
   * If there is a locally served zone between 'apex' and 'name'
6338
   * then don't cache.
6339
   */
6340
0
  dns_ztfind_t options = DNS_ZTFIND_NOEXACT | DNS_ZTFIND_MIRROR;
6341
0
  result = dns_view_findzone(fctx->res->view, name, options, &zone);
6342
0
  if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
6343
0
    dns_name_t *zname = dns_zone_getorigin(zone);
6344
0
    dns_namereln_t reln = dns_name_fullcompare(
6345
0
      zname, apex, &(int){ 0 }, &(unsigned int){ 0U });
6346
0
    dns_zone_detach(&zone);
6347
0
    if (reln == dns_namereln_subdomain) {
6348
0
      return true;
6349
0
    }
6350
0
  }
6351
6352
  /*
6353
   * Look for a forward declaration below 'name'.
6354
   */
6355
0
  result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
6356
0
           &forwarders);
6357
6358
0
  if (ISFORWARDER(fctx->addrinfo)) {
6359
    /*
6360
     * See if the forwarder declaration is better.
6361
     */
6362
0
    if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
6363
0
      bool better = !dns_name_equal(&forwarders->name,
6364
0
                  fctx->fwdname);
6365
0
      dns_forwarders_detach(&forwarders);
6366
0
      return better;
6367
0
    }
6368
6369
    /*
6370
     * If the lookup failed, the configuration must have
6371
     * changed: play it safe and don't cache.
6372
     */
6373
0
    return true;
6374
0
  } else if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
6375
    /*
6376
     * If 'name' is covered by a 'forward only' clause then we
6377
     * can't cache this response.
6378
     */
6379
0
    bool nocache = (forwarders->fwdpolicy == dns_fwdpolicy_only &&
6380
0
        !ISC_LIST_EMPTY(forwarders->fwdrs));
6381
0
    dns_forwarders_detach(&forwarders);
6382
0
    return nocache;
6383
0
  }
6384
6385
0
  return false;
6386
0
}
6387
6388
static isc_result_t
6389
check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
6390
0
        dns_rdataset_t *found, dns_section_t section) {
6391
0
  respctx_t *rctx = arg;
6392
0
  fetchctx_t *fctx = rctx->fctx;
6393
0
  isc_result_t result;
6394
0
  dns_name_t *name = NULL;
6395
0
  bool external;
6396
0
  dns_rdatatype_t rtype;
6397
0
  bool gluing;
6398
6399
0
  REQUIRE(VALID_FCTX(fctx));
6400
6401
#if CHECK_FOR_GLUE_IN_ANSWER
6402
  if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a) {
6403
    return ISC_R_SUCCESS;
6404
  }
6405
#endif /* if CHECK_FOR_GLUE_IN_ANSWER */
6406
6407
0
  gluing = (GLUING(fctx) || (fctx->type == dns_rdatatype_ns &&
6408
0
           dns_name_equal(fctx->name, dns_rootname)));
6409
6410
0
  result = dns_message_findname(rctx->query->rmessage, section, addname,
6411
0
              dns_rdatatype_any, 0, &name, NULL);
6412
0
  if (result == ISC_R_SUCCESS) {
6413
0
    external = name_external(name, type, fctx);
6414
0
    if (type == dns_rdatatype_a) {
6415
0
      ISC_LIST_FOREACH(name->list, rdataset, link) {
6416
0
        if (dns_rdatatype_issig(rdataset->type)) {
6417
0
          rtype = rdataset->covers;
6418
0
        } else {
6419
0
          rtype = rdataset->type;
6420
0
        }
6421
0
        if (dns_rdatatype_isaddr(rtype)) {
6422
0
          mark_related(name, rdataset, external,
6423
0
                 gluing);
6424
0
        }
6425
0
      }
6426
0
    } else {
6427
0
      dns_rdataset_t *rdataset = NULL;
6428
0
      result = dns_message_findtype(name, type, 0, &rdataset);
6429
0
      if (result == ISC_R_SUCCESS) {
6430
0
        mark_related(name, rdataset, external, gluing);
6431
0
        if (found != NULL) {
6432
0
          dns_rdataset_clone(rdataset, found);
6433
0
        }
6434
        /*
6435
         * Do we have its SIG too?
6436
         */
6437
0
        rdataset = NULL;
6438
0
        result = dns_message_findtype(
6439
0
          name, dns_rdatatype_rrsig, type,
6440
0
          &rdataset);
6441
0
        if (result == ISC_R_SUCCESS) {
6442
0
          mark_related(name, rdataset, external,
6443
0
                 gluing);
6444
0
        }
6445
0
      }
6446
0
    }
6447
0
  }
6448
6449
0
  return ISC_R_SUCCESS;
6450
0
}
6451
6452
static isc_result_t
6453
check_related(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
6454
0
        dns_rdataset_t *found DNS__DB_FLARG) {
6455
0
  return check_section(arg, addname, type, found, DNS_SECTION_ADDITIONAL);
6456
0
}
6457
6458
#ifndef CHECK_FOR_GLUE_IN_ANSWER
6459
#define CHECK_FOR_GLUE_IN_ANSWER 0
6460
#endif /* ifndef CHECK_FOR_GLUE_IN_ANSWER */
6461
6462
#if CHECK_FOR_GLUE_IN_ANSWER
6463
static isc_result_t
6464
check_answer(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
6465
       dns_rdataset_t *found) {
6466
  return check_section(arg, addname, type, found, DNS_SECTION_ANSWER);
6467
}
6468
#endif /* if CHECK_FOR_GLUE_IN_ANSWER */
6469
6470
static bool
6471
is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
6472
0
       dns_rdataset_t *rdataset) {
6473
0
  isc_result_t result;
6474
0
  dns_rdata_t rdata = DNS_RDATA_INIT;
6475
0
  struct in_addr ina;
6476
0
  struct in6_addr in6a;
6477
0
  isc_netaddr_t netaddr;
6478
0
  char addrbuf[ISC_NETADDR_FORMATSIZE];
6479
0
  char namebuf[DNS_NAME_FORMATSIZE];
6480
0
  char classbuf[64];
6481
0
  char typebuf[64];
6482
0
  int match;
6483
6484
  /* By default, we allow any addresses. */
6485
0
  if (view->denyansweracl == NULL) {
6486
0
    return true;
6487
0
  }
6488
6489
  /*
6490
   * If the owner name matches one in the exclusion list, either
6491
   * exactly or partially, allow it.
6492
   */
6493
0
  if (dns_nametree_covered(view->answeracl_exclude, name, NULL, 0)) {
6494
0
    return true;
6495
0
  }
6496
6497
  /*
6498
   * Otherwise, search the filter list for a match for each
6499
   * address record.  If a match is found, the address should be
6500
   * filtered, so should the entire answer.
6501
   */
6502
0
  DNS_RDATASET_FOREACH(rdataset) {
6503
0
    dns_rdata_reset(&rdata);
6504
0
    dns_rdataset_current(rdataset, &rdata);
6505
0
    if (rdataset->type == dns_rdatatype_a) {
6506
0
      INSIST(rdata.length == sizeof(ina.s_addr));
6507
0
      memmove(&ina.s_addr, rdata.data, sizeof(ina.s_addr));
6508
0
      isc_netaddr_fromin(&netaddr, &ina);
6509
0
    } else {
6510
0
      INSIST(rdata.length == sizeof(in6a.s6_addr));
6511
0
      memmove(in6a.s6_addr, rdata.data, sizeof(in6a.s6_addr));
6512
0
      isc_netaddr_fromin6(&netaddr, &in6a);
6513
0
    }
6514
6515
0
    result = dns_acl_match(&netaddr, NULL, view->denyansweracl,
6516
0
               view->aclenv, &match, NULL);
6517
0
    if (result == ISC_R_SUCCESS && match > 0) {
6518
0
      isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
6519
0
      dns_name_format(name, namebuf, sizeof(namebuf));
6520
0
      dns_rdatatype_format(rdataset->type, typebuf,
6521
0
               sizeof(typebuf));
6522
0
      dns_rdataclass_format(rdataset->rdclass, classbuf,
6523
0
                sizeof(classbuf));
6524
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
6525
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
6526
0
              "answer address %s denied for %s/%s/%s",
6527
0
              addrbuf, namebuf, typebuf, classbuf);
6528
0
      return false;
6529
0
    }
6530
0
  }
6531
6532
0
  return true;
6533
0
}
6534
6535
static bool
6536
is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
6537
0
      dns_rdataset_t *rdataset, bool *chainingp) {
6538
0
  isc_result_t result;
6539
0
  dns_name_t *tname = NULL;
6540
0
  dns_rdata_cname_t cname;
6541
0
  dns_rdata_dname_t dname;
6542
0
  dns_view_t *view = fctx->res->view;
6543
0
  dns_rdata_t rdata = DNS_RDATA_INIT;
6544
0
  unsigned int nlabels;
6545
0
  dns_fixedname_t fixed;
6546
0
  dns_name_t prefix;
6547
0
  int order;
6548
6549
0
  REQUIRE(rdataset != NULL);
6550
0
  REQUIRE(dns_rdatatype_isalias(rdataset->type));
6551
6552
  /*
6553
   * By default, we allow any target name.
6554
   * If newqname != NULL we also need to extract the newqname.
6555
   */
6556
0
  if (chainingp == NULL && view->denyanswernames == NULL) {
6557
0
    return true;
6558
0
  }
6559
6560
0
  result = dns_rdataset_first(rdataset);
6561
0
  RUNTIME_CHECK(result == ISC_R_SUCCESS);
6562
0
  dns_rdataset_current(rdataset, &rdata);
6563
0
  switch (rdataset->type) {
6564
0
  case dns_rdatatype_cname:
6565
0
    result = dns_rdata_tostruct(&rdata, &cname, NULL);
6566
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
6567
0
    tname = &cname.cname;
6568
0
    break;
6569
0
  case dns_rdatatype_dname:
6570
0
    if (dns_name_fullcompare(qname, rname, &order, &nlabels) !=
6571
0
        dns_namereln_subdomain)
6572
0
    {
6573
0
      return true;
6574
0
    }
6575
0
    result = dns_rdata_tostruct(&rdata, &dname, NULL);
6576
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
6577
0
    dns_name_init(&prefix);
6578
0
    tname = dns_fixedname_initname(&fixed);
6579
0
    nlabels = dns_name_countlabels(rname);
6580
0
    dns_name_split(qname, nlabels, &prefix, NULL);
6581
0
    result = dns_name_concatenate(&prefix, &dname.dname, tname);
6582
0
    if (result == DNS_R_NAMETOOLONG) {
6583
0
      SET_IF_NOT_NULL(chainingp, true);
6584
0
      return true;
6585
0
    }
6586
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
6587
0
    break;
6588
0
  default:
6589
0
    UNREACHABLE();
6590
0
  }
6591
6592
0
  SET_IF_NOT_NULL(chainingp, true);
6593
6594
0
  if (view->denyanswernames == NULL) {
6595
0
    return true;
6596
0
  }
6597
6598
  /*
6599
   * If the owner name matches one in the exclusion list, either
6600
   * exactly or partially, allow it.
6601
   */
6602
0
  if (dns_nametree_covered(view->answernames_exclude, qname, NULL, 0)) {
6603
0
    return true;
6604
0
  }
6605
6606
  /*
6607
   * If the target name is a subdomain of the search domain, allow
6608
   * it.
6609
   *
6610
   * Note that if BIND is configured as a forwarding DNS server,
6611
   * the search domain will always match the root domain ("."), so
6612
   * we must also check whether forwarding is enabled so that
6613
   * filters can be applied; see GL #1574.
6614
   */
6615
0
  if (!fctx->forwarding && dns_name_issubdomain(tname, fctx->domain)) {
6616
0
    return true;
6617
0
  }
6618
6619
  /*
6620
   * Otherwise, apply filters.
6621
   */
6622
0
  if (dns_nametree_covered(view->denyanswernames, tname, NULL, 0)) {
6623
0
    char qnamebuf[DNS_NAME_FORMATSIZE];
6624
0
    char tnamebuf[DNS_NAME_FORMATSIZE];
6625
0
    char classbuf[64];
6626
0
    char typebuf[64];
6627
0
    dns_name_format(qname, qnamebuf, sizeof(qnamebuf));
6628
0
    dns_name_format(tname, tnamebuf, sizeof(tnamebuf));
6629
0
    dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
6630
0
    dns_rdataclass_format(view->rdclass, classbuf,
6631
0
              sizeof(classbuf));
6632
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
6633
0
            ISC_LOG_NOTICE, "%s target %s denied for %s/%s",
6634
0
            typebuf, tnamebuf, qnamebuf, classbuf);
6635
0
    return false;
6636
0
  }
6637
6638
0
  return true;
6639
0
}
6640
6641
static void
6642
0
trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) {
6643
0
  if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) {
6644
0
    char ns_namebuf[DNS_NAME_FORMATSIZE];
6645
0
    char namebuf[DNS_NAME_FORMATSIZE];
6646
0
    char tbuf[DNS_RDATATYPE_FORMATSIZE];
6647
6648
0
    dns_name_format(name, ns_namebuf, sizeof(ns_namebuf));
6649
0
    dns_name_format(fctx->name, namebuf, sizeof(namebuf));
6650
0
    dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf));
6651
6652
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
6653
0
            ISC_LOG_DEBUG(10),
6654
0
            "fctx %p: trimming ttl of %s/NS for %s/%s: "
6655
0
            "%u -> %u",
6656
0
            fctx, ns_namebuf, namebuf, tbuf, rdataset->ttl,
6657
0
            fctx->ns_ttl);
6658
0
    rdataset->ttl = fctx->ns_ttl;
6659
0
  }
6660
0
}
6661
6662
static bool
6663
0
validinanswer(dns_rdataset_t *rdataset, fetchctx_t *fctx) {
6664
0
  if (rdataset->type == dns_rdatatype_nsec3) {
6665
    /*
6666
     * NSEC3 records are not allowed to
6667
     * appear in the answer section.
6668
     */
6669
0
    log_formerr(fctx, "NSEC3 in answer");
6670
0
    return false;
6671
0
  }
6672
0
  if (rdataset->type == dns_rdatatype_tkey) {
6673
    /*
6674
     * TKEY is not a valid record in a
6675
     * response to any query we can make.
6676
     */
6677
0
    log_formerr(fctx, "TKEY in answer");
6678
0
    return false;
6679
0
  }
6680
0
  if (rdataset->rdclass != fctx->res->rdclass) {
6681
0
    log_formerr(fctx, "Mismatched class in answer");
6682
0
    return false;
6683
0
  }
6684
0
  return true;
6685
0
}
6686
6687
#if DNS_RESOLVER_TRACE
6688
ISC_REFCOUNT_TRACE_IMPL(fetchctx, fctx_destroy);
6689
#else
6690
ISC_REFCOUNT_IMPL(fetchctx, fctx_destroy);
6691
#endif
6692
6693
static void
6694
0
resume_dslookup(void *arg) {
6695
0
  dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg;
6696
0
  fetchctx_t *fctx = resp->arg;
6697
0
  isc_loop_t *loop = resp->loop;
6698
0
  isc_result_t result;
6699
0
  dns_resolver_t *res = NULL;
6700
0
  dns_rdataset_t *frdataset = NULL, *nsrdataset = NULL;
6701
0
  dns_rdataset_t nameservers;
6702
0
  dns_fixedname_t fixed;
6703
0
  dns_name_t *domain = NULL;
6704
0
  unsigned int n;
6705
0
  dns_fetch_t *fetch = NULL;
6706
6707
0
  REQUIRE(VALID_FCTX(fctx));
6708
6709
0
  res = fctx->res;
6710
6711
0
  REQUIRE(fctx->tid == isc_tid());
6712
6713
0
  FCTXTRACE("resume_dslookup");
6714
6715
0
  if (resp->node != NULL) {
6716
0
    dns_db_detachnode(&resp->node);
6717
0
  }
6718
0
  if (resp->db != NULL) {
6719
0
    dns_db_detach(&resp->db);
6720
0
  }
6721
6722
  /* Preserve data from resp before freeing it. */
6723
0
  frdataset = resp->rdataset; /* a.k.a. fctx->nsrrset */
6724
0
  result = resp->result;
6725
6726
0
  dns_resolver_freefresp(&resp);
6727
6728
0
  LOCK(&fctx->lock);
6729
0
  if (SHUTTINGDOWN(fctx)) {
6730
0
    result = ISC_R_SHUTTINGDOWN;
6731
0
  }
6732
0
  UNLOCK(&fctx->lock);
6733
6734
0
  fetch = fctx->nsfetch;
6735
0
  fctx->nsfetch = NULL;
6736
6737
0
  FTRACE("resume_dslookup");
6738
6739
0
  switch (result) {
6740
0
  case ISC_R_SUCCESS:
6741
0
    FCTXTRACE("resuming DS lookup");
6742
6743
0
    if (dns_rdataset_isassociated(&fctx->nameservers)) {
6744
0
      dns_rdataset_disassociate(&fctx->nameservers);
6745
0
    }
6746
0
    dns_rdataset_clone(frdataset, &fctx->nameservers);
6747
6748
    /*
6749
     * Disassociate now the NS's are saved.
6750
     */
6751
0
    if (dns_rdataset_isassociated(frdataset)) {
6752
0
      dns_rdataset_disassociate(frdataset);
6753
0
    }
6754
6755
0
    fctx->ns_ttl = fctx->nameservers.ttl;
6756
0
    fctx->ns_ttl_ok = true;
6757
0
    log_ns_ttl(fctx, "resume_dslookup");
6758
6759
0
    fcount_decr(fctx);
6760
0
    dns_name_copy(fctx->nsname, fctx->domain);
6761
0
    result = fcount_incr(fctx, false);
6762
0
    if (result != ISC_R_SUCCESS) {
6763
0
      goto cleanup;
6764
0
    }
6765
6766
    /* Try again. */
6767
0
    fctx_try(fctx, true);
6768
0
    break;
6769
6770
0
  case ISC_R_SHUTTINGDOWN:
6771
0
  case ISC_R_CANCELED:
6772
    /* Don't try anymore. */
6773
    /* Can't be done in cleanup. */
6774
0
    if (dns_rdataset_isassociated(frdataset)) {
6775
0
      dns_rdataset_disassociate(frdataset);
6776
0
    }
6777
0
    goto cleanup;
6778
6779
0
  default:
6780
    /*
6781
     * Disassociate for the next dns_resolver_createfetch call.
6782
     */
6783
0
    if (dns_rdataset_isassociated(frdataset)) {
6784
0
      dns_rdataset_disassociate(frdataset);
6785
0
    }
6786
6787
    /*
6788
     * If the chain of resume_dslookup() invocations managed to
6789
     * chop off enough labels from the original DS owner name to
6790
     * reach the top of the namespace, no further progress can be
6791
     * made.  Interrupt the DS chasing process, returning SERVFAIL.
6792
     */
6793
0
    if (dns_name_equal(fctx->nsname, fetch->private->domain)) {
6794
0
      result = DNS_R_SERVFAIL;
6795
0
      goto cleanup;
6796
0
    }
6797
6798
    /* Get nameservers from fetch before we destroy it. */
6799
0
    dns_rdataset_init(&nameservers);
6800
0
    if (dns_rdataset_isassociated(&fetch->private->nameservers)) {
6801
0
      dns_rdataset_clone(&fetch->private->nameservers,
6802
0
             &nameservers);
6803
0
      nsrdataset = &nameservers;
6804
6805
      /* Get domain from fetch before we destroy it. */
6806
0
      domain = dns_fixedname_initname(&fixed);
6807
0
      dns_name_copy(fetch->private->domain, domain);
6808
0
    }
6809
6810
0
    n = dns_name_countlabels(fctx->nsname);
6811
0
    dns_name_getlabelsequence(fctx->nsname, 1, n - 1, fctx->nsname);
6812
6813
0
    FCTXTRACE("continuing to look for parent's NS records");
6814
6815
0
    fetchctx_ref(fctx);
6816
0
    result = dns_resolver_createfetch(
6817
0
      res, fctx->nsname, dns_rdatatype_ns, domain, nsrdataset,
6818
0
      NULL, NULL, 0, fctx->options, 0, fctx->qc, fctx->gqc,
6819
0
      loop, resume_dslookup, fctx, &fctx->edectx,
6820
0
      &fctx->nsrrset, NULL, &fctx->nsfetch);
6821
0
    if (result != ISC_R_SUCCESS) {
6822
0
      fetchctx_unref(fctx);
6823
0
      if (result == DNS_R_DUPLICATE) {
6824
0
        result = DNS_R_SERVFAIL;
6825
0
      }
6826
0
    }
6827
6828
0
    if (dns_rdataset_isassociated(&nameservers)) {
6829
0
      dns_rdataset_disassociate(&nameservers);
6830
0
    }
6831
0
  }
6832
6833
0
cleanup:
6834
0
  dns_resolver_destroyfetch(&fetch);
6835
6836
0
  if (result != ISC_R_SUCCESS) {
6837
    /* An error occurred, tear down whole fctx */
6838
0
    fctx_done_unref(fctx, result);
6839
0
  }
6840
6841
0
  fetchctx_detach(&fctx);
6842
0
}
6843
6844
static void
6845
0
checknamessection(dns_message_t *message, dns_section_t section) {
6846
0
  MSG_SECTION_FOREACH(message, section, name) {
6847
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
6848
0
      DNS_RDATASET_FOREACH(rdataset) {
6849
0
        dns_rdata_t rdata = DNS_RDATA_INIT;
6850
0
        dns_rdataset_current(rdataset, &rdata);
6851
0
        if (!dns_rdata_checkowner(name, rdata.rdclass,
6852
0
                rdata.type, false) ||
6853
0
            !dns_rdata_checknames(&rdata, name, NULL))
6854
0
        {
6855
0
          rdataset->attributes.checknames = true;
6856
0
        }
6857
0
      }
6858
0
    }
6859
0
  }
6860
0
}
6861
6862
static void
6863
0
checknames(dns_message_t *message) {
6864
0
  checknamessection(message, DNS_SECTION_ANSWER);
6865
0
  checknamessection(message, DNS_SECTION_AUTHORITY);
6866
0
  checknamessection(message, DNS_SECTION_ADDITIONAL);
6867
0
}
6868
6869
static void
6870
0
make_hex(unsigned char *src, size_t srclen, char *buf, size_t buflen) {
6871
0
  isc_buffer_t b;
6872
0
  isc_region_t r;
6873
0
  isc_result_t result;
6874
6875
0
  r.base = src;
6876
0
  r.length = srclen;
6877
0
  isc_buffer_init(&b, buf, buflen);
6878
0
  result = isc_hex_totext(&r, 0, "", &b);
6879
0
  RUNTIME_CHECK(result == ISC_R_SUCCESS);
6880
0
  isc_buffer_putuint8(&b, '\0');
6881
0
}
6882
6883
static void
6884
0
make_printable(unsigned char *src, size_t srclen, char *buf, size_t buflen) {
6885
0
  INSIST(buflen > srclen);
6886
0
  while (srclen-- > 0) {
6887
0
    unsigned char c = *src++;
6888
0
    *buf++ = isprint(c) ? c : '.';
6889
0
  }
6890
0
  *buf = '\0';
6891
0
}
6892
6893
/*
6894
 * Log server NSID at log level 'level'
6895
 */
6896
static void
6897
log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, int level,
6898
0
   isc_mem_t *mctx) {
6899
0
  char addrbuf[ISC_SOCKADDR_FORMATSIZE], *buf = NULL, *pbuf = NULL;
6900
0
  size_t buflen;
6901
6902
0
  REQUIRE(nsid_len <= UINT16_MAX);
6903
6904
  /* Allocate buffer for storing hex version of the NSID */
6905
0
  buflen = nsid_len * 2 + 1;
6906
0
  buf = isc_mem_get(mctx, buflen);
6907
0
  pbuf = isc_mem_get(mctx, nsid_len + 1);
6908
6909
  /* Convert to hex */
6910
0
  make_hex(isc_buffer_current(opt), nsid_len, buf, buflen);
6911
6912
  /* Make printable version */
6913
0
  make_printable(isc_buffer_current(opt), nsid_len, pbuf, nsid_len + 1);
6914
6915
0
  isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
6916
0
          sizeof(addrbuf));
6917
0
  isc_log_write(DNS_LOGCATEGORY_NSID, DNS_LOGMODULE_RESOLVER, level,
6918
0
          "received NSID %s (\"%s\") from %s", buf, pbuf, addrbuf);
6919
6920
0
  isc_mem_put(mctx, pbuf, nsid_len + 1);
6921
0
  isc_mem_put(mctx, buf, buflen);
6922
0
}
6923
6924
static void
6925
log_zoneversion(unsigned char *version, size_t version_len, unsigned char *nsid,
6926
    size_t nsid_len, resquery_t *query, int level,
6927
0
    isc_mem_t *mctx) {
6928
0
  char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6929
0
  char namebuf[DNS_NAME_FORMATSIZE];
6930
0
  size_t nsid_buflen = 0;
6931
0
  char *nsid_buf = NULL;
6932
0
  char *nsid_pbuf = NULL;
6933
0
  const char *nsid_hex = "";
6934
0
  const char *nsid_print = "";
6935
0
  const char *sep_1 = "";
6936
0
  const char *sep_2 = "";
6937
0
  const char *sep_3 = "";
6938
0
  dns_name_t suffix = DNS_NAME_INITEMPTY;
6939
0
  unsigned int labels;
6940
6941
0
  REQUIRE(version_len <= UINT16_MAX);
6942
6943
  /*
6944
   * Don't log reflected ZONEVERSION option.
6945
   */
6946
0
  if (version_len == 0) {
6947
0
    return;
6948
0
  }
6949
6950
  /* Enforced by dns_rdata_fromwire. */
6951
0
  INSIST(version_len >= 2);
6952
6953
  /*
6954
   * Sanity check on label count.
6955
   */
6956
0
  labels = version[0] + 1;
6957
0
  if (dns_name_countlabels(query->fctx->name) < labels) {
6958
0
    return;
6959
0
  }
6960
6961
  /*
6962
   * Get zone name.
6963
   */
6964
0
  dns_name_split(query->fctx->name, labels, NULL, &suffix);
6965
0
  dns_name_format(&suffix, namebuf, sizeof(namebuf));
6966
6967
0
  if (nsid != NULL) {
6968
0
    nsid_buflen = nsid_len * 2 + 1;
6969
0
    nsid_hex = nsid_buf = isc_mem_get(mctx, nsid_buflen);
6970
0
    nsid_print = nsid_pbuf = isc_mem_get(mctx, nsid_len + 1);
6971
6972
    /* Convert to hex */
6973
0
    make_hex(nsid, nsid_len, nsid_buf, nsid_buflen);
6974
6975
    /* Convert to printable */
6976
0
    make_printable(nsid, nsid_len, nsid_pbuf, nsid_len + 1);
6977
6978
0
    sep_1 = " (NSID ";
6979
0
    sep_2 = " (";
6980
0
    sep_3 = "))";
6981
0
  }
6982
6983
0
  isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
6984
0
          sizeof(addrbuf));
6985
0
  if (version[1] == 0 && version_len == 6) {
6986
0
    uint32_t serial = version[2] << 24 | version[3] << 2 |
6987
0
          version[4] << 8 | version[5];
6988
0
    isc_log_write(DNS_LOGCATEGORY_ZONEVERSION,
6989
0
            DNS_LOGMODULE_RESOLVER, level,
6990
0
            "received ZONEVERSION serial %u from %s for %s "
6991
0
            "zone %s%s%s%s%s%s",
6992
0
            serial, addrbuf, query->fctx->info, namebuf,
6993
0
            sep_1, nsid_hex, sep_2, nsid_print, sep_3);
6994
0
  } else {
6995
0
    size_t version_buflen = version_len * 2 + 1;
6996
0
    char *version_hex = isc_mem_get(mctx, version_buflen);
6997
0
    char *version_pbuf = isc_mem_get(mctx, version_len - 1);
6998
6999
    /* Convert to hex */
7000
0
    make_hex(version + 2, version_len - 2, version_hex,
7001
0
       version_buflen);
7002
7003
    /* Convert to printable */
7004
0
    make_printable(version + 2, version_len - 2, version_pbuf,
7005
0
             version_len - 1);
7006
7007
0
    isc_log_write(DNS_LOGCATEGORY_ZONEVERSION,
7008
0
            DNS_LOGMODULE_RESOLVER, level,
7009
0
            "received ZONEVERSION type %u value %s (%s) from "
7010
0
            "%s for %s zone %s%s%s%s%s%s",
7011
0
            version[1], version_hex, version_pbuf, addrbuf,
7012
0
            query->fctx->info, namebuf, sep_1, nsid_hex,
7013
0
            sep_2, nsid_print, sep_3);
7014
0
    isc_mem_put(mctx, version_hex, version_buflen);
7015
0
    isc_mem_put(mctx, version_pbuf, version_len - 1);
7016
0
  }
7017
7018
0
  if (nsid_pbuf != NULL) {
7019
0
    isc_mem_put(mctx, nsid_pbuf, nsid_len + 1);
7020
0
  }
7021
0
  if (nsid_buf != NULL) {
7022
0
    isc_mem_put(mctx, nsid_buf, nsid_buflen);
7023
0
  }
7024
0
}
7025
7026
static bool
7027
0
betterreferral(respctx_t *rctx) {
7028
0
  dns_message_t *msg = rctx->query->rmessage;
7029
7030
0
  MSG_SECTION_FOREACH(msg, DNS_SECTION_AUTHORITY, name) {
7031
0
    if (!isstrictsubdomain(name, rctx->fctx->domain)) {
7032
0
      continue;
7033
0
    }
7034
7035
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
7036
0
      if (rdataset->type == dns_rdatatype_ns) {
7037
0
        return true;
7038
0
      }
7039
0
    }
7040
0
  }
7041
0
  return false;
7042
0
}
7043
7044
/*
7045
 * Handles responses received in response to iterative queries sent by
7046
 * resquery_send(). Sets up a response context (respctx_t).
7047
 */
7048
static void
7049
0
resquery_response(isc_result_t eresult, isc_region_t *region, void *arg) {
7050
0
  isc_result_t result;
7051
0
  resquery_t *query = (resquery_t *)arg;
7052
0
  fetchctx_t *fctx = NULL;
7053
0
  respctx_t *rctx = NULL;
7054
7055
0
  if (eresult == ISC_R_CANCELED) {
7056
0
    return;
7057
0
  }
7058
7059
0
  REQUIRE(VALID_QUERY(query));
7060
0
  fctx = query->fctx;
7061
0
  REQUIRE(VALID_FCTX(fctx));
7062
0
  REQUIRE(fctx->tid == isc_tid());
7063
7064
0
  QTRACE("response");
7065
7066
0
  if (eresult == ISC_R_SUCCESS) {
7067
0
    if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET) {
7068
0
      inc_stats(fctx->res, dns_resstatscounter_responsev4);
7069
0
    } else {
7070
0
      inc_stats(fctx->res, dns_resstatscounter_responsev6);
7071
0
    }
7072
0
  }
7073
7074
0
  rctx = isc_mem_get(fctx->mctx, sizeof(*rctx));
7075
0
  rctx_respinit(query, fctx, eresult, region, rctx);
7076
7077
0
  if (eresult == ISC_R_SHUTTINGDOWN ||
7078
0
      atomic_load_acquire(&fctx->res->exiting))
7079
0
  {
7080
0
    result = ISC_R_SHUTTINGDOWN;
7081
0
    FCTXTRACE("resolver shutting down");
7082
0
    rctx->finish = NULL;
7083
0
    rctx_done(rctx, result);
7084
0
    goto cleanup;
7085
0
  }
7086
7087
0
  result = rctx_timedout(rctx);
7088
0
  if (result == ISC_R_COMPLETE) {
7089
0
    goto cleanup;
7090
0
  }
7091
7092
0
  fctx->addrinfo = query->addrinfo;
7093
0
  fctx->timeout = false;
7094
0
  fctx->timeouts = 0;
7095
7096
  /*
7097
   * Check whether the dispatcher has failed; if so we're done
7098
   */
7099
0
  result = rctx_dispfail(rctx);
7100
0
  if (result == ISC_R_COMPLETE) {
7101
0
    goto cleanup;
7102
0
  }
7103
7104
0
  if (query->tsig != NULL) {
7105
0
    dns_message_setquerytsig(query->rmessage, query->tsig);
7106
0
  }
7107
7108
0
  if (query->tsigkey != NULL) {
7109
0
    result = dns_message_settsigkey(query->rmessage,
7110
0
            query->tsigkey);
7111
0
    if (result != ISC_R_SUCCESS) {
7112
0
      FCTXTRACE3("unable to set tsig key", result);
7113
0
      rctx_done(rctx, result);
7114
0
      goto cleanup;
7115
0
    }
7116
0
  }
7117
7118
0
  dns_message_setclass(query->rmessage, fctx->res->rdclass);
7119
7120
0
  if ((rctx->retryopts & DNS_FETCHOPT_TCP) == 0) {
7121
0
    if ((rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) {
7122
0
      dns_adb_setudpsize(
7123
0
        fctx->adb, query->addrinfo,
7124
0
        isc_buffer_usedlength(&rctx->buffer));
7125
0
    } else {
7126
0
      dns_adb_plainresponse(fctx->adb, query->addrinfo);
7127
0
    }
7128
0
  }
7129
7130
  /*
7131
   * Parse response message.
7132
   */
7133
0
  result = rctx_parse(rctx);
7134
0
  if (result == ISC_R_COMPLETE) {
7135
0
    goto cleanup;
7136
0
  }
7137
7138
  /*
7139
   * Log the incoming packet.
7140
   */
7141
0
  rctx_logpacket(rctx);
7142
7143
0
  if (query->rmessage->rdclass != fctx->res->rdclass) {
7144
0
    rctx->resend = true;
7145
0
    FCTXTRACE("bad class");
7146
0
    rctx_done(rctx, result);
7147
0
    goto cleanup;
7148
0
  }
7149
7150
  /*
7151
   * Process receive opt record.
7152
   */
7153
0
  rctx->opt = dns_message_getopt(query->rmessage);
7154
0
  if (rctx->opt != NULL) {
7155
0
    rctx_opt(rctx);
7156
0
  }
7157
7158
0
  if (query->rmessage->cc_bad &&
7159
0
      (rctx->retryopts & DNS_FETCHOPT_TCP) == 0)
7160
0
  {
7161
    /*
7162
     * If the COOKIE is bad, assume it is an attack and
7163
     * keep listening for a good answer.
7164
     */
7165
0
    rctx->nextitem = true;
7166
0
    if (isc_log_wouldlog(ISC_LOG_INFO)) {
7167
0
      char addrbuf[ISC_SOCKADDR_FORMATSIZE];
7168
0
      isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
7169
0
              sizeof(addrbuf));
7170
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
7171
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
7172
0
              "bad cookie from %s", addrbuf);
7173
0
    }
7174
0
    rctx_done(rctx, result);
7175
0
    goto cleanup;
7176
0
  }
7177
7178
  /*
7179
   * Is the question the same as the one we asked?
7180
   * NOERROR/NXDOMAIN/YXDOMAIN/REFUSED/SERVFAIL/BADCOOKIE must
7181
   * have the same question. FORMERR/NOTIMP if they have a
7182
   * question section then it must match.
7183
   */
7184
0
  switch (query->rmessage->rcode) {
7185
0
  case dns_rcode_notimp:
7186
0
  case dns_rcode_formerr:
7187
0
    if (query->rmessage->counts[DNS_SECTION_QUESTION] == 0) {
7188
0
      break;
7189
0
    }
7190
0
    FALLTHROUGH;
7191
0
  case dns_rcode_nxrrset: /* Not expected. */
7192
0
  case dns_rcode_badcookie:
7193
0
  case dns_rcode_noerror:
7194
0
  case dns_rcode_nxdomain:
7195
0
  case dns_rcode_yxdomain:
7196
0
  case dns_rcode_refused:
7197
0
  case dns_rcode_servfail:
7198
0
  default:
7199
0
    result = same_question(fctx, query->rmessage);
7200
0
    if (result != ISC_R_SUCCESS) {
7201
0
      FCTXTRACE3("question section invalid", result);
7202
0
      rctx->nextitem = true;
7203
0
      rctx_done(rctx, result);
7204
0
      goto cleanup;
7205
0
    }
7206
0
    break;
7207
0
  }
7208
7209
0
  if (query->rmessage->tsigkey == NULL && query->rmessage->tsig == NULL &&
7210
0
      query->rmessage->sig0 != NULL)
7211
0
  {
7212
    /*
7213
     * If the message is not TSIG-signed (which has priorty) and is
7214
     * SIG(0)-signed (which consumes more resources), then run an
7215
     * asynchronous check.
7216
     */
7217
0
    result = dns_message_checksig_async(
7218
0
      query->rmessage, fctx->res->view, fctx->loop,
7219
0
      resquery_response_continue, rctx);
7220
0
    INSIST(result == DNS_R_WAIT);
7221
0
  } else {
7222
    /*
7223
     * If the message is signed, check the signature.  If not, this
7224
     * returns success anyway.
7225
     */
7226
0
    result = dns_message_checksig(query->rmessage, fctx->res->view);
7227
0
    resquery_response_continue(rctx, result);
7228
0
  }
7229
7230
0
  return;
7231
7232
0
cleanup:
7233
0
  isc_mem_putanddetach(&rctx->mctx, rctx, sizeof(*rctx));
7234
0
}
7235
7236
static isc_result_t
7237
0
rctx_cookiecheck(respctx_t *rctx) {
7238
0
  fetchctx_t *fctx = rctx->fctx;
7239
0
  resquery_t *query = rctx->query;
7240
7241
  /*
7242
   * If TSIG signed, sent via TCP, or cookie present,
7243
   * no need to continue.
7244
   */
7245
0
  if (dns_message_gettsig(query->rmessage, NULL) != NULL ||
7246
0
      query->rmessage->cc_ok || query->rmessage->cc_bad ||
7247
0
      (rctx->retryopts & DNS_FETCHOPT_TCP) != 0)
7248
0
  {
7249
0
    return ISC_R_SUCCESS;
7250
0
  }
7251
7252
  /*
7253
   * If we've had a cookie from the same server previously,
7254
   * retry with TCP. This may be a misconfigured anycast server
7255
   * or an attempt to send a spoofed response.
7256
   */
7257
0
  if (dns_adb_getcookie(query->addrinfo, NULL, 0) > CLIENT_COOKIE_SIZE) {
7258
0
    if (isc_log_wouldlog(ISC_LOG_INFO)) {
7259
0
      char addrbuf[ISC_SOCKADDR_FORMATSIZE];
7260
0
      isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
7261
0
              sizeof(addrbuf));
7262
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
7263
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
7264
0
              "missing expected cookie "
7265
0
              "from %s",
7266
0
              addrbuf);
7267
0
    }
7268
0
    rctx->retryopts |= DNS_FETCHOPT_TCP;
7269
0
    rctx->resend = true;
7270
0
    rctx_done(rctx, ISC_R_SUCCESS);
7271
0
    return ISC_R_COMPLETE;
7272
0
  }
7273
7274
  /*
7275
   * Retry over TCP if require-cookie is true.
7276
   */
7277
0
  if (fctx->res->view->peers != NULL) {
7278
0
    isc_result_t result;
7279
0
    dns_peer_t *peer = NULL;
7280
0
    bool required = false;
7281
0
    isc_netaddr_t netaddr;
7282
7283
0
    isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
7284
0
    result = dns_peerlist_peerbyaddr(fctx->res->view->peers,
7285
0
             &netaddr, &peer);
7286
0
    if (result == ISC_R_SUCCESS) {
7287
0
      dns_peer_getrequirecookie(peer, &required);
7288
0
    }
7289
0
    if (!required) {
7290
0
      return ISC_R_SUCCESS;
7291
0
    }
7292
7293
0
    if (isc_log_wouldlog(ISC_LOG_INFO)) {
7294
0
      char addrbuf[ISC_SOCKADDR_FORMATSIZE];
7295
0
      isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
7296
0
              sizeof(addrbuf));
7297
0
      isc_log_write(DNS_LOGCATEGORY_RESOLVER,
7298
0
              DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
7299
0
              "missing required "
7300
0
              "cookie from %s",
7301
0
              addrbuf);
7302
0
    }
7303
7304
0
    rctx->retryopts |= DNS_FETCHOPT_TCP;
7305
0
    rctx->resend = true;
7306
0
    rctx_done(rctx, ISC_R_SUCCESS);
7307
0
    return ISC_R_COMPLETE;
7308
0
  }
7309
7310
0
  return ISC_R_SUCCESS;
7311
0
}
7312
7313
static void
7314
0
resquery_response_continue(void *arg, isc_result_t result) {
7315
0
  respctx_t *rctx = arg;
7316
0
  fetchctx_t *fctx = rctx->fctx;
7317
0
  resquery_t *query = rctx->query;
7318
7319
0
  QTRACE("response_continue");
7320
7321
0
  if (result != ISC_R_SUCCESS) {
7322
0
    FCTXTRACE3("signature check failed", result);
7323
0
    if (result == DNS_R_UNEXPECTEDTSIG ||
7324
0
        result == DNS_R_EXPECTEDTSIG)
7325
0
    {
7326
0
      rctx->nextitem = true;
7327
0
    }
7328
0
    rctx_done(rctx, result);
7329
0
    goto cleanup;
7330
0
  }
7331
7332
  /*
7333
   * The dispatcher should ensure we only get responses with QR
7334
   * set.
7335
   */
7336
0
  INSIST((query->rmessage->flags & DNS_MESSAGEFLAG_QR) != 0);
7337
7338
  /*
7339
   * Check for cookie issues.
7340
   */
7341
0
  result = rctx_cookiecheck(rctx);
7342
0
  if (result == ISC_R_COMPLETE) {
7343
0
    goto cleanup;
7344
0
  }
7345
7346
  /*
7347
   * Check for EDNS issues.
7348
   */
7349
0
  rctx_edns(rctx);
7350
7351
  /*
7352
   * Deal with truncated responses by retrying using TCP.
7353
   */
7354
0
  if ((query->rmessage->flags & DNS_MESSAGEFLAG_TC) != 0) {
7355
0
    rctx->truncated = true;
7356
0
  }
7357
7358
0
  if (rctx->truncated) {
7359
0
    inc_stats(fctx->res, dns_resstatscounter_truncated);
7360
0
    if ((rctx->retryopts & DNS_FETCHOPT_TCP) != 0) {
7361
0
      rctx->broken_server = DNS_R_TRUNCATEDTCP;
7362
0
      rctx->next_server = true;
7363
0
    } else {
7364
0
      rctx->retryopts |= DNS_FETCHOPT_TCP;
7365
0
      rctx->resend = true;
7366
0
    }
7367
0
    FCTXTRACE3("message truncated", result);
7368
0
    rctx_done(rctx, result);
7369
0
    goto cleanup;
7370
0
  }
7371
7372
  /*
7373
   * Is it a query response?
7374
   */
7375
0
  if (query->rmessage->opcode != dns_opcode_query) {
7376
0
    rctx->broken_server = DNS_R_UNEXPECTEDOPCODE;
7377
0
    rctx->next_server = true;
7378
0
    FCTXTRACE("invalid message opcode");
7379
0
    rctx_done(rctx, result);
7380
0
    goto cleanup;
7381
0
  }
7382
7383
  /*
7384
   * Update statistics about erroneous responses.
7385
   */
7386
0
  switch (query->rmessage->rcode) {
7387
0
  case dns_rcode_noerror:
7388
    /* no error */
7389
0
    break;
7390
0
  case dns_rcode_nxdomain:
7391
0
    inc_stats(fctx->res, dns_resstatscounter_nxdomain);
7392
0
    break;
7393
0
  case dns_rcode_servfail:
7394
0
    inc_stats(fctx->res, dns_resstatscounter_servfail);
7395
0
    break;
7396
0
  case dns_rcode_formerr:
7397
0
    inc_stats(fctx->res, dns_resstatscounter_formerr);
7398
0
    break;
7399
0
  case dns_rcode_refused:
7400
0
    inc_stats(fctx->res, dns_resstatscounter_refused);
7401
0
    break;
7402
0
  case dns_rcode_badvers:
7403
0
    inc_stats(fctx->res, dns_resstatscounter_badvers);
7404
0
    break;
7405
0
  case dns_rcode_badcookie:
7406
0
    inc_stats(fctx->res, dns_resstatscounter_badcookie);
7407
0
    break;
7408
0
  default:
7409
0
    inc_stats(fctx->res, dns_resstatscounter_othererror);
7410
0
    break;
7411
0
  }
7412
7413
  /*
7414
   * Bad server?
7415
   */
7416
0
  result = rctx_badserver(rctx, result);
7417
0
  if (result == ISC_R_COMPLETE) {
7418
0
    goto cleanup;
7419
0
  }
7420
7421
  /*
7422
   * Lame server?
7423
   */
7424
0
  result = rctx_lameserver(rctx);
7425
0
  if (result == ISC_R_COMPLETE) {
7426
0
    goto cleanup;
7427
0
  }
7428
7429
  /*
7430
   * Optionally call dns_rdata_checkowner() and
7431
   * dns_rdata_checknames() to validate the names in the response
7432
   * message.
7433
   */
7434
0
  if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0) {
7435
0
    checknames(query->rmessage);
7436
0
  }
7437
7438
  /*
7439
   * Clear cache bits.
7440
   */
7441
0
  FCTX_ATTR_CLR(fctx, FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE);
7442
7443
  /*
7444
   * Did we get any answers?
7445
   */
7446
0
  if (query->rmessage->counts[DNS_SECTION_ANSWER] > 0 &&
7447
0
      (query->rmessage->rcode == dns_rcode_noerror ||
7448
0
       query->rmessage->rcode == dns_rcode_yxdomain ||
7449
0
       query->rmessage->rcode == dns_rcode_nxdomain))
7450
0
  {
7451
0
    result = rctx_answer(rctx);
7452
0
    if (result == ISC_R_COMPLETE) {
7453
0
      goto cleanup;
7454
0
    }
7455
0
  } else if (query->rmessage->counts[DNS_SECTION_AUTHORITY] > 0 ||
7456
0
       query->rmessage->rcode == dns_rcode_noerror ||
7457
0
       query->rmessage->rcode == dns_rcode_nxdomain)
7458
0
  {
7459
    /*
7460
     * This might be an NXDOMAIN, NXRRSET, or referral.
7461
     * Call rctx_answer_none() to determine which it is.
7462
     */
7463
0
    result = rctx_answer_none(rctx);
7464
0
    switch (result) {
7465
0
    case ISC_R_SUCCESS:
7466
0
    case DNS_R_CHASEDSSERVERS:
7467
0
      break;
7468
0
    case DNS_R_DELEGATION:
7469
      /*
7470
       * With NOFOLLOW we want to pass return
7471
       * DNS_R_DELEGATION to resume_qmin.
7472
       */
7473
0
      if ((fctx->options & DNS_FETCHOPT_NOFOLLOW) == 0) {
7474
0
        result = ISC_R_SUCCESS;
7475
0
      }
7476
0
      break;
7477
0
    default:
7478
      /*
7479
       * Something has gone wrong.
7480
       */
7481
0
      if (result == DNS_R_FORMERR) {
7482
0
        rctx->next_server = true;
7483
0
      }
7484
0
      FCTXTRACE3("rctx_answer_none", result);
7485
0
      rctx_done(rctx, result);
7486
0
      goto cleanup;
7487
0
    }
7488
0
  } else {
7489
    /*
7490
     * The server is insane.
7491
     */
7492
    /* XXXRTH Log */
7493
0
    rctx->broken_server = DNS_R_UNEXPECTEDRCODE;
7494
0
    rctx->next_server = true;
7495
0
    FCTXTRACE("broken server: unexpected rcode");
7496
0
    rctx_done(rctx, result);
7497
0
    goto cleanup;
7498
0
  }
7499
7500
  /*
7501
   * Follow additional section data chains.
7502
   */
7503
0
  rctx_additional(rctx);
7504
7505
  /*
7506
   * Cache the cacheable parts of the message.  This may also
7507
   * cause work to be queued to the DNSSEC validator.
7508
   */
7509
0
  if (WANTCACHE(fctx)) {
7510
0
    isc_result_t tresult;
7511
0
    tresult = rctx_cachemessage(rctx);
7512
0
    if (tresult != ISC_R_SUCCESS) {
7513
0
      FCTXTRACE3("rctx_cachemessage complete", tresult);
7514
0
      rctx_done(rctx, tresult);
7515
0
      goto cleanup;
7516
0
    }
7517
0
  }
7518
7519
  /*
7520
   * Negative caching
7521
   */
7522
0
  rctx_ncache(rctx);
7523
7524
0
  FCTXTRACE("resquery_response done");
7525
0
  rctx_done(rctx, result);
7526
7527
0
cleanup:
7528
0
  isc_mem_putanddetach(&rctx->mctx, rctx, sizeof(*rctx));
7529
0
}
7530
7531
/*
7532
 * rctx_respinit():
7533
 * Initialize the response context structure 'rctx' to all zeroes, then
7534
 * set the loop, event, query and fctx information from
7535
 * resquery_response().
7536
 */
7537
static void
7538
rctx_respinit(resquery_t *query, fetchctx_t *fctx, isc_result_t result,
7539
0
        isc_region_t *region, respctx_t *rctx) {
7540
0
  *rctx = (respctx_t){ .result = result,
7541
0
           .query = query,
7542
0
           .fctx = fctx,
7543
0
           .broken_type = badns_response,
7544
0
           .retryopts = query->options };
7545
0
  if (result == ISC_R_SUCCESS) {
7546
0
    REQUIRE(region != NULL);
7547
0
    isc_buffer_init(&rctx->buffer, region->base, region->length);
7548
0
    isc_buffer_add(&rctx->buffer, region->length);
7549
0
  } else {
7550
0
    isc_buffer_initnull(&rctx->buffer);
7551
0
  }
7552
0
  rctx->tnow = isc_time_now();
7553
0
  rctx->finish = &rctx->tnow;
7554
0
  rctx->now = (isc_stdtime_t)isc_time_seconds(&rctx->tnow);
7555
0
  isc_mem_attach(fctx->mctx, &rctx->mctx);
7556
0
}
7557
7558
/*
7559
 * rctx_answer_init():
7560
 * Clear and reinitialize those portions of 'rctx' that will be needed
7561
 * when scanning the answer section of the response message. This can be
7562
 * called more than once if scanning needs to be restarted (though
7563
 * currently there are no cases in which this occurs).
7564
 */
7565
static void
7566
0
rctx_answer_init(respctx_t *rctx) {
7567
0
  fetchctx_t *fctx = rctx->fctx;
7568
7569
0
  rctx->aa = ((rctx->query->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0);
7570
0
  if (rctx->aa) {
7571
0
    rctx->trust = dns_trust_authanswer;
7572
0
  } else {
7573
0
    rctx->trust = dns_trust_answer;
7574
0
  }
7575
7576
  /*
7577
   * There can be multiple RRSIG and SIG records at a name so
7578
   * we treat these types as a subset of ANY.
7579
   */
7580
0
  rctx->type = fctx->type;
7581
0
  if (dns_rdatatype_issig(fctx->type)) {
7582
0
    rctx->type = dns_rdatatype_any;
7583
0
  }
7584
7585
  /*
7586
   * Bigger than any valid DNAME label count.
7587
   */
7588
0
  rctx->dname_labels = dns_name_countlabels(fctx->name);
7589
0
  rctx->domain_labels = dns_name_countlabels(fctx->domain);
7590
7591
0
  rctx->found_type = dns_rdatatype_none;
7592
7593
0
  rctx->aname = NULL;
7594
0
  rctx->ardataset = NULL;
7595
7596
0
  rctx->cname = NULL;
7597
0
  rctx->crdataset = NULL;
7598
7599
0
  rctx->dname = NULL;
7600
0
  rctx->drdataset = NULL;
7601
7602
0
  rctx->ns_name = NULL;
7603
0
  rctx->ns_rdataset = NULL;
7604
7605
0
  rctx->soa_name = NULL;
7606
0
  rctx->ds_name = NULL;
7607
0
  rctx->found_name = NULL;
7608
7609
0
  rctx->vrdataset = NULL;
7610
0
  rctx->vsigrdataset = NULL;
7611
0
}
7612
7613
/*
7614
 * rctx_dispfail():
7615
 * Handle the case where the dispatcher failed
7616
 */
7617
static isc_result_t
7618
0
rctx_dispfail(respctx_t *rctx) {
7619
0
  fetchctx_t *fctx = rctx->fctx;
7620
7621
0
  if (rctx->result == ISC_R_SUCCESS) {
7622
0
    return ISC_R_SUCCESS;
7623
0
  }
7624
7625
  /*
7626
   * There's no hope for this response.
7627
   */
7628
0
  rctx->next_server = true;
7629
7630
  /*
7631
   * If this is a network failure, the operation is cancelled,
7632
   * or the network manager is being shut down, we mark the server
7633
   * as bad so that we won't try it for this fetch again. Also
7634
   * adjust finish and no_response so that we penalize this
7635
   * address in SRTT adjustments later.
7636
   */
7637
0
  switch (rctx->result) {
7638
0
  case ISC_R_EOF:
7639
0
  case ISC_R_HOSTDOWN:
7640
0
  case ISC_R_HOSTUNREACH:
7641
0
  case ISC_R_NETDOWN:
7642
0
  case ISC_R_NETUNREACH:
7643
0
  case ISC_R_CONNREFUSED:
7644
0
  case ISC_R_CONNECTIONRESET:
7645
0
  case ISC_R_INVALIDPROTO:
7646
0
  case ISC_R_CANCELED:
7647
0
  case ISC_R_SHUTTINGDOWN:
7648
0
    rctx->broken_server = rctx->result;
7649
0
    rctx->broken_type = badns_unreachable;
7650
0
    rctx->finish = NULL;
7651
0
    rctx->no_response = true;
7652
0
    break;
7653
0
  default:
7654
0
    break;
7655
0
  }
7656
7657
0
  FCTXTRACE3("dispatcher failure", rctx->result);
7658
0
  rctx_done(rctx, ISC_R_SUCCESS);
7659
0
  return ISC_R_COMPLETE;
7660
0
}
7661
7662
/*
7663
 * rctx_timedout():
7664
 * Handle the case where a dispatch read timed out.
7665
 */
7666
static isc_result_t
7667
0
rctx_timedout(respctx_t *rctx) {
7668
0
  fetchctx_t *fctx = rctx->fctx;
7669
7670
0
  if (rctx->result == ISC_R_TIMEDOUT) {
7671
0
    isc_time_t now;
7672
7673
0
    inc_stats(fctx->res, dns_resstatscounter_querytimeout);
7674
0
    FCTX_ATTR_CLR(fctx, FCTX_ATTR_ADDRWAIT);
7675
0
    fctx->timeout = true;
7676
0
    fctx->timeouts++;
7677
7678
0
    rctx->no_response = true;
7679
0
    rctx->finish = NULL;
7680
7681
0
    now = isc_time_now();
7682
    /* netmgr timeouts are accurate to the millisecond */
7683
0
    if (isc_time_microdiff(&fctx->expires, &now) < US_PER_MS) {
7684
0
      FCTXTRACE("query timed out; stopped trying to make "
7685
0
          "fetch happen");
7686
0
      dns_ede_add(&fctx->edectx, DNS_EDE_NOREACHABLEAUTH,
7687
0
            NULL);
7688
0
    } else {
7689
0
      FCTXTRACE("query timed out; trying next server");
7690
      /* try next server */
7691
0
      rctx->next_server = true;
7692
0
    }
7693
7694
0
    rctx_done(rctx, rctx->result);
7695
0
    return ISC_R_COMPLETE;
7696
0
  }
7697
7698
0
  return ISC_R_SUCCESS;
7699
0
}
7700
7701
/*
7702
 * rctx_parse():
7703
 * Parse the response message.
7704
 */
7705
static isc_result_t
7706
0
rctx_parse(respctx_t *rctx) {
7707
0
  isc_result_t result;
7708
0
  fetchctx_t *fctx = rctx->fctx;
7709
0
  resquery_t *query = rctx->query;
7710
7711
0
  result = dns_message_parse(query->rmessage, &rctx->buffer, 0);
7712
0
  if (result == ISC_R_SUCCESS) {
7713
0
    return ISC_R_SUCCESS;
7714
0
  }
7715
7716
0
  FCTXTRACE3("message failed to parse", result);
7717
7718
0
  switch (result) {
7719
0
  case ISC_R_UNEXPECTEDEND:
7720
0
    if (query->rmessage->question_ok &&
7721
0
        (query->rmessage->flags & DNS_MESSAGEFLAG_TC) != 0 &&
7722
0
        (rctx->retryopts & DNS_FETCHOPT_TCP) == 0)
7723
0
    {
7724
      /*
7725
       * We defer retrying via TCP for a bit so we can
7726
       * check out this message further.
7727
       */
7728
0
      rctx->truncated = true;
7729
0
      return ISC_R_SUCCESS;
7730
0
    }
7731
7732
    /*
7733
     * Either the message ended prematurely,
7734
     * and/or wasn't marked as being truncated,
7735
     * and/or this is a response to a query we
7736
     * sent over TCP.  In all of these cases,
7737
     * something is wrong with the remote
7738
     * server and we don't want to retry using
7739
     * TCP.
7740
     */
7741
0
    if ((rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) {
7742
      /*
7743
       * The problem might be that they
7744
       * don't understand EDNS0.  Turn it
7745
       * off and try again.
7746
       */
7747
0
      rctx->retryopts |= DNS_FETCHOPT_NOEDNS0;
7748
0
      rctx->resend = true;
7749
0
      inc_stats(fctx->res, dns_resstatscounter_edns0fail);
7750
0
    } else {
7751
0
      rctx->broken_server = result;
7752
0
      rctx->next_server = true;
7753
0
    }
7754
7755
0
    rctx_done(rctx, result);
7756
0
    break;
7757
0
  case DNS_R_FORMERR:
7758
0
    if ((rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) {
7759
      /*
7760
       * The problem might be that they
7761
       * don't understand EDNS0.  Turn it
7762
       * off and try again.
7763
       */
7764
0
      rctx->retryopts |= DNS_FETCHOPT_NOEDNS0;
7765
0
      rctx->resend = true;
7766
0
      inc_stats(fctx->res, dns_resstatscounter_edns0fail);
7767
0
    } else {
7768
0
      rctx->broken_server = DNS_R_UNEXPECTEDRCODE;
7769
0
      rctx->next_server = true;
7770
0
    }
7771
7772
0
    rctx_done(rctx, result);
7773
0
    break;
7774
0
  default:
7775
    /*
7776
     * Something bad has happened.
7777
     */
7778
0
    rctx_done(rctx, result);
7779
0
    break;
7780
0
  }
7781
7782
0
  return ISC_R_COMPLETE;
7783
0
}
7784
7785
/*
7786
 * rctx_opt():
7787
 * Process the OPT record in the response.
7788
 */
7789
static void
7790
0
rctx_opt(respctx_t *rctx) {
7791
0
  resquery_t *query = rctx->query;
7792
0
  fetchctx_t *fctx = rctx->fctx;
7793
0
  dns_rdata_t rdata;
7794
0
  isc_buffer_t optbuf;
7795
0
  isc_result_t result;
7796
0
  bool seen_cookie = false;
7797
0
  bool seen_nsid = false;
7798
0
  bool seen_zoneversion = false;
7799
0
  unsigned char *nsid = NULL;
7800
0
  uint16_t nsidlen = 0;
7801
0
  unsigned char *zoneversion = NULL;
7802
0
  uint16_t zoneversionlen = 0;
7803
7804
0
  result = dns_rdataset_first(rctx->opt);
7805
0
  if (result != ISC_R_SUCCESS) {
7806
0
    return;
7807
0
  }
7808
7809
0
  dns_rdata_init(&rdata);
7810
0
  dns_rdataset_current(rctx->opt, &rdata);
7811
0
  isc_buffer_init(&optbuf, rdata.data, rdata.length);
7812
0
  isc_buffer_add(&optbuf, rdata.length);
7813
7814
0
  while (isc_buffer_remaininglength(&optbuf) >= 4) {
7815
0
    uint16_t optcode;
7816
0
    uint16_t optlen;
7817
0
    unsigned char *optvalue;
7818
0
    unsigned char cookie[CLIENT_COOKIE_SIZE];
7819
0
    optcode = isc_buffer_getuint16(&optbuf);
7820
0
    optlen = isc_buffer_getuint16(&optbuf);
7821
0
    INSIST(optlen <= isc_buffer_remaininglength(&optbuf));
7822
0
    switch (optcode) {
7823
0
    case DNS_OPT_NSID:
7824
0
      if (seen_nsid) {
7825
0
        break;
7826
0
      }
7827
0
      seen_nsid = true;
7828
0
      nsid = isc_buffer_current(&optbuf);
7829
0
      nsidlen = optlen;
7830
0
      if ((query->options & DNS_FETCHOPT_WANTNSID) != 0) {
7831
0
        log_nsid(&optbuf, optlen, query, ISC_LOG_INFO,
7832
0
           fctx->mctx);
7833
0
      }
7834
0
      break;
7835
0
    case DNS_OPT_COOKIE:
7836
      /* Only process the first cookie option. */
7837
0
      if (seen_cookie) {
7838
0
        break;
7839
0
      }
7840
0
      seen_cookie = true;
7841
7842
0
      optvalue = isc_buffer_current(&optbuf);
7843
0
      compute_cc(query, cookie, sizeof(cookie));
7844
0
      INSIST(query->rmessage->cc_bad == 0 &&
7845
0
             query->rmessage->cc_ok == 0);
7846
7847
0
      inc_stats(fctx->res, dns_resstatscounter_cookiein);
7848
7849
0
      if (optlen < CLIENT_COOKIE_SIZE ||
7850
0
          memcmp(cookie, optvalue, CLIENT_COOKIE_SIZE) != 0)
7851
0
      {
7852
0
        query->rmessage->cc_bad = 1;
7853
0
        break;
7854
0
      }
7855
7856
      /* Cookie OK */
7857
0
      if (optlen == CLIENT_COOKIE_SIZE) {
7858
0
        query->rmessage->cc_echoed = 1;
7859
0
      } else {
7860
0
        query->rmessage->cc_ok = 1;
7861
0
        inc_stats(fctx->res,
7862
0
            dns_resstatscounter_cookieok);
7863
0
        dns_adb_setcookie(fctx->adb, query->addrinfo,
7864
0
              optvalue, optlen);
7865
0
      }
7866
0
      break;
7867
0
    case DNS_OPT_ZONEVERSION:
7868
0
      if (seen_zoneversion) {
7869
0
        break;
7870
0
      }
7871
0
      seen_zoneversion = true;
7872
0
      zoneversion = isc_buffer_current(&optbuf);
7873
0
      zoneversionlen = optlen;
7874
0
      break;
7875
0
    default:
7876
0
      break;
7877
0
    }
7878
0
    isc_buffer_forward(&optbuf, optlen);
7879
0
  }
7880
0
  INSIST(isc_buffer_remaininglength(&optbuf) == 0U);
7881
7882
0
  if ((query->options & DNS_FETCHOPT_WANTZONEVERSION) != 0 &&
7883
0
      zoneversion != NULL)
7884
0
  {
7885
0
    log_zoneversion(zoneversion, zoneversionlen, nsid, nsidlen,
7886
0
        query, ISC_LOG_INFO, fctx->mctx);
7887
0
  }
7888
0
}
7889
7890
/*
7891
 * rctx_edns():
7892
 * Determine whether the remote server is using EDNS correctly or
7893
 * incorrectly and record that information if needed.
7894
 */
7895
static void
7896
0
rctx_edns(respctx_t *rctx) {
7897
0
  resquery_t *query = rctx->query;
7898
0
  fetchctx_t *fctx = rctx->fctx;
7899
7900
  /*
7901
   * If we get a non error EDNS response record the fact so we
7902
   * won't fallback to plain DNS in the future for this server.
7903
   */
7904
0
  if (rctx->opt != NULL && !EDNSOK(query->addrinfo) &&
7905
0
      (rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0 &&
7906
0
      (query->rmessage->rcode == dns_rcode_noerror ||
7907
0
       query->rmessage->rcode == dns_rcode_nxdomain ||
7908
0
       query->rmessage->rcode == dns_rcode_refused ||
7909
0
       query->rmessage->rcode == dns_rcode_yxdomain))
7910
0
  {
7911
0
    dns_adb_changeflags(fctx->adb, query->addrinfo,
7912
0
            FCTX_ADDRINFO_EDNSOK, FCTX_ADDRINFO_EDNSOK);
7913
0
  }
7914
0
}
7915
7916
/*
7917
 * rctx_answer():
7918
 * We might have answers, or we might have a malformed delegation with
7919
 * records in the answer section. Call rctx_answer_positive() or
7920
 * rctx_answer_none() as appropriate.
7921
 */
7922
static isc_result_t
7923
0
rctx_answer(respctx_t *rctx) {
7924
0
  isc_result_t result;
7925
0
  fetchctx_t *fctx = rctx->fctx;
7926
0
  resquery_t *query = rctx->query;
7927
7928
0
  if ((query->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0 ||
7929
0
      ISFORWARDER(query->addrinfo))
7930
0
  {
7931
0
    result = rctx_answer_positive(rctx);
7932
0
    if (result != ISC_R_SUCCESS) {
7933
0
      FCTXTRACE3("rctx_answer_positive (AA/fwd)", result);
7934
0
    }
7935
0
  } else if (fctx->type != dns_rdatatype_ns && !betterreferral(rctx)) {
7936
0
    result = rctx_answer_positive(rctx);
7937
0
    if (result != ISC_R_SUCCESS) {
7938
0
      FCTXTRACE3("rctx_answer_positive (!NS)", result);
7939
0
    }
7940
0
  } else {
7941
    /*
7942
     * This may be a delegation.
7943
     */
7944
7945
0
    result = rctx_answer_none(rctx);
7946
0
    if (result != ISC_R_SUCCESS) {
7947
0
      FCTXTRACE3("rctx_answer_none", result);
7948
0
    }
7949
7950
0
    if (result == DNS_R_DELEGATION) {
7951
      /*
7952
       * With NOFOLLOW we want to return DNS_R_DELEGATION to
7953
       * resume_qmin.
7954
       */
7955
0
      if ((rctx->fctx->options & DNS_FETCHOPT_NOFOLLOW) != 0)
7956
0
      {
7957
0
        return result;
7958
0
      }
7959
0
      result = ISC_R_SUCCESS;
7960
0
    } else {
7961
      /*
7962
       * At this point, AA is not set, the response
7963
       * is not a referral, and the server is not a
7964
       * forwarder.  It is technically lame and it's
7965
       * easier to treat it as such than to figure out
7966
       * some more elaborate course of action.
7967
       */
7968
0
      rctx->broken_server = DNS_R_LAME;
7969
0
      rctx->next_server = true;
7970
0
      FCTXTRACE3("rctx_answer lame", result);
7971
0
      rctx_done(rctx, result);
7972
0
      return ISC_R_COMPLETE;
7973
0
    }
7974
0
  }
7975
7976
0
  if (result != ISC_R_SUCCESS) {
7977
0
    if (result == DNS_R_FORMERR) {
7978
0
      rctx->next_server = true;
7979
0
    }
7980
0
    FCTXTRACE3("rctx_answer failed", result);
7981
0
    rctx_done(rctx, result);
7982
0
    return ISC_R_COMPLETE;
7983
0
  }
7984
7985
0
  return ISC_R_SUCCESS;
7986
0
}
7987
7988
/*
7989
 * rctx_answer_positive():
7990
 * Handles positive responses. Depending which type of answer this is
7991
 * (matching QNAME/QTYPE, CNAME, DNAME, ANY) calls the proper routine
7992
 * to handle it (rctx_answer_match(), rctx_answer_cname(),
7993
 * rctx_answer_dname(), rctx_answer_any()).
7994
 */
7995
static isc_result_t
7996
0
rctx_answer_positive(respctx_t *rctx) {
7997
0
  isc_result_t result;
7998
0
  fetchctx_t *fctx = rctx->fctx;
7999
8000
0
  FCTXTRACE("rctx_answer_positive");
8001
8002
0
  rctx_answer_init(rctx);
8003
0
  rctx_answer_scan(rctx);
8004
8005
  /*
8006
   * Determine which type of positive answer this is:
8007
   * type ANY, CNAME, DNAME, or an answer matching QNAME/QTYPE.
8008
   * Call the appropriate routine to handle the answer type.
8009
   */
8010
0
  if (rctx->aname != NULL && rctx->type == dns_rdatatype_any) {
8011
0
    result = rctx_answer_any(rctx);
8012
0
    if (result == ISC_R_COMPLETE) {
8013
0
      return rctx->result;
8014
0
    }
8015
0
  } else if (rctx->aname != NULL) {
8016
0
    result = rctx_answer_match(rctx);
8017
0
    if (result == ISC_R_COMPLETE) {
8018
0
      return rctx->result;
8019
0
    }
8020
0
  } else if (rctx->cname != NULL) {
8021
0
    result = rctx_answer_cname(rctx);
8022
0
    if (result == ISC_R_COMPLETE) {
8023
0
      return rctx->result;
8024
0
    }
8025
0
  } else if (rctx->dname != NULL) {
8026
0
    result = rctx_answer_dname(rctx);
8027
0
    if (result == ISC_R_COMPLETE) {
8028
0
      return rctx->result;
8029
0
    }
8030
0
  } else {
8031
0
    log_formerr(fctx, "reply has no answer");
8032
0
    return DNS_R_FORMERR;
8033
0
  }
8034
8035
  /*
8036
   * This response is now potentially cacheable.
8037
   */
8038
0
  FCTX_ATTR_SET(fctx, FCTX_ATTR_WANTCACHE);
8039
8040
  /*
8041
   * Did chaining end before we got the final answer?
8042
   */
8043
0
  if (rctx->chaining) {
8044
0
    return ISC_R_SUCCESS;
8045
0
  }
8046
8047
  /*
8048
   * We didn't end with an incomplete chain, so the rcode should
8049
   * be "no error".
8050
   */
8051
0
  if (rctx->query->rmessage->rcode != dns_rcode_noerror) {
8052
0
    log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE "
8053
0
          "indicates error");
8054
0
    return DNS_R_FORMERR;
8055
0
  }
8056
8057
  /*
8058
   * Cache records in the authority section, if
8059
   * there are any suitable for caching.
8060
   */
8061
0
  rctx_authority_positive(rctx);
8062
8063
0
  log_ns_ttl(fctx, "rctx_answer");
8064
8065
0
  if (rctx->ns_rdataset != NULL &&
8066
0
      dns_name_equal(fctx->domain, rctx->ns_name) &&
8067
0
      !dns_name_equal(rctx->ns_name, dns_rootname))
8068
0
  {
8069
0
    trim_ns_ttl(fctx, rctx->ns_name, rctx->ns_rdataset);
8070
0
  }
8071
8072
0
  return ISC_R_SUCCESS;
8073
0
}
8074
8075
/*
8076
 * rctx_answer_scan():
8077
 * Perform a single pass over the answer section of a response, looking
8078
 * for an answer that matches QNAME/QTYPE, or a CNAME matching QNAME, or
8079
 * a covering DNAME. If more than one rdataset is found matching these
8080
 * criteria, then only one is kept. Order of preference is 1) the
8081
 * shortest DNAME, 2) the first matching answer, or 3) the first CNAME.
8082
 */
8083
static void
8084
0
rctx_answer_scan(respctx_t *rctx) {
8085
0
  fetchctx_t *fctx = rctx->fctx;
8086
0
  dns_message_t *msg = rctx->query->rmessage;
8087
8088
0
  MSG_SECTION_FOREACH(msg, DNS_SECTION_ANSWER, name) {
8089
0
    int order;
8090
0
    unsigned int nlabels;
8091
0
    dns_namereln_t namereln;
8092
8093
0
    namereln = dns_name_fullcompare(fctx->name, name, &order,
8094
0
            &nlabels);
8095
0
    switch (namereln) {
8096
0
    case dns_namereln_equal:
8097
0
      ISC_LIST_FOREACH(name->list, rdataset, link) {
8098
0
        if (rdataset->type == rctx->type ||
8099
0
            rctx->type == dns_rdatatype_any)
8100
0
        {
8101
0
          rctx->aname = name;
8102
0
          if (rctx->type != dns_rdatatype_any) {
8103
0
            rctx->ardataset = rdataset;
8104
0
          }
8105
0
          break;
8106
0
        }
8107
0
        if (rdataset->type == dns_rdatatype_cname) {
8108
0
          rctx->cname = name;
8109
0
          rctx->crdataset = rdataset;
8110
0
          break;
8111
0
        }
8112
0
      }
8113
0
      break;
8114
8115
0
    case dns_namereln_subdomain:
8116
      /*
8117
       * Don't accept DNAME from parent namespace.
8118
       */
8119
0
      if (name_external(name, dns_rdatatype_dname, fctx)) {
8120
0
        continue;
8121
0
      }
8122
8123
      /*
8124
       * In-scope DNAME records must have at least
8125
       * as many labels as the domain being queried.
8126
       * They also must be less that qname's labels
8127
       * and any previously found dname.
8128
       */
8129
0
      if (nlabels >= rctx->dname_labels ||
8130
0
          nlabels < rctx->domain_labels)
8131
0
      {
8132
0
        continue;
8133
0
      }
8134
8135
      /*
8136
       * We are looking for the shortest DNAME if
8137
       * there are multiple ones (which there
8138
       * shouldn't be).
8139
       */
8140
0
      ISC_LIST_FOREACH(name->list, rdataset, link) {
8141
0
        if (rdataset->type != dns_rdatatype_dname) {
8142
0
          continue;
8143
0
        }
8144
0
        rctx->dname = name;
8145
0
        rctx->drdataset = rdataset;
8146
0
        rctx->dname_labels = nlabels;
8147
0
        break;
8148
0
      }
8149
0
      break;
8150
0
    default:
8151
0
      break;
8152
0
    }
8153
0
  }
8154
8155
  /*
8156
   * If a DNAME was found, then any CNAME or other answer matching
8157
   * QNAME that may also have been found must be ignored.
8158
   * Similarly, if a matching answer was found along with a CNAME,
8159
   * the CNAME must be ignored.
8160
   */
8161
0
  if (rctx->dname != NULL) {
8162
0
    rctx->aname = NULL;
8163
0
    rctx->ardataset = NULL;
8164
0
    rctx->cname = NULL;
8165
0
    rctx->crdataset = NULL;
8166
0
  } else if (rctx->aname != NULL) {
8167
0
    rctx->cname = NULL;
8168
0
    rctx->crdataset = NULL;
8169
0
  }
8170
0
}
8171
8172
/*
8173
 * rctx_answer_any():
8174
 * Handle responses to queries of type ANY. Scan the answer section,
8175
 * and as long as each RRset is of a type that is valid in the answer
8176
 * section, and the rdata isn't filtered, cache it.
8177
 */
8178
static isc_result_t
8179
0
rctx_answer_any(respctx_t *rctx) {
8180
0
  fetchctx_t *fctx = rctx->fctx;
8181
8182
0
  ISC_LIST_FOREACH(rctx->aname->list, rdataset, link) {
8183
0
    if (!validinanswer(rdataset, fctx)) {
8184
0
      rctx->result = DNS_R_FORMERR;
8185
0
      return ISC_R_COMPLETE;
8186
0
    }
8187
8188
0
    if (dns_rdatatype_issig(fctx->type) &&
8189
0
        rdataset->type != fctx->type)
8190
0
    {
8191
0
      continue;
8192
0
    }
8193
8194
0
    if (dns_rdatatype_isaddr(rdataset->type) &&
8195
0
        !is_answeraddress_allowed(fctx->res->view, rctx->aname,
8196
0
                rdataset))
8197
0
    {
8198
0
      rctx->result = DNS_R_SERVFAIL;
8199
0
      return ISC_R_COMPLETE;
8200
0
    }
8201
8202
0
    if (dns_rdatatype_isalias(rdataset->type) &&
8203
0
        !is_answertarget_allowed(fctx, fctx->name, rctx->aname,
8204
0
               rdataset, NULL))
8205
0
    {
8206
0
      rctx->result = DNS_R_SERVFAIL;
8207
0
      return ISC_R_COMPLETE;
8208
0
    }
8209
8210
0
    rctx->aname->attributes.cache = true;
8211
0
    rctx->aname->attributes.answer = true;
8212
0
    if (dns_rdatatype_issig(rdataset->type)) {
8213
0
      rdataset->attributes.answersig = true;
8214
0
    } else {
8215
0
      rdataset->attributes.answer = true;
8216
0
    }
8217
0
    rdataset->attributes.cache = true;
8218
0
    rdataset->trust = rctx->trust;
8219
0
  }
8220
8221
0
  return ISC_R_SUCCESS;
8222
0
}
8223
8224
/*
8225
 * rctx_answer_match():
8226
 * Handle responses that match the QNAME/QTYPE of the resolver query.
8227
 * If QTYPE is valid in the answer section and the rdata isn't filtered,
8228
 * the answer can be cached. If there is additional section data related
8229
 * to the answer, it can be cached as well.
8230
 */
8231
static isc_result_t
8232
0
rctx_answer_match(respctx_t *rctx) {
8233
0
  fetchctx_t *fctx = rctx->fctx;
8234
8235
0
  if (!validinanswer(rctx->ardataset, fctx)) {
8236
0
    rctx->result = DNS_R_FORMERR;
8237
0
    return ISC_R_COMPLETE;
8238
0
  }
8239
8240
0
  if (dns_rdatatype_isaddr(rctx->ardataset->type) &&
8241
0
      !is_answeraddress_allowed(fctx->res->view, rctx->aname,
8242
0
              rctx->ardataset))
8243
0
  {
8244
0
    rctx->result = DNS_R_SERVFAIL;
8245
0
    return ISC_R_COMPLETE;
8246
0
  }
8247
0
  if (dns_rdatatype_isalias(rctx->ardataset->type) &&
8248
0
      rctx->type != rctx->ardataset->type &&
8249
0
      rctx->type != dns_rdatatype_any &&
8250
0
      !is_answertarget_allowed(fctx, fctx->name, rctx->aname,
8251
0
             rctx->ardataset, NULL))
8252
0
  {
8253
0
    rctx->result = DNS_R_SERVFAIL;
8254
0
    return ISC_R_COMPLETE;
8255
0
  }
8256
8257
0
  rctx->aname->attributes.cache = true;
8258
0
  rctx->aname->attributes.answer = true;
8259
0
  rctx->ardataset->attributes.answer = true;
8260
0
  rctx->ardataset->attributes.cache = true;
8261
0
  rctx->ardataset->trust = rctx->trust;
8262
0
  (void)dns_rdataset_additionaldata(rctx->ardataset, rctx->aname,
8263
0
            check_related, rctx,
8264
0
            DNS_RDATASET_MAXADDITIONAL);
8265
8266
0
  ISC_LIST_FOREACH(rctx->aname->list, sigrdataset, link) {
8267
0
    if (!validinanswer(sigrdataset, fctx)) {
8268
0
      rctx->result = DNS_R_FORMERR;
8269
0
      return ISC_R_COMPLETE;
8270
0
    }
8271
8272
0
    if (!dns_rdataset_issigtype(sigrdataset, rctx->type)) {
8273
0
      continue;
8274
0
    }
8275
8276
0
    sigrdataset->attributes.answersig = true;
8277
0
    sigrdataset->attributes.cache = true;
8278
0
    sigrdataset->trust = rctx->trust;
8279
0
    break;
8280
0
  }
8281
8282
0
  return ISC_R_SUCCESS;
8283
0
}
8284
8285
/*
8286
 * rctx_answer_cname():
8287
 * Handle answers containing a CNAME. Cache the CNAME, and flag that
8288
 * there may be additional chain answers to find.
8289
 */
8290
static isc_result_t
8291
0
rctx_answer_cname(respctx_t *rctx) {
8292
0
  fetchctx_t *fctx = rctx->fctx;
8293
8294
0
  if (!validinanswer(rctx->crdataset, fctx)) {
8295
0
    rctx->result = DNS_R_FORMERR;
8296
0
    return ISC_R_COMPLETE;
8297
0
  }
8298
8299
0
  if (rctx->type == dns_rdatatype_rrsig ||
8300
0
      rctx->type == dns_rdatatype_key || rctx->type == dns_rdatatype_nsec)
8301
0
  {
8302
0
    char buf[DNS_RDATATYPE_FORMATSIZE];
8303
0
    dns_rdatatype_format(rctx->type, buf, sizeof(buf));
8304
0
    log_formerr(fctx, "CNAME response for %s RR", buf);
8305
0
    rctx->result = DNS_R_FORMERR;
8306
0
    return ISC_R_COMPLETE;
8307
0
  }
8308
8309
0
  if (!is_answertarget_allowed(fctx, fctx->name, rctx->cname,
8310
0
             rctx->crdataset, NULL))
8311
0
  {
8312
0
    rctx->result = DNS_R_SERVFAIL;
8313
0
    return ISC_R_COMPLETE;
8314
0
  }
8315
8316
0
  rctx->cname->attributes.cache = true;
8317
0
  rctx->cname->attributes.answer = true;
8318
0
  rctx->cname->attributes.chaining = true;
8319
0
  rctx->crdataset->attributes.answer = true;
8320
0
  rctx->crdataset->attributes.cache = true;
8321
0
  rctx->crdataset->attributes.chaining = true;
8322
0
  rctx->crdataset->trust = rctx->trust;
8323
8324
0
  ISC_LIST_FOREACH(rctx->cname->list, sigrdataset, link) {
8325
0
    if (!validinanswer(sigrdataset, fctx)) {
8326
0
      rctx->result = DNS_R_FORMERR;
8327
0
      return ISC_R_COMPLETE;
8328
0
    }
8329
8330
0
    if (sigrdataset->type != dns_rdatatype_rrsig ||
8331
0
        sigrdataset->covers != dns_rdatatype_cname)
8332
0
    {
8333
0
      continue;
8334
0
    }
8335
8336
0
    sigrdataset->attributes.answersig = true;
8337
0
    sigrdataset->attributes.cache = true;
8338
0
    sigrdataset->trust = rctx->trust;
8339
0
    break;
8340
0
  }
8341
8342
0
  rctx->chaining = true;
8343
0
  return ISC_R_SUCCESS;
8344
0
}
8345
8346
/*
8347
 * rctx_answer_dname():
8348
 * Handle responses with covering DNAME records.
8349
 */
8350
static isc_result_t
8351
0
rctx_answer_dname(respctx_t *rctx) {
8352
0
  fetchctx_t *fctx = rctx->fctx;
8353
8354
0
  if (!validinanswer(rctx->drdataset, fctx)) {
8355
0
    rctx->result = DNS_R_FORMERR;
8356
0
    return ISC_R_COMPLETE;
8357
0
  }
8358
8359
0
  if (!is_answertarget_allowed(fctx, fctx->name, rctx->dname,
8360
0
             rctx->drdataset, &rctx->chaining))
8361
0
  {
8362
0
    rctx->result = DNS_R_SERVFAIL;
8363
0
    return ISC_R_COMPLETE;
8364
0
  }
8365
8366
0
  rctx->dname->attributes.cache = true;
8367
0
  rctx->dname->attributes.answer = true;
8368
0
  rctx->dname->attributes.chaining = true;
8369
0
  rctx->drdataset->attributes.answer = true;
8370
0
  rctx->drdataset->attributes.cache = true;
8371
0
  rctx->drdataset->attributes.chaining = true;
8372
0
  rctx->drdataset->trust = rctx->trust;
8373
8374
0
  ISC_LIST_FOREACH(rctx->dname->list, sigrdataset, link) {
8375
0
    if (!validinanswer(sigrdataset, fctx)) {
8376
0
      rctx->result = DNS_R_FORMERR;
8377
0
      return ISC_R_COMPLETE;
8378
0
    }
8379
8380
0
    if (sigrdataset->type != dns_rdatatype_rrsig ||
8381
0
        sigrdataset->covers != dns_rdatatype_dname)
8382
0
    {
8383
0
      continue;
8384
0
    }
8385
8386
0
    sigrdataset->attributes.answersig = true;
8387
0
    sigrdataset->attributes.cache = true;
8388
0
    sigrdataset->trust = rctx->trust;
8389
0
    break;
8390
0
  }
8391
8392
0
  return ISC_R_SUCCESS;
8393
0
}
8394
8395
/*
8396
 * rctx_authority_positive():
8397
 * Examine the records in the authority section (if there are any) for a
8398
 * positive answer.  We expect the names for all rdatasets in this
8399
 * section to be subdomains of the domain being queried; any that are
8400
 * not are skipped.  We expect to find only *one* owner name; any names
8401
 * after the first one processed are ignored. We expect to find only
8402
 * rdatasets of type NS, RRSIG, or SIG; all others are ignored. Whatever
8403
 * remains can be cached at trust level authauthority or additional
8404
 * (depending on whether the AA bit was set on the answer).
8405
 */
8406
static void
8407
0
rctx_authority_positive(respctx_t *rctx) {
8408
0
  fetchctx_t *fctx = rctx->fctx;
8409
8410
0
  dns_message_t *msg = rctx->query->rmessage;
8411
0
  MSG_SECTION_FOREACH(msg, DNS_SECTION_AUTHORITY, name) {
8412
0
    if (!name_external(name, dns_rdatatype_ns, fctx)) {
8413
      /*
8414
       * We expect to find NS or SIG NS rdatasets, and
8415
       * nothing else.
8416
       */
8417
0
      ISC_LIST_FOREACH(name->list, rdataset, link) {
8418
0
        if (dns_rdataset_matchestype(rdataset,
8419
0
                   dns_rdatatype_ns))
8420
0
        {
8421
0
          name->attributes.cache = true;
8422
0
          rdataset->attributes.cache = true;
8423
8424
0
          if (rctx->aa) {
8425
0
            rdataset->trust =
8426
0
              dns_trust_authauthority;
8427
0
          } else {
8428
0
            rdataset->trust =
8429
0
              dns_trust_additional;
8430
0
          }
8431
8432
0
          if (rdataset->type == dns_rdatatype_ns)
8433
0
          {
8434
0
            rctx->ns_name = name;
8435
0
            rctx->ns_rdataset = rdataset;
8436
0
          }
8437
          /*
8438
           * Mark any additional data
8439
           * related to this rdataset.
8440
           */
8441
0
          (void)dns_rdataset_additionaldata(
8442
0
            rdataset, name, check_related,
8443
0
            rctx,
8444
0
            DNS_RDATASET_MAXADDITIONAL);
8445
0
          return;
8446
0
        }
8447
0
      }
8448
0
    }
8449
0
  }
8450
0
}
8451
8452
/*
8453
 * rctx_answer_none():
8454
 * Handles a response without an answer: this is either a negative
8455
 * response (NXDOMAIN or NXRRSET) or a referral. Determine which it is,
8456
 * then either scan the authority section for negative caching and
8457
 * DNSSEC proof of nonexistence, or else call rctx_referral().
8458
 */
8459
static isc_result_t
8460
0
rctx_answer_none(respctx_t *rctx) {
8461
0
  isc_result_t result;
8462
0
  fetchctx_t *fctx = rctx->fctx;
8463
8464
0
  FCTXTRACE("rctx_answer_none");
8465
8466
0
  rctx_answer_init(rctx);
8467
8468
  /*
8469
   * Sometimes we can tell if its a negative response by looking
8470
   * at the message header.
8471
   */
8472
0
  if (rctx->query->rmessage->rcode == dns_rcode_nxdomain ||
8473
0
      (rctx->query->rmessage->counts[DNS_SECTION_ANSWER] == 0 &&
8474
0
       rctx->query->rmessage->counts[DNS_SECTION_AUTHORITY] == 0))
8475
0
  {
8476
0
    rctx->negative = true;
8477
0
  }
8478
8479
  /*
8480
   * Process the authority section
8481
   */
8482
0
  result = rctx_authority_negative(rctx);
8483
0
  if (result == ISC_R_COMPLETE) {
8484
0
    return rctx->result;
8485
0
  }
8486
8487
0
  log_ns_ttl(fctx, "rctx_answer_none");
8488
8489
0
  if (rctx->ns_rdataset != NULL &&
8490
0
      dns_name_equal(fctx->domain, rctx->ns_name) &&
8491
0
      !dns_name_equal(rctx->ns_name, dns_rootname))
8492
0
  {
8493
0
    trim_ns_ttl(fctx, rctx->ns_name, rctx->ns_rdataset);
8494
0
  }
8495
8496
  /*
8497
   * A negative response has a SOA record (Type 2)
8498
   * and a optional NS RRset (Type 1) or it has neither
8499
   * a SOA or a NS RRset (Type 3, handled above) or
8500
   * rcode is NXDOMAIN (handled above) in which case
8501
   * the NS RRset is allowed (Type 4).
8502
   */
8503
0
  if (rctx->soa_name != NULL) {
8504
0
    rctx->negative = true;
8505
0
  }
8506
8507
  /*
8508
   * Process DNSSEC records in the authority section.
8509
   */
8510
0
  result = rctx_authority_dnssec(rctx);
8511
0
  if (result == ISC_R_COMPLETE) {
8512
0
    return rctx->result;
8513
0
  }
8514
8515
  /*
8516
   * Trigger lookups for DNS nameservers.
8517
   */
8518
0
  if (rctx->negative &&
8519
0
      rctx->query->rmessage->rcode == dns_rcode_noerror &&
8520
0
      fctx->type == dns_rdatatype_ds && rctx->soa_name != NULL &&
8521
0
      dns_name_equal(rctx->soa_name, fctx->name) &&
8522
0
      !dns_name_equal(fctx->name, dns_rootname))
8523
0
  {
8524
0
    return DNS_R_CHASEDSSERVERS;
8525
0
  }
8526
8527
  /*
8528
   * Did we find anything?
8529
   */
8530
0
  if (!rctx->negative && rctx->ns_name == NULL) {
8531
    /*
8532
     * The responder is insane.
8533
     */
8534
0
    if (rctx->found_name == NULL) {
8535
0
      log_formerr(fctx, "invalid response");
8536
0
      return DNS_R_FORMERR;
8537
0
    }
8538
0
    if (!dns_name_issubdomain(rctx->found_name, fctx->domain)) {
8539
0
      char nbuf[DNS_NAME_FORMATSIZE];
8540
0
      char dbuf[DNS_NAME_FORMATSIZE];
8541
0
      char tbuf[DNS_RDATATYPE_FORMATSIZE];
8542
8543
0
      dns_rdatatype_format(rctx->found_type, tbuf,
8544
0
               sizeof(tbuf));
8545
0
      dns_name_format(rctx->found_name, nbuf, sizeof(nbuf));
8546
0
      dns_name_format(fctx->domain, dbuf, sizeof(dbuf));
8547
8548
0
      log_formerr(fctx,
8549
0
            "Name %s (%s) not subdomain"
8550
0
            " of zone %s -- invalid response",
8551
0
            nbuf, tbuf, dbuf);
8552
0
    } else {
8553
0
      log_formerr(fctx, "invalid response");
8554
0
    }
8555
0
    return DNS_R_FORMERR;
8556
0
  }
8557
8558
  /*
8559
   * If we found both NS and SOA, they should be the same name.
8560
   */
8561
0
  if (rctx->ns_name != NULL && rctx->soa_name != NULL &&
8562
0
      rctx->ns_name != rctx->soa_name)
8563
0
  {
8564
0
    log_formerr(fctx, "NS/SOA mismatch");
8565
0
    return DNS_R_FORMERR;
8566
0
  }
8567
8568
  /*
8569
   * Handle a referral.
8570
   */
8571
0
  result = rctx_referral(rctx);
8572
0
  if (result == ISC_R_COMPLETE) {
8573
0
    return rctx->result;
8574
0
  }
8575
8576
  /*
8577
   * Since we're not doing a referral, we don't want to cache any
8578
   * NS RRs we may have found.
8579
   */
8580
0
  if (rctx->ns_name != NULL) {
8581
0
    rctx->ns_name->attributes.cache = false;
8582
0
  }
8583
8584
0
  if (rctx->negative) {
8585
0
    FCTX_ATTR_SET(fctx, FCTX_ATTR_WANTNCACHE);
8586
0
  }
8587
8588
0
  return ISC_R_SUCCESS;
8589
0
}
8590
8591
/*
8592
 * rctx_authority_negative():
8593
 * Scan the authority section of a negative answer, handling
8594
 * NS and SOA records. (Note that this function does *not* handle
8595
 * DNSSEC records; those are addressed separately in
8596
 * rctx_authority_dnssec() below.)
8597
 */
8598
static isc_result_t
8599
0
rctx_authority_negative(respctx_t *rctx) {
8600
0
  fetchctx_t *fctx = rctx->fctx;
8601
0
  dns_section_t section;
8602
8603
0
  section = DNS_SECTION_AUTHORITY;
8604
8605
0
  dns_message_t *msg = rctx->query->rmessage;
8606
0
  MSG_SECTION_FOREACH(msg, section, name) {
8607
0
    if (!dns_name_issubdomain(name, fctx->domain)) {
8608
0
      continue;
8609
0
    }
8610
8611
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
8612
0
      dns_rdatatype_t type = rdataset->type;
8613
0
      if (dns_rdatatype_issig(rdataset->type)) {
8614
0
        type = rdataset->covers;
8615
0
      }
8616
0
      if ((type == dns_rdatatype_ns ||
8617
0
           type == dns_rdatatype_soa) &&
8618
0
          !dns_name_issubdomain(fctx->name, name))
8619
0
      {
8620
0
        char qbuf[DNS_NAME_FORMATSIZE];
8621
0
        char nbuf[DNS_NAME_FORMATSIZE];
8622
0
        char tbuf[DNS_RDATATYPE_FORMATSIZE];
8623
0
        dns_rdatatype_format(type, tbuf, sizeof(tbuf));
8624
0
        dns_name_format(name, nbuf, sizeof(nbuf));
8625
0
        dns_name_format(fctx->name, qbuf, sizeof(qbuf));
8626
0
        log_formerr(fctx,
8627
0
              "unrelated %s %s in "
8628
0
              "%s authority section",
8629
0
              tbuf, nbuf, qbuf);
8630
0
        break;
8631
0
      }
8632
8633
0
      switch (type) {
8634
0
      case dns_rdatatype_ns:
8635
        /*
8636
         * NS or RRSIG NS.
8637
         *
8638
         * Only one set of NS RRs is allowed.
8639
         */
8640
0
        if (rdataset->type == dns_rdatatype_ns) {
8641
0
          if (rctx->ns_name != NULL &&
8642
0
              name != rctx->ns_name)
8643
0
          {
8644
0
            log_formerr(fctx, "multiple NS "
8645
0
                  "RRsets "
8646
0
                  "in "
8647
0
                  "authority "
8648
0
                  "section");
8649
0
            rctx->result = DNS_R_FORMERR;
8650
0
            return ISC_R_COMPLETE;
8651
0
          }
8652
0
          rctx->ns_name = name;
8653
0
          rctx->ns_rdataset = rdataset;
8654
0
        }
8655
0
        name->attributes.cache = true;
8656
0
        rdataset->attributes.cache = true;
8657
0
        rdataset->trust = dns_trust_glue;
8658
0
        break;
8659
0
      case dns_rdatatype_soa:
8660
        /*
8661
         * SOA, or RRSIG SOA.
8662
         *
8663
         * Only one SOA is allowed.
8664
         */
8665
0
        if (rdataset->type == dns_rdatatype_soa) {
8666
0
          if (rctx->soa_name != NULL &&
8667
0
              name != rctx->soa_name)
8668
0
          {
8669
0
            log_formerr(fctx, "multiple "
8670
0
                  "SOA RRs "
8671
0
                  "in "
8672
0
                  "authority "
8673
0
                  "section");
8674
0
            rctx->result = DNS_R_FORMERR;
8675
0
            return ISC_R_COMPLETE;
8676
0
          }
8677
0
          rctx->soa_name = name;
8678
0
        }
8679
0
        name->attributes.ncache = true;
8680
0
        rdataset->attributes.ncache = true;
8681
0
        if (rctx->aa) {
8682
0
          rdataset->trust =
8683
0
            dns_trust_authauthority;
8684
0
        } else if (ISFORWARDER(fctx->addrinfo)) {
8685
0
          rdataset->trust = dns_trust_answer;
8686
0
        } else {
8687
0
          rdataset->trust = dns_trust_additional;
8688
0
        }
8689
0
        break;
8690
0
      default:
8691
0
        continue;
8692
0
      }
8693
0
    }
8694
0
  }
8695
8696
0
  return ISC_R_SUCCESS;
8697
0
}
8698
8699
/*
8700
 * rctx_authority_dnssec():
8701
 *
8702
 * Scan the authority section of a negative answer or referral,
8703
 * handling DNSSEC records (i.e. NSEC, NSEC3, DS).
8704
 */
8705
static isc_result_t
8706
0
rctx_authority_dnssec(respctx_t *rctx) {
8707
0
  fetchctx_t *fctx = rctx->fctx;
8708
8709
0
  dns_message_t *msg = rctx->query->rmessage;
8710
0
  MSG_SECTION_FOREACH(msg, DNS_SECTION_AUTHORITY, name) {
8711
0
    if (!dns_name_issubdomain(name, fctx->domain)) {
8712
      /*
8713
       * Invalid name found; preserve it for logging
8714
       * later.
8715
       */
8716
0
      rctx->found_name = name;
8717
0
      rctx->found_type = ISC_LIST_HEAD(name->list)->type;
8718
0
      continue;
8719
0
    }
8720
8721
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
8722
0
      bool secure_domain = false;
8723
0
      dns_rdatatype_t type = rdataset->type;
8724
8725
0
      if (dns_rdatatype_issig(type)) {
8726
0
        type = rdataset->covers;
8727
0
      }
8728
8729
0
      switch (type) {
8730
0
      case dns_rdatatype_nsec:
8731
0
      case dns_rdatatype_nsec3:
8732
0
        if (rctx->negative) {
8733
0
          name->attributes.ncache = true;
8734
0
          rdataset->attributes.ncache = true;
8735
0
        } else if (type == dns_rdatatype_nsec) {
8736
0
          name->attributes.cache = true;
8737
0
          rdataset->attributes.cache = true;
8738
0
        }
8739
8740
0
        if (rctx->aa) {
8741
0
          rdataset->trust =
8742
0
            dns_trust_authauthority;
8743
0
        } else if (ISFORWARDER(fctx->addrinfo)) {
8744
0
          rdataset->trust = dns_trust_answer;
8745
0
        } else {
8746
0
          rdataset->trust = dns_trust_additional;
8747
0
        }
8748
        /*
8749
         * No additional data needs to be
8750
         * marked.
8751
         */
8752
0
        break;
8753
0
      case dns_rdatatype_ds:
8754
        /*
8755
         * DS or SIG DS.
8756
         *
8757
         * These should only be here if this is
8758
         * a referral, and there should only be
8759
         * one DS RRset.
8760
         */
8761
0
        if (rctx->ns_name == NULL) {
8762
0
          log_formerr(fctx, "DS with no "
8763
0
                "referral");
8764
0
          rctx->result = DNS_R_FORMERR;
8765
0
          return ISC_R_COMPLETE;
8766
0
        }
8767
8768
0
        if (rdataset->type == dns_rdatatype_ds) {
8769
0
          if (rctx->ds_name != NULL &&
8770
0
              name != rctx->ds_name)
8771
0
          {
8772
0
            log_formerr(fctx, "DS doesn't "
8773
0
                  "match "
8774
0
                  "referral "
8775
0
                  "(NS)");
8776
0
            rctx->result = DNS_R_FORMERR;
8777
0
            return ISC_R_COMPLETE;
8778
0
          }
8779
0
          rctx->ds_name = name;
8780
0
        }
8781
8782
0
        name->attributes.cache = true;
8783
0
        rdataset->attributes.cache = true;
8784
8785
0
        secure_domain = issecuredomain(fctx, name,
8786
0
                     dns_rdatatype_ds,
8787
0
                     fctx->now, NULL);
8788
0
        if (secure_domain) {
8789
0
          rdataset->trust =
8790
0
            dns_trust_pending_answer;
8791
0
        } else if (rctx->aa) {
8792
0
          rdataset->trust =
8793
0
            dns_trust_authauthority;
8794
0
        } else if (ISFORWARDER(fctx->addrinfo)) {
8795
0
          rdataset->trust = dns_trust_answer;
8796
0
        } else {
8797
0
          rdataset->trust = dns_trust_additional;
8798
0
        }
8799
0
        break;
8800
0
      default:
8801
0
        continue;
8802
0
      }
8803
0
    }
8804
0
  }
8805
8806
0
  return ISC_R_SUCCESS;
8807
0
}
8808
8809
/*
8810
 * rctx_referral():
8811
 * Handles referral responses. Check for sanity, find glue as needed,
8812
 * and update the fetch context to follow the delegation.
8813
 */
8814
static isc_result_t
8815
0
rctx_referral(respctx_t *rctx) {
8816
0
  isc_result_t result;
8817
0
  fetchctx_t *fctx = rctx->fctx;
8818
8819
0
  if (rctx->negative || rctx->ns_name == NULL) {
8820
0
    return ISC_R_SUCCESS;
8821
0
  }
8822
8823
  /*
8824
   * We already know ns_name is a subdomain of fctx->domain.
8825
   * If ns_name is equal to fctx->domain, we're not making
8826
   * progress.  We return DNS_R_FORMERR so that we'll keep
8827
   * trying other servers.
8828
   */
8829
0
  if (dns_name_equal(rctx->ns_name, fctx->domain)) {
8830
0
    log_formerr(fctx, "non-improving referral");
8831
0
    rctx->result = DNS_R_FORMERR;
8832
0
    return ISC_R_COMPLETE;
8833
0
  }
8834
8835
  /*
8836
   * If the referral name is not a parent of the query
8837
   * name, consider the responder insane.
8838
   */
8839
0
  if (!dns_name_issubdomain(fctx->name, rctx->ns_name)) {
8840
    /* Logged twice */
8841
0
    log_formerr(fctx, "referral to non-parent");
8842
0
    FCTXTRACE("referral to non-parent");
8843
0
    rctx->result = DNS_R_FORMERR;
8844
0
    return ISC_R_COMPLETE;
8845
0
  }
8846
8847
  /*
8848
   * Mark any additional data related to this rdataset.
8849
   * It's important that we do this before we change the
8850
   * query domain.
8851
   */
8852
0
  INSIST(rctx->ns_rdataset != NULL);
8853
0
  FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
8854
  /*
8855
   * We want to append **all** the GLUE records here.
8856
   */
8857
0
  (void)dns_rdataset_additionaldata(rctx->ns_rdataset, rctx->ns_name,
8858
0
            check_related, rctx, 0);
8859
#if CHECK_FOR_GLUE_IN_ANSWER
8860
  /*
8861
   * Look in the answer section for "glue" that is incorrectly
8862
   * returned as a answer.  This is needed if the server also
8863
   * minimizes the response size by not adding records to the
8864
   * additional section that are in the answer section or if
8865
   * the record gets dropped due to message size constraints.
8866
   */
8867
  if (rctx->glue_in_answer && dns_rdatatype_isaddr(fctx->type)) {
8868
    (void)dns_rdataset_additionaldata(
8869
      rctx->ns_rdataset, rctx->ns_name, check_answer, fctx);
8870
  }
8871
#endif /* if CHECK_FOR_GLUE_IN_ANSWER */
8872
0
  FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING);
8873
8874
  /*
8875
   * NS rdatasets with 0 TTL cause problems.
8876
   * dns_view_findzonecut() will not find them when we
8877
   * try to follow the referral, and we'll SERVFAIL
8878
   * because the best nameservers are now above QDOMAIN.
8879
   * We force the TTL to 1 second to prevent this.
8880
   */
8881
0
  if (rctx->ns_rdataset->ttl == 0) {
8882
0
    rctx->ns_rdataset->ttl = 1;
8883
0
  }
8884
8885
  /*
8886
   * Set the current query domain to the referral name.
8887
   *
8888
   * XXXRTH  We should check if we're in forward-only mode, and
8889
   *    if so we should bail out.
8890
   */
8891
0
  INSIST(dns_name_countlabels(fctx->domain) > 0);
8892
0
  fcount_decr(fctx);
8893
8894
0
  if (dns_rdataset_isassociated(&fctx->nameservers)) {
8895
0
    dns_rdataset_disassociate(&fctx->nameservers);
8896
0
  }
8897
8898
0
  dns_name_copy(rctx->ns_name, fctx->domain);
8899
8900
0
  if ((fctx->options & DNS_FETCHOPT_QMINIMIZE) != 0) {
8901
0
    dns_name_copy(rctx->ns_name, fctx->qmindcname);
8902
8903
0
    fctx_minimize_qname(fctx);
8904
0
  }
8905
8906
0
  result = fcount_incr(fctx, false);
8907
0
  if (result != ISC_R_SUCCESS) {
8908
0
    rctx->result = result;
8909
0
    return ISC_R_COMPLETE;
8910
0
  }
8911
8912
0
  FCTX_ATTR_SET(fctx, FCTX_ATTR_WANTCACHE);
8913
0
  fctx->ns_ttl_ok = false;
8914
0
  log_ns_ttl(fctx, "DELEGATION");
8915
0
  rctx->result = DNS_R_DELEGATION;
8916
8917
  /*
8918
   * Reinitialize 'rctx' to prepare for following the delegation:
8919
   * set the get_nameservers and next_server flags appropriately
8920
   * and reset the fetch context counters.
8921
   *
8922
   */
8923
0
  if ((rctx->fctx->options & DNS_FETCHOPT_NOFOLLOW) == 0) {
8924
0
    rctx->get_nameservers = true;
8925
0
    rctx->next_server = true;
8926
0
    rctx->fctx->restarts = 0;
8927
0
    rctx->fctx->referrals++;
8928
0
    rctx->fctx->querysent = 0;
8929
0
    rctx->fctx->lamecount = 0;
8930
0
    rctx->fctx->quotacount = 0;
8931
0
    rctx->fctx->neterr = 0;
8932
0
    rctx->fctx->badresp = 0;
8933
0
    rctx->fctx->adberr = 0;
8934
0
  }
8935
8936
0
  return ISC_R_COMPLETE;
8937
0
}
8938
8939
/*
8940
 * rctx_additional():
8941
 * Scan the additional section of a response to find records related
8942
 * to answers we were interested in.
8943
 */
8944
static void
8945
0
rctx_additional(respctx_t *rctx) {
8946
0
  bool rescan;
8947
0
  dns_section_t section = DNS_SECTION_ADDITIONAL;
8948
8949
0
again:
8950
0
  rescan = false;
8951
8952
0
  dns_message_t *msg = rctx->query->rmessage;
8953
0
  MSG_SECTION_FOREACH(msg, section, name) {
8954
0
    if (!name->attributes.chase) {
8955
0
      continue;
8956
0
    }
8957
0
    name->attributes.chase = false;
8958
0
    ISC_LIST_FOREACH(name->list, rdataset, link) {
8959
0
      if (CHASE(rdataset)) {
8960
0
        rdataset->attributes.chase = false;
8961
0
        (void)dns_rdataset_additionaldata(
8962
0
          rdataset, name, check_related, rctx,
8963
0
          DNS_RDATASET_MAXADDITIONAL);
8964
0
        rescan = true;
8965
0
      }
8966
0
    }
8967
0
  }
8968
0
  if (rescan) {
8969
0
    goto again;
8970
0
  }
8971
0
}
8972
8973
/*
8974
 * rctx_nextserver():
8975
 * We found something wrong with the remote server, but it may be
8976
 * useful to try another one.
8977
 */
8978
static void
8979
rctx_nextserver(respctx_t *rctx, dns_message_t *message,
8980
0
    dns_adbaddrinfo_t *addrinfo, isc_result_t result) {
8981
0
  fetchctx_t *fctx = rctx->fctx;
8982
0
  bool retrying = true;
8983
8984
0
  if (result == DNS_R_FORMERR) {
8985
0
    rctx->broken_server = DNS_R_FORMERR;
8986
0
  }
8987
0
  if (rctx->broken_server != ISC_R_SUCCESS) {
8988
    /*
8989
     * Add this server to the list of bad servers for
8990
     * this fctx.
8991
     */
8992
0
    add_bad(fctx, message, addrinfo, rctx->broken_server,
8993
0
      rctx->broken_type);
8994
0
  }
8995
8996
0
  if (rctx->get_nameservers) {
8997
0
    dns_fixedname_t foundname, founddc;
8998
0
    dns_name_t *name, *fname, *dcname;
8999
0
    unsigned int findoptions = 0;
9000
9001
0
    fname = dns_fixedname_initname(&foundname);
9002
0
    dcname = dns_fixedname_initname(&founddc);
9003
9004
0
    if (result != ISC_R_SUCCESS) {
9005
0
      fctx_done_detach(&rctx->fctx, DNS_R_SERVFAIL);
9006
0
      return;
9007
0
    }
9008
0
    if (dns_rdatatype_atparent(fctx->type)) {
9009
0
      findoptions |= DNS_DBFIND_NOEXACT;
9010
0
    }
9011
    /* FIXME: Why??? */
9012
0
    if ((rctx->retryopts & DNS_FETCHOPT_UNSHARED) == 0) {
9013
0
      name = fctx->name;
9014
0
    } else {
9015
0
      name = fctx->domain;
9016
0
    }
9017
0
    result = dns_view_findzonecut(
9018
0
      fctx->res->view, name, fname, dcname, fctx->now,
9019
0
      findoptions, true, true, &fctx->nameservers, NULL);
9020
0
    if (result != ISC_R_SUCCESS) {
9021
0
      FCTXTRACE("couldn't find a zonecut");
9022
0
      fctx_done_detach(&rctx->fctx, DNS_R_SERVFAIL);
9023
0
      return;
9024
0
    }
9025
0
    if (!dns_name_issubdomain(fname, fctx->domain)) {
9026
      /*
9027
       * The best nameservers are now above our
9028
       * QDOMAIN.
9029
       */
9030
0
      FCTXTRACE("nameservers now above QDOMAIN");
9031
0
      fctx_done_detach(&rctx->fctx, DNS_R_SERVFAIL);
9032
0
      return;
9033
0
    }
9034
9035
0
    fcount_decr(fctx);
9036
9037
0
    dns_name_copy(fname, fctx->domain);
9038
0
    dns_name_copy(dcname, fctx->qmindcname);
9039
9040
0
    result = fcount_incr(fctx, true);
9041
0
    if (result != ISC_R_SUCCESS) {
9042
0
      fctx_done_detach(&rctx->fctx, DNS_R_SERVFAIL);
9043
0
      return;
9044
0
    }
9045
0
    fctx->ns_ttl = fctx->nameservers.ttl;
9046
0
    fctx->ns_ttl_ok = true;
9047
0
    fctx_cancelqueries(fctx, true, false);
9048
0
    fctx_cleanup(fctx);
9049
0
    retrying = false;
9050
0
  }
9051
9052
  /*
9053
   * Try again.
9054
   */
9055
0
  fctx_try(fctx, retrying);
9056
0
}
9057
9058
/*
9059
 * rctx_resend():
9060
 *
9061
 * Resend the query, probably with the options changed. Calls
9062
 * fctx_query(), passing rctx->retryopts (which is based on
9063
 * query->options, but may have been updated since the last time
9064
 * fctx_query() was called).
9065
 */
9066
static void
9067
0
rctx_resend(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo) {
9068
0
  fetchctx_t *fctx = rctx->fctx;
9069
0
  isc_result_t result;
9070
9071
0
  FCTXTRACE("resend");
9072
0
  inc_stats(fctx->res, dns_resstatscounter_retry);
9073
0
  result = fctx_query(fctx, addrinfo, rctx->retryopts);
9074
0
  if (result != ISC_R_SUCCESS) {
9075
0
    fctx_done_detach(&rctx->fctx, result);
9076
0
  }
9077
0
}
9078
9079
/*
9080
 * rctx_next():
9081
 * We got what appeared to be a response but it didn't match the
9082
 * question or the cookie; it may have been meant for someone else, or
9083
 * it may be a spoofing attack. Drop it and continue listening for the
9084
 * response we wanted.
9085
 */
9086
static isc_result_t
9087
0
rctx_next(respctx_t *rctx) {
9088
0
  fetchctx_t *fctx = rctx->fctx;
9089
0
  isc_result_t result;
9090
9091
0
  FCTXTRACE("nextitem");
9092
0
  inc_stats(rctx->fctx->res, dns_resstatscounter_nextitem);
9093
0
  INSIST(rctx->query->dispentry != NULL);
9094
0
  dns_message_reset(rctx->query->rmessage, DNS_MESSAGE_INTENTPARSE);
9095
0
  result = dns_dispatch_getnext(rctx->query->dispentry);
9096
0
  return result;
9097
0
}
9098
9099
/*
9100
 * rctx_chaseds():
9101
 * Look up the parent zone's NS records so that DS records can be
9102
 * fetched.
9103
 */
9104
static void
9105
rctx_chaseds(respctx_t *rctx, dns_message_t *message,
9106
0
       dns_adbaddrinfo_t *addrinfo, isc_result_t result) {
9107
0
  fetchctx_t *fctx = rctx->fctx;
9108
0
  unsigned int n;
9109
9110
0
  add_bad(fctx, message, addrinfo, result, rctx->broken_type);
9111
0
  fctx_cancelqueries(fctx, true, false);
9112
0
  fctx_cleanup(fctx);
9113
9114
0
  n = dns_name_countlabels(fctx->name);
9115
0
  dns_name_getlabelsequence(fctx->name, 1, n - 1, fctx->nsname);
9116
9117
0
  FCTXTRACE("suspending DS lookup to find parent's NS records");
9118
9119
0
  fetchctx_ref(fctx);
9120
0
  result = dns_resolver_createfetch(
9121
0
    fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
9122
0
    NULL, 0, fctx->options, 0, fctx->qc, fctx->gqc, fctx->loop,
9123
0
    resume_dslookup, fctx, &fctx->edectx, &fctx->nsrrset, NULL,
9124
0
    &fctx->nsfetch);
9125
0
  if (result != ISC_R_SUCCESS) {
9126
0
    if (result == DNS_R_DUPLICATE) {
9127
0
      result = DNS_R_SERVFAIL;
9128
0
    }
9129
0
    fctx_done_detach(&rctx->fctx, result);
9130
0
    fetchctx_detach(&fctx);
9131
0
    return;
9132
0
  }
9133
0
}
9134
9135
/*
9136
 * rctx_done():
9137
 * This resolver query response is finished, either because we
9138
 * encountered a problem or because we've gotten all the information
9139
 * from it that we can.  We either wait for another response, resend the
9140
 * query to the same server, resend to a new server, or clean up and
9141
 * shut down the fetch.
9142
 */
9143
static void
9144
0
rctx_done(respctx_t *rctx, isc_result_t result) {
9145
0
  resquery_t *query = rctx->query;
9146
0
  fetchctx_t *fctx = rctx->fctx;
9147
0
  dns_adbaddrinfo_t *addrinfo = query->addrinfo;
9148
0
  dns_message_t *message = NULL;
9149
9150
  /*
9151
   * Need to attach to the message until the scope
9152
   * of this function ends, since there are many places
9153
   * where the message is used and/or may be destroyed
9154
   * before this function ends.
9155
   */
9156
0
  dns_message_attach(query->rmessage, &message);
9157
9158
0
  FCTXTRACE4("query canceled in rctx_done();",
9159
0
       rctx->no_response ? "no response" : "responding", result);
9160
9161
#ifdef ENABLE_AFL
9162
  if (dns_fuzzing_resolver &&
9163
      (rctx->next_server || rctx->resend || rctx->nextitem))
9164
  {
9165
    fctx_cancelquery(&query, rctx->finish, rctx->no_response,
9166
         false);
9167
    fctx_done_detach(&rctx->fctx, DNS_R_SERVFAIL);
9168
    goto detach;
9169
  }
9170
#endif /* ifdef ENABLE_AFL */
9171
9172
0
  if (rctx->nextitem) {
9173
0
    REQUIRE(!rctx->next_server);
9174
0
    REQUIRE(!rctx->resend);
9175
9176
0
    result = rctx_next(rctx);
9177
0
    if (result == ISC_R_SUCCESS) {
9178
0
      goto detach;
9179
0
    }
9180
0
  }
9181
9182
  /* Cancel the query */
9183
0
  fctx_cancelquery(&query, rctx->finish, rctx->no_response, false);
9184
9185
  /*
9186
   * If nobody's waiting for results, don't resend or try next server.
9187
   */
9188
0
  LOCK(&fctx->lock);
9189
0
  if (ISC_LIST_EMPTY(fctx->resps)) {
9190
0
    rctx->next_server = false;
9191
0
    rctx->resend = false;
9192
0
  }
9193
0
  UNLOCK(&fctx->lock);
9194
9195
0
  if (rctx->next_server) {
9196
0
    rctx_nextserver(rctx, message, addrinfo, result);
9197
0
  } else if (rctx->resend) {
9198
0
    rctx_resend(rctx, addrinfo);
9199
0
  } else if (result == DNS_R_CHASEDSSERVERS) {
9200
0
    rctx_chaseds(rctx, message, addrinfo, result);
9201
0
  } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
9202
    /*
9203
     * All has gone well so far, but we are waiting for the DNSSEC
9204
     * validator to validate the answer.
9205
     */
9206
0
    FCTXTRACE("wait for validator");
9207
0
    fctx_cancelqueries(fctx, true, false);
9208
0
  } else {
9209
    /*
9210
     * We're done.
9211
     */
9212
0
    fctx_done_detach(&rctx->fctx, result);
9213
0
  }
9214
9215
0
detach:
9216
0
  dns_message_detach(&message);
9217
0
}
9218
9219
/*
9220
 * rctx_logpacket():
9221
 * Log the incoming packet; also log to DNSTAP if configured.
9222
 */
9223
static void
9224
0
rctx_logpacket(respctx_t *rctx) {
9225
0
  fetchctx_t *fctx = rctx->fctx;
9226
0
  isc_result_t result;
9227
0
  isc_sockaddr_t localaddr, *la = NULL;
9228
#ifdef HAVE_DNSTAP
9229
  unsigned char zone[DNS_NAME_MAXWIRE];
9230
  dns_transport_type_t transport_type;
9231
  dns_dtmsgtype_t dtmsgtype;
9232
  dns_compress_t cctx;
9233
  isc_region_t zr;
9234
  isc_buffer_t zb;
9235
#endif /* HAVE_DNSTAP */
9236
9237
0
  result = dns_dispentry_getlocaladdress(rctx->query->dispentry,
9238
0
                 &localaddr);
9239
0
  if (result == ISC_R_SUCCESS) {
9240
0
    la = &localaddr;
9241
0
  }
9242
9243
0
  dns_message_logpacketfromto(
9244
0
    rctx->query->rmessage, "received packet",
9245
0
    &rctx->query->addrinfo->sockaddr, la, DNS_LOGCATEGORY_RESOLVER,
9246
0
    DNS_LOGMODULE_PACKETS, ISC_LOG_DEBUG(10), fctx->mctx);
9247
9248
#ifdef HAVE_DNSTAP
9249
  /*
9250
   * Log the response via dnstap.
9251
   */
9252
  memset(&zr, 0, sizeof(zr));
9253
  dns_compress_init(&cctx, fctx->mctx, 0);
9254
  dns_compress_setpermitted(&cctx, false);
9255
  isc_buffer_init(&zb, zone, sizeof(zone));
9256
  result = dns_name_towire(fctx->domain, &cctx, &zb);
9257
  if (result == ISC_R_SUCCESS) {
9258
    isc_buffer_usedregion(&zb, &zr);
9259
  }
9260
  dns_compress_invalidate(&cctx);
9261
9262
  if ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0) {
9263
    dtmsgtype = DNS_DTTYPE_FR;
9264
  } else {
9265
    dtmsgtype = DNS_DTTYPE_RR;
9266
  }
9267
9268
  if (rctx->query->addrinfo->transport != NULL) {
9269
    transport_type = dns_transport_get_type(
9270
      rctx->query->addrinfo->transport);
9271
  } else if ((rctx->query->options & DNS_FETCHOPT_TCP) != 0) {
9272
    transport_type = DNS_TRANSPORT_TCP;
9273
  } else {
9274
    transport_type = DNS_TRANSPORT_UDP;
9275
  }
9276
9277
  dns_dt_send(fctx->res->view, dtmsgtype, la,
9278
        &rctx->query->addrinfo->sockaddr, transport_type, &zr,
9279
        &rctx->query->start, NULL, &rctx->buffer);
9280
#endif /* HAVE_DNSTAP */
9281
0
}
9282
9283
/*
9284
 * rctx_badserver():
9285
 * Is the remote server broken, or does it dislike us?
9286
 */
9287
static isc_result_t
9288
0
rctx_badserver(respctx_t *rctx, isc_result_t result) {
9289
0
  fetchctx_t *fctx = rctx->fctx;
9290
0
  resquery_t *query = rctx->query;
9291
0
  isc_buffer_t b;
9292
0
  char code[64];
9293
0
  dns_rcode_t rcode = rctx->query->rmessage->rcode;
9294
9295
0
  QTRACE("rctx_badserver");
9296
9297
0
  if (rcode == dns_rcode_noerror || rcode == dns_rcode_yxdomain ||
9298
0
      rcode == dns_rcode_nxdomain)
9299
0
  {
9300
0
    return ISC_R_SUCCESS;
9301
0
  }
9302
9303
0
  if ((rcode == dns_rcode_formerr) && rctx->opt == NULL &&
9304
0
      (rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
9305
0
  {
9306
    /*
9307
     * It's very likely they don't like EDNS0.
9308
     */
9309
0
    rctx->retryopts |= DNS_FETCHOPT_NOEDNS0;
9310
0
    rctx->resend = true;
9311
    /*
9312
     * Remember that they may not like EDNS0.
9313
     */
9314
0
    inc_stats(fctx->res, dns_resstatscounter_edns0fail);
9315
0
  } else if (rcode == dns_rcode_formerr) {
9316
0
    if (query->rmessage->cc_echoed) {
9317
      /*
9318
       * Retry without DNS COOKIE.
9319
       */
9320
0
      query->addrinfo->flags |= FCTX_ADDRINFO_NOCOOKIE;
9321
0
      rctx->resend = true;
9322
0
      log_formerr(fctx, "server sent FORMERR with echoed DNS "
9323
0
            "COOKIE");
9324
0
    } else {
9325
      /*
9326
       * The server (or forwarder) doesn't understand us,
9327
       * but others might.
9328
       */
9329
0
      rctx->next_server = true;
9330
0
      rctx->broken_server = DNS_R_REMOTEFORMERR;
9331
0
      log_formerr(fctx, "server sent FORMERR");
9332
0
    }
9333
0
  } else if (rcode == dns_rcode_badvers) {
9334
0
    unsigned int version;
9335
#if DNS_EDNS_VERSION > 0
9336
    unsigned int flags, mask;
9337
#endif /* if DNS_EDNS_VERSION > 0 */
9338
9339
0
    INSIST(rctx->opt != NULL);
9340
0
    version = (rctx->opt->ttl >> 16) & 0xff;
9341
#if DNS_EDNS_VERSION > 0
9342
    flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) |
9343
      DNS_FETCHOPT_EDNSVERSIONSET;
9344
    mask = DNS_FETCHOPT_EDNSVERSIONMASK |
9345
           DNS_FETCHOPT_EDNSVERSIONSET;
9346
#endif /* if DNS_EDNS_VERSION > 0 */
9347
9348
    /*
9349
     * Record that we got a good EDNS response.
9350
     */
9351
0
    if (query->ednsversion > (int)version &&
9352
0
        !EDNSOK(query->addrinfo))
9353
0
    {
9354
0
      dns_adb_changeflags(fctx->adb, query->addrinfo,
9355
0
              FCTX_ADDRINFO_EDNSOK,
9356
0
              FCTX_ADDRINFO_EDNSOK);
9357
0
    }
9358
9359
    /*
9360
     * RFC 2671 was not clear that unknown options should
9361
     * be ignored.  RFC 6891 is clear that that they
9362
     * should be ignored. If we are supporting the
9363
     * experimental EDNS > 0 then perform strict
9364
     * version checking of badvers responses.  We won't
9365
     * be sending COOKIE etc. in that case.
9366
     */
9367
#if DNS_EDNS_VERSION > 0
9368
    if ((int)version < query->ednsversion) {
9369
      dns_adb_changeflags(fctx->adb, query->addrinfo, flags,
9370
              mask);
9371
      rctx->resend = true;
9372
    } else {
9373
      rctx->broken_server = DNS_R_BADVERS;
9374
      rctx->next_server = true;
9375
    }
9376
#else  /* if DNS_EDNS_VERSION > 0 */
9377
0
    rctx->broken_server = DNS_R_BADVERS;
9378
0
    rctx->next_server = true;
9379
0
#endif /* if DNS_EDNS_VERSION > 0 */
9380
0
  } else if (rcode == dns_rcode_badcookie && rctx->query->rmessage->cc_ok)
9381
0
  {
9382
    /*
9383
     * We have recorded the new cookie.
9384
     */
9385
0
    if (BADCOOKIE(query->addrinfo)) {
9386
0
      rctx->retryopts |= DNS_FETCHOPT_TCP;
9387
0
    }
9388
0
    query->addrinfo->flags |= FCTX_ADDRINFO_BADCOOKIE;
9389
0
    rctx->resend = true;
9390
0
  } else if (ISFORWARDER(query->addrinfo) &&
9391
0
       query->rmessage->rcode == dns_rcode_servfail &&
9392
0
       (query->options & DNS_FETCHOPT_TRYCD) != 0)
9393
0
  {
9394
    /*
9395
     * We got a SERVFAIL from a forwarder with
9396
     * CD=0; try again with CD=1.
9397
     */
9398
0
    rctx->retryopts |= DNS_FETCHOPT_TRYCD;
9399
0
    rctx->resend = true;
9400
0
  } else {
9401
0
    rctx->broken_server = DNS_R_UNEXPECTEDRCODE;
9402
0
    rctx->next_server = true;
9403
0
  }
9404
9405
0
  isc_buffer_init(&b, code, sizeof(code) - 1);
9406
0
  dns_rcode_totext(rcode, &b);
9407
0
  code[isc_buffer_usedlength(&b)] = '\0';
9408
0
  FCTXTRACE2("remote server broken: returned ", code);
9409
0
  rctx_done(rctx, result);
9410
9411
0
  return ISC_R_COMPLETE;
9412
0
}
9413
9414
/*
9415
 * rctx_lameserver():
9416
 * Is the server lame?
9417
 */
9418
static isc_result_t
9419
0
rctx_lameserver(respctx_t *rctx) {
9420
0
  isc_result_t result = ISC_R_SUCCESS;
9421
0
  fetchctx_t *fctx = rctx->fctx;
9422
0
  resquery_t *query = rctx->query;
9423
9424
0
  if (ISFORWARDER(query->addrinfo) || !is_lame(fctx, query->rmessage)) {
9425
0
    return ISC_R_SUCCESS;
9426
0
  }
9427
9428
0
  inc_stats(fctx->res, dns_resstatscounter_lame);
9429
0
  log_lame(fctx, query->addrinfo);
9430
0
  rctx->broken_server = DNS_R_LAME;
9431
0
  rctx->next_server = true;
9432
0
  FCTXTRACE("lame server");
9433
0
  rctx_done(rctx, result);
9434
9435
0
  return ISC_R_COMPLETE;
9436
0
}
9437
9438
/***
9439
 *** Resolver Methods
9440
 ***/
9441
static void
9442
0
dns_resolver__destroy(dns_resolver_t *res) {
9443
0
  alternate_t *a = NULL;
9444
9445
0
  REQUIRE(!atomic_load_acquire(&res->priming));
9446
0
  REQUIRE(res->primefetch == NULL);
9447
9448
0
  RTRACE("destroy");
9449
9450
0
  res->magic = 0;
9451
9452
0
  dns_nametree_detach(&res->algorithms);
9453
0
  dns_nametree_detach(&res->digests);
9454
9455
0
  if (res->querystats != NULL) {
9456
0
    dns_stats_detach(&res->querystats);
9457
0
  }
9458
0
  if (res->stats != NULL) {
9459
0
    isc_stats_detach(&res->stats);
9460
0
  }
9461
9462
0
  isc_mutex_destroy(&res->primelock);
9463
0
  isc_mutex_destroy(&res->lock);
9464
9465
0
  INSIST(isc_hashmap_count(res->fctxs) == 0);
9466
0
  isc_hashmap_destroy(&res->fctxs);
9467
0
  isc_rwlock_destroy(&res->fctxs_lock);
9468
9469
0
  INSIST(isc_hashmap_count(res->counters) == 0);
9470
0
  isc_hashmap_destroy(&res->counters);
9471
0
  isc_rwlock_destroy(&res->counters_lock);
9472
9473
0
  if (res->dispatches4 != NULL) {
9474
0
    dns_dispatchset_destroy(&res->dispatches4);
9475
0
  }
9476
0
  if (res->dispatches6 != NULL) {
9477
0
    dns_dispatchset_destroy(&res->dispatches6);
9478
0
  }
9479
0
  while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
9480
0
    ISC_LIST_UNLINK(res->alternates, a, link);
9481
0
    if (!a->isaddress) {
9482
0
      dns_name_free(&a->_u._n.name, res->mctx);
9483
0
    }
9484
0
    isc_mem_put(res->mctx, a, sizeof(*a));
9485
0
  }
9486
9487
0
  dns_view_weakdetach(&res->view);
9488
9489
0
  for (size_t i = 0; i < res->nloops; i++) {
9490
0
    dns_message_destroypools(&res->namepools[i], &res->rdspools[i]);
9491
0
  }
9492
0
  isc_mem_cput(res->mctx, res->rdspools, res->nloops,
9493
0
         sizeof(res->rdspools[0]));
9494
0
  isc_mem_cput(res->mctx, res->namepools, res->nloops,
9495
0
         sizeof(res->namepools[0]));
9496
9497
0
  isc_mem_putanddetach(&res->mctx, res, sizeof(*res));
9498
0
}
9499
9500
static void
9501
0
spillattimer_countdown(void *arg) {
9502
0
  dns_resolver_t *res = (dns_resolver_t *)arg;
9503
0
  unsigned int spillat = 0;
9504
9505
0
  REQUIRE(VALID_RESOLVER(res));
9506
9507
0
  if (atomic_load(&res->exiting)) {
9508
0
    isc_timer_destroy(&res->spillattimer);
9509
0
    return;
9510
0
  }
9511
9512
0
  LOCK(&res->lock);
9513
0
  INSIST(!atomic_load_acquire(&res->exiting));
9514
0
  if (res->spillat > res->spillatmin) {
9515
0
    spillat = --res->spillat;
9516
0
  }
9517
0
  if (res->spillat <= res->spillatmin) {
9518
0
    isc_timer_destroy(&res->spillattimer);
9519
0
  }
9520
0
  UNLOCK(&res->lock);
9521
0
  if (spillat > 0) {
9522
0
    isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
9523
0
            ISC_LOG_NOTICE,
9524
0
            "clients-per-query decreased to %u", spillat);
9525
0
  }
9526
0
}
9527
9528
isc_result_t
9529
dns_resolver_create(dns_view_t *view, unsigned int options,
9530
        isc_tlsctx_cache_t *tlsctx_cache,
9531
        dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
9532
0
        dns_resolver_t **resp) {
9533
0
  dns_resolver_t *res = NULL;
9534
9535
  /*
9536
   * Create a resolver.
9537
   */
9538
9539
0
  REQUIRE(DNS_VIEW_VALID(view));
9540
0
  REQUIRE(resp != NULL && *resp == NULL);
9541
0
  REQUIRE(tlsctx_cache != NULL);
9542
0
  REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
9543
9544
0
  res = isc_mem_get(view->mctx, sizeof(*res));
9545
0
  *res = (dns_resolver_t){
9546
0
    .rdclass = view->rdclass,
9547
0
    .options = options,
9548
0
    .tlsctx_cache = tlsctx_cache,
9549
0
    .spillatmin = 10,
9550
0
    .spillat = 10,
9551
0
    .spillatmax = 100,
9552
0
    .retryinterval = 800,
9553
0
    .nonbackofftries = 3,
9554
0
    .query_timeout = DEFAULT_QUERY_TIMEOUT,
9555
0
    .maxdepth = DEFAULT_RECURSION_DEPTH,
9556
0
    .maxqueries = DEFAULT_MAX_QUERIES,
9557
0
    .alternates = ISC_LIST_INITIALIZER,
9558
0
    .nloops = isc_loopmgr_nloops(),
9559
0
    .maxvalidations = DEFAULT_MAX_VALIDATIONS,
9560
0
    .maxvalidationfails = DEFAULT_MAX_VALIDATION_FAILURES,
9561
0
  };
9562
9563
0
  RTRACE("create");
9564
9565
0
  dns_view_weakattach(view, &res->view);
9566
0
  isc_mem_attach(view->mctx, &res->mctx);
9567
9568
0
  res->quotaresp[dns_quotatype_zone] = DNS_R_DROP;
9569
0
  res->quotaresp[dns_quotatype_server] = DNS_R_SERVFAIL;
9570
9571
#if DNS_RESOLVER_TRACE
9572
  fprintf(stderr, "dns_resolver__init:%s:%s:%d:%p->references = 1\n",
9573
    __func__, __FILE__, __LINE__, res);
9574
#endif
9575
0
  isc_refcount_init(&res->references, 1);
9576
9577
0
  isc_hashmap_create(view->mctx, RES_DOMAIN_HASH_BITS, &res->fctxs);
9578
0
  isc_rwlock_init(&res->fctxs_lock);
9579
9580
0
  isc_hashmap_create(view->mctx, RES_DOMAIN_HASH_BITS, &res->counters);
9581
0
  isc_rwlock_init(&res->counters_lock);
9582
9583
0
  if (dispatchv4 != NULL) {
9584
0
    dns_dispatchset_create(res->mctx, dispatchv4, &res->dispatches4,
9585
0
               res->nloops);
9586
0
  }
9587
9588
0
  if (dispatchv6 != NULL) {
9589
0
    dns_dispatchset_create(res->mctx, dispatchv6, &res->dispatches6,
9590
0
               res->nloops);
9591
0
  }
9592
9593
0
  isc_mutex_init(&res->lock);
9594
0
  isc_mutex_init(&res->primelock);
9595
9596
0
  dns_nametree_create(res->mctx, DNS_NAMETREE_BITS, "algorithms",
9597
0
          &res->algorithms);
9598
0
  dns_nametree_create(res->mctx, DNS_NAMETREE_BITS, "ds-digests",
9599
0
          &res->digests);
9600
9601
0
  res->namepools = isc_mem_cget(res->mctx, res->nloops,
9602
0
              sizeof(res->namepools[0]));
9603
0
  res->rdspools = isc_mem_cget(res->mctx, res->nloops,
9604
0
             sizeof(res->rdspools[0]));
9605
0
  for (size_t i = 0; i < res->nloops; i++) {
9606
0
    isc_loop_t *loop = isc_loop_get(i);
9607
0
    isc_mem_t *pool_mctx = isc_loop_getmctx(loop);
9608
9609
0
    dns_message_createpools(pool_mctx, &res->namepools[i],
9610
0
          &res->rdspools[i]);
9611
0
  }
9612
9613
0
  res->magic = RES_MAGIC;
9614
9615
0
  *resp = res;
9616
9617
0
  return ISC_R_SUCCESS;
9618
0
}
9619
9620
static void
9621
0
prime_done(void *arg) {
9622
0
  dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg;
9623
0
  dns_resolver_t *res = resp->arg;
9624
0
  dns_fetch_t *fetch = NULL;
9625
0
  dns_db_t *db = NULL;
9626
9627
0
  REQUIRE(VALID_RESOLVER(res));
9628
9629
0
  int level = (resp->result == ISC_R_SUCCESS) ? ISC_LOG_DEBUG(1)
9630
0
                : ISC_LOG_NOTICE;
9631
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, level,
9632
0
          "resolver priming query complete: %s",
9633
0
          isc_result_totext(resp->result));
9634
9635
0
  LOCK(&res->primelock);
9636
0
  fetch = res->primefetch;
9637
0
  res->primefetch = NULL;
9638
0
  UNLOCK(&res->primelock);
9639
9640
0
  atomic_compare_exchange_enforced(&res->priming, &(bool){ true }, false);
9641
9642
0
  if (resp->result == ISC_R_SUCCESS && res->view->cache != NULL &&
9643
0
      res->view->hints != NULL)
9644
0
  {
9645
0
    dns_cache_attachdb(res->view->cache, &db);
9646
0
    dns_root_checkhints(res->view, res->view->hints, db);
9647
0
    dns_db_detach(&db);
9648
0
  }
9649
9650
0
  if (resp->node != NULL) {
9651
0
    dns_db_detachnode(&resp->node);
9652
0
  }
9653
0
  if (resp->db != NULL) {
9654
0
    dns_db_detach(&resp->db);
9655
0
  }
9656
0
  if (dns_rdataset_isassociated(resp->rdataset)) {
9657
0
    dns_rdataset_disassociate(resp->rdataset);
9658
0
  }
9659
0
  INSIST(resp->sigrdataset == NULL);
9660
9661
0
  isc_mem_put(res->mctx, resp->rdataset, sizeof(*resp->rdataset));
9662
0
  dns_resolver_freefresp(&resp);
9663
0
  dns_resolver_destroyfetch(&fetch);
9664
0
}
9665
9666
void
9667
0
dns_resolver_prime(dns_resolver_t *res) {
9668
0
  bool want_priming = false;
9669
0
  isc_result_t result;
9670
9671
0
  REQUIRE(VALID_RESOLVER(res));
9672
0
  REQUIRE(res->frozen);
9673
9674
0
  RTRACE("dns_resolver_prime");
9675
9676
0
  if (!atomic_load_acquire(&res->exiting)) {
9677
0
    want_priming = atomic_compare_exchange_strong_acq_rel(
9678
0
      &res->priming, &(bool){ false }, true);
9679
0
  }
9680
9681
0
  if (want_priming) {
9682
    /*
9683
     * To avoid any possible recursive locking problems, we
9684
     * start the priming fetch like any other fetch, and
9685
     * holding no resolver locks.  No one else will try to
9686
     * start it because we're the ones who set res->priming
9687
     * to true. Any other callers of dns_resolver_prime()
9688
     * while we're running will see that res->priming is
9689
     * already true and do nothing.
9690
     */
9691
0
    RTRACE("priming");
9692
9693
0
    dns_rdataset_t *rdataset = isc_mem_get(res->mctx,
9694
0
                   sizeof(*rdataset));
9695
0
    dns_rdataset_init(rdataset);
9696
9697
0
    LOCK(&res->primelock);
9698
0
    result = dns_resolver_createfetch(
9699
0
      res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL,
9700
0
      NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, NULL,
9701
0
      isc_loop(), prime_done, res, NULL, rdataset, NULL,
9702
0
      &res->primefetch);
9703
0
    UNLOCK(&res->primelock);
9704
9705
0
    if (result != ISC_R_SUCCESS) {
9706
0
      isc_mem_put(res->mctx, rdataset, sizeof(*rdataset));
9707
0
      atomic_compare_exchange_enforced(
9708
0
        &res->priming, &(bool){ true }, false);
9709
0
    }
9710
0
    inc_stats(res, dns_resstatscounter_priming);
9711
0
  }
9712
0
}
9713
9714
void
9715
0
dns_resolver_freeze(dns_resolver_t *res) {
9716
  /*
9717
   * Freeze resolver.
9718
   */
9719
9720
0
  REQUIRE(VALID_RESOLVER(res));
9721
9722
0
  res->frozen = true;
9723
0
}
9724
9725
void
9726
0
dns_resolver_shutdown(dns_resolver_t *res) {
9727
0
  isc_result_t result;
9728
0
  bool is_false = false;
9729
9730
0
  REQUIRE(VALID_RESOLVER(res));
9731
9732
0
  RTRACE("shutdown");
9733
9734
0
  if (atomic_compare_exchange_strong(&res->exiting, &is_false, true)) {
9735
0
    isc_hashmap_iter_t *it = NULL;
9736
9737
0
    RTRACE("exiting");
9738
9739
0
    RWLOCK(&res->fctxs_lock, isc_rwlocktype_write);
9740
0
    isc_hashmap_iter_create(res->fctxs, &it);
9741
0
    for (result = isc_hashmap_iter_first(it);
9742
0
         result == ISC_R_SUCCESS;
9743
0
         result = isc_hashmap_iter_next(it))
9744
0
    {
9745
0
      fetchctx_t *fctx = NULL;
9746
9747
0
      isc_hashmap_iter_current(it, (void **)&fctx);
9748
0
      INSIST(fctx != NULL);
9749
9750
0
      fetchctx_ref(fctx);
9751
0
      isc_async_run(fctx->loop, fctx_shutdown, fctx);
9752
0
    }
9753
0
    isc_hashmap_iter_destroy(&it);
9754
0
    RWUNLOCK(&res->fctxs_lock, isc_rwlocktype_write);
9755
9756
0
    LOCK(&res->lock);
9757
0
    if (res->spillattimer != NULL) {
9758
0
      isc_timer_async_destroy(&res->spillattimer);
9759
0
    }
9760
0
    UNLOCK(&res->lock);
9761
0
  }
9762
0
}
9763
9764
#if DNS_RESOLVER_TRACE
9765
ISC_REFCOUNT_TRACE_IMPL(dns_resolver, dns_resolver__destroy);
9766
#else
9767
ISC_REFCOUNT_IMPL(dns_resolver, dns_resolver__destroy);
9768
#endif
9769
9770
static void
9771
0
log_fetch(const dns_name_t *name, dns_rdatatype_t type) {
9772
0
  char namebuf[DNS_NAME_FORMATSIZE];
9773
0
  char typebuf[DNS_RDATATYPE_FORMATSIZE];
9774
0
  int level = ISC_LOG_DEBUG(1);
9775
9776
  /*
9777
   * If there's no chance of logging it, don't render (format) the
9778
   * name and RDATA type (further below), and return early.
9779
   */
9780
0
  if (!isc_log_wouldlog(level)) {
9781
0
    return;
9782
0
  }
9783
9784
0
  dns_name_format(name, namebuf, sizeof(namebuf));
9785
0
  dns_rdatatype_format(type, typebuf, sizeof(typebuf));
9786
9787
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, level,
9788
0
          "fetch: %s/%s", namebuf, typebuf);
9789
0
}
9790
9791
static void
9792
0
fctx_minimize_qname(fetchctx_t *fctx) {
9793
0
  isc_result_t result;
9794
0
  unsigned int dlabels, nlabels;
9795
0
  dns_name_t name;
9796
9797
0
  REQUIRE(VALID_FCTX(fctx));
9798
9799
0
  dns_name_init(&name);
9800
9801
0
  dlabels = dns_name_countlabels(fctx->qmindcname);
9802
0
  nlabels = dns_name_countlabels(fctx->name);
9803
9804
0
  if (dlabels > fctx->qmin_labels) {
9805
0
    fctx->qmin_labels = dlabels + 1;
9806
0
  } else {
9807
0
    fctx->qmin_labels++;
9808
0
  }
9809
9810
0
  if (fctx->ip6arpaskip) {
9811
    /*
9812
     * For ip6.arpa we want to skip some of the labels, with
9813
     * boundaries at /16, /32, /48, /56, /64 and /128
9814
     * In 'label count' terms that's equal to
9815
     *    7    11   15   17   19      35
9816
     * We fix fctx->qmin_labels to point to the nearest
9817
     * boundary
9818
     */
9819
0
    if (fctx->qmin_labels < 7) {
9820
0
      fctx->qmin_labels = 7;
9821
0
    } else if (fctx->qmin_labels < 11) {
9822
0
      fctx->qmin_labels = 11;
9823
0
    } else if (fctx->qmin_labels < 15) {
9824
0
      fctx->qmin_labels = 15;
9825
0
    } else if (fctx->qmin_labels < 17) {
9826
0
      fctx->qmin_labels = 17;
9827
0
    } else if (fctx->qmin_labels < 19) {
9828
0
      fctx->qmin_labels = 19;
9829
0
    } else if (fctx->qmin_labels < 35) {
9830
0
      fctx->qmin_labels = 35;
9831
0
    } else {
9832
0
      fctx->qmin_labels = nlabels + 1;
9833
0
    }
9834
0
  } else if (fctx->qmin_labels > DNS_QMIN_MAXLABELS) {
9835
0
    fctx->qmin_labels = DNS_NAME_MAXLABELS;
9836
0
  }
9837
9838
0
  if (fctx->qmin_labels <= nlabels) {
9839
0
    dns_rdataset_t rdataset;
9840
0
    dns_fixedname_t fixed;
9841
0
    dns_name_t *fname = dns_fixedname_initname(&fixed);
9842
0
    dns_rdataset_init(&rdataset);
9843
0
    do {
9844
      /*
9845
       * We want to query for qmin_labels from fctx->name.
9846
       */
9847
0
      dns_name_split(fctx->name, fctx->qmin_labels, NULL,
9848
0
               &name);
9849
      /*
9850
       * Look to see if we have anything cached about NS
9851
       * RRsets at this name and if so skip this name and
9852
       * try with an additional label prepended.
9853
       */
9854
0
      result = dns_db_find(fctx->cache, &name, NULL,
9855
0
               dns_rdatatype_ns, 0, 0, NULL,
9856
0
               fname, &rdataset, NULL);
9857
0
      if (dns_rdataset_isassociated(&rdataset)) {
9858
0
        dns_rdataset_disassociate(&rdataset);
9859
0
      }
9860
0
      switch (result) {
9861
0
      case ISC_R_SUCCESS:
9862
0
      case DNS_R_CNAME:
9863
0
      case DNS_R_DNAME:
9864
0
      case DNS_R_NCACHENXDOMAIN:
9865
0
      case DNS_R_NCACHENXRRSET:
9866
0
        fctx->qmin_labels++;
9867
0
        continue;
9868
0
      default:
9869
0
        break;
9870
0
      }
9871
0
      break;
9872
0
    } while (fctx->qmin_labels <= nlabels);
9873
0
  }
9874
9875
  /*
9876
   * DS lookups come from the parent zone so we don't need to do a
9877
   * NS lookup at the QNAME.  If the QTYPE is NS we are not leaking
9878
   * the type if we just do the final NS lookup.
9879
   */
9880
0
  if (fctx->qmin_labels < nlabels ||
9881
0
      (fctx->type != dns_rdatatype_ns && fctx->type != dns_rdatatype_ds &&
9882
0
       fctx->qmin_labels == nlabels))
9883
0
  {
9884
0
    dns_name_copy(&name, fctx->qminname);
9885
0
    fctx->qmintype = dns_rdatatype_ns;
9886
0
    fctx->minimized = true;
9887
0
  } else {
9888
    /* Minimization is done, we'll ask for whole qname */
9889
0
    dns_name_copy(fctx->name, fctx->qminname);
9890
0
    fctx->qmintype = fctx->type;
9891
0
    fctx->minimized = false;
9892
0
  }
9893
9894
0
  char domainbuf[DNS_NAME_FORMATSIZE];
9895
0
  dns_name_format(fctx->qminname, domainbuf, sizeof(domainbuf));
9896
0
  isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
9897
0
          ISC_LOG_DEBUG(5),
9898
0
          "QNAME minimization - %s minimized, qmintype %d "
9899
0
          "qminname %s",
9900
0
          fctx->minimized ? "" : "not", fctx->qmintype, domainbuf);
9901
0
}
9902
9903
static isc_result_t
9904
get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
9905
      dns_rdatatype_t type, const dns_name_t *domain,
9906
      dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
9907
      unsigned int options, unsigned int depth, isc_counter_t *qc,
9908
0
      isc_counter_t *gqc, fetchctx_t **fctxp, bool *new_fctx) {
9909
0
  isc_result_t result;
9910
0
  fetchctx_t key = {
9911
0
    .name = UNCONST(name),
9912
0
    .options = options,
9913
0
    .type = type,
9914
0
  };
9915
0
  fetchctx_t *fctx = NULL;
9916
0
  isc_rwlocktype_t locktype = isc_rwlocktype_read;
9917
0
  uint32_t hashval = fctx_hash(&key);
9918
9919
0
again:
9920
0
  RWLOCK(&res->fctxs_lock, locktype);
9921
0
  result = isc_hashmap_find(res->fctxs, hashval, fctx_match, &key,
9922
0
          (void **)&fctx);
9923
0
  switch (result) {
9924
0
  case ISC_R_SUCCESS:
9925
0
    break;
9926
0
  case ISC_R_NOTFOUND:
9927
0
    result = fctx_create(res, loop, name, type, domain, nameservers,
9928
0
             client, options, depth, qc, gqc, &fctx);
9929
0
    if (result != ISC_R_SUCCESS) {
9930
0
      RWUNLOCK(&res->fctxs_lock, locktype);
9931
0
      return result;
9932
0
    }
9933
9934
0
    UPGRADELOCK(&res->fctxs_lock, locktype);
9935
9936
0
    void *found = NULL;
9937
0
    result = isc_hashmap_add(res->fctxs, hashval, fctx_match, fctx,
9938
0
           fctx, &found);
9939
0
    if (result == ISC_R_SUCCESS) {
9940
0
      *new_fctx = true;
9941
0
    } else {
9942
      /*
9943
       * The fctx_done() tries to acquire the fctxs_lock.
9944
       * Destroy the newly created fetchctx directly.
9945
       */
9946
0
      fctx->state = fetchstate_done;
9947
0
      isc_timer_destroy(&fctx->timer);
9948
9949
0
      fetchctx_detach(&fctx);
9950
0
      fctx = found;
9951
0
      result = ISC_R_SUCCESS;
9952
0
    }
9953
0
    break;
9954
0
  default:
9955
0
    UNREACHABLE();
9956
0
  }
9957
0
  INSIST(result == ISC_R_SUCCESS);
9958
0
  fetchctx_ref(fctx);
9959
9960
  /*
9961
   * We need to lock the fetch context before unlocking the hash table to
9962
   * prevent other threads from looking up this thread before it has been
9963
   * properly initialized and started.
9964
   */
9965
0
  LOCK(&fctx->lock);
9966
0
  RWUNLOCK(&res->fctxs_lock, locktype);
9967
9968
0
  if (SHUTTINGDOWN(fctx) || fctx->cloned) {
9969
    /*
9970
     * This is the single place where fctx might get
9971
     * accesses from a different thread, so we need to
9972
     * double check whether fctxs is done (or cloned) and
9973
     * help with the release if the fctx has been cloned.
9974
     */
9975
0
    UNLOCK(&fctx->lock);
9976
9977
    /* The fctx will get deleted either here or in fctx__done() */
9978
0
    RWLOCK(&res->fctxs_lock, isc_rwlocktype_write);
9979
0
    (void)isc_hashmap_delete(res->fctxs, fctx_hash(fctx), match_ptr,
9980
0
           fctx);
9981
0
    RWUNLOCK(&res->fctxs_lock, isc_rwlocktype_write);
9982
9983
0
    fetchctx_detach(&fctx);
9984
0
    goto again;
9985
0
  }
9986
9987
  /*
9988
   * The function returns a locked fetch context,
9989
   */
9990
0
  *fctxp = fctx;
9991
9992
0
  return result;
9993
0
}
9994
9995
isc_result_t
9996
dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
9997
       dns_rdatatype_t type, const dns_name_t *domain,
9998
       dns_rdataset_t *nameservers,
9999
       dns_forwarders_t *forwarders,
10000
       const isc_sockaddr_t *client, dns_messageid_t id,
10001
       unsigned int options, unsigned int depth,
10002
       isc_counter_t *qc, isc_counter_t *gqc,
10003
       isc_loop_t *loop, isc_job_cb cb, void *arg,
10004
       dns_edectx_t *edectx, dns_rdataset_t *rdataset,
10005
0
       dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) {
10006
0
  dns_fetch_t *fetch = NULL;
10007
0
  fetchctx_t *fctx = NULL;
10008
0
  isc_result_t result = ISC_R_SUCCESS;
10009
0
  bool new_fctx = false;
10010
0
  unsigned int count = 0;
10011
0
  unsigned int spillat;
10012
0
  unsigned int spillatmin;
10013
0
  isc_mem_t *mctx = isc_loop_getmctx(loop);
10014
10015
0
  UNUSED(forwarders);
10016
10017
0
  REQUIRE(VALID_RESOLVER(res));
10018
0
  REQUIRE(res->frozen);
10019
  /* XXXRTH  Check for meta type */
10020
0
  if (domain != NULL) {
10021
0
    REQUIRE(DNS_RDATASET_VALID(nameservers));
10022
0
    REQUIRE(nameservers->type == dns_rdatatype_ns);
10023
0
  } else {
10024
0
    REQUIRE(nameservers == NULL);
10025
0
  }
10026
0
  REQUIRE(forwarders == NULL);
10027
0
  REQUIRE(!dns_rdataset_isassociated(rdataset));
10028
0
  REQUIRE(sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset));
10029
0
  REQUIRE(fetchp != NULL && *fetchp == NULL);
10030
10031
0
  if (atomic_load_acquire(&res->exiting)) {
10032
0
    return ISC_R_SHUTTINGDOWN;
10033
0
  }
10034
10035
0
  log_fetch(name, type);
10036
10037
0
  fetch = isc_mem_get(mctx, sizeof(*fetch));
10038
0
  *fetch = (dns_fetch_t){ 0 };
10039
10040
0
  dns_resolver_attach(res, &fetch->res);
10041
0
  isc_mem_attach(mctx, &fetch->mctx);
10042
10043
0
  if ((options & DNS_FETCHOPT_UNSHARED) == 0) {
10044
    /*
10045
     * We don't save the unshared fetch context to a bucket because
10046
     * we also would never match it again.
10047
     */
10048
10049
0
    LOCK(&res->lock);
10050
0
    spillat = res->spillat;
10051
0
    spillatmin = res->spillatmin;
10052
0
    UNLOCK(&res->lock);
10053
10054
0
    result = get_attached_fctx(res, loop, name, type, domain,
10055
0
             nameservers, client, options, depth,
10056
0
             qc, gqc, &fctx, &new_fctx);
10057
0
    if (result != ISC_R_SUCCESS) {
10058
0
      goto fail;
10059
0
    }
10060
10061
    /* On success, the fctx is locked in get_attached_fctx() */
10062
0
    INSIST(!SHUTTINGDOWN(fctx));
10063
10064
    /* Is this a duplicate? */
10065
0
    if (client != NULL) {
10066
0
      ISC_LIST_FOREACH(fctx->resps, resp, link) {
10067
0
        if (resp->client != NULL && resp->id == id &&
10068
0
            isc_sockaddr_equal(resp->client, client))
10069
0
        {
10070
0
          result = DNS_R_DUPLICATE;
10071
0
          goto unlock;
10072
0
        }
10073
10074
0
        count++;
10075
0
      }
10076
0
    }
10077
0
    if (count >= spillatmin && spillatmin != 0) {
10078
0
      if (count >= spillat) {
10079
0
        fctx->spilled = true;
10080
0
      }
10081
0
      if (fctx->spilled) {
10082
0
        inc_stats(res, dns_resstatscounter_clientquota);
10083
0
        fctx->dropped++;
10084
0
        result = DNS_R_DROP;
10085
0
        goto unlock;
10086
0
      }
10087
0
    }
10088
0
  } else {
10089
0
    result = fctx_create(res, loop, name, type, domain, nameservers,
10090
0
             client, options, depth, qc, gqc, &fctx);
10091
0
    if (result != ISC_R_SUCCESS) {
10092
0
      goto fail;
10093
0
    }
10094
0
    new_fctx = true;
10095
0
  }
10096
10097
0
  RUNTIME_CHECK(fctx != NULL);
10098
10099
0
  if (fctx->depth > depth) {
10100
0
    fctx->depth = depth;
10101
0
  }
10102
10103
0
  fctx->allowed++;
10104
10105
0
  fctx_join(fctx, loop, client, id, cb, arg, edectx, rdataset,
10106
0
      sigrdataset, fetch);
10107
10108
0
  if (new_fctx) {
10109
0
    fetchctx_ref(fctx);
10110
0
    isc_async_run(fctx->loop, fctx_start, fctx);
10111
0
  }
10112
10113
0
unlock:
10114
0
  if ((options & DNS_FETCHOPT_UNSHARED) == 0) {
10115
0
    UNLOCK(&fctx->lock);
10116
0
    fetchctx_unref(fctx);
10117
0
  }
10118
10119
0
fail:
10120
0
  if (result != ISC_R_SUCCESS) {
10121
0
    dns_resolver_detach(&fetch->res);
10122
0
    isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch));
10123
0
    return result;
10124
0
  }
10125
10126
0
  FTRACE("created");
10127
0
  *fetchp = fetch;
10128
10129
0
  return ISC_R_SUCCESS;
10130
0
}
10131
10132
void
10133
0
dns_resolver_cancelfetch(dns_fetch_t *fetch) {
10134
0
  fetchctx_t *fctx = NULL;
10135
0
  bool last_fetch = false;
10136
10137
0
  REQUIRE(DNS_FETCH_VALID(fetch));
10138
0
  fctx = fetch->private;
10139
0
  REQUIRE(VALID_FCTX(fctx));
10140
10141
0
  FTRACE("cancelfetch");
10142
10143
0
  LOCK(&fctx->lock);
10144
10145
  /*
10146
   * Find the completion event associated with this fetch (as opposed
10147
   * to those for other fetches that have joined the same fctx) and run
10148
   * the callback asynchronously with a ISC_R_CANCELED result.
10149
   */
10150
0
  if (fctx->state != fetchstate_done) {
10151
0
    ISC_LIST_FOREACH(fctx->resps, resp, link) {
10152
0
      if (resp->fetch == fetch) {
10153
0
        resp->result = ISC_R_CANCELED;
10154
0
        ISC_LIST_UNLINK(fctx->resps, resp, link);
10155
0
        isc_async_run(resp->loop, resp->cb, resp);
10156
0
        break;
10157
0
      }
10158
0
    }
10159
0
  }
10160
10161
0
  if (ISC_LIST_EMPTY(fctx->resps)) {
10162
0
    last_fetch = true;
10163
0
  }
10164
0
  UNLOCK(&fctx->lock);
10165
10166
0
  if (last_fetch) {
10167
0
    fetchctx_ref(fctx);
10168
0
    isc_async_run(fctx->loop, fctx_shutdown, fctx);
10169
0
  }
10170
0
}
10171
10172
void
10173
0
dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
10174
0
  dns_fetch_t *fetch = NULL;
10175
0
  dns_resolver_t *res = NULL;
10176
0
  fetchctx_t *fctx = NULL;
10177
10178
0
  REQUIRE(fetchp != NULL);
10179
0
  fetch = *fetchp;
10180
0
  *fetchp = NULL;
10181
0
  REQUIRE(DNS_FETCH_VALID(fetch));
10182
0
  fctx = fetch->private;
10183
0
  REQUIRE(VALID_FCTX(fctx));
10184
0
  res = fetch->res;
10185
10186
0
  FTRACE("destroyfetch");
10187
10188
0
  fetch->magic = 0;
10189
10190
0
  LOCK(&fctx->lock);
10191
  /*
10192
   * Sanity check: the caller should have gotten its event before
10193
   * trying to destroy the fetch.
10194
   */
10195
0
  if (fctx->state != fetchstate_done) {
10196
0
    ISC_LIST_FOREACH(fctx->resps, resp, link) {
10197
0
      RUNTIME_CHECK(resp->fetch != fetch);
10198
0
    }
10199
0
  }
10200
0
  UNLOCK(&fctx->lock);
10201
10202
0
  isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch));
10203
10204
0
  fetchctx_detach(&fctx);
10205
0
  dns_resolver_detach(&res);
10206
0
}
10207
10208
void
10209
dns_resolver_logfetch(dns_fetch_t *fetch, isc_logcategory_t category,
10210
0
          isc_logmodule_t module, int level, bool duplicateok) {
10211
0
  fetchctx_t *fctx = NULL;
10212
10213
0
  REQUIRE(DNS_FETCH_VALID(fetch));
10214
0
  fctx = fetch->private;
10215
0
  REQUIRE(VALID_FCTX(fctx));
10216
10217
0
  LOCK(&fctx->lock);
10218
10219
0
  if (!fctx->logged || duplicateok) {
10220
0
    char domainbuf[DNS_NAME_FORMATSIZE];
10221
0
    dns_name_format(fctx->domain, domainbuf, sizeof(domainbuf));
10222
0
    isc_log_write(category, module, level,
10223
0
            "fetch completed for %s in "
10224
0
            "%" PRIu64 "."
10225
0
            "%06" PRIu64 ": %s/%s "
10226
0
            "[domain:%s,referral:%u,restart:%u,qrysent:%u,"
10227
0
            "timeout:%u,lame:%u,quota:%u,neterr:%u,"
10228
0
            "badresp:%u,adberr:%u,findfail:%u,valfail:%u]",
10229
0
            fctx->info, fctx->duration / US_PER_SEC,
10230
0
            fctx->duration % US_PER_SEC,
10231
0
            isc_result_totext(fctx->result),
10232
0
            isc_result_totext(fctx->vresult), domainbuf,
10233
0
            fctx->referrals, fctx->restarts, fctx->querysent,
10234
0
            fctx->timeouts, fctx->lamecount, fctx->quotacount,
10235
0
            fctx->neterr, fctx->badresp, fctx->adberr,
10236
0
            fctx->findfail, fctx->valfail);
10237
0
    fctx->logged = true;
10238
0
  }
10239
10240
0
  UNLOCK(&fctx->lock);
10241
0
}
10242
10243
dns_dispatch_t *
10244
0
dns_resolver_dispatchv4(dns_resolver_t *resolver) {
10245
0
  REQUIRE(VALID_RESOLVER(resolver));
10246
0
  return dns_dispatchset_get(resolver->dispatches4);
10247
0
}
10248
10249
dns_dispatch_t *
10250
0
dns_resolver_dispatchv6(dns_resolver_t *resolver) {
10251
0
  REQUIRE(VALID_RESOLVER(resolver));
10252
0
  return dns_dispatchset_get(resolver->dispatches6);
10253
0
}
10254
10255
void
10256
dns_resolver_addalternate(dns_resolver_t *res, const isc_sockaddr_t *alt,
10257
0
        const dns_name_t *name, in_port_t port) {
10258
0
  alternate_t *a;
10259
10260
0
  REQUIRE(VALID_RESOLVER(res));
10261
0
  REQUIRE(!res->frozen);
10262
0
  REQUIRE((alt == NULL) ^ (name == NULL));
10263
10264
0
  a = isc_mem_get(res->mctx, sizeof(*a));
10265
0
  if (alt != NULL) {
10266
0
    a->isaddress = true;
10267
0
    a->_u.addr = *alt;
10268
0
  } else {
10269
0
    a->isaddress = false;
10270
0
    a->_u._n.port = port;
10271
0
    dns_name_init(&a->_u._n.name);
10272
0
    dns_name_dup(name, res->mctx, &a->_u._n.name);
10273
0
  }
10274
0
  ISC_LINK_INIT(a, link);
10275
0
  ISC_LIST_APPEND(res->alternates, a, link);
10276
0
}
10277
10278
isc_result_t
10279
dns_resolver_disable_algorithm(dns_resolver_t *resolver, const dns_name_t *name,
10280
0
             unsigned int alg) {
10281
0
  REQUIRE(VALID_RESOLVER(resolver));
10282
10283
0
  if (alg >= DST_MAX_ALGS) {
10284
0
    return ISC_R_RANGE;
10285
0
  }
10286
10287
0
  return dns_nametree_add(resolver->algorithms, name, alg);
10288
0
}
10289
10290
isc_result_t
10291
dns_resolver_disable_ds_digest(dns_resolver_t *resolver, const dns_name_t *name,
10292
0
             unsigned int digest_type) {
10293
0
  REQUIRE(VALID_RESOLVER(resolver));
10294
10295
0
  if (digest_type > 255) {
10296
0
    return ISC_R_RANGE;
10297
0
  }
10298
10299
0
  return dns_nametree_add(resolver->digests, name, digest_type);
10300
0
}
10301
10302
bool
10303
dns_resolver_algorithm_supported(dns_resolver_t *resolver,
10304
         const dns_name_t *name, unsigned int alg,
10305
0
         unsigned char *private, size_t len) {
10306
0
  REQUIRE(VALID_RESOLVER(resolver));
10307
10308
0
  if ((alg == DST_ALG_DH) || (alg == DST_ALG_INDIRECT)) {
10309
0
    return false;
10310
0
  }
10311
10312
  /*
10313
   * Look up the DST algorithm identifier for private-OID
10314
   * and private-DNS keys.
10315
   */
10316
0
  if (alg == DST_ALG_PRIVATEDNS && private != NULL) {
10317
0
    isc_buffer_t b;
10318
0
    isc_buffer_init(&b, private, len);
10319
0
    isc_buffer_add(&b, len);
10320
0
    alg = dst_algorithm_fromprivatedns(&b);
10321
0
    if (alg == 0) {
10322
0
      return false;
10323
0
    }
10324
0
  }
10325
10326
0
  if (alg == DST_ALG_PRIVATEOID && private != NULL) {
10327
0
    isc_buffer_t b;
10328
0
    isc_buffer_init(&b, private, len);
10329
0
    isc_buffer_add(&b, len);
10330
0
    alg = dst_algorithm_fromprivateoid(&b);
10331
0
    if (alg == 0) {
10332
0
      return false;
10333
0
    }
10334
0
  }
10335
0
  if (dns_nametree_covered(resolver->algorithms, name, NULL, alg)) {
10336
0
    return false;
10337
0
  }
10338
10339
0
  return dst_algorithm_supported(alg);
10340
0
}
10341
10342
bool
10343
dns_resolver_ds_digest_supported(dns_resolver_t *resolver,
10344
         const dns_name_t *name,
10345
0
         unsigned int digest_type) {
10346
0
  REQUIRE(VALID_RESOLVER(resolver));
10347
10348
0
  if (dns_nametree_covered(resolver->digests, name, NULL, digest_type)) {
10349
0
    return false;
10350
0
  }
10351
10352
0
  return dst_ds_digest_supported(digest_type);
10353
0
}
10354
10355
void
10356
dns_resolver_getclientsperquery(dns_resolver_t *resolver, uint32_t *cur,
10357
0
        uint32_t *min, uint32_t *max) {
10358
0
  REQUIRE(VALID_RESOLVER(resolver));
10359
10360
0
  LOCK(&resolver->lock);
10361
0
  SET_IF_NOT_NULL(cur, resolver->spillat);
10362
0
  SET_IF_NOT_NULL(min, resolver->spillatmin);
10363
0
  SET_IF_NOT_NULL(max, resolver->spillatmax);
10364
0
  UNLOCK(&resolver->lock);
10365
0
}
10366
10367
void
10368
dns_resolver_setclientsperquery(dns_resolver_t *resolver, uint32_t min,
10369
0
        uint32_t max) {
10370
0
  REQUIRE(VALID_RESOLVER(resolver));
10371
10372
0
  LOCK(&resolver->lock);
10373
0
  resolver->spillatmin = resolver->spillat = min;
10374
0
  resolver->spillatmax = max;
10375
0
  UNLOCK(&resolver->lock);
10376
0
}
10377
10378
void
10379
0
dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients) {
10380
0
  REQUIRE(VALID_RESOLVER(resolver));
10381
10382
0
  atomic_store_release(&resolver->zspill, clients);
10383
0
}
10384
10385
uint32_t
10386
0
dns_resolver_getfetchesperzone(dns_resolver_t *resolver) {
10387
0
  REQUIRE(VALID_RESOLVER(resolver));
10388
10389
0
  return atomic_load_relaxed(&resolver->zspill);
10390
0
}
10391
10392
bool
10393
0
dns_resolver_getzeronosoattl(dns_resolver_t *resolver) {
10394
0
  REQUIRE(VALID_RESOLVER(resolver));
10395
10396
0
  return resolver->zero_no_soa_ttl;
10397
0
}
10398
10399
void
10400
0
dns_resolver_setzeronosoattl(dns_resolver_t *resolver, bool state) {
10401
0
  REQUIRE(VALID_RESOLVER(resolver));
10402
10403
0
  resolver->zero_no_soa_ttl = state;
10404
0
}
10405
10406
unsigned int
10407
0
dns_resolver_getoptions(dns_resolver_t *resolver) {
10408
0
  REQUIRE(VALID_RESOLVER(resolver));
10409
10410
0
  return resolver->options;
10411
0
}
10412
10413
unsigned int
10414
0
dns_resolver_gettimeout(dns_resolver_t *resolver) {
10415
0
  REQUIRE(VALID_RESOLVER(resolver));
10416
10417
0
  return resolver->query_timeout;
10418
0
}
10419
10420
void
10421
0
dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int timeout) {
10422
0
  REQUIRE(VALID_RESOLVER(resolver));
10423
10424
0
  if (timeout < MINIMUM_QUERY_TIMEOUT) {
10425
0
    timeout *= 1000;
10426
0
  }
10427
10428
0
  if (timeout == 0) {
10429
0
    timeout = DEFAULT_QUERY_TIMEOUT;
10430
0
  }
10431
0
  if (timeout > MAXIMUM_QUERY_TIMEOUT) {
10432
0
    timeout = MAXIMUM_QUERY_TIMEOUT;
10433
0
  }
10434
0
  if (timeout < MINIMUM_QUERY_TIMEOUT) {
10435
0
    timeout = MINIMUM_QUERY_TIMEOUT;
10436
0
  }
10437
10438
0
  resolver->query_timeout = timeout;
10439
0
}
10440
10441
void
10442
0
dns_resolver_setmaxvalidations(dns_resolver_t *resolver, uint32_t max) {
10443
0
  REQUIRE(VALID_RESOLVER(resolver));
10444
0
  atomic_store(&resolver->maxvalidations, max);
10445
0
}
10446
10447
void
10448
0
dns_resolver_setmaxvalidationfails(dns_resolver_t *resolver, uint32_t max) {
10449
0
  REQUIRE(VALID_RESOLVER(resolver));
10450
0
  atomic_store(&resolver->maxvalidationfails, max);
10451
0
}
10452
10453
void
10454
0
dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) {
10455
0
  REQUIRE(VALID_RESOLVER(resolver));
10456
0
  resolver->maxdepth = maxdepth;
10457
0
}
10458
10459
unsigned int
10460
0
dns_resolver_getmaxdepth(dns_resolver_t *resolver) {
10461
0
  REQUIRE(VALID_RESOLVER(resolver));
10462
0
  return resolver->maxdepth;
10463
0
}
10464
10465
void
10466
0
dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) {
10467
0
  REQUIRE(VALID_RESOLVER(resolver));
10468
0
  resolver->maxqueries = queries;
10469
0
}
10470
10471
unsigned int
10472
0
dns_resolver_getmaxqueries(dns_resolver_t *resolver) {
10473
0
  REQUIRE(VALID_RESOLVER(resolver));
10474
0
  return resolver->maxqueries;
10475
0
}
10476
10477
void
10478
dns_resolver_dumpfetches(dns_resolver_t *res, isc_statsformat_t format,
10479
0
       FILE *fp) {
10480
0
  isc_result_t result;
10481
0
  isc_hashmap_iter_t *it = NULL;
10482
10483
0
  REQUIRE(VALID_RESOLVER(res));
10484
0
  REQUIRE(fp != NULL);
10485
0
  REQUIRE(format == isc_statsformat_file);
10486
10487
0
  LOCK(&res->lock);
10488
0
  fprintf(fp, "clients-per-query: %u/%u/%u\n", res->spillatmin,
10489
0
    res->spillat, res->spillatmax);
10490
0
  UNLOCK(&res->lock);
10491
10492
0
  RWLOCK(&res->fctxs_lock, isc_rwlocktype_read);
10493
0
  isc_hashmap_iter_create(res->fctxs, &it);
10494
0
  for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
10495
0
       result = isc_hashmap_iter_next(it))
10496
0
  {
10497
0
    char typebuf[DNS_RDATATYPE_FORMATSIZE];
10498
0
    char timebuf[1024];
10499
0
    fetchctx_t *fctx = NULL;
10500
0
    unsigned int resp_count = 0, query_count = 0;
10501
10502
0
    isc_hashmap_iter_current(it, (void **)&fctx);
10503
10504
0
    LOCK(&fctx->lock);
10505
0
    dns_name_print(fctx->name, fp);
10506
10507
0
    isc_time_formatISO8601ms(&fctx->start, timebuf,
10508
0
           sizeof(timebuf));
10509
10510
0
    dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
10511
10512
0
    fprintf(fp, "/%s (%s): started %s, ", typebuf,
10513
0
      fctx->state == fetchstate_active ? "active" : "done",
10514
0
      timebuf);
10515
10516
0
    ISC_LIST_FOREACH(fctx->resps, resp, link) {
10517
0
      resp_count++;
10518
0
    }
10519
10520
0
    ISC_LIST_FOREACH(fctx->queries, query, link) {
10521
0
      query_count++;
10522
0
    }
10523
10524
0
    if (isc_timer_running(fctx->timer)) {
10525
0
      strlcpy(timebuf, "expires ", sizeof(timebuf));
10526
0
      isc_time_formatISO8601ms(&fctx->expires, timebuf + 8,
10527
0
             sizeof(timebuf) - 8);
10528
0
    } else {
10529
0
      strlcpy(timebuf, "not running", sizeof(timebuf));
10530
0
    }
10531
10532
0
    fprintf(fp,
10533
0
      "fetches: %u active (%" PRIuFAST32
10534
0
      " allowed, %" PRIuFAST32
10535
0
      " dropped%s), queries: %u, timer %s\n",
10536
0
      resp_count, fctx->allowed, fctx->dropped,
10537
0
      fctx->spilled ? ", spilled" : "", query_count, timebuf);
10538
10539
0
    UNLOCK(&fctx->lock);
10540
0
  }
10541
0
  isc_hashmap_iter_destroy(&it);
10542
0
  RWUNLOCK(&res->fctxs_lock, isc_rwlocktype_read);
10543
0
}
10544
10545
isc_result_t
10546
0
dns_resolver_dumpquota(dns_resolver_t *res, isc_buffer_t **buf) {
10547
0
  isc_result_t result;
10548
0
  isc_hashmap_iter_t *it = NULL;
10549
0
  uint_fast32_t spill;
10550
10551
0
  REQUIRE(VALID_RESOLVER(res));
10552
10553
0
  spill = atomic_load_acquire(&res->zspill);
10554
0
  if (spill == 0) {
10555
0
    return ISC_R_SUCCESS;
10556
0
  }
10557
10558
0
  RWLOCK(&res->counters_lock, isc_rwlocktype_read);
10559
0
  isc_hashmap_iter_create(res->counters, &it);
10560
0
  for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
10561
0
       result = isc_hashmap_iter_next(it))
10562
0
  {
10563
0
    fctxcount_t *counter = NULL;
10564
0
    uint_fast32_t count, dropped, allowed;
10565
0
    char nb[DNS_NAME_FORMATSIZE];
10566
0
    char text[DNS_NAME_FORMATSIZE + BUFSIZ];
10567
10568
0
    isc_hashmap_iter_current(it, (void **)&counter);
10569
10570
0
    LOCK(&counter->lock);
10571
0
    count = counter->count;
10572
0
    dropped = counter->dropped;
10573
0
    allowed = counter->allowed;
10574
0
    UNLOCK(&counter->lock);
10575
10576
0
    if (count < spill) {
10577
0
      continue;
10578
0
    }
10579
10580
0
    dns_name_format(counter->domain, nb, sizeof(nb));
10581
0
    snprintf(text, sizeof(text),
10582
0
       "\n- %s: %" PRIuFAST32 " active (allowed %" PRIuFAST32
10583
0
       " spilled %" PRIuFAST32 ")",
10584
0
       nb, count, allowed, dropped);
10585
10586
0
    result = isc_buffer_reserve(*buf, strlen(text));
10587
0
    if (result != ISC_R_SUCCESS) {
10588
0
      goto cleanup;
10589
0
    }
10590
0
    isc_buffer_putstr(*buf, text);
10591
0
  }
10592
0
  if (result == ISC_R_NOMORE) {
10593
0
    result = ISC_R_SUCCESS;
10594
0
  }
10595
10596
0
cleanup:
10597
0
  isc_hashmap_iter_destroy(&it);
10598
0
  RWUNLOCK(&res->counters_lock, isc_rwlocktype_read);
10599
0
  return result;
10600
0
}
10601
10602
void
10603
dns_resolver_setquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which,
10604
0
            isc_result_t resp) {
10605
0
  REQUIRE(VALID_RESOLVER(resolver));
10606
0
  REQUIRE(which == dns_quotatype_zone || which == dns_quotatype_server);
10607
0
  REQUIRE(resp == DNS_R_DROP || resp == DNS_R_SERVFAIL);
10608
10609
0
  resolver->quotaresp[which] = resp;
10610
0
}
10611
10612
isc_result_t
10613
0
dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which) {
10614
0
  REQUIRE(VALID_RESOLVER(resolver));
10615
0
  REQUIRE(which == dns_quotatype_zone || which == dns_quotatype_server);
10616
10617
0
  return resolver->quotaresp[which];
10618
0
}
10619
10620
void
10621
0
dns_resolver_setstats(dns_resolver_t *res, isc_stats_t *stats) {
10622
0
  REQUIRE(VALID_RESOLVER(res));
10623
0
  REQUIRE(res->stats == NULL);
10624
10625
0
  isc_stats_attach(stats, &res->stats);
10626
10627
  /* initialize the bucket "counter"; it's a static value */
10628
0
  set_stats(res, dns_resstatscounter_buckets, isc_loopmgr_nloops());
10629
0
}
10630
10631
void
10632
0
dns_resolver_getstats(dns_resolver_t *res, isc_stats_t **statsp) {
10633
0
  REQUIRE(VALID_RESOLVER(res));
10634
0
  REQUIRE(statsp != NULL && *statsp == NULL);
10635
10636
0
  if (res->stats != NULL) {
10637
0
    isc_stats_attach(res->stats, statsp);
10638
0
  }
10639
0
}
10640
10641
void
10642
0
dns_resolver_incstats(dns_resolver_t *res, isc_statscounter_t counter) {
10643
0
  REQUIRE(VALID_RESOLVER(res));
10644
10645
0
  isc_stats_increment(res->stats, counter);
10646
0
}
10647
10648
void
10649
0
dns_resolver_setquerystats(dns_resolver_t *res, dns_stats_t *stats) {
10650
0
  REQUIRE(VALID_RESOLVER(res));
10651
0
  REQUIRE(res->querystats == NULL);
10652
10653
0
  dns_stats_attach(stats, &res->querystats);
10654
0
}
10655
10656
void
10657
0
dns_resolver_getquerystats(dns_resolver_t *res, dns_stats_t **statsp) {
10658
0
  REQUIRE(VALID_RESOLVER(res));
10659
0
  REQUIRE(statsp != NULL && *statsp == NULL);
10660
10661
0
  if (res->querystats != NULL) {
10662
0
    dns_stats_attach(res->querystats, statsp);
10663
0
  }
10664
0
}
10665
10666
void
10667
0
dns_resolver_freefresp(dns_fetchresponse_t **frespp) {
10668
0
  REQUIRE(frespp != NULL);
10669
10670
0
  if (*frespp == NULL) {
10671
0
    return;
10672
0
  }
10673
10674
0
  dns_fetchresponse_t *fresp = *frespp;
10675
10676
0
  *frespp = NULL;
10677
0
  isc_mem_putanddetach(&fresp->mctx, fresp, sizeof(*fresp));
10678
0
}