Coverage Report

Created: 2026-07-30 06:31

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