Coverage Report

Created: 2025-07-18 07:02

/src/bind9/lib/dns/xfrin.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 <inttypes.h>
17
#include <stdbool.h>
18
19
#include <isc/async.h>
20
#include <isc/atomic.h>
21
#include <isc/log.h>
22
#include <isc/mem.h>
23
#include <isc/random.h>
24
#include <isc/result.h>
25
#include <isc/string.h>
26
#include <isc/util.h>
27
#include <isc/work.h>
28
29
#include <dns/callbacks.h>
30
#include <dns/catz.h>
31
#include <dns/db.h>
32
#include <dns/diff.h>
33
#include <dns/dispatch.h>
34
#include <dns/journal.h>
35
#include <dns/message.h>
36
#include <dns/peer.h>
37
#include <dns/rdataclass.h>
38
#include <dns/rdatalist.h>
39
#include <dns/rdataset.h>
40
#include <dns/result.h>
41
#include <dns/soa.h>
42
#include <dns/trace.h>
43
#include <dns/transport.h>
44
#include <dns/tsig.h>
45
#include <dns/unreachcache.h>
46
#include <dns/view.h>
47
#include <dns/xfrin.h>
48
#include <dns/zone.h>
49
50
#include <dst/dst.h>
51
52
#include "probes.h"
53
54
/*
55
 * Incoming AXFR and IXFR.
56
 */
57
58
#define CHECK(op)                              \
59
0
  {                                      \
60
0
    result = (op);                 \
61
0
    if (result != ISC_R_SUCCESS) { \
62
0
      goto failure;          \
63
0
    }                              \
64
0
  }
65
66
/*%
67
 * The states of the *XFR state machine.  We handle both IXFR and AXFR
68
 * with a single integrated state machine because they cannot be
69
 * distinguished immediately - an AXFR response to an IXFR request can
70
 * only be detected when the first two (2) response RRs have already
71
 * been received.
72
 */
73
typedef enum {
74
  XFRST_SOAQUERY,
75
  XFRST_GOTSOA,
76
  XFRST_ZONEXFRREQUEST,
77
  XFRST_FIRSTDATA,
78
  XFRST_IXFR_DELSOA,
79
  XFRST_IXFR_DEL,
80
  XFRST_IXFR_ADDSOA,
81
  XFRST_IXFR_ADD,
82
  XFRST_IXFR_END,
83
  XFRST_AXFR,
84
  XFRST_AXFR_END
85
} xfrin_state_t;
86
87
/*%
88
 * Incoming zone transfer context.
89
 */
90
91
struct dns_xfrin {
92
  unsigned int magic;
93
  isc_mem_t *mctx;
94
  dns_zone_t *zone;
95
  dns_view_t *view;
96
97
  isc_refcount_t references;
98
99
  atomic_bool shuttingdown;
100
101
  isc_result_t shutdown_result;
102
103
  dns_name_t name; /*%< Name of zone to transfer */
104
  dns_rdataclass_t rdclass;
105
106
  dns_messageid_t id;
107
108
  /*%
109
   * Requested transfer type (dns_rdatatype_axfr or
110
   * dns_rdatatype_ixfr).  The actual transfer type
111
   * may differ due to IXFR->AXFR fallback.
112
   */
113
  dns_rdatatype_t reqtype;
114
115
  isc_sockaddr_t primaryaddr;
116
  isc_sockaddr_t sourceaddr;
117
118
  dns_dispatch_t *disp;
119
  dns_dispentry_t *dispentry;
120
121
  /*% Buffer for IXFR/AXFR request message */
122
  isc_buffer_t qbuffer;
123
  unsigned char qbuffer_data[512];
124
125
  /*%
126
   * Whether the zone originally had a database attached at the time this
127
   * transfer context was created.  Used by xfrin_destroy() when making
128
   * logging decisions.
129
   */
130
  bool zone_had_db;
131
132
  dns_db_t *db;
133
  dns_dbversion_t *ver;
134
  dns_diff_t diff; /*%< Pending database changes */
135
136
  /* Diff queue */
137
  bool diff_running;
138
  struct __cds_wfcq_head diff_head;
139
  struct cds_wfcq_tail diff_tail;
140
141
  _Atomic xfrin_state_t state;
142
  uint32_t expireopt;
143
  bool edns, expireoptset;
144
  atomic_bool is_ixfr;
145
146
  /*
147
   * Following variable were made atomic only for loading the values for
148
   * the statistics channel, thus all accesses can be **relaxed** because
149
   * all store and load operations that affect XFR are done on the same
150
   * thread and only the statistics channel thread could perform a load
151
   * operation from a different thread and it's ok to not be precise in
152
   * the statistics.
153
   */
154
  atomic_uint nmsg;      /*%< Number of messages recvd */
155
  atomic_uint nrecs;       /*%< Number of records recvd */
156
  atomic_uint_fast64_t nbytes; /*%< Number of bytes received */
157
  _Atomic(isc_time_t) start;   /*%< Start time of the transfer */
158
  atomic_uint_fast64_t rate_bytes_per_second;
159
  _Atomic(dns_transport_type_t) soa_transport_type;
160
  atomic_uint_fast32_t end_serial;
161
162
  unsigned int maxrecords; /*%< The maximum number of
163
          *   records set for the zone */
164
  uint64_t nbytes_saved;   /*%< For enforcing the minimum transfer rate */
165
166
  dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
167
  isc_buffer_t *lasttsig; /*%< The last TSIG */
168
  dst_context_t *tsigctx; /*%< TSIG verification context */
169
  unsigned int sincetsig; /*%< recvd since the last TSIG */
170
171
  dns_transport_t *transport;
172
173
  dns_xfrindone_t done;
174
175
  /*%
176
   * AXFR- and IXFR-specific data.  Only one is used at a time
177
   * according to the is_ixfr flag, so this could be a union,
178
   * but keeping them separate makes it a bit simpler to clean
179
   * things up when destroying the context.
180
   */
181
  dns_rdatacallbacks_t axfr;
182
183
  struct {
184
    uint32_t diffs;
185
    uint32_t maxdiffs;
186
    uint32_t request_serial;
187
    uint32_t current_serial;
188
    dns_journal_t *journal;
189
  } ixfr;
190
191
  dns_rdata_t firstsoa;
192
  unsigned char *firstsoa_data;
193
194
  isc_tlsctx_cache_t *tlsctx_cache;
195
196
  isc_loop_t *loop;
197
198
  isc_timer_t *min_rate_timer;
199
  isc_timer_t *max_time_timer;
200
  isc_timer_t *max_idle_timer;
201
202
  char info[DNS_NAME_MAXTEXT + 32];
203
};
204
205
0
#define XFRIN_MAGIC    ISC_MAGIC('X', 'f', 'r', 'I')
206
#define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
207
208
0
#define XFRIN_WORK_MAGIC    ISC_MAGIC('X', 'f', 'r', 'W')
209
#define VALID_XFRIN_WORK(x) ISC_MAGIC_VALID(x, XFRIN_WORK_MAGIC)
210
211
typedef struct xfrin_work {
212
  unsigned int magic;
213
  isc_result_t result;
214
  dns_xfrin_t *xfr;
215
} xfrin_work_t;
216
217
/**************************************************************************/
218
/*
219
 * Forward declarations.
220
 */
221
222
static void
223
xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop,
224
       dns_name_t *zonename, dns_rdataclass_t rdclass,
225
       dns_rdatatype_t reqtype, uint32_t ixfr_maxdiffs,
226
       const isc_sockaddr_t *primaryaddr,
227
       const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
228
       dns_transport_type_t soa_transport_type,
229
       dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
230
       dns_xfrin_t **xfrp);
231
232
static isc_result_t
233
axfr_init(dns_xfrin_t *xfr);
234
static isc_result_t
235
axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
236
       dns_rdata_t *rdata);
237
static void
238
axfr_commit(dns_xfrin_t *xfr);
239
static isc_result_t
240
axfr_finalize(dns_xfrin_t *xfr);
241
242
static isc_result_t
243
ixfr_init(dns_xfrin_t *xfr);
244
static isc_result_t
245
ixfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
246
       dns_rdata_t *rdata);
247
static isc_result_t
248
ixfr_commit(dns_xfrin_t *xfr);
249
250
static isc_result_t
251
xfr_rr(dns_xfrin_t *xfr, dns_name_t *name, uint32_t ttl, dns_rdata_t *rdata);
252
253
static isc_result_t
254
xfrin_start(dns_xfrin_t *xfr);
255
256
static void
257
xfrin_connect_done(isc_result_t result, isc_region_t *region, void *arg);
258
static isc_result_t
259
xfrin_send_request(dns_xfrin_t *xfr);
260
static void
261
xfrin_send_done(isc_result_t eresult, isc_region_t *region, void *arg);
262
static void
263
xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg);
264
265
static void
266
xfrin_end(dns_xfrin_t *xfr, isc_result_t result);
267
268
static void
269
xfrin_destroy(dns_xfrin_t *xfr);
270
271
static void
272
xfrin_timedout(void *);
273
static void
274
xfrin_idledout(void *);
275
static void
276
xfrin_minratecheck(void *);
277
static void
278
xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg);
279
static isc_result_t
280
render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
281
282
static void
283
xfrin_log(dns_xfrin_t *xfr, int level, const char *fmt, ...)
284
  ISC_FORMAT_PRINTF(3, 4);
285
286
/**************************************************************************/
287
/*
288
 * AXFR handling
289
 */
290
291
static isc_result_t
292
0
axfr_init(dns_xfrin_t *xfr) {
293
0
  isc_result_t result;
294
295
0
  atomic_store(&xfr->is_ixfr, false);
296
297
0
  if (xfr->db != NULL) {
298
0
    dns_db_detach(&xfr->db);
299
0
  }
300
301
0
  CHECK(dns_zone_makedb(xfr->zone, &xfr->db));
302
303
0
  dns_zone_rpz_enable_db(xfr->zone, xfr->db);
304
0
  dns_zone_catz_enable_db(xfr->zone, xfr->db);
305
306
0
  dns_rdatacallbacks_init(&xfr->axfr);
307
0
  CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
308
0
  result = ISC_R_SUCCESS;
309
0
failure:
310
0
  return result;
311
0
}
312
313
static void
314
axfr_apply(void *arg);
315
316
static isc_result_t
317
axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
318
0
       dns_rdata_t *rdata) {
319
0
  isc_result_t result;
320
321
0
  dns_difftuple_t *tuple = NULL;
322
323
0
  if (rdata->rdclass != xfr->rdclass) {
324
0
    return DNS_R_BADCLASS;
325
0
  }
326
327
0
  CHECK(dns_zone_checknames(xfr->zone, name, rdata));
328
0
  if (dns_diff_size(&xfr->diff) > 128 &&
329
0
      dns_diff_is_boundary(&xfr->diff, name))
330
0
  {
331
0
    xfrin_work_t work = (xfrin_work_t){
332
0
      .magic = XFRIN_WORK_MAGIC,
333
0
      .result = ISC_R_UNSET,
334
0
      .xfr = xfr,
335
0
    };
336
0
    axfr_apply((void *)&work);
337
0
    CHECK(work.result);
338
0
  }
339
340
0
  dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple);
341
0
  dns_diff_append(&xfr->diff, &tuple);
342
343
0
  result = ISC_R_SUCCESS;
344
0
failure:
345
0
  return result;
346
0
}
347
348
/*
349
 * Store a set of AXFR RRs in the database.
350
 */
