Coverage Report

Created: 2023-06-07 06:23

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