Coverage Report

Created: 2026-06-09 06:11

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