351
static void
352
0
axfr_apply(void *arg) {
353
0
  xfrin_work_t *work = arg;
354
0
  REQUIRE(VALID_XFRIN_WORK(work));
355
356
0
  dns_xfrin_t *xfr = work->xfr;
357
0
  REQUIRE(VALID_XFRIN(xfr));
358
359
0
  isc_result_t result = ISC_R_SUCCESS;
360
0
  uint64_t records;
361
362
0
  if (atomic_load(&xfr->shuttingdown)) {
363
0
    result = ISC_R_SHUTTINGDOWN;
364
0
    goto failure;
365
0
  }
366
367
0
  CHECK(dns_diff_load(&xfr->diff, &xfr->axfr));
368
0
  if (xfr->maxrecords != 0U) {
369
0
    result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
370
0
    if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
371
0
      result = DNS_R_TOOMANYRECORDS;
372
0
      goto failure;
373
0
    }
374
0
  }
375
376
0
failure:
377
0
  dns_diff_clear(&xfr->diff);
378
0
  work->result = result;
379
0
}
380
381
static void
382
0
axfr_apply_done(void *arg) {
383
0
  xfrin_work_t *work = arg;
384
0
  dns_xfrin_t *xfr = work->xfr;
385
0
  isc_result_t result = work->result;
386
387
0
  REQUIRE(VALID_XFRIN(xfr));
388
0
  REQUIRE(VALID_XFRIN_WORK(work));
389
390
0
  if (atomic_load(&xfr->shuttingdown)) {
391
0
    result = ISC_R_SHUTTINGDOWN;
392
0
  }
393
394
0
  if (result == ISC_R_SUCCESS) {
395
0
    CHECK(dns_db_endload(xfr->db, &xfr->axfr));
396
0
    CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL));
397
0
    CHECK(axfr_finalize(xfr));
398
0
  } else {
399
0
    (void)dns_db_endload(xfr->db, &xfr->axfr);
400
0
  }
401
402
0
failure:
403
0
  xfr->diff_running = false;
404
405
0
  isc_mem_put(xfr->mctx, work, sizeof(*work));
406
407
0
  if (result == ISC_R_SUCCESS) {
408
0
    if (atomic_load(&xfr->state) == XFRST_AXFR_END) {
409
0
      xfrin_end(xfr, result);
410
0
    }
411
0
  } else {
412
0
    xfrin_fail(xfr, result, "failed while processing responses");
413
0
  }
414
415
0
  dns_xfrin_detach(&xfr);
416
0
}
417
418
static void
419
0
axfr_commit(dns_xfrin_t *xfr) {
420
0
  REQUIRE(!xfr->diff_running);
421
422
0
  xfrin_work_t *work = isc_mem_get(xfr->mctx, sizeof(*work));
423
0
  *work = (xfrin_work_t){
424
0
    .magic = XFRIN_WORK_MAGIC,
425
0
    .result = ISC_R_UNSET,
426
0
    .xfr = dns_xfrin_ref(xfr),
427
0
  };
428
0
  xfr->diff_running = true;
429
0
  isc_work_enqueue(xfr->loop, axfr_apply, axfr_apply_done, work);
430
0
}
431
432
static isc_result_t
433
0
axfr_finalize(dns_xfrin_t *xfr) {
434
0
  isc_result_t result;
435
436
0
  LIBDNS_XFRIN_AXFR_FINALIZE_BEGIN(xfr, xfr->info);
437
0
  result = dns_zone_replacedb(xfr->zone, xfr->db, true);
438
0
  LIBDNS_XFRIN_AXFR_FINALIZE_END(xfr, xfr->info, result);
439
440
0
  return result;
441
0
}
442
443
/**************************************************************************/
444
/*
445
 * IXFR handling
446
 */
447
448
typedef struct ixfr_apply_data {
449
  dns_diff_t diff; /*%< Pending database changes */
450
  struct cds_wfcq_node wfcq_node;
451
} ixfr_apply_data_t;
452
453
static isc_result_t
454
0
ixfr_init(dns_xfrin_t *xfr) {
455
0
  isc_result_t result;
456
0
  char *journalfile = NULL;
457
458
0
  if (xfr->reqtype != dns_rdatatype_ixfr) {
459
0
    xfrin_log(xfr, ISC_LOG_NOTICE,
460
0
        "got incremental response to AXFR request");
461
0
    return DNS_R_FORMERR;
462
0
  }
463
464
0
  atomic_store(&xfr->is_ixfr, true);
465
0
  INSIST(xfr->db != NULL);
466
467
0
  journalfile = dns_zone_getjournal(xfr->zone);
468
0
  if (journalfile != NULL) {
469
0
    CHECK(dns_journal_open(xfr->mctx, journalfile,
470
0
               DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
471
0
  }
472
473
0
  result = ISC_R_SUCCESS;
474
0
failure:
475
0
  return result;
476
0
}
477
478
static isc_result_t
479
ixfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
480
0
       dns_rdata_t *rdata) {
481
0
  isc_result_t result = ISC_R_SUCCESS;
482
0
  dns_difftuple_t *tuple = NULL;
483
484
0
  if (rdata->rdclass != xfr->rdclass) {
485
0
    return DNS_R_BADCLASS;
486
0
  }
487
488
0
  if (op == DNS_DIFFOP_ADD) {
489
0
    CHECK(dns_zone_checknames(xfr->zone, name, rdata));
490
0
  }
491
492
0
  dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple);
493
0
  dns_diff_append(&xfr->diff, &tuple);
494
495
0
  xfr->ixfr.diffs++;
496
0
failure:
497
0
  return result;
498
0
}
499
500
static isc_result_t
501
0
ixfr_begin_transaction(dns_xfrin_t *xfr) {
502
0
  isc_result_t result = ISC_R_SUCCESS;
503
504
0
  if (xfr->ixfr.journal != NULL) {
505
0
    CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
506
0
  }
507
0
failure:
508
0
  return result;
509
0
}
510
511
static isc_result_t
512
0
ixfr_end_transaction(dns_xfrin_t *xfr) {
513
0
  isc_result_t result = ISC_R_SUCCESS;
514
515
0
  CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver));
516
  /* XXX enter ready-to-commit state here */
517
0
  if (xfr->ixfr.journal != NULL) {
518
0
    CHECK(dns_journal_commit(xfr->ixfr.journal));
519
0
  }
520
0
failure:
521
0
  return result;
522
0
}
523
524
static isc_result_t
525
0
ixfr_apply_one(dns_xfrin_t *xfr, ixfr_apply_data_t *data) {
526
0
  isc_result_t result = ISC_R_SUCCESS;
527
0
  uint64_t records;
528
529
0
  CHECK(ixfr_begin_transaction(xfr));
530
531
0
  CHECK(dns_diff_apply(&data->diff, xfr->db, xfr->ver));
532
0
  if (xfr->maxrecords != 0U) {
533
0
    result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
534
0
    if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
535
0
      result = DNS_R_TOOMANYRECORDS;
536
0
      goto failure;
537
0
    }
538
0
  }
539
0
  if (xfr->ixfr.journal != NULL) {
540
0
    CHECK(dns_journal_writediff(xfr->ixfr.journal, &data->diff));
541
0
  }
542
543
0
  result = ixfr_end_transaction(xfr);
544
545
0
  return result;
546
0
failure:
547
  /* We need to end the transaction, but keep the previous error */
548
0
  (void)ixfr_end_transaction(xfr);
549
550
0
  return result;
551
0
}
552
553
static void
554
0
ixfr_apply(void *arg) {
555
0
  xfrin_work_t *work = arg;
556
0
  dns_xfrin_t *xfr = work->xfr;
557
0
  isc_result_t result = ISC_R_SUCCESS;
558
559
0
  REQUIRE(VALID_XFRIN(xfr));
560
0
  REQUIRE(VALID_XFRIN_WORK(work));
561
562
0
  struct __cds_wfcq_head diff_head;
563
0
  struct cds_wfcq_tail diff_tail;
564
565
  /* Initialize local wfcqueue */
566
0
  __cds_wfcq_init(&diff_head, &diff_tail);
567
568
0
  enum cds_wfcq_ret ret = __cds_wfcq_splice_blocking(
569
0
    &diff_head, &diff_tail, &xfr->diff_head, &xfr->diff_tail);
570
0
  INSIST(ret == CDS_WFCQ_RET_DEST_EMPTY);
571
572
0
  struct cds_wfcq_node *node, *next;
573
0
  __cds_wfcq_for_each_blocking_safe(&diff_head, &diff_tail, node, next) {
574
0
    ixfr_apply_data_t *data =
575
0
      caa_container_of(node, ixfr_apply_data_t, wfcq_node);
576
577
0
    if (atomic_load(&xfr->shuttingdown)) {
578
0
      result = ISC_R_SHUTTINGDOWN;
579
0
    }
580
581
    /* Apply only until first failure */
582
0
    if (result == ISC_R_SUCCESS) {
583
      /* This also checks for shuttingdown condition */
584
0
      result = ixfr_apply_one(xfr, data);
585
0
    }
586
587
    /* We need to clear and free all data chunks */
588
0
    dns_diff_clear(&data->diff);
589
0
    isc_mem_put(xfr->mctx, data, sizeof(*data));
590
0
  }
591
592
0
  work->result = result;
593
0
}
594
595
static void
596
0
ixfr_apply_done(void *arg) {
597
0
  xfrin_work_t *work = arg;
598
0
  REQUIRE(VALID_XFRIN_WORK(work));
599
600
0
  dns_xfrin_t *xfr = work->xfr;
601
0
  REQUIRE(VALID_XFRIN(xfr));
602
603
0
  isc_result_t result = work->result;
604
605
0
  if (atomic_load(&xfr->shuttingdown)) {
606
0
    result = ISC_R_SHUTTINGDOWN;
607
0
  }
608
609
0
  if (result != ISC_R_SUCCESS) {
610
0
    goto failure;
611
0
  }
612
613
  /* Reschedule */
614
0
  if (!cds_wfcq_empty(&xfr->diff_head, &xfr->diff_tail)) {
615
0
    isc_work_enqueue(xfr->loop, ixfr_apply, ixfr_apply_done, work);
616
0
    return;
617
0
  }
618
619
0
failure:
620
0
  xfr->diff_running = false;
621
622
0
  isc_mem_put(xfr->mctx, work, sizeof(*work));
623
624
0
  if (result == ISC_R_SUCCESS) {
625
0
    dns_db_closeversion(xfr->db, &xfr->ver, true);
626
0
    dns_zone_markdirty(xfr->zone);
627
628
0
    if (atomic_load(&xfr->state) == XFRST_IXFR_END) {
629
0
      xfrin_end(xfr, result);
630
0
    }
631
0
  } else {
632
0
    dns_db_closeversion(xfr->db, &xfr->ver, false);
633
634
0
    xfrin_fail(xfr, result, "failed while processing responses");
635
0
  }
636
637
0
  dns_xfrin_detach(&xfr);
638
0
}
639
640
/*
641
 * Apply a set of IXFR changes to the database.
642
 */
643
static isc_result_t
644
0
ixfr_commit(dns_xfrin_t *xfr) {
645
0
  isc_result_t result = ISC_R_SUCCESS;
646
0
  ixfr_apply_data_t *data = isc_mem_get(xfr->mctx, sizeof(*data));
647
648
0
  *data = (ixfr_apply_data_t){ 0 };
649
0
  cds_wfcq_node_init(&data->wfcq_node);
650
651
0
  if (xfr->ver == NULL) {
652
0
    CHECK(dns_db_newversion(xfr->db, &xfr->ver));
653
0
  }
654
655
0
  dns_diff_init(xfr->mctx, &data->diff);
656
  /* FIXME: Should we add dns_diff_move() */
657
0
  ISC_LIST_MOVE(data->diff.tuples, xfr->diff.tuples);
658
659
0
  (void)cds_wfcq_enqueue(&xfr->diff_head, &xfr->diff_tail,
660
0
             &data->wfcq_node);
661
662
0
  if (!xfr->diff_running) {
663
0
    xfrin_work_t *work = isc_mem_get(xfr->mctx, sizeof(*work));
664
0
    *work = (xfrin_work_t){
665
0
      .magic = XFRIN_WORK_MAGIC,
666
0
      .result = ISC_R_UNSET,
667
0
      .xfr = dns_xfrin_ref(xfr),
668
0
    };
669
0
    xfr->diff_running = true;
670
0
    isc_work_enqueue(xfr->loop, ixfr_apply, ixfr_apply_done, work);
671
0
  }
672
673
0
failure:
674
0
  return result;
675
0
}
676
677
/**************************************************************************/
678
/*
679
 * Common AXFR/IXFR protocol code
680
 */
681
682
/*
683
 * Handle a single incoming resource record according to the current
684
 * state.
685
 */
686
static isc_result_t
687
0
xfr_rr(dns_xfrin_t *xfr, dns_name_t *name, uint32_t ttl, dns_rdata_t *rdata) {
688
0
  isc_result_t result;
689
0
  uint_fast32_t end_serial;
690
691
0
  atomic_fetch_add_relaxed(&xfr->nrecs, 1);
692
693
0
  if (rdata->type == dns_rdatatype_none ||
694
0
      dns_rdatatype_ismeta(rdata->type))
695
0
  {
696
0
    char buf[64];
697
0
    dns_rdatatype_format(rdata->type, buf, sizeof(buf));
698
0
    xfrin_log(xfr, ISC_LOG_NOTICE,
699
0
        "Unexpected %s record in zone transfer", buf);
700
0
    result = DNS_R_FORMERR;
701
0
    goto failure;
702
0
  }
703
704
  /*
705
   * Immediately reject the entire transfer if the RR that is currently
706
   * being processed is an SOA record that is not placed at the zone
707
   * apex.
708
   */
709
0
  if (rdata->type == dns_rdatatype_soa &&
710
0
      !dns_name_equal(&xfr->name, name))
711
0
  {
712
0
    char namebuf[DNS_NAME_FORMATSIZE];
713
0
    dns_name_format(name, namebuf, sizeof(namebuf));
714
0
    xfrin_log(xfr, ISC_LOG_DEBUG(3), "SOA name mismatch: '%s'",
715
0
        namebuf);
716
0
    result = DNS_R_NOTZONETOP;
717
0
    goto failure;
718
0
  }
719
720
0
redo:
721
0
  switch (atomic_load(&xfr->state)) {
722
0
  case XFRST_SOAQUERY:
723
0
    if (rdata->type != dns_rdatatype_soa) {
724
0
      xfrin_log(xfr, ISC_LOG_NOTICE,
725
0
          "non-SOA response to SOA query");
726
0
      result = DNS_R_FORMERR;
727
0
      goto failure;
728
0
    }
729
0
    end_serial = dns_soa_getserial(rdata);
730
0
    atomic_store_relaxed(&xfr->end_serial, end_serial);
731
0
    if (!DNS_SERIAL_GT(end_serial, xfr->ixfr.request_serial) &&
732
0
        !dns_zone_isforced(xfr->zone))
733
0
    {
734
0
      xfrin_log(xfr, ISC_LOG_DEBUG(3),
735
0
          "requested serial %u, "
736
0
          "primary has %" PRIuFAST32 ", not updating",
737
0
          xfr->ixfr.request_serial, end_serial);
738
0
      result = DNS_R_UPTODATE;
739
0
      goto failure;
740
0
    }
741
0
    atomic_store(&xfr->state, XFRST_GOTSOA);
742
0
    break;
743
744
0
  case XFRST_GOTSOA:
745
    /*
746
     * Skip other records in the answer section.
747
     */
748
0
    break;
749
750
0
  case XFRST_ZONEXFRREQUEST:
751
0
    if (rdata->type != dns_rdatatype_soa) {
752
0
      xfrin_log(xfr, ISC_LOG_NOTICE,
753
0
          "first RR in zone transfer must be SOA");
754
0
      result = DNS_R_FORMERR;
755
0
      goto failure;
756
0
    }
757
    /*
758
     * Remember the serial number in the initial SOA.
759
     * We need it to recognize the end of an IXFR.
760
     */
761
0
    end_serial = dns_soa_getserial(rdata);
762
0
    atomic_store_relaxed(&xfr->end_serial, end_serial);
763
0
    if (xfr->reqtype == dns_rdatatype_ixfr &&
764
0
        !DNS_SERIAL_GT(end_serial, xfr->ixfr.request_serial) &&
765
0
        !dns_zone_isforced(xfr->zone))
766
0
    {
767
      /*
768
       * This must be the single SOA record that is
769
       * sent when the current version on the primary
770
       * is not newer than the version in the request.
771
       */
772
0
      xfrin_log(xfr, ISC_LOG_DEBUG(3),
773
0
          "requested serial %u, "
774
0
          "primary has %" PRIuFAST32 ", not updating",
775
0
          xfr->ixfr.request_serial, end_serial);
776
0
      result = DNS_R_UPTODATE;
777
0
      goto failure;
778
0
    }
779
0
    xfr->firstsoa = *rdata;
780
0
    if (xfr->firstsoa_data != NULL) {
781
0
      isc_mem_free(xfr->mctx, xfr->firstsoa_data);
782
0
    }
783
0
    xfr->firstsoa_data = isc_mem_allocate(xfr->mctx, rdata->length);
784
0
    memcpy(xfr->firstsoa_data, rdata->data, rdata->length);
785
0
    xfr->firstsoa.data = xfr->firstsoa_data;
786
0
    atomic_store(&xfr->state, XFRST_FIRSTDATA);
787
0
    break;
788
789
0
  case XFRST_FIRSTDATA:
790
    /*
791
     * If the transfer begins with one SOA record, it is an AXFR,
792
     * if it begins with two SOAs, it is an IXFR.
793
     */
794
0
    if (xfr->reqtype == dns_rdatatype_ixfr &&
795
0
        rdata->type == dns_rdatatype_soa &&
796
0
        xfr->ixfr.request_serial == dns_soa_getserial(rdata))
797
0
    {
798
0
      xfrin_log(xfr, ISC_LOG_DEBUG(3),
799
0
          "got incremental response");
800
0
      CHECK(ixfr_init(xfr));
801
0
      atomic_store(&xfr->state, XFRST_IXFR_DELSOA);
802
0
    } else {
803
0
      xfrin_log(xfr, ISC_LOG_DEBUG(3),
804
0
          "got nonincremental response");
805
0
      CHECK(axfr_init(xfr));
806
0
      atomic_store(&xfr->state, XFRST_AXFR);
807
0
    }
808
0
    goto redo;
809
810
0
  case XFRST_IXFR_DELSOA:
811
0
    INSIST(rdata->type == dns_rdatatype_soa);
812
0
    CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
813
0
    atomic_store(&xfr->state, XFRST_IXFR_DEL);
814
0
    break;
815
816
0
  case XFRST_IXFR_DEL:
817
0
    if (rdata->type == dns_rdatatype_soa) {
818
0
      uint32_t soa_serial = dns_soa_getserial(rdata);
819
0
      atomic_store(&xfr->state, XFRST_IXFR_ADDSOA);
820
0
      xfr->ixfr.current_serial = soa_serial;
821
0
      goto redo;
822
0
    }
823
0
    CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
824
0
    break;
825
826
0
  case XFRST_IXFR_ADDSOA:
827
0
    INSIST(rdata->type == dns_rdatatype_soa);
828
0
    CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
829
0
    atomic_store(&xfr->state, XFRST_IXFR_ADD);
830
0
    break;
831
832
0
  case XFRST_IXFR_ADD:
833
0
    if (rdata->type == dns_rdatatype_soa) {
834
0
      uint32_t soa_serial = dns_soa_getserial(rdata);
835
0
      if (soa_serial == atomic_load_relaxed(&xfr->end_serial))
836
0
      {
837
0
        CHECK(ixfr_commit(xfr));
838
0
        atomic_store(&xfr->state, XFRST_IXFR_END);
839
0
        break;
840
0
      } else if (soa_serial != xfr->ixfr.current_serial) {
841
0
        xfrin_log(xfr, ISC_LOG_NOTICE,
842
0
            "IXFR out of sync: "
843
0
            "expected serial %u, got %u",
844
0
            xfr->ixfr.current_serial, soa_serial);
845
0
        result = DNS_R_FORMERR;
846
0
        goto failure;
847
0
      } else {
848
0
        CHECK(ixfr_commit(xfr));
849
0
        atomic_store(&xfr->state, XFRST_IXFR_DELSOA);
850
0
        goto redo;
851
0
      }
852
0
    }
853
0
    if (rdata->type == dns_rdatatype_ns &&
854
0
        dns_name_iswildcard(name))
855
0
    {
856
0
      result = DNS_R_INVALIDNS;
857
0
      goto failure;
858
0
    }
859
0
    CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
860
0
    break;
861
862
0
  case XFRST_AXFR:
863
    /*
864
     * Old BINDs sent cross class A records for non IN classes.
865
     */
866
0
    if (rdata->type == dns_rdatatype_a &&
867
0
        rdata->rdclass != xfr->rdclass &&
868
0
        xfr->rdclass != dns_rdataclass_in)
869
0
    {
870
0
      break;
871
0
    }
872
0
    CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
873
0
    if (rdata->type == dns_rdatatype_soa) {
874
      /*
875
       * Use dns_rdata_compare instead of memcmp to
876
       * allow for case differences.
877
       */
878
0
      if (dns_rdata_compare(rdata, &xfr->firstsoa) != 0) {
879
0
        xfrin_log(xfr, ISC_LOG_NOTICE,
880
0
            "start and ending SOA records "
881
0
            "mismatch");
882
0
        result = DNS_R_FORMERR;
883
0
        goto failure;
884
0
      }
885
0
      axfr_commit(xfr);
886
0
      atomic_store(&xfr->state, XFRST_AXFR_END);
887
0
      break;
888
0
    }
889
0
    break;
890
0
  case XFRST_AXFR_END:
891
0
  case XFRST_IXFR_END:
892
0
    result = DNS_R_EXTRADATA;
893
0
    goto failure;
894
0
  default:
895
0
    UNREACHABLE();
896
0
  }
897
0
  result = ISC_R_SUCCESS;
898
0
failure:
899
0
  return result;
900
0
}
901
902
void
903
dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
904
     uint32_t ixfr_maxdiffs, const isc_sockaddr_t *primaryaddr,
905
     const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
906
     dns_transport_type_t soa_transport_type,
907
     dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
908
0
     isc_mem_t *mctx, dns_xfrin_t **xfrp) {
909
0
  dns_name_t *zonename = dns_zone_getorigin(zone);
910
0
  dns_xfrin_t *xfr = NULL;
911
0
  dns_db_t *db = NULL;
912
0
  isc_loop_t *loop = NULL;
913
914
0
  REQUIRE(xfrp != NULL && *xfrp == NULL);
915
0
  REQUIRE(isc_sockaddr_getport(primaryaddr) != 0);
916
0
  REQUIRE(zone != NULL);
917
0
  REQUIRE(dns_zone_getview(zone) != NULL);
918
919
0
  loop = dns_zone_getloop(zone);
920
921
0
  (void)dns_zone_getdb(zone, &db);
922
923
0
  if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) {
924
0
    REQUIRE(db != NULL);
925
0
  }
926
927
0
  xfrin_create(mctx, zone, db, loop, zonename, dns_zone_getclass(zone),
928
0
         xfrtype, ixfr_maxdiffs, primaryaddr, sourceaddr, tsigkey,
929
0
         soa_transport_type, transport, tlsctx_cache, &xfr);
930
931
0
  if (db != NULL) {
932
0
    xfr->zone_had_db = true;
933
0
    dns_db_detach(&db);
934
0
  }
935
936
0
  *xfrp = xfr;
937
0
}
938
939
isc_result_t
940
0
dns_xfrin_start(dns_xfrin_t *xfr, dns_xfrindone_t done) {
941
0
  isc_result_t result;
942
943
0
  REQUIRE(xfr != NULL);
944
0
  REQUIRE(xfr->zone != NULL);
945
0
  REQUIRE(done != NULL);
946
947
0
  xfr->done = done;
948
949
0
  result = xfrin_start(xfr);
950
0
  if (result != ISC_R_SUCCESS) {
951
0
    xfr->done = NULL;
952
0
    xfrin_fail(xfr, result, "zone transfer start failed");
953
0
  }
954
955
0
  return result;
956
0
}
957
958
static void
959
0
xfrin_timedout(void *xfr) {
960
0
  REQUIRE(VALID_XFRIN(xfr));
961
962
0
  xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum transfer time exceeded");
963
0
}
964
965
static void
966
0
xfrin_idledout(void *xfr) {
967
0
  REQUIRE(VALID_XFRIN(xfr));
968
969
0
  xfrin_fail(xfr, ISC_R_TIMEDOUT, "maximum idle time exceeded");
970
0
}
971
972
static void
973
0
xfrin_minratecheck(void *arg) {
974
0
  dns_xfrin_t *xfr = arg;
975
976
0
  REQUIRE(VALID_XFRIN(xfr));
977
978
0
  const uint64_t nbytes = atomic_load_relaxed(&xfr->nbytes);
979
0
  const uint64_t min = dns_zone_getminxfrratebytesin(xfr->zone);
980
0
  uint64_t rate = nbytes - xfr->nbytes_saved;
981
982
0
  if (rate < min) {
983
0
    isc_timer_stop(xfr->min_rate_timer);
984
0
    xfrin_fail(xfr, ISC_R_TIMEDOUT,
985
0
         "minimum transfer rate reached");
986
0
  } else {
987
0
    xfr->nbytes_saved = nbytes;
988
989
    /*
990
     * Calculate and store for the statistics channel the transfer
991
     * rate in bytes-per-second for the latest interval.
992
     */
993
0
    rate /= dns_zone_getminxfrratesecondsin(xfr->zone);
994
0
    atomic_store_relaxed(&xfr->rate_bytes_per_second, rate);
995
0
  }
996
0
}
997
998
isc_time_t
999
0
dns_xfrin_getstarttime(dns_xfrin_t *xfr) {
1000
0
  REQUIRE(VALID_XFRIN(xfr));
1001
1002
0
  return atomic_load_relaxed(&xfr->start);
1003
0
}
1004
1005
void
1006
dns_xfrin_getstate(const dns_xfrin_t *xfr, const char **statestr,
1007
0
       bool *is_first_data_received, bool *is_ixfr) {
1008
0
  xfrin_state_t state;
1009
1010
0
  REQUIRE(VALID_XFRIN(xfr));
1011
0
  REQUIRE(statestr != NULL && *statestr == NULL);
1012
0
  REQUIRE(is_ixfr != NULL);
1013
1014
0
  state = atomic_load(&xfr->state);
1015
0
  *statestr = "";
1016
0
  *is_first_data_received = (state > XFRST_FIRSTDATA);
1017
0
  *is_ixfr = atomic_load(&xfr->is_ixfr);
1018
1019
0
  switch (state) {
1020
0
  case XFRST_SOAQUERY:
1021
0
    *statestr = "SOA Query";
1022
0
    break;
1023
0
  case XFRST_GOTSOA:
1024
0
    *statestr = "Got SOA";
1025
0
    break;
1026
0
  case XFRST_ZONEXFRREQUEST:
1027
0
    *statestr = "Zone Transfer Request";
1028
0
    break;
1029
0
  case XFRST_FIRSTDATA:
1030
0
    *statestr = "First Data";
1031
0
    break;
1032
0
  case XFRST_IXFR_DELSOA:
1033
0
  case XFRST_IXFR_DEL:
1034
0
  case XFRST_IXFR_ADDSOA:
1035
0
  case XFRST_IXFR_ADD:
1036
0
    *statestr = "Receiving IXFR Data";
1037
0
    break;
1038
0
  case XFRST_IXFR_END:
1039
0
    *statestr = "Finalizing IXFR";
1040
0
    break;
1041
0
  case XFRST_AXFR:
1042
0
    *statestr = "Receiving AXFR Data";
1043
0
    break;
1044
0
  case XFRST_AXFR_END:
1045
0
    *statestr = "Finalizing AXFR";
1046
0
    break;
1047
0
  }
1048
0
}
1049
1050
uint32_t
1051
0
dns_xfrin_getendserial(dns_xfrin_t *xfr) {
1052
0
  REQUIRE(VALID_XFRIN(xfr));
1053
1054
0
  return atomic_load_relaxed(&xfr->end_serial);
1055
0
}
1056
1057
void
1058
dns_xfrin_getstats(dns_xfrin_t *xfr, unsigned int *nmsgp, unsigned int *nrecsp,
1059
0
       uint64_t *nbytesp, uint64_t *ratep) {
1060
0
  REQUIRE(VALID_XFRIN(xfr));
1061
0
  REQUIRE(nmsgp != NULL && nrecsp != NULL && nbytesp != NULL);
1062
1063
0
  uint64_t rate = atomic_load_relaxed(&xfr->rate_bytes_per_second);
1064
0
  if (rate == 0) {
1065
    /*
1066
     * Likely the first 'min-transfer-rate-in <bytes> <minutes>'
1067
     * minutes interval hasn't passed yet. Calculate the overall
1068
     * average transfer rate instead.
1069
     */
1070
0
    isc_time_t now = isc_time_now();
1071
0
    isc_time_t start = atomic_load_relaxed(&xfr->start);
1072
0
    uint64_t sec = isc_time_microdiff(&now, &start) / US_PER_SEC;
1073
0
    if (sec > 0) {
1074
0
      rate = atomic_load_relaxed(&xfr->nbytes) / sec;
1075
0
    }
1076
0
  }
1077
1078
0
  SET_IF_NOT_NULL(nmsgp, atomic_load_relaxed(&xfr->nmsg));
1079
0
  SET_IF_NOT_NULL(nrecsp, atomic_load_relaxed(&xfr->nrecs));
1080
0
  SET_IF_NOT_NULL(nbytesp, atomic_load_relaxed(&xfr->nbytes));
1081
0
  SET_IF_NOT_NULL(ratep, rate);
1082
0
}
1083
1084
const isc_sockaddr_t *
1085
0
dns_xfrin_getsourceaddr(const dns_xfrin_t *xfr) {
1086
0
  REQUIRE(VALID_XFRIN(xfr));
1087
1088
0
  return &xfr->sourceaddr;
1089
0
}
1090
1091
const isc_sockaddr_t *
1092
0
dns_xfrin_getprimaryaddr(const dns_xfrin_t *xfr) {
1093
0
  REQUIRE(VALID_XFRIN(xfr));
1094
1095
0
  return &xfr->primaryaddr;
1096
0
}
1097
1098
dns_transport_type_t
1099
0
dns_xfrin_gettransporttype(const dns_xfrin_t *xfr) {
1100
0
  REQUIRE(VALID_XFRIN(xfr));
1101
1102
0
  if (xfr->transport != NULL) {
1103
0
    return dns_transport_get_type(xfr->transport);
1104
0
  }
1105
1106
0
  return DNS_TRANSPORT_TCP;
1107
0
}
1108
1109
dns_transport_type_t
1110
0
dns_xfrin_getsoatransporttype(dns_xfrin_t *xfr) {
1111
0
  REQUIRE(VALID_XFRIN(xfr));
1112
1113
0
  return atomic_load_relaxed(&xfr->soa_transport_type);
1114
0
}
1115
1116
const dns_name_t *
1117
0
dns_xfrin_gettsigkeyname(const dns_xfrin_t *xfr) {
1118
0
  REQUIRE(VALID_XFRIN(xfr));
1119
1120
0
  if (xfr->tsigkey == NULL || xfr->tsigkey->key == NULL) {
1121
0
    return NULL;
1122
0
  }
1123
1124
0
  return dst_key_name(xfr->tsigkey->key);
1125
0
}
1126
1127
static void
1128
0
xfrin_shutdown(void *arg) {
1129
0
  dns_xfrin_t *xfr = arg;
1130
1131
0
  REQUIRE(VALID_XFRIN(xfr));
1132
1133
0
  xfrin_fail(xfr, ISC_R_SHUTTINGDOWN, "shut down");
1134
0
  dns_xfrin_detach(&xfr);
1135
0
}
1136
1137
void
1138
0
dns_xfrin_shutdown(dns_xfrin_t *xfr) {
1139
0
  REQUIRE(VALID_XFRIN(xfr));
1140
1141
0
  if (xfr->loop != isc_loop()) {
1142
0
    dns_xfrin_ref(xfr);
1143
0
    isc_async_run(xfr->loop, xfrin_shutdown, xfr);
1144
0
  } else {
1145
0
    xfrin_fail(xfr, ISC_R_SHUTTINGDOWN, "shut down");
1146
0
  }
1147
0
}
1148
1149
#if DNS_XFRIN_TRACE
1150
ISC_REFCOUNT_TRACE_IMPL(dns_xfrin, xfrin_destroy);
1151
#else
1152
ISC_REFCOUNT_IMPL(dns_xfrin, xfrin_destroy);
1153
#endif
1154
1155
static void
1156
0
xfrin_cancelio(dns_xfrin_t *xfr) {
1157
0
  if (xfr->dispentry != NULL) {
1158
0
    dns_dispatch_done(&xfr->dispentry);
1159
0
  }
1160
0
  if (xfr->disp != NULL) {
1161
0
    dns_dispatch_detach(&xfr->disp);
1162
0
  }
1163
0
}
1164
1165
static void
1166
0
xfrin_reset(dns_xfrin_t *xfr) {
1167
0
  REQUIRE(VALID_XFRIN(xfr));
1168
1169
0
  xfrin_log(xfr, ISC_LOG_INFO, "resetting");
1170
1171
0
  if (xfr->lasttsig != NULL) {
1172
0
    isc_buffer_free(&xfr->lasttsig);
1173
0
  }
1174
1175
0
  dns_diff_clear(&xfr->diff);
1176
0
  xfr->ixfr.diffs = 0;
1177
1178
0
  if (xfr->ixfr.journal != NULL) {
1179
0
    dns_journal_destroy(&xfr->ixfr.journal);
1180
0
  }
1181
1182
0
  if (xfr->axfr.add_private != NULL) {
1183
0
    (void)dns_db_endload(xfr->db, &xfr->axfr);
1184
0
  }
1185
1186
0
  if (xfr->ver != NULL) {
1187
0
    dns_db_closeversion(xfr->db, &xfr->ver, false);
1188
0
  }
1189
0
}
1190
1191
static void
1192
0
xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) {
1193
0
  REQUIRE(VALID_XFRIN(xfr));
1194
1195
0
  dns_xfrin_ref(xfr);
1196
1197
  /* Make sure only the first xfrin_fail() trumps */
1198
0
  if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false },
1199
0
             true))
1200
0
  {
1201
0
    if (result != DNS_R_UPTODATE) {
1202
0
      xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
1203
0
          isc_result_totext(result));
1204
0
      if (atomic_load(&xfr->is_ixfr) &&
1205
0
          result != ISC_R_CANCELED &&
1206
0
          result != ISC_R_SHUTTINGDOWN)
1207
0
      {
1208
        /*
1209
         * Pass special result code to force AXFR retry
1210
         */
1211
0
        result = DNS_R_BADIXFR;
1212
0
      }
1213
0
    }
1214
1215
0
    xfrin_cancelio(xfr);
1216
1217
0
    xfrin_end(xfr, result);
1218
0
  }
1219
1220
0
  dns_xfrin_detach(&xfr);
1221
0
}
1222
1223
static void
1224
xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop,
1225
       dns_name_t *zonename, dns_rdataclass_t rdclass,
1226
       dns_rdatatype_t reqtype, uint32_t ixfr_maxdiffs,
1227
       const isc_sockaddr_t *primaryaddr,
1228
       const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
1229
       dns_transport_type_t soa_transport_type,
1230
       dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
1231
0
       dns_xfrin_t **xfrp) {
1232
0
  dns_xfrin_t *xfr = NULL;
1233
1234
0
  xfr = isc_mem_get(mctx, sizeof(*xfr));
1235
0
  *xfr = (dns_xfrin_t){
1236
0
    .shutdown_result = ISC_R_UNSET,
1237
0
    .rdclass = rdclass,
1238
0
    .reqtype = reqtype,
1239
0
    .ixfr.maxdiffs = ixfr_maxdiffs,
1240
0
    .maxrecords = dns_zone_getmaxrecords(zone),
1241
0
    .primaryaddr = *primaryaddr,
1242
0
    .sourceaddr = *sourceaddr,
1243
0
    .soa_transport_type = soa_transport_type,
1244
0
    .firstsoa = DNS_RDATA_INIT,
1245
0
    .edns = true,
1246
0
    .references = 1,
1247
0
    .magic = XFRIN_MAGIC,
1248
0
  };
1249
1250
0
  isc_loop_attach(loop, &xfr->loop);
1251
0
  isc_mem_attach(mctx, &xfr->mctx);
1252
0
  dns_zone_iattach(zone, &xfr->zone);
1253
0
  dns_view_weakattach(dns_zone_getview(zone), &xfr->view);
1254
0
  dns_name_init(&xfr->name);
1255
1256
0
  __cds_wfcq_init(&xfr->diff_head, &xfr->diff_tail);
1257
1258
0
  atomic_init(&xfr->is_ixfr, false);
1259
1260
0
  if (db != NULL) {
1261
0
    dns_db_attach(db, &xfr->db);
1262
0
  }
1263
1264
0
  dns_diff_init(xfr->mctx, &xfr->diff);
1265
1266
0
  if (reqtype == dns_rdatatype_soa) {
1267
0
    atomic_init(&xfr->state, XFRST_SOAQUERY);
1268
0
  } else {
1269
0
    atomic_init(&xfr->state, XFRST_ZONEXFRREQUEST);
1270
0
  }
1271
1272
0
  atomic_init(&xfr->start, isc_time_now());
1273
1274
0
  if (tsigkey != NULL) {
1275
0
    dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
1276
0
  }
1277
1278
0
  if (transport != NULL) {
1279
0
    dns_transport_attach(transport, &xfr->transport);
1280
0
  }
1281
1282
0
  dns_name_dup(zonename, mctx, &xfr->name);
1283
1284
0
  INSIST(isc_sockaddr_pf(primaryaddr) == isc_sockaddr_pf(sourceaddr));
1285
0
  isc_sockaddr_setport(&xfr->sourceaddr, 0);
1286
1287
  /*
1288
   * Reserve 2 bytes for TCP length at the beginning of the buffer.
1289
   */
1290
0
  isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
1291
0
      sizeof(xfr->qbuffer_data) - 2);
1292
1293
0
  isc_tlsctx_cache_attach(tlsctx_cache, &xfr->tlsctx_cache);
1294
1295
0
  dns_zone_name(xfr->zone, xfr->info, sizeof(xfr->info));
1296
1297
0
  *xfrp = xfr;
1298
0
}
1299
1300
static isc_result_t
1301
0
xfrin_start(dns_xfrin_t *xfr) {
1302
0
  isc_result_t result = ISC_R_FAILURE;
1303
0
  isc_interval_t interval;
1304
0
  uint32_t primaries_timeout;
1305
1306
0
  dns_xfrin_ref(xfr);
1307
1308
  /* If this is a retry, we need to cancel the previous dispentry */
1309
0
  xfrin_cancelio(xfr);
1310
1311
0
  dns_dispatchmgr_t *dispmgr = dns_view_getdispatchmgr(xfr->view);
1312
0
  if (dispmgr == NULL) {
1313
0
    result = ISC_R_SHUTTINGDOWN;
1314
0
    goto failure;
1315
0
  }
1316
1317
0
  primaries_timeout =
1318
0
    isc_nm_getprimariestimeout(dns_dispatchmgr_getnetmgr(dispmgr));
1319
0
  result = dns_dispatch_createtcp(dispmgr, &xfr->sourceaddr,
1320
0
          &xfr->primaryaddr, xfr->transport,
1321
0
          DNS_DISPATCHOPT_UNSHARED, &xfr->disp);
1322
0
  dns_dispatchmgr_detach(&dispmgr);
1323
0
  if (result != ISC_R_SUCCESS) {
1324
0
    goto failure;
1325
0
  }
1326
1327
0
  LIBDNS_XFRIN_START(xfr, xfr->info);
1328
1329
  /*
1330
   * If the transfer is started when the 'state' is XFRST_SOAQUERY, it
1331
   * means the SOA query will be performed by xfrin. A transfer could also
1332
   * be initiated starting from the XFRST_ZONEXFRREQUEST state, which
1333
   * means that the SOA query was already performed by other means (e.g.
1334
   * by zone.c:soa_query()), or that it's a transfer without a preceding
1335
   * SOA request, and 'soa_transport_type' is already correctly
1336
   * set by the creator of the xfrin.
1337
   */
1338
0
  if (atomic_load(&xfr->state) == XFRST_SOAQUERY) {
1339
    /*
1340
     * The "SOA before" mode is used, where the SOA request is
1341
     * using the same transport as the XFR.
1342
     */
1343
0
    atomic_store_relaxed(&xfr->soa_transport_type,
1344
0
             dns_xfrin_gettransporttype(xfr));
1345
0
  }
1346
1347
  /*
1348
   * The read timeout timer is disabled on the dispatch level because
1349
   * the xfr module has its own timeouts.
1350
   */
1351
0
  const unsigned int read_timeout = 0;
1352
1353
0
  CHECK(dns_dispatch_add(xfr->disp, xfr->loop, 0, primaries_timeout,
1354
0
             read_timeout, &xfr->primaryaddr, xfr->transport,
1355
0
             xfr->tlsctx_cache, xfrin_connect_done,
1356
0
             xfrin_send_done, xfrin_recv_done, xfr, &xfr->id,
1357
0
             &xfr->dispentry));
1358
1359
  /* Set the maximum timer */
1360
0
  if (xfr->max_time_timer == NULL) {
1361
0
    isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_timedout,
1362
0
         xfr, &xfr->max_time_timer);
1363
0
  }
1364
0
  isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
1365
0
  isc_timer_start(xfr->max_time_timer, isc_timertype_once, &interval);
1366
1367
  /* Set the idle timer */
1368
0
  if (xfr->max_idle_timer == NULL) {
1369
0
    isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_idledout,
1370
0
         xfr, &xfr->max_idle_timer);
1371
0
  }
1372
0
  isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
1373
0
  isc_timer_start(xfr->max_idle_timer, isc_timertype_once, &interval);
1374
1375
  /* Set the minimum transfer rate checking timer */
1376
0
  if (xfr->min_rate_timer == NULL) {
1377
0
    isc_timer_create(dns_zone_getloop(xfr->zone),
1378
0
         xfrin_minratecheck, xfr, &xfr->min_rate_timer);
1379
0
  }
1380
0
  isc_interval_set(&interval, dns_zone_getminxfrratesecondsin(xfr->zone),
1381
0
       0);
1382
0
  isc_timer_start(xfr->min_rate_timer, isc_timertype_ticker, &interval);
1383
1384
  /*
1385
   * The connect has to be the last thing that is called before returning,
1386
   * as it can end synchronously and destroy the xfr object.
1387
   */
1388
0
  CHECK(dns_dispatch_connect(xfr->dispentry));
1389
1390
0
  return ISC_R_SUCCESS;
1391
1392
0
failure:
1393
0
  xfrin_cancelio(xfr);
1394
0
  dns_xfrin_detach(&xfr);
1395
1396
0
  return result;
1397
0
}
1398
1399
/* XXX the resolver could use this, too */
1400
1401
static isc_result_t
1402
0
render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
1403
0
  dns_compress_t cctx;
1404
0
  isc_result_t result;
1405
1406
0
  dns_compress_init(&cctx, mctx, 0);
1407
0
  CHECK(dns_message_renderbegin(msg, &cctx, buf));
1408
0
  CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
1409
0
  CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
1410
0
  CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
1411
0
  CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
1412
0
  CHECK(dns_message_renderend(msg));
1413
0
  result = ISC_R_SUCCESS;
1414
0
failure:
1415
0
  dns_compress_invalidate(&cctx);
1416
0
  return result;
1417
0
}
1418
1419
/*
1420
 * A connection has been established.
1421
 */
1422
static void
1423
xfrin_connect_done(isc_result_t result, isc_region_t *region ISC_ATTR_UNUSED,
1424
0
       void *arg) {
1425
0
  dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
1426
0
  char addrtext[ISC_SOCKADDR_FORMATSIZE];
1427
0
  char signerbuf[DNS_NAME_FORMATSIZE];
1428
0
  const char *signer = "", *sep = "";
1429
0
  dns_zonemgr_t *zmgr = NULL;
1430
1431
0
  REQUIRE(VALID_XFRIN(xfr));
1432
1433
0
  if (atomic_load(&xfr->shuttingdown)) {
1434
0
    result = ISC_R_SHUTTINGDOWN;
1435
0
  }
1436
1437
0
  LIBDNS_XFRIN_CONNECTED(xfr, xfr->info, result);
1438
1439
0
  if (result != ISC_R_SUCCESS) {
1440
0
    xfrin_fail(xfr, result, "failed to connect");
1441
0
    goto failure;
1442
0
  }
1443
1444
0
  result = dns_dispatch_checkperm(xfr->disp);
1445
0
  if (result != ISC_R_SUCCESS) {
1446
0
    xfrin_fail(xfr, result, "connected but unable to transfer");
1447
0
    goto failure;
1448
0
  }
1449
1450
0
  zmgr = dns_zone_getmgr(xfr->zone);
1451
0
  if (zmgr != NULL) {
1452
0
    dns_view_t *view = dns_zone_getview(xfr->zone);
1453
0
    dns_unreachcache_remove(view->unreachcache, &xfr->primaryaddr,
1454
0
          &xfr->sourceaddr);
1455
0
  }
1456
1457
0
  if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
1458
0
    dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
1459
0
        sizeof(signerbuf));
1460
0
    sep = " TSIG ";
1461
0
    signer = signerbuf;
1462
0
  }
1463
1464
0
  isc_sockaddr_format(&xfr->primaryaddr, addrtext, sizeof(addrtext));
1465
0
  xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", addrtext, sep,
1466
0
      signer);
1467
1468
0
  result = xfrin_send_request(xfr);
1469
0
  if (result != ISC_R_SUCCESS) {
1470
0
    xfrin_fail(xfr, result, "connected but unable to send");
1471
0
    goto detach;
1472
0
  }
1473
1474
0
  return;
1475
1476
0
failure:
1477
0
  switch (result) {
1478
0
  case ISC_R_NETDOWN:
1479
0
  case ISC_R_HOSTDOWN:
1480
0
  case ISC_R_NETUNREACH:
1481
0
  case ISC_R_HOSTUNREACH:
1482
0
  case ISC_R_CONNREFUSED:
1483
0
  case ISC_R_TIMEDOUT:
1484
    /*
1485
     * Add the server to unreachable primaries cache if
1486
     * the server has a permanent networking error or
1487
     * the connection attempt as timed out.
1488
     */
1489
0
    zmgr = dns_zone_getmgr(xfr->zone);
1490
0
    if (zmgr != NULL) {
1491
0
      dns_view_t *view = dns_zone_getview(xfr->zone);
1492
0
      dns_unreachcache_add(view->unreachcache,
1493
0
               &xfr->primaryaddr,
1494
0
               &xfr->sourceaddr);
1495
0
    }
1496
0
    break;
1497
0
  default:
1498
    /* Retry sooner than in 10 minutes */
1499
0
    break;
1500
0
  }
1501
1502
0
detach:
1503
0
  dns_xfrin_detach(&xfr);
1504
0
}
1505
1506
/*
1507
 * Convert a tuple into a dns_name_t suitable for inserting
1508
 * into the given dns_message_t.
1509
 */
1510
static void
1511
0
tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
1512
0
  dns_rdata_t *rdata = NULL;
1513
0
  dns_rdatalist_t *rdl = NULL;
1514
0
  dns_rdataset_t *rds = NULL;
1515
0
  dns_name_t *name = NULL;
1516
1517
0
  REQUIRE(target != NULL && *target == NULL);
1518
1519
0
  dns_message_gettemprdata(msg, &rdata);
1520
0
  dns_rdata_clone(&tuple->rdata, rdata);
1521
1522
0
  dns_message_gettemprdatalist(msg, &rdl);
1523
0
  rdl->type = tuple->rdata.type;
1524
0
  rdl->rdclass = tuple->rdata.rdclass;
1525
0
  rdl->ttl = tuple->ttl;
1526
0
  ISC_LIST_APPEND(rdl->rdata, rdata, link);
1527
1528
0
  dns_message_gettemprdataset(msg, &rds);
1529
0
  dns_rdatalist_tordataset(rdl, rds);
1530
1531
0
  dns_message_gettempname(msg, &name);
1532
0
  dns_name_clone(&tuple->name, name);
1533
0
  ISC_LIST_APPEND(name->list, rds, link);
1534
1535
0
  *target = name;
1536
0
}
1537
1538
static const char *
1539
0
request_type(dns_xfrin_t *xfr) {
1540
0
  switch (xfr->reqtype) {
1541
0
  case dns_rdatatype_soa:
1542
0
    return "SOA";
1543
0
  case dns_rdatatype_axfr:
1544
0
    return "AXFR";
1545
0
  case dns_rdatatype_ixfr:
1546
0
    return "IXFR";
1547
0
  default:
1548
0
    ISC_UNREACHABLE();
1549
0
  }
1550
0
}
1551
1552
static isc_result_t
1553
add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
1554
0
  bool reqexpire) {
1555
0
  isc_result_t result;
1556
0
  dns_rdataset_t *rdataset = NULL;
1557
0
  dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
1558
0
  int count = 0;
1559
1560
  /* Set EDNS options if applicable. */
1561
0
  if (reqnsid) {
1562
0
    INSIST(count < DNS_EDNSOPTIONS);
1563
0
    ednsopts[count].code = DNS_OPT_NSID;
1564
0
    ednsopts[count].length = 0;
1565
0
    ednsopts[count].value = NULL;
1566
0
    count++;
1567
0
  }
1568
0
  if (reqexpire) {
1569
0
    INSIST(count < DNS_EDNSOPTIONS);
1570
0
    ednsopts[count].code = DNS_OPT_EXPIRE;
1571
0
    ednsopts[count].length = 0;
1572
0
    ednsopts[count].value = NULL;
1573
0
    count++;
1574
0
  }
1575
0
  result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
1576
0
              ednsopts, count);
1577
0
  if (result != ISC_R_SUCCESS) {
1578
0
    return result;
1579
0
  }
1580
1581
0
  return dns_message_setopt(message, rdataset);
1582
0
}
1583
1584
/*
1585
 * Build an *XFR request and send its length prefix.
1586
 */
1587
static isc_result_t
1588
0
xfrin_send_request(dns_xfrin_t *xfr) {
1589
0
  isc_result_t result;
1590
0
  isc_region_t region;
1591
0
  dns_rdataset_t *qrdataset = NULL;
1592
0
  dns_message_t *msg = NULL;
1593
0
  dns_difftuple_t *soatuple = NULL;
1594
0
  dns_name_t *qname = NULL;
1595
0
  dns_dbversion_t *ver = NULL;
1596
0
  dns_name_t *msgsoaname = NULL;
1597
0
  bool edns = xfr->edns;
1598
0
  bool reqnsid = xfr->view->requestnsid;
1599
0
  bool reqexpire = dns_zone_getrequestexpire(xfr->zone);
1600
0
  uint16_t udpsize = dns_view_getudpsize(xfr->view);
1601
1602
0
  LIBDNS_XFRIN_RECV_SEND_REQUEST(xfr, xfr->info);
1603
1604
  /* Create the request message */
1605
0
  dns_message_create(xfr->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER,
1606
0
         &msg);
1607
0
  CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1608
1609
  /* Create a name for the question section. */
1610
0
  dns_message_gettempname(msg, &qname);
1611
0
  dns_name_clone(&xfr->name, qname);
1612
1613
  /* Formulate the question and attach it to the question name. */
1614
0
  dns_message_gettemprdataset(msg, &qrdataset);
1615
0
  dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1616
0
  ISC_LIST_APPEND(qname->list, qrdataset, link);
1617
0
  qrdataset = NULL;
1618
1619
0
  dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1620
0
  qname = NULL;
1621
1622
0
  if (xfr->reqtype == dns_rdatatype_ixfr) {
1623
    /* Get the SOA and add it to the authority section. */
1624
0
    dns_db_currentversion(xfr->db, &ver);
1625
0
    CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1626
0
              DNS_DIFFOP_EXISTS, &soatuple));
1627
0
    xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1628
0
    xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1629
0
    xfrin_log(xfr, ISC_LOG_DEBUG(3),
1630
0
        "requesting IXFR for serial %u",
1631
0
        xfr->ixfr.request_serial);
1632
1633
0
    tuple2msgname(soatuple, msg, &msgsoaname);
1634
0
    dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1635
0
  } else if (xfr->reqtype == dns_rdatatype_soa) {
1636
0
    CHECK(dns_db_getsoaserial(xfr->db, NULL,
1637
0
            &xfr->ixfr.request_serial));
1638
0
  }
1639
1640
0
  if (edns && xfr->view->peers != NULL) {
1641
0
    dns_peer_t *peer = NULL;
1642
0
    isc_netaddr_t primaryip;
1643
0
    isc_netaddr_fromsockaddr(&primaryip, &xfr->primaryaddr);
1644
0
    result = dns_peerlist_peerbyaddr(xfr->view->peers, &primaryip,
1645
0
             &peer);
1646
0
    if (result == ISC_R_SUCCESS) {
1647
0
      (void)dns_peer_getsupportedns(peer, &edns);
1648
0
      (void)dns_peer_getudpsize(peer, &udpsize);
1649
0
      (void)dns_peer_getrequestnsid(peer, &reqnsid);
1650
0
      (void)dns_peer_getrequestexpire(peer, &reqexpire);
1651
0
    }
1652
0
  }
1653
1654
0
  if (edns) {
1655
0
    CHECK(add_opt(msg, udpsize, reqnsid, reqexpire));
1656
0
  }
1657
1658
0
  atomic_store_relaxed(&xfr->nmsg, 0);
1659
0
  atomic_store_relaxed(&xfr->nrecs, 0);
1660
0
  atomic_store_relaxed(&xfr->nbytes, 0);
1661
0
  atomic_store_relaxed(&xfr->start, isc_time_now());
1662
1663
0
  xfr->nbytes_saved = 0;
1664
1665
0
  msg->id = xfr->id;
1666
0
  if (xfr->tsigctx != NULL) {
1667
0
    dst_context_destroy(&xfr->tsigctx);
1668
0
  }
1669
1670
0
  CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1671
1672
  /*
1673
   * Free the last tsig, if there is one.
1674
   */
1675
0
  if (xfr->lasttsig != NULL) {
1676
0
    isc_buffer_free(&xfr->lasttsig);
1677
0
  }
1678
1679
  /*
1680
   * Save the query TSIG and don't let message_destroy free it.
1681
   */
1682
0
  CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1683
1684
0
  isc_buffer_usedregion(&xfr->qbuffer, &region);
1685
0
  INSIST(region.length <= 65535);
1686
1687
0
  dns_xfrin_ref(xfr);
1688
0
  dns_dispatch_send(xfr->dispentry, &region);
1689
0
  xfrin_log(xfr, ISC_LOG_DEBUG(3), "sending %s request, QID %d",
1690
0
      request_type(xfr), xfr->id);
1691
1692
0
failure:
1693
0
  dns_message_detach(&msg);
1694
0
  if (soatuple != NULL) {
1695
0
    dns_difftuple_free(&soatuple);
1696
0
  }
1697
0
  if (ver != NULL) {
1698
0
    dns_db_closeversion(xfr->db, &ver, false);
1699
0
  }
1700
1701
0
  return result;
1702
0
}
1703
1704
static void
1705
0
xfrin_send_done(isc_result_t result, isc_region_t *region, void *arg) {
1706
0
  dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
1707
1708
0
  UNUSED(region);
1709
1710
0
  REQUIRE(VALID_XFRIN(xfr));
1711
1712
0
  if (atomic_load(&xfr->shuttingdown)) {
1713
0
    result = ISC_R_SHUTTINGDOWN;
1714
0
  }
1715
1716
0
  LIBDNS_XFRIN_SENT(xfr, xfr->info, result);
1717
1718
0
  CHECK(result);
1719
1720
0
  xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1721
1722
0
failure:
1723
0
  if (result != ISC_R_SUCCESS) {
1724
0
    xfrin_fail(xfr, result, "failed sending request data");
1725
0
  }
1726
1727
0
  dns_xfrin_detach(&xfr);
1728
0
}
1729
1730
static void
1731
0
get_edns_expire(dns_xfrin_t *xfr, dns_message_t *msg) {
1732
0
  isc_result_t result;
1733
0
  dns_rdata_t rdata = DNS_RDATA_INIT;
1734
0
  isc_buffer_t optbuf;
1735
0
  uint16_t optcode;
1736
0
  uint16_t optlen;
1737
1738
0
  result = dns_rdataset_first(msg->opt);
1739
0
  if (result == ISC_R_SUCCESS) {
1740
0
    dns_rdataset_current(msg->opt, &rdata);
1741
0
    isc_buffer_init(&optbuf, rdata.data, rdata.length);
1742
0
    isc_buffer_add(&optbuf, rdata.length);
1743
0
    while (isc_buffer_remaininglength(&optbuf) >= 4) {
1744
0
      optcode = isc_buffer_getuint16(&optbuf);
1745
0
      optlen = isc_buffer_getuint16(&optbuf);
1746
      /*
1747
       * A EDNS EXPIRE response has a length of 4.
1748
       */
1749
0
      if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
1750
0
        isc_buffer_forward(&optbuf, optlen);
1751
0
        continue;
1752
0
      }
1753
0
      xfr->expireopt = isc_buffer_getuint32(&optbuf);
1754
0
      xfr->expireoptset = true;
1755
0
      dns_zone_log(xfr->zone, ISC_LOG_DEBUG(1),
1756
0
             "got EDNS EXPIRE of %u", xfr->expireopt);
1757
0
      break;
1758
0
    }
1759
0
  }
1760
0
}
1761
1762
static void
1763
0
xfrin_end(dns_xfrin_t *xfr, isc_result_t result) {
1764
  /* Inform the caller. */
1765
0
  if (xfr->done != NULL) {
1766
0
    LIBDNS_XFRIN_DONE_CALLBACK_BEGIN(xfr, xfr->info, result);
1767
0
    (xfr->done)(xfr->zone,
1768
0
          xfr->expireoptset ? &xfr->expireopt : NULL, result);
1769
0
    xfr->done = NULL;
1770
0
    LIBDNS_XFRIN_DONE_CALLBACK_END(xfr, xfr->info, result);
1771
0
  }
1772
1773
0
  atomic_store(&xfr->shuttingdown, true);
1774
1775
0
  if (xfr->max_time_timer != NULL) {
1776
0
    isc_timer_stop(xfr->max_time_timer);
1777
0
    isc_timer_destroy(&xfr->max_time_timer);
1778
0
  }
1779
0
  if (xfr->max_idle_timer != NULL) {
1780
0
    isc_timer_stop(xfr->max_idle_timer);
1781
0
    isc_timer_destroy(&xfr->max_idle_timer);
1782
0
  }
1783
0
  if (xfr->min_rate_timer != NULL) {
1784
0
    isc_timer_stop(xfr->min_rate_timer);
1785
0
    isc_timer_destroy(&xfr->min_rate_timer);
1786
0
  }
1787
1788
0
  if (xfr->shutdown_result == ISC_R_UNSET) {
1789
0
    xfr->shutdown_result = result;
1790
0
  }
1791
0
}
1792
1793
static void
1794
0
xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) {
1795
0
  dns_xfrin_t *xfr = (dns_xfrin_t *)arg;
1796
0
  dns_message_t *msg = NULL;
1797
0
  const dns_name_t *tsigowner = NULL;
1798
0
  isc_buffer_t buffer;
1799
1800
0
  REQUIRE(VALID_XFRIN(xfr));
1801
1802
0
  if (atomic_load(&xfr->shuttingdown)) {
1803
0
    result = ISC_R_SHUTTINGDOWN;
1804
0
  }
1805
1806
  /* Stop the idle timer */
1807
0
  isc_timer_stop(xfr->max_idle_timer);
1808
1809
0
  LIBDNS_XFRIN_RECV_START(xfr, xfr->info, result);
1810
1811
0
  CHECK(result);
1812
1813
0
  xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", region->length);
1814
1815
0
  dns_message_create(xfr->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE,
1816
0
         &msg);
1817
1818
0
  CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1819
0
  dns_message_setquerytsig(msg, xfr->lasttsig);
1820
1821
0
  msg->tsigctx = xfr->tsigctx;
1822
0
  xfr->tsigctx = NULL;
1823
1824
0
  dns_message_setclass(msg, xfr->rdclass);
1825
1826
0
  msg->tcp_continuation = (atomic_load_relaxed(&xfr->nmsg) > 0) ? 1 : 0;
1827
1828
0
  isc_buffer_init(&buffer, region->base, region->length);
1829
0
  isc_buffer_add(&buffer, region->length);
1830
1831
0
  result = dns_message_parse(msg, &buffer,
1832
0
           DNS_MESSAGEPARSE_PRESERVEORDER);
1833
0
  if (result == ISC_R_SUCCESS) {
1834
0
    dns_message_logpacketfrom(
1835
0
      msg, "received message", &xfr->primaryaddr,
1836
0
      DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
1837
0
      ISC_LOG_DEBUG(10), xfr->mctx);
1838
0
  } else {
1839
0
    xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
1840
0
        isc_result_totext(result));
1841
0
  }
1842
1843
0
  LIBDNS_XFRIN_RECV_PARSED(xfr, xfr->info, result);
1844
1845
0
  if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1846
0
      msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass)
1847
0
  {
1848
0
    if (result == ISC_R_SUCCESS &&
1849
0
        msg->rcode == dns_rcode_formerr && xfr->edns &&
1850
0
        (atomic_load(&xfr->state) == XFRST_SOAQUERY ||
1851
0
         atomic_load(&xfr->state) == XFRST_ZONEXFRREQUEST))
1852
0
    {
1853
0
      xfr->edns = false;
1854
0
      dns_message_detach(&msg);
1855
0
      xfrin_reset(xfr);
1856
0
      goto try_again;
1857
0
    } else if (result == ISC_R_SUCCESS &&
1858
0
         msg->rcode != dns_rcode_noerror)
1859
0
    {
1860
0
      result = dns_result_fromrcode(msg->rcode);
1861
0
    } else if (result == ISC_R_SUCCESS &&
1862
0
         msg->opcode != dns_opcode_query)
1863
0
    {
1864
0
      result = DNS_R_UNEXPECTEDOPCODE;
1865
0
    } else if (result == ISC_R_SUCCESS &&
1866
0
         msg->rdclass != xfr->rdclass)
1867
0
    {
1868
0
      result = DNS_R_BADCLASS;
1869
0
    } else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) {
1870
0
      result = DNS_R_UNEXPECTEDID;
1871
0
    }
1872
1873
0
    if (xfr->reqtype == dns_rdatatype_axfr ||
1874
0
        xfr->reqtype == dns_rdatatype_soa)
1875
0
    {
1876
0
      goto failure;
1877
0
    }
1878
1879
0
    xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1880
0
        isc_result_totext(result));
1881
0
  try_axfr:
1882
0
    LIBDNS_XFRIN_RECV_TRY_AXFR(xfr, xfr->info, result);
1883
0
    dns_message_detach(&msg);
1884
0
    xfrin_reset(xfr);
1885
0
    xfr->reqtype = dns_rdatatype_soa;
1886
0
    atomic_store(&xfr->state, XFRST_SOAQUERY);
1887
0
  try_again:
1888
0
    result = xfrin_start(xfr);
1889
0
    if (result != ISC_R_SUCCESS) {
1890
0
      xfrin_fail(xfr, result, "failed setting up socket");
1891
0
    }
1892
0
    dns_xfrin_detach(&xfr);
1893
0
    return;
1894
0
  }
1895
1896
  /*
1897
   * The question section should exist for SOA and in the first
1898
   * message of a AXFR or IXFR response.  The question section
1899
   * may exist in the 2nd and subsequent messages in a AXFR or
1900
   * IXFR response.  If the question section exists it should
1901
   * match the question that was sent.
1902
   */
1903
0
  if (msg->counts[DNS_SECTION_QUESTION] > 1) {
1904
0
    xfrin_log(xfr, ISC_LOG_NOTICE, "too many questions (%u)",
1905
0
        msg->counts[DNS_SECTION_QUESTION]);
1906
0
    result = DNS_R_FORMERR;
1907
0
    goto failure;
1908
0
  }
1909
1910
0
  if ((atomic_load(&xfr->state) == XFRST_SOAQUERY ||
1911
0
       atomic_load(&xfr->state) == XFRST_ZONEXFRREQUEST) &&
1912
0
      msg->counts[DNS_SECTION_QUESTION] != 1)
1913
0
  {
1914
0
    xfrin_log(xfr, ISC_LOG_NOTICE, "missing question section");
1915
0
    result = DNS_R_FORMERR;
1916
0
    goto failure;
1917
0
  }
1918
1919
0
  MSG_SECTION_FOREACH (msg, DNS_SECTION_QUESTION, name) {
1920
0
    dns_rdataset_t *rds = NULL;
1921
1922
0
    LIBDNS_XFRIN_RECV_QUESTION(xfr, xfr->info, msg);
1923
1924
0
    if (!dns_name_equal(name, &xfr->name)) {
1925
0
      xfrin_log(xfr, ISC_LOG_NOTICE,
1926
0
          "question name mismatch");
1927
0
      result = DNS_R_FORMERR;
1928
0
      goto failure;
1929
0
    }
1930
0
    rds = ISC_LIST_HEAD(name->list);
1931
0
    INSIST(rds != NULL);
1932
0
    if (rds->type != xfr->reqtype) {
1933
0
      xfrin_log(xfr, ISC_LOG_NOTICE,
1934
0
          "question type mismatch");
1935
0
      result = DNS_R_FORMERR;
1936
0
      goto failure;
1937
0
    }
1938
0
    if (rds->rdclass != xfr->rdclass) {
1939
0
      xfrin_log(xfr, ISC_LOG_NOTICE,
1940
0
          "question class mismatch");
1941
0
      result = DNS_R_FORMERR;
1942
0
      goto failure;
1943
0
    }
1944
0
  }
1945
1946
  /*
1947
   * Does the server know about IXFR?  If it doesn't we will get
1948
   * a message with a empty answer section or a potentially a CNAME /
1949
   * DNAME, the later is handled by xfr_rr() which will return FORMERR
1950
   * if the first RR in the answer section is not a SOA record.
1951
   */
1952
0
  if (xfr->reqtype == dns_rdatatype_ixfr &&
1953
0
      atomic_load(&xfr->state) == XFRST_ZONEXFRREQUEST &&
1954
0
      msg->counts[DNS_SECTION_ANSWER] == 0)
1955
0
  {
1956
0
    xfrin_log(xfr, ISC_LOG_DEBUG(3),
1957
0
        "empty answer section, retrying with AXFR");
1958
0
    goto try_axfr;
1959
0
  }
1960
1961
0
  if (xfr->reqtype == dns_rdatatype_soa &&
1962
0
      (msg->flags & DNS_MESSAGEFLAG_AA) == 0)
1963
0
  {
1964
0
    result = DNS_R_NOTAUTHORITATIVE;
1965
0
    goto failure;
1966
0
  }
1967
1968
0
  result = dns_message_checksig(msg, xfr->view);
1969
0
  if (result != ISC_R_SUCCESS) {
1970
0
    xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1971
0
        isc_result_totext(result));
1972
0
    goto failure;
1973
0
  }
1974
1975
0
  MSG_SECTION_FOREACH (msg, DNS_SECTION_ANSWER, name) {
1976
0
    LIBDNS_XFRIN_RECV_ANSWER(xfr, xfr->info, msg);
1977
1978
0
    ISC_LIST_FOREACH (name->list, rds, link) {
1979
0
      DNS_RDATASET_FOREACH (rds) {
1980
0
        dns_rdata_t rdata = DNS_RDATA_INIT;
1981
0
        dns_rdataset_current(rds, &rdata);
1982
0
        CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1983
1984
        /*
1985
         * Did we hit the maximum ixfr diffs limit?
1986
         */
1987
0
        if (xfr->reqtype == dns_rdatatype_ixfr &&
1988
0
            xfr->ixfr.maxdiffs != 0 &&
1989
0
            xfr->ixfr.diffs >= xfr->ixfr.maxdiffs)
1990
0
        {
1991
0
          xfrin_log(xfr, ISC_LOG_DEBUG(3),
1992
0
              "too many diffs, "
1993
0
              "retrying with AXFR");
1994
0
          goto try_axfr;
1995
0
        }
1996
0
      }
1997
0
    }
1998
0
  }
1999
2000
0
  if (dns_message_gettsig(msg, &tsigowner) != NULL) {
2001
    /*
2002
     * Reset the counter.
2003
     */
2004
0
    xfr->sincetsig = 0;
2005
2006
    /*
2007
     * Free the last tsig, if there is one.
2008
     */
2009
0
    if (xfr->lasttsig != NULL) {
2010
0
      isc_buffer_free(&xfr->lasttsig);
2011
0
    }
2012
2013
    /*
2014
     * Update the last tsig pointer.
2015
     */
2016
0
    CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
2017
0
  } else if (dns_message_gettsigkey(msg) != NULL) {
2018
0
    xfr->sincetsig++;
2019
0
    if (xfr->sincetsig > 100 ||
2020
0
        atomic_load_relaxed(&xfr->nmsg) == 0 ||
2021
0
        atomic_load(&xfr->state) == XFRST_AXFR_END ||
2022
0
        atomic_load(&xfr->state) == XFRST_IXFR_END)
2023
0
    {
2024
0
      result = DNS_R_EXPECTEDTSIG;
2025
0
      goto failure;
2026
0
    }
2027
0
  }
2028
2029
  /*
2030
   * Update the number of messages and bytes received.
2031
   */
2032
0
  atomic_fetch_add_relaxed(&xfr->nmsg, 1);
2033
0
  atomic_fetch_add_relaxed(&xfr->nbytes, buffer.used);
2034
2035
  /*
2036
   * Take the context back.
2037
   */
2038
0
  INSIST(xfr->tsigctx == NULL);
2039
0
  xfr->tsigctx = msg->tsigctx;
2040
0
  msg->tsigctx = NULL;
2041
2042
0
  if (!xfr->expireoptset && msg->opt != NULL) {
2043
0
    get_edns_expire(xfr, msg);
2044
0
  }
2045
2046
0
  switch (atomic_load(&xfr->state)) {
2047
0
  case XFRST_GOTSOA:
2048
0
    xfr->reqtype = dns_rdatatype_axfr;
2049
0
    atomic_store(&xfr->state, XFRST_ZONEXFRREQUEST);
2050
0
    CHECK(xfrin_start(xfr));
2051
0
    break;
2052
0
  case XFRST_AXFR_END:
2053
0
  case XFRST_IXFR_END:
2054
    /* We are at the end, cancel the timers and IO */
2055
0
    isc_timer_stop(xfr->min_rate_timer);
2056
0
    isc_timer_stop(xfr->max_idle_timer);
2057
0
    isc_timer_stop(xfr->max_time_timer);
2058
0
    xfrin_cancelio(xfr);
2059
0
    break;
2060
0
  default:
2061
    /*
2062
     * Read the next message.
2063
     */
2064
0
    dns_message_detach(&msg);
2065
0
    result = dns_dispatch_getnext(xfr->dispentry);
2066
0
    if (result != ISC_R_SUCCESS) {
2067
0
      goto failure;
2068
0
    }
2069
2070
0
    isc_interval_t interval;
2071
0
    isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
2072
0
    isc_timer_start(xfr->max_idle_timer, isc_timertype_once,
2073
0
        &interval);
2074
2075
0
    LIBDNS_XFRIN_READ(xfr, xfr->info, result);
2076
0
    return;
2077
0
  }
2078
2079
0
failure:
2080
0
  if (result != ISC_R_SUCCESS) {
2081
0
    xfrin_fail(xfr, result, "failed while receiving responses");
2082
0
  }
2083
2084
0
  if (msg != NULL) {
2085
0
    dns_message_detach(&msg);
2086
0
  }
2087
0
  dns_xfrin_detach(&xfr);
2088
0
  LIBDNS_XFRIN_RECV_DONE(xfr, xfr->info, result);
2089
0
}
2090
2091
static void
2092
0
xfrin_destroy(dns_xfrin_t *xfr) {
2093
0
  uint64_t msecs, persec;
2094
0
  isc_time_t now = isc_time_now();
2095
0
  char expireopt[sizeof("4000000000")] = { 0 };
2096
0
  const char *sep = "";
2097
2098
0
  REQUIRE(VALID_XFRIN(xfr));
2099
2100
  /* Safe-guards */
2101
0
  REQUIRE(atomic_load(&xfr->shuttingdown));
2102
2103
0
  INSIST(xfr->shutdown_result != ISC_R_UNSET);
2104
2105
  /*
2106
   * If we're called through dns_xfrin_detach() and are not
2107
   * shutting down, we can't know what the transfer status is as
2108
   * we are only called when the last reference is lost.
2109
   */
2110
0
  xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s",
2111
0
      isc_result_totext(xfr->shutdown_result));
2112
2113
  /*
2114
   * Calculate the length of time the transfer took,
2115
   * and print a log message with the bytes and rate.
2116
   */
2117
0
  isc_time_t start = atomic_load_relaxed(&xfr->start);
2118
0
  msecs = isc_time_microdiff(&now, &start) / 1000;
2119
0
  if (msecs == 0) {
2120
0
    msecs = 1;
2121
0
  }
2122
0
  persec = (atomic_load_relaxed(&xfr->nbytes) * 1000) / msecs;
2123
2124
0
  if (xfr->expireoptset) {
2125
0
    sep = ", expire option ";
2126
0
    snprintf(expireopt, sizeof(expireopt), "%u", xfr->expireopt);
2127
0
  }
2128
2129
0
  xfrin_log(xfr, ISC_LOG_INFO,
2130
0
      "Transfer completed: %d messages, %d records, "
2131
0
      "%" PRIu64 " bytes, "
2132
0
      "%u.%03u secs (%u bytes/sec) (serial %" PRIuFAST32 "%s%s)",
2133
0
      atomic_load_relaxed(&xfr->nmsg),
2134
0
      atomic_load_relaxed(&xfr->nrecs),
2135
0
      atomic_load_relaxed(&xfr->nbytes),
2136
0
      (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
2137
0
      (unsigned int)persec, atomic_load_relaxed(&xfr->end_serial),
2138
0
      sep, expireopt);
2139
2140
  /* Cleanup unprocessed IXFR data */
2141
0
  struct cds_wfcq_node *node, *next;
2142
0
  __cds_wfcq_for_each_blocking_safe(&xfr->diff_head, &xfr->diff_tail,
2143
0
            node, next) {
2144
0
    ixfr_apply_data_t *data =
2145
0
      caa_container_of(node, ixfr_apply_data_t, wfcq_node);
2146
    /* We need to clear and free all data chunks */
2147
0
    dns_diff_clear(&data->diff);
2148
0
    isc_mem_put(xfr->mctx, data, sizeof(*data));
2149
0
  }
2150
2151
  /* Cleanup unprocessed AXFR data */
2152
0
  dns_diff_clear(&xfr->diff);
2153
2154
0
  xfrin_cancelio(xfr);
2155
2156
0
  if (xfr->transport != NULL) {
2157
0
    dns_transport_detach(&xfr->transport);
2158
0
  }
2159
2160
0
  if (xfr->tsigkey != NULL) {
2161
0
    dns_tsigkey_detach(&xfr->tsigkey);
2162
0
  }
2163
2164
0
  if (xfr->lasttsig != NULL) {
2165
0
    isc_buffer_free(&xfr->lasttsig);
2166
0
  }
2167
2168
0
  if (xfr->ixfr.journal != NULL) {
2169
0
    dns_journal_destroy(&xfr->ixfr.journal);
2170
0
  }
2171
2172
0
  if (xfr->axfr.add_private != NULL) {
2173
0
    (void)dns_db_endload(xfr->db, &xfr->axfr);
2174
0
  }
2175
2176
0
  if (xfr->tsigctx != NULL) {
2177
0
    dst_context_destroy(&xfr->tsigctx);
2178
0
  }
2179
2180
0
  if (xfr->name.attributes.dynamic) {
2181
0
    dns_name_free(&xfr->name, xfr->mctx);
2182
0
  }
2183
2184
0
  if (xfr->ver != NULL) {
2185
0
    dns_db_closeversion(xfr->db, &xfr->ver, false);
2186
0
  }
2187
2188
0
  if (xfr->db != NULL) {
2189
0
    dns_db_detach(&xfr->db);
2190
0
  }
2191
2192
0
  if (xfr->zone != NULL) {
2193
0
    if (!xfr->zone_had_db &&
2194
0
        xfr->shutdown_result == ISC_R_SUCCESS &&
2195
0
        dns_zone_gettype(xfr->zone) == dns_zone_mirror)
2196
0
    {
2197
0
      dns_zone_log(xfr->zone, ISC_LOG_INFO,
2198
0
             "mirror zone is now in use");
2199
0
    }
2200
0
    xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context");
2201
    /*
2202
     * xfr->zone must not be detached before xfrin_log() is called.
2203
     */
2204
0
    dns_zone_idetach(&xfr->zone);
2205
0
  }
2206
2207
0
  if (xfr->view != NULL) {
2208
0
    dns_view_weakdetach(&xfr->view);
2209
0
  }
2210
2211
0
  if (xfr->firstsoa_data != NULL) {
2212
0
    isc_mem_free(xfr->mctx, xfr->firstsoa_data);
2213
0
  }
2214
2215
0
  if (xfr->tlsctx_cache != NULL) {
2216
0
    isc_tlsctx_cache_detach(&xfr->tlsctx_cache);
2217
0
  }
2218
2219
0
  INSIST(xfr->max_time_timer == NULL);
2220
0
  INSIST(xfr->max_idle_timer == NULL);
2221
0
  INSIST(xfr->min_rate_timer == NULL);
2222
2223
0
  isc_loop_detach(&xfr->loop);
2224
2225
0
  isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
2226
0
}
2227
2228
/*
2229
 * Log incoming zone transfer messages in a format like
2230
 * transfer of <zone> from <address>: <message>
2231
 */
2232
2233
static void
2234
0
xfrin_log(dns_xfrin_t *xfr, int level, const char *fmt, ...) {
2235
0
  va_list ap;
2236
0
  char primarytext[ISC_SOCKADDR_FORMATSIZE];
2237
0
  char msgtext[2048];
2238
2239
0
  if (!isc_log_wouldlog(level)) {
2240
0
    return;
2241
0
  }
2242
2243
0
  isc_sockaddr_format(&xfr->primaryaddr, primarytext,
2244
0
          sizeof(primarytext));
2245
0
  va_start(ap, fmt);
2246
0
  vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
2247
0
  va_end(ap);
2248
2249
0
  isc_log_write(DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN, level,
2250
0
          "%p: transfer of '%s' from %s: %s", xfr, xfr->info,
2251
0
          primarytext, msgtext);
2252
0
}