xfrin.c revision 1.9 1 /* $NetBSD: xfrin.c,v 1.9 2021/04/29 17:26:11 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
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/mem.h>
20 #include <isc/print.h>
21 #include <isc/random.h>
22 #include <isc/string.h> /* Required for HP/UX (and others?) */
23 #include <isc/task.h>
24 #include <isc/timer.h>
25 #include <isc/util.h>
26
27 #include <dns/callbacks.h>
28 #include <dns/catz.h>
29 #include <dns/db.h>
30 #include <dns/diff.h>
31 #include <dns/events.h>
32 #include <dns/journal.h>
33 #include <dns/log.h>
34 #include <dns/message.h>
35 #include <dns/rdataclass.h>
36 #include <dns/rdatalist.h>
37 #include <dns/rdataset.h>
38 #include <dns/result.h>
39 #include <dns/soa.h>
40 #include <dns/tcpmsg.h>
41 #include <dns/timer.h>
42 #include <dns/tsig.h>
43 #include <dns/view.h>
44 #include <dns/xfrin.h>
45 #include <dns/zone.h>
46
47 #include <dst/dst.h>
48
49 /*
50 * Incoming AXFR and IXFR.
51 */
52
53 /*%
54 * It would be non-sensical (or at least obtuse) to use FAIL() with an
55 * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
56 * from complaining about "end-of-loop code not reached".
57 */
58 #define FAIL(code) \
59 do { \
60 result = (code); \
61 if (result != ISC_R_SUCCESS) \
62 goto failure; \
63 } while (0)
64
65 #define CHECK(op) \
66 do { \
67 result = (op); \
68 if (result != ISC_R_SUCCESS) \
69 goto failure; \
70 } while (0)
71
72 /*%
73 * The states of the *XFR state machine. We handle both IXFR and AXFR
74 * with a single integrated state machine because they cannot be distinguished
75 * immediately - an AXFR response to an IXFR request can only be detected
76 * when the first two (2) response RRs have already been received.
77 */
78 typedef enum {
79 XFRST_SOAQUERY,
80 XFRST_GOTSOA,
81 XFRST_INITIALSOA,
82 XFRST_FIRSTDATA,
83 XFRST_IXFR_DELSOA,
84 XFRST_IXFR_DEL,
85 XFRST_IXFR_ADDSOA,
86 XFRST_IXFR_ADD,
87 XFRST_IXFR_END,
88 XFRST_AXFR,
89 XFRST_AXFR_END
90 } xfrin_state_t;
91
92 /*%
93 * Incoming zone transfer context.
94 */
95
96 struct dns_xfrin_ctx {
97 unsigned int magic;
98 isc_mem_t *mctx;
99 dns_zone_t *zone;
100
101 int refcount;
102
103 isc_task_t *task;
104 isc_timer_t *timer;
105 isc_socketmgr_t *socketmgr;
106
107 int connects; /*%< Connect in progress */
108 int sends; /*%< Send in progress */
109 int recvs; /*%< Receive in progress */
110 bool shuttingdown;
111 isc_result_t shutdown_result;
112
113 dns_name_t name; /*%< Name of zone to transfer */
114 dns_rdataclass_t rdclass;
115
116 bool checkid, logit;
117 dns_messageid_t id;
118
119 /*%
120 * Requested transfer type (dns_rdatatype_axfr or
121 * dns_rdatatype_ixfr). The actual transfer type
122 * may differ due to IXFR->AXFR fallback.
123 */
124 dns_rdatatype_t reqtype;
125 isc_dscp_t dscp;
126
127 isc_sockaddr_t masteraddr;
128 isc_sockaddr_t sourceaddr;
129 isc_socket_t *socket;
130
131 /*% Buffer for IXFR/AXFR request message */
132 isc_buffer_t qbuffer;
133 unsigned char qbuffer_data[512];
134
135 /*% Incoming reply TCP message */
136 dns_tcpmsg_t tcpmsg;
137 bool tcpmsg_valid;
138
139 /*%
140 * Whether the zone originally had a database attached at the time this
141 * transfer context was created. Used by maybe_free() when making
142 * logging decisions.
143 */
144 bool zone_had_db;
145
146 dns_db_t *db;
147 dns_dbversion_t *ver;
148 dns_diff_t diff; /*%< Pending database changes */
149 int difflen; /*%< Number of pending tuples */
150
151 xfrin_state_t state;
152 uint32_t end_serial;
153 bool is_ixfr;
154
155 unsigned int nmsg; /*%< Number of messages recvd */
156 unsigned int nrecs; /*%< Number of records recvd */
157 uint64_t nbytes; /*%< Number of bytes received */
158
159 unsigned int maxrecords; /*%< The maximum number of
160 * records set for the zone */
161
162 isc_time_t start; /*%< Start time of the transfer */
163 isc_time_t end; /*%< End time of the transfer */
164
165 dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
166 isc_buffer_t *lasttsig; /*%< The last TSIG */
167 dst_context_t *tsigctx; /*%< TSIG verification context */
168 unsigned int sincetsig; /*%< recvd since the last TSIG */
169 dns_xfrindone_t done;
170
171 /*%
172 * AXFR- and IXFR-specific data. Only one is used at a time
173 * according to the is_ixfr flag, so this could be a union,
174 * but keeping them separate makes it a bit simpler to clean
175 * things up when destroying the context.
176 */
177 dns_rdatacallbacks_t axfr;
178
179 struct {
180 uint32_t request_serial;
181 uint32_t current_serial;
182 dns_journal_t *journal;
183 } ixfr;
184 };
185
186 #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
187 #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
188
189 /**************************************************************************/
190 /*
191 * Forward declarations.
192 */
193
194 static isc_result_t
195 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
196 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
197 dns_name_t *zonename, dns_rdataclass_t rdclass,
198 dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
199 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
200 dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp);
201
202 static isc_result_t
203 axfr_init(dns_xfrin_ctx_t *xfr);
204 static isc_result_t
205 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
206 static isc_result_t
207 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
208 dns_ttl_t ttl, dns_rdata_t *rdata);
209 static isc_result_t
210 axfr_apply(dns_xfrin_ctx_t *xfr);
211 static isc_result_t
212 axfr_commit(dns_xfrin_ctx_t *xfr);
213 static isc_result_t
214 axfr_finalize(dns_xfrin_ctx_t *xfr);
215
216 static isc_result_t
217 ixfr_init(dns_xfrin_ctx_t *xfr);
218 static isc_result_t
219 ixfr_apply(dns_xfrin_ctx_t *xfr);
220 static isc_result_t
221 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
222 dns_ttl_t ttl, dns_rdata_t *rdata);
223 static isc_result_t
224 ixfr_commit(dns_xfrin_ctx_t *xfr);
225
226 static isc_result_t
227 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
228 dns_rdata_t *rdata);
229
230 static isc_result_t
231 xfrin_start(dns_xfrin_ctx_t *xfr);
232
233 static void
234 xfrin_connect_done(isc_task_t *task, isc_event_t *event);
235 static isc_result_t
236 xfrin_send_request(dns_xfrin_ctx_t *xfr);
237 static void
238 xfrin_send_done(isc_task_t *task, isc_event_t *event);
239 static void
240 xfrin_recv_done(isc_task_t *task, isc_event_t *event);
241 static void
242 xfrin_timeout(isc_task_t *task, isc_event_t *event);
243
244 static void
245 maybe_free(dns_xfrin_ctx_t *xfr);
246
247 static void
248 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
249 static isc_result_t
250 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
251
252 static void
253 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
254 const char *fmt, va_list ap) ISC_FORMAT_PRINTF(4, 0);
255
256 static void
257 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
258 const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
259
260 static void
261 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
262 ISC_FORMAT_PRINTF(3, 4);
263
264 /**************************************************************************/
265 /*
266 * AXFR handling
267 */
268
269 static isc_result_t
270 axfr_init(dns_xfrin_ctx_t *xfr) {
271 isc_result_t result;
272
273 xfr->is_ixfr = false;
274
275 if (xfr->db != NULL) {
276 dns_db_detach(&xfr->db);
277 }
278
279 CHECK(axfr_makedb(xfr, &xfr->db));
280 dns_rdatacallbacks_init(&xfr->axfr);
281 CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
282 result = ISC_R_SUCCESS;
283 failure:
284 return (result);
285 }
286
287 static isc_result_t
288 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
289 isc_result_t result;
290
291 result = dns_db_create(xfr->mctx, /* XXX */
292 "rbt", /* XXX guess */
293 &xfr->name, dns_dbtype_zone, xfr->rdclass, 0,
294 NULL, /* XXX guess */
295 dbp);
296 if (result == ISC_R_SUCCESS) {
297 dns_zone_rpz_enable_db(xfr->zone, *dbp);
298 dns_zone_catz_enable_db(xfr->zone, *dbp);
299 }
300 return (result);
301 }
302
303 static isc_result_t
304 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
305 dns_ttl_t ttl, dns_rdata_t *rdata) {
306 isc_result_t result;
307
308 dns_difftuple_t *tuple = NULL;
309
310 if (rdata->rdclass != xfr->rdclass) {
311 return (DNS_R_BADCLASS);
312 }
313
314 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
315 CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
316 &tuple));
317 dns_diff_append(&xfr->diff, &tuple);
318 if (++xfr->difflen > 100) {
319 CHECK(axfr_apply(xfr));
320 }
321 result = ISC_R_SUCCESS;
322 failure:
323 return (result);
324 }
325
326 /*
327 * Store a set of AXFR RRs in the database.
328 */
329 static isc_result_t
330 axfr_apply(dns_xfrin_ctx_t *xfr) {
331 isc_result_t result;
332 uint64_t records;
333
334 CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private));
335 xfr->difflen = 0;
336 dns_diff_clear(&xfr->diff);
337 if (xfr->maxrecords != 0U) {
338 result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
339 if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
340 result = DNS_R_TOOMANYRECORDS;
341 goto failure;
342 }
343 }
344 result = ISC_R_SUCCESS;
345 failure:
346 return (result);
347 }
348
349 static isc_result_t
350 axfr_commit(dns_xfrin_ctx_t *xfr) {
351 isc_result_t result;
352
353 CHECK(axfr_apply(xfr));
354 CHECK(dns_db_endload(xfr->db, &xfr->axfr));
355 CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL));
356
357 result = ISC_R_SUCCESS;
358 failure:
359 return (result);
360 }
361
362 static isc_result_t
363 axfr_finalize(dns_xfrin_ctx_t *xfr) {
364 isc_result_t result;
365
366 CHECK(dns_zone_replacedb(xfr->zone, xfr->db, true));
367
368 result = ISC_R_SUCCESS;
369 failure:
370 return (result);
371 }
372
373 /**************************************************************************/
374 /*
375 * IXFR handling
376 */
377
378 static isc_result_t
379 ixfr_init(dns_xfrin_ctx_t *xfr) {
380 isc_result_t result;
381 char *journalfile;
382
383 if (xfr->reqtype != dns_rdatatype_ixfr) {
384 xfrin_log(xfr, ISC_LOG_ERROR,
385 "got incremental response to AXFR request");
386 return (DNS_R_FORMERR);
387 }
388
389 xfr->is_ixfr = true;
390 INSIST(xfr->db != NULL);
391 xfr->difflen = 0;
392
393 journalfile = dns_zone_getjournal(xfr->zone);
394 if (journalfile != NULL) {
395 CHECK(dns_journal_open(xfr->mctx, journalfile,
396 DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
397 }
398
399 result = ISC_R_SUCCESS;
400 failure:
401 return (result);
402 }
403
404 static isc_result_t
405 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
406 dns_ttl_t ttl, dns_rdata_t *rdata) {
407 isc_result_t result;
408 dns_difftuple_t *tuple = NULL;
409
410 if (rdata->rdclass != xfr->rdclass) {
411 return (DNS_R_BADCLASS);
412 }
413
414 if (op == DNS_DIFFOP_ADD) {
415 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
416 }
417 CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata,
418 &tuple));
419 dns_diff_append(&xfr->diff, &tuple);
420 if (++xfr->difflen > 100) {
421 CHECK(ixfr_apply(xfr));
422 }
423 result = ISC_R_SUCCESS;
424 failure:
425 return (result);
426 }
427
428 /*
429 * Apply a set of IXFR changes to the database.
430 */
431 static isc_result_t
432 ixfr_apply(dns_xfrin_ctx_t *xfr) {
433 isc_result_t result;
434 uint64_t records;
435
436 if (xfr->ver == NULL) {
437 CHECK(dns_db_newversion(xfr->db, &xfr->ver));
438 if (xfr->ixfr.journal != NULL) {
439 CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
440 }
441 }
442 CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
443 if (xfr->maxrecords != 0U) {
444 result = dns_db_getsize(xfr->db, xfr->ver, &records, NULL);
445 if (result == ISC_R_SUCCESS && records > xfr->maxrecords) {
446 result = DNS_R_TOOMANYRECORDS;
447 goto failure;
448 }
449 }
450 if (xfr->ixfr.journal != NULL) {
451 result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
452 if (result != ISC_R_SUCCESS) {
453 goto failure;
454 }
455 }
456 dns_diff_clear(&xfr->diff);
457 xfr->difflen = 0;
458 result = ISC_R_SUCCESS;
459 failure:
460 return (result);
461 }
462
463 static isc_result_t
464 ixfr_commit(dns_xfrin_ctx_t *xfr) {
465 isc_result_t result;
466
467 CHECK(ixfr_apply(xfr));
468 if (xfr->ver != NULL) {
469 CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver));
470 /* XXX enter ready-to-commit state here */
471 if (xfr->ixfr.journal != NULL) {
472 CHECK(dns_journal_commit(xfr->ixfr.journal));
473 }
474 dns_db_closeversion(xfr->db, &xfr->ver, true);
475 dns_zone_markdirty(xfr->zone);
476 }
477 result = ISC_R_SUCCESS;
478 failure:
479 return (result);
480 }
481
482 /**************************************************************************/
483 /*
484 * Common AXFR/IXFR protocol code
485 */
486
487 /*
488 * Handle a single incoming resource record according to the current
489 * state.
490 */
491 static isc_result_t
492 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl,
493 dns_rdata_t *rdata) {
494 isc_result_t result;
495
496 xfr->nrecs++;
497
498 if (rdata->type == dns_rdatatype_none ||
499 dns_rdatatype_ismeta(rdata->type)) {
500 FAIL(DNS_R_FORMERR);
501 }
502
503 /*
504 * Immediately reject the entire transfer if the RR that is currently
505 * being processed is an SOA record that is not placed at the zone
506 * apex.
507 */
508 if (rdata->type == dns_rdatatype_soa &&
509 !dns_name_equal(&xfr->name, name)) {
510 char namebuf[DNS_NAME_FORMATSIZE];
511 dns_name_format(name, namebuf, sizeof(namebuf));
512 xfrin_log(xfr, ISC_LOG_DEBUG(3), "SOA name mismatch: '%s'",
513 namebuf);
514 FAIL(DNS_R_NOTZONETOP);
515 }
516
517 redo:
518 switch (xfr->state) {
519 case XFRST_SOAQUERY:
520 if (rdata->type != dns_rdatatype_soa) {
521 xfrin_log(xfr, ISC_LOG_ERROR,
522 "non-SOA response to SOA query");
523 FAIL(DNS_R_FORMERR);
524 }
525 xfr->end_serial = dns_soa_getserial(rdata);
526 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
527 !dns_zone_isforced(xfr->zone))
528 {
529 xfrin_log(xfr, ISC_LOG_DEBUG(3),
530 "requested serial %u, "
531 "master has %u, not updating",
532 xfr->ixfr.request_serial, xfr->end_serial);
533 FAIL(DNS_R_UPTODATE);
534 }
535 xfr->state = XFRST_GOTSOA;
536 break;
537
538 case XFRST_GOTSOA:
539 /*
540 * Skip other records in the answer section.
541 */
542 break;
543
544 case XFRST_INITIALSOA:
545 if (rdata->type != dns_rdatatype_soa) {
546 xfrin_log(xfr, ISC_LOG_ERROR,
547 "first RR in zone transfer must be SOA");
548 FAIL(DNS_R_FORMERR);
549 }
550 /*
551 * Remember the serial number in the initial SOA.
552 * We need it to recognize the end of an IXFR.
553 */
554 xfr->end_serial = dns_soa_getserial(rdata);
555 if (xfr->reqtype == dns_rdatatype_ixfr &&
556 !DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
557 !dns_zone_isforced(xfr->zone))
558 {
559 /*
560 * This must be the single SOA record that is
561 * sent when the current version on the master
562 * is not newer than the version in the request.
563 */
564 xfrin_log(xfr, ISC_LOG_DEBUG(3),
565 "requested serial %u, "
566 "master has %u, not updating",
567 xfr->ixfr.request_serial, xfr->end_serial);
568 FAIL(DNS_R_UPTODATE);
569 }
570 if (xfr->reqtype == dns_rdatatype_axfr) {
571 xfr->checkid = false;
572 }
573 xfr->state = XFRST_FIRSTDATA;
574 break;
575
576 case XFRST_FIRSTDATA:
577 /*
578 * If the transfer begins with one SOA record, it is an AXFR,
579 * if it begins with two SOAs, it is an IXFR.
580 */
581 if (xfr->reqtype == dns_rdatatype_ixfr &&
582 rdata->type == dns_rdatatype_soa &&
583 xfr->ixfr.request_serial == dns_soa_getserial(rdata))
584 {
585 xfrin_log(xfr, ISC_LOG_DEBUG(3),
586 "got incremental response");
587 CHECK(ixfr_init(xfr));
588 xfr->state = XFRST_IXFR_DELSOA;
589 } else {
590 xfrin_log(xfr, ISC_LOG_DEBUG(3),
591 "got nonincremental response");
592 CHECK(axfr_init(xfr));
593 xfr->state = XFRST_AXFR;
594 }
595 goto redo;
596
597 case XFRST_IXFR_DELSOA:
598 INSIST(rdata->type == dns_rdatatype_soa);
599 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
600 xfr->state = XFRST_IXFR_DEL;
601 break;
602
603 case XFRST_IXFR_DEL:
604 if (rdata->type == dns_rdatatype_soa) {
605 uint32_t soa_serial = dns_soa_getserial(rdata);
606 xfr->state = XFRST_IXFR_ADDSOA;
607 xfr->ixfr.current_serial = soa_serial;
608 goto redo;
609 }
610 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
611 break;
612
613 case XFRST_IXFR_ADDSOA:
614 INSIST(rdata->type == dns_rdatatype_soa);
615 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
616 xfr->state = XFRST_IXFR_ADD;
617 break;
618
619 case XFRST_IXFR_ADD:
620 if (rdata->type == dns_rdatatype_soa) {
621 uint32_t soa_serial = dns_soa_getserial(rdata);
622 if (soa_serial == xfr->end_serial) {
623 CHECK(ixfr_commit(xfr));
624 xfr->state = XFRST_IXFR_END;
625 break;
626 } else if (soa_serial != xfr->ixfr.current_serial) {
627 xfrin_log(xfr, ISC_LOG_ERROR,
628 "IXFR out of sync: "
629 "expected serial %u, got %u",
630 xfr->ixfr.current_serial, soa_serial);
631 FAIL(DNS_R_FORMERR);
632 } else {
633 CHECK(ixfr_commit(xfr));
634 xfr->state = XFRST_IXFR_DELSOA;
635 goto redo;
636 }
637 }
638 if (rdata->type == dns_rdatatype_ns &&
639 dns_name_iswildcard(name)) {
640 FAIL(DNS_R_INVALIDNS);
641 }
642 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
643 break;
644
645 case XFRST_AXFR:
646 /*
647 * Old BINDs sent cross class A records for non IN classes.
648 */
649 if (rdata->type == dns_rdatatype_a &&
650 rdata->rdclass != xfr->rdclass &&
651 xfr->rdclass != dns_rdataclass_in)
652 {
653 break;
654 }
655 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
656 if (rdata->type == dns_rdatatype_soa) {
657 CHECK(axfr_commit(xfr));
658 xfr->state = XFRST_AXFR_END;
659 break;
660 }
661 break;
662 case XFRST_AXFR_END:
663 case XFRST_IXFR_END:
664 FAIL(DNS_R_EXTRADATA);
665 /* NOTREACHED */
666 /* FALLTHROUGH */
667 default:
668 INSIST(0);
669 ISC_UNREACHABLE();
670 }
671 result = ISC_R_SUCCESS;
672 failure:
673 return (result);
674 }
675
676 isc_result_t
677 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
678 const isc_sockaddr_t *masteraddr,
679 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
680 dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
681 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
682 isc_task_t *task, dns_xfrindone_t done,
683 dns_xfrin_ctx_t **xfrp) {
684 dns_name_t *zonename = dns_zone_getorigin(zone);
685 dns_xfrin_ctx_t *xfr = NULL;
686 isc_result_t result;
687 dns_db_t *db = NULL;
688
689 REQUIRE(xfrp != NULL && *xfrp == NULL);
690
691 (void)dns_zone_getdb(zone, &db);
692
693 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) {
694 REQUIRE(db != NULL);
695 }
696
697 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
698 dns_zone_getclass(zone), xfrtype, masteraddr,
699 sourceaddr, dscp, tsigkey, &xfr));
700
701 if (db != NULL) {
702 xfr->zone_had_db = true;
703 }
704
705 CHECK(xfrin_start(xfr));
706
707 xfr->done = done;
708 if (xfr->done != NULL) {
709 xfr->refcount++;
710 }
711 *xfrp = xfr;
712
713 failure:
714 if (db != NULL) {
715 dns_db_detach(&db);
716 }
717 if (result != ISC_R_SUCCESS) {
718 char zonetext[DNS_NAME_MAXTEXT + 32];
719 dns_zone_name(zone, zonetext, sizeof(zonetext));
720 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
721 "zone transfer setup failed");
722 }
723 return (result);
724 }
725
726 void
727 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
728 if (!xfr->shuttingdown) {
729 xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
730 }
731 }
732
733 void
734 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
735 REQUIRE(target != NULL && *target == NULL);
736 source->refcount++;
737 *target = source;
738 }
739
740 void
741 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
742 dns_xfrin_ctx_t *xfr = *xfrp;
743 *xfrp = NULL;
744 INSIST(xfr->refcount > 0);
745 xfr->refcount--;
746 maybe_free(xfr);
747 }
748
749 static void
750 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
751 if (xfr->connects > 0) {
752 isc_socket_cancel(xfr->socket, xfr->task,
753 ISC_SOCKCANCEL_CONNECT);
754 } else if (xfr->recvs > 0) {
755 dns_tcpmsg_cancelread(&xfr->tcpmsg);
756 } else if (xfr->sends > 0) {
757 isc_socket_cancel(xfr->socket, xfr->task, ISC_SOCKCANCEL_SEND);
758 }
759 }
760
761 static void
762 xfrin_reset(dns_xfrin_ctx_t *xfr) {
763 REQUIRE(VALID_XFRIN(xfr));
764
765 xfrin_log(xfr, ISC_LOG_INFO, "resetting");
766
767 xfrin_cancelio(xfr);
768
769 if (xfr->socket != NULL) {
770 isc_socket_detach(&xfr->socket);
771 }
772
773 if (xfr->lasttsig != NULL) {
774 isc_buffer_free(&xfr->lasttsig);
775 }
776
777 dns_diff_clear(&xfr->diff);
778 xfr->difflen = 0;
779
780 if (xfr->ixfr.journal != NULL) {
781 dns_journal_destroy(&xfr->ixfr.journal);
782 }
783
784 if (xfr->axfr.add_private != NULL) {
785 (void)dns_db_endload(xfr->db, &xfr->axfr);
786 }
787
788 if (xfr->tcpmsg_valid) {
789 dns_tcpmsg_invalidate(&xfr->tcpmsg);
790 xfr->tcpmsg_valid = false;
791 }
792
793 if (xfr->ver != NULL) {
794 dns_db_closeversion(xfr->db, &xfr->ver, false);
795 }
796 }
797
798 static void
799 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
800 if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) {
801 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
802 isc_result_totext(result));
803 if (xfr->is_ixfr) {
804 /* Pass special result code to force AXFR retry */
805 result = DNS_R_BADIXFR;
806 }
807 }
808 xfrin_cancelio(xfr);
809 /*
810 * Close the journal.
811 */
812 if (xfr->ixfr.journal != NULL) {
813 dns_journal_destroy(&xfr->ixfr.journal);
814 }
815 if (xfr->done != NULL) {
816 (xfr->done)(xfr->zone, result);
817 xfr->done = NULL;
818 }
819 xfr->shuttingdown = true;
820 xfr->shutdown_result = result;
821 maybe_free(xfr);
822 }
823
824 static isc_result_t
825 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
826 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
827 dns_name_t *zonename, dns_rdataclass_t rdclass,
828 dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
829 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
830 dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp) {
831 dns_xfrin_ctx_t *xfr = NULL;
832 isc_result_t result;
833
834 xfr = isc_mem_get(mctx, sizeof(*xfr));
835 xfr->mctx = NULL;
836 isc_mem_attach(mctx, &xfr->mctx);
837 xfr->refcount = 0;
838 xfr->zone = NULL;
839 dns_zone_iattach(zone, &xfr->zone);
840 xfr->task = NULL;
841 isc_task_attach(task, &xfr->task);
842 xfr->timer = NULL;
843 xfr->socketmgr = socketmgr;
844 xfr->done = NULL;
845
846 xfr->connects = 0;
847 xfr->sends = 0;
848 xfr->recvs = 0;
849 xfr->shuttingdown = false;
850 xfr->shutdown_result = ISC_R_UNSET;
851
852 dns_name_init(&xfr->name, NULL);
853 xfr->rdclass = rdclass;
854 xfr->checkid = true;
855 xfr->logit = true;
856 xfr->id = (dns_messageid_t)isc_random16();
857 xfr->reqtype = reqtype;
858 xfr->dscp = dscp;
859
860 /* sockaddr */
861 xfr->socket = NULL;
862 /* qbuffer */
863 /* qbuffer_data */
864 /* tcpmsg */
865 xfr->tcpmsg_valid = false;
866
867 xfr->zone_had_db = false;
868 xfr->db = NULL;
869 if (db != NULL) {
870 dns_db_attach(db, &xfr->db);
871 }
872 xfr->ver = NULL;
873 dns_diff_init(xfr->mctx, &xfr->diff);
874 xfr->difflen = 0;
875
876 if (reqtype == dns_rdatatype_soa) {
877 xfr->state = XFRST_SOAQUERY;
878 } else {
879 xfr->state = XFRST_INITIALSOA;
880 }
881 /* end_serial */
882
883 xfr->nmsg = 0;
884 xfr->nrecs = 0;
885 xfr->nbytes = 0;
886 xfr->maxrecords = dns_zone_getmaxrecords(zone);
887 isc_time_now(&xfr->start);
888
889 xfr->tsigkey = NULL;
890 if (tsigkey != NULL) {
891 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
892 }
893 xfr->lasttsig = NULL;
894 xfr->tsigctx = NULL;
895 xfr->sincetsig = 0;
896 xfr->is_ixfr = false;
897
898 /* ixfr.request_serial */
899 /* ixfr.current_serial */
900 xfr->ixfr.journal = NULL;
901
902 xfr->axfr.add = NULL;
903 xfr->axfr.add_private = NULL;
904
905 dns_name_dup(zonename, mctx, &xfr->name);
906
907 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
908 task, xfrin_timeout, xfr, &xfr->timer));
909 CHECK(dns_timer_setidle(xfr->timer, dns_zone_getmaxxfrin(xfr->zone),
910 dns_zone_getidlein(xfr->zone), false));
911
912 xfr->masteraddr = *masteraddr;
913
914 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
915 xfr->sourceaddr = *sourceaddr;
916 isc_sockaddr_setport(&xfr->sourceaddr, 0);
917
918 /*
919 * Reserve 2 bytes for TCP length at the beginning of the buffer.
920 */
921 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
922 sizeof(xfr->qbuffer_data) - 2);
923
924 xfr->magic = XFRIN_MAGIC;
925 *xfrp = xfr;
926 return (ISC_R_SUCCESS);
927
928 failure:
929 if (xfr->timer != NULL) {
930 isc_timer_detach(&xfr->timer);
931 }
932 if (dns_name_dynamic(&xfr->name)) {
933 dns_name_free(&xfr->name, xfr->mctx);
934 }
935 if (xfr->tsigkey != NULL) {
936 dns_tsigkey_detach(&xfr->tsigkey);
937 }
938 if (xfr->db != NULL) {
939 dns_db_detach(&xfr->db);
940 }
941 isc_task_detach(&xfr->task);
942 dns_zone_idetach(&xfr->zone);
943 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
944
945 return (result);
946 }
947
948 static isc_result_t
949 xfrin_start(dns_xfrin_ctx_t *xfr) {
950 isc_result_t result;
951 CHECK(isc_socket_create(xfr->socketmgr,
952 isc_sockaddr_pf(&xfr->sourceaddr),
953 isc_sockettype_tcp, &xfr->socket));
954 isc_socket_setname(xfr->socket, "xfrin", NULL);
955 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
956 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
957 ISC_SOCKET_REUSEADDRESS));
958 #endif /* ifndef BROKEN_TCP_BIND_BEFORE_CONNECT */
959 isc_socket_dscp(xfr->socket, xfr->dscp);
960 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
961 xfrin_connect_done, xfr));
962 xfr->connects++;
963 return (ISC_R_SUCCESS);
964 failure:
965 xfrin_fail(xfr, result, "failed setting up socket");
966 return (result);
967 }
968
969 /* XXX the resolver could use this, too */
970
971 static isc_result_t
972 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
973 dns_compress_t cctx;
974 bool cleanup_cctx = false;
975 isc_result_t result;
976
977 CHECK(dns_compress_init(&cctx, -1, mctx));
978 cleanup_cctx = true;
979 CHECK(dns_message_renderbegin(msg, &cctx, buf));
980 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
981 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
982 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
983 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
984 CHECK(dns_message_renderend(msg));
985 result = ISC_R_SUCCESS;
986 failure:
987 if (cleanup_cctx) {
988 dns_compress_invalidate(&cctx);
989 }
990 return (result);
991 }
992
993 /*
994 * A connection has been established.
995 */
996 static void
997 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
998 isc_socket_connev_t *cev = (isc_socket_connev_t *)event;
999 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
1000 isc_result_t result = cev->result;
1001 char sourcetext[ISC_SOCKADDR_FORMATSIZE];
1002 char signerbuf[DNS_NAME_FORMATSIZE];
1003 const char *signer = "", *sep = "";
1004 isc_sockaddr_t sockaddr;
1005 dns_zonemgr_t *zmgr;
1006 isc_time_t now;
1007
1008 REQUIRE(VALID_XFRIN(xfr));
1009
1010 UNUSED(task);
1011
1012 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
1013 isc_event_free(&event);
1014
1015 xfr->connects--;
1016 if (xfr->shuttingdown) {
1017 maybe_free(xfr);
1018 return;
1019 }
1020
1021 zmgr = dns_zone_getmgr(xfr->zone);
1022 if (zmgr != NULL) {
1023 if (result != ISC_R_SUCCESS) {
1024 TIME_NOW(&now);
1025 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
1026 &xfr->sourceaddr, &now);
1027 goto failure;
1028 } else {
1029 dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
1030 &xfr->sourceaddr);
1031 }
1032 }
1033
1034 result = isc_socket_getsockname(xfr->socket, &sockaddr);
1035 if (result == ISC_R_SUCCESS) {
1036 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
1037 } else {
1038 strlcpy(sourcetext, "<UNKNOWN>", sizeof(sourcetext));
1039 }
1040
1041 if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
1042 dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
1043 sizeof(signerbuf));
1044 sep = " TSIG ";
1045 signer = signerbuf;
1046 }
1047
1048 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", sourcetext, sep,
1049 signer);
1050
1051 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
1052 xfr->tcpmsg_valid = true;
1053
1054 CHECK(xfrin_send_request(xfr));
1055 failure:
1056 if (result != ISC_R_SUCCESS) {
1057 xfrin_fail(xfr, result, "failed to connect");
1058 }
1059 }
1060
1061 /*
1062 * Convert a tuple into a dns_name_t suitable for inserting
1063 * into the given dns_message_t.
1064 */
1065 static isc_result_t
1066 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
1067 isc_result_t result;
1068 dns_rdata_t *rdata = NULL;
1069 dns_rdatalist_t *rdl = NULL;
1070 dns_rdataset_t *rds = NULL;
1071 dns_name_t *name = NULL;
1072
1073 REQUIRE(target != NULL && *target == NULL);
1074
1075 CHECK(dns_message_gettemprdata(msg, &rdata));
1076 dns_rdata_init(rdata);
1077 dns_rdata_clone(&tuple->rdata, rdata);
1078
1079 CHECK(dns_message_gettemprdatalist(msg, &rdl));
1080 dns_rdatalist_init(rdl);
1081 rdl->type = tuple->rdata.type;
1082 rdl->rdclass = tuple->rdata.rdclass;
1083 rdl->ttl = tuple->ttl;
1084 ISC_LIST_APPEND(rdl->rdata, rdata, link);
1085
1086 CHECK(dns_message_gettemprdataset(msg, &rds));
1087 CHECK(dns_rdatalist_tordataset(rdl, rds));
1088
1089 CHECK(dns_message_gettempname(msg, &name));
1090 dns_name_init(name, NULL);
1091 dns_name_clone(&tuple->name, name);
1092 ISC_LIST_APPEND(name->list, rds, link);
1093
1094 *target = name;
1095 return (ISC_R_SUCCESS);
1096
1097 failure:
1098
1099 if (rds != NULL) {
1100 dns_rdataset_disassociate(rds);
1101 dns_message_puttemprdataset(msg, &rds);
1102 }
1103 if (rdl != NULL) {
1104 ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1105 dns_message_puttemprdatalist(msg, &rdl);
1106 }
1107 if (rdata != NULL) {
1108 dns_message_puttemprdata(msg, &rdata);
1109 }
1110
1111 return (result);
1112 }
1113
1114 /*
1115 * Build an *XFR request and send its length prefix.
1116 */
1117 static isc_result_t
1118 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1119 isc_result_t result;
1120 isc_region_t region;
1121 dns_rdataset_t *qrdataset = NULL;
1122 dns_message_t *msg = NULL;
1123 dns_difftuple_t *soatuple = NULL;
1124 dns_name_t *qname = NULL;
1125 dns_dbversion_t *ver = NULL;
1126 dns_name_t *msgsoaname = NULL;
1127
1128 /* Create the request message */
1129 dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg);
1130 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1131
1132 /* Create a name for the question section. */
1133 CHECK(dns_message_gettempname(msg, &qname));
1134 dns_name_init(qname, NULL);
1135 dns_name_clone(&xfr->name, qname);
1136
1137 /* Formulate the question and attach it to the question name. */
1138 CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1139 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1140 ISC_LIST_APPEND(qname->list, qrdataset, link);
1141 qrdataset = NULL;
1142
1143 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1144 qname = NULL;
1145
1146 if (xfr->reqtype == dns_rdatatype_ixfr) {
1147 /* Get the SOA and add it to the authority section. */
1148 /* XXX is using the current version the right thing? */
1149 dns_db_currentversion(xfr->db, &ver);
1150 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1151 DNS_DIFFOP_EXISTS, &soatuple));
1152 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1153 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1154 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1155 "requesting IXFR for serial %u",
1156 xfr->ixfr.request_serial);
1157
1158 CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1159 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1160 } else if (xfr->reqtype == dns_rdatatype_soa) {
1161 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1162 &xfr->ixfr.request_serial));
1163 }
1164
1165 xfr->checkid = true;
1166 xfr->logit = true;
1167 xfr->id++;
1168 xfr->nmsg = 0;
1169 xfr->nrecs = 0;
1170 xfr->nbytes = 0;
1171 isc_time_now(&xfr->start);
1172 msg->id = xfr->id;
1173 if (xfr->tsigctx != NULL) {
1174 dst_context_destroy(&xfr->tsigctx);
1175 }
1176
1177 CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1178
1179 /*
1180 * Free the last tsig, if there is one.
1181 */
1182 if (xfr->lasttsig != NULL) {
1183 isc_buffer_free(&xfr->lasttsig);
1184 }
1185
1186 /*
1187 * Save the query TSIG and don't let message_destroy free it.
1188 */
1189 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1190
1191 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1192 INSIST(region.length <= 65535);
1193
1194 /*
1195 * Record message length and adjust region to include TCP
1196 * length field.
1197 */
1198 xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
1199 xfr->qbuffer_data[1] = region.length & 0xff;
1200 region.base -= 2;
1201 region.length += 2;
1202 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task, xfrin_send_done,
1203 xfr));
1204 xfr->sends++;
1205
1206 failure:
1207 if (qname != NULL) {
1208 dns_message_puttempname(msg, &qname);
1209 }
1210 if (qrdataset != NULL) {
1211 dns_message_puttemprdataset(msg, &qrdataset);
1212 }
1213 if (msg != NULL) {
1214 dns_message_detach(&msg);
1215 }
1216 if (soatuple != NULL) {
1217 dns_difftuple_free(&soatuple);
1218 }
1219 if (ver != NULL) {
1220 dns_db_closeversion(xfr->db, &ver, false);
1221 }
1222 return (result);
1223 }
1224
1225 static void
1226 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
1227 isc_socketevent_t *sev = (isc_socketevent_t *)event;
1228 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
1229 isc_result_t result;
1230
1231 REQUIRE(VALID_XFRIN(xfr));
1232
1233 UNUSED(task);
1234
1235 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1236
1237 xfr->sends--;
1238 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1239 CHECK(sev->result);
1240
1241 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, xfrin_recv_done,
1242 xfr));
1243 xfr->recvs++;
1244 failure:
1245 isc_event_free(&event);
1246 if (result != ISC_R_SUCCESS) {
1247 xfrin_fail(xfr, result, "failed sending request data");
1248 }
1249 }
1250
1251 static void
1252 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
1253 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)ev->ev_arg;
1254 isc_result_t result;
1255 dns_message_t *msg = NULL;
1256 dns_name_t *name;
1257 dns_tcpmsg_t *tcpmsg;
1258 const dns_name_t *tsigowner = NULL;
1259
1260 REQUIRE(VALID_XFRIN(xfr));
1261
1262 UNUSED(task);
1263
1264 INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
1265 tcpmsg = ev->ev_sender;
1266 isc_event_free(&ev);
1267
1268 xfr->recvs--;
1269 if (xfr->shuttingdown) {
1270 maybe_free(xfr);
1271 return;
1272 }
1273
1274 CHECK(tcpmsg->result);
1275
1276 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
1277 tcpmsg->buffer.used);
1278
1279 CHECK(isc_timer_touch(xfr->timer));
1280
1281 dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
1282
1283 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1284 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1285
1286 msg->tsigctx = xfr->tsigctx;
1287 xfr->tsigctx = NULL;
1288
1289 dns_message_setclass(msg, xfr->rdclass);
1290
1291 if (xfr->nmsg > 0) {
1292 msg->tcp_continuation = 1;
1293 }
1294
1295 result = dns_message_parse(msg, &tcpmsg->buffer,
1296 DNS_MESSAGEPARSE_PRESERVEORDER);
1297
1298 if (result == ISC_R_SUCCESS) {
1299 dns_message_logpacket(msg, "received message from",
1300 &tcpmsg->address, DNS_LOGCATEGORY_XFER_IN,
1301 DNS_LOGMODULE_XFER_IN, ISC_LOG_DEBUG(10),
1302 xfr->mctx);
1303 } else {
1304 xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
1305 dns_result_totext(result));
1306 }
1307
1308 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1309 msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass ||
1310 (xfr->checkid && msg->id != xfr->id))
1311 {
1312 if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
1313 {
1314 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
1315 } else if (result == ISC_R_SUCCESS &&
1316 msg->opcode != dns_opcode_query) {
1317 result = DNS_R_UNEXPECTEDOPCODE;
1318 } else if (result == ISC_R_SUCCESS &&
1319 msg->rdclass != xfr->rdclass) {
1320 result = DNS_R_BADCLASS;
1321 } else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) {
1322 result = DNS_R_UNEXPECTEDID;
1323 }
1324 if (xfr->reqtype == dns_rdatatype_axfr ||
1325 xfr->reqtype == dns_rdatatype_soa) {
1326 goto failure;
1327 }
1328 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1329 isc_result_totext(result));
1330 try_axfr:
1331 dns_message_detach(&msg);
1332 xfrin_reset(xfr);
1333 xfr->reqtype = dns_rdatatype_soa;
1334 xfr->state = XFRST_SOAQUERY;
1335 (void)xfrin_start(xfr);
1336 return;
1337 } else if (!xfr->checkid && msg->id != xfr->id && xfr->logit) {
1338 xfrin_log(xfr, ISC_LOG_WARNING,
1339 "detected message ID mismatch on incoming AXFR "
1340 "stream, transfer will fail in BIND 9.17.2 and "
1341 "later if AXFR source is not fixed");
1342 xfr->logit = false;
1343 }
1344
1345 /*
1346 * Does the server know about IXFR? If it doesn't we will get
1347 * a message with a empty answer section or a potentially a CNAME /
1348 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1349 * if the first RR in the answer section is not a SOA record.
1350 */
1351 if (xfr->reqtype == dns_rdatatype_ixfr &&
1352 xfr->state == XFRST_INITIALSOA &&
1353 msg->counts[DNS_SECTION_ANSWER] == 0)
1354 {
1355 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1356 "empty answer section, retrying with AXFR");
1357 goto try_axfr;
1358 }
1359
1360 if (xfr->reqtype == dns_rdatatype_soa &&
1361 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
1362 FAIL(DNS_R_NOTAUTHORITATIVE);
1363 }
1364
1365 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1366 if (result != ISC_R_SUCCESS) {
1367 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1368 isc_result_totext(result));
1369 goto failure;
1370 }
1371
1372 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1373 result == ISC_R_SUCCESS;
1374 result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1375 {
1376 dns_rdataset_t *rds;
1377
1378 name = NULL;
1379 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1380 for (rds = ISC_LIST_HEAD(name->list); rds != NULL;
1381 rds = ISC_LIST_NEXT(rds, link))
1382 {
1383 for (result = dns_rdataset_first(rds);
1384 result == ISC_R_SUCCESS;
1385 result = dns_rdataset_next(rds))
1386 {
1387 dns_rdata_t rdata = DNS_RDATA_INIT;
1388 dns_rdataset_current(rds, &rdata);
1389 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1390 }
1391 }
1392 }
1393 if (result != ISC_R_NOMORE) {
1394 goto failure;
1395 }
1396
1397 if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1398 /*
1399 * Reset the counter.
1400 */
1401 xfr->sincetsig = 0;
1402
1403 /*
1404 * Free the last tsig, if there is one.
1405 */
1406 if (xfr->lasttsig != NULL) {
1407 isc_buffer_free(&xfr->lasttsig);
1408 }
1409
1410 /*
1411 * Update the last tsig pointer.
1412 */
1413 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1414 } else if (dns_message_gettsigkey(msg) != NULL) {
1415 xfr->sincetsig++;
1416 if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1417 xfr->state == XFRST_AXFR_END ||
1418 xfr->state == XFRST_IXFR_END)
1419 {
1420 result = DNS_R_EXPECTEDTSIG;
1421 goto failure;
1422 }
1423 }
1424
1425 /*
1426 * Update the number of messages received.
1427 */
1428 xfr->nmsg++;
1429
1430 /*
1431 * Update the number of bytes received.
1432 */
1433 xfr->nbytes += tcpmsg->buffer.used;
1434
1435 /*
1436 * Take the context back.
1437 */
1438 INSIST(xfr->tsigctx == NULL);
1439 xfr->tsigctx = msg->tsigctx;
1440 msg->tsigctx = NULL;
1441
1442 dns_message_detach(&msg);
1443
1444 switch (xfr->state) {
1445 case XFRST_GOTSOA:
1446 xfr->reqtype = dns_rdatatype_axfr;
1447 xfr->state = XFRST_INITIALSOA;
1448 CHECK(xfrin_send_request(xfr));
1449 break;
1450 case XFRST_AXFR_END:
1451 CHECK(axfr_finalize(xfr));
1452 /* FALLTHROUGH */
1453 case XFRST_IXFR_END:
1454 /*
1455 * Close the journal.
1456 */
1457 if (xfr->ixfr.journal != NULL) {
1458 dns_journal_destroy(&xfr->ixfr.journal);
1459 }
1460
1461 /*
1462 * Inform the caller we succeeded.
1463 */
1464 if (xfr->done != NULL) {
1465 (xfr->done)(xfr->zone, ISC_R_SUCCESS);
1466 xfr->done = NULL;
1467 }
1468 /*
1469 * We should have no outstanding events at this
1470 * point, thus maybe_free() should succeed.
1471 */
1472 xfr->shuttingdown = true;
1473 xfr->shutdown_result = ISC_R_SUCCESS;
1474 maybe_free(xfr);
1475 break;
1476 default:
1477 /*
1478 * Read the next message.
1479 */
1480 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1481 xfrin_recv_done, xfr));
1482 xfr->recvs++;
1483 }
1484 return;
1485
1486 failure:
1487 if (msg != NULL) {
1488 dns_message_detach(&msg);
1489 }
1490 if (result != ISC_R_SUCCESS) {
1491 xfrin_fail(xfr, result, "failed while receiving responses");
1492 }
1493 }
1494
1495 static void
1496 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
1497 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
1498
1499 REQUIRE(VALID_XFRIN(xfr));
1500
1501 UNUSED(task);
1502
1503 isc_event_free(&event);
1504 /*
1505 * This will log "giving up: timeout".
1506 */
1507 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
1508 }
1509
1510 static void
1511 maybe_free(dns_xfrin_ctx_t *xfr) {
1512 uint64_t msecs;
1513 uint64_t persec;
1514 const char *result_str;
1515
1516 REQUIRE(VALID_XFRIN(xfr));
1517
1518 if (!xfr->shuttingdown || xfr->refcount != 0 || xfr->connects != 0 ||
1519 xfr->sends != 0 || xfr->recvs != 0)
1520 {
1521 return;
1522 }
1523
1524 INSIST(!xfr->shuttingdown || xfr->shutdown_result != ISC_R_UNSET);
1525
1526 /* If we're called through dns_xfrin_detach() and are not
1527 * shutting down, we can't know what the transfer status is as
1528 * we are only called when the last reference is lost.
1529 */
1530 result_str = (xfr->shuttingdown
1531 ? isc_result_totext(xfr->shutdown_result)
1532 : "unknown");
1533 xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str);
1534
1535 /*
1536 * Calculate the length of time the transfer took,
1537 * and print a log message with the bytes and rate.
1538 */
1539 isc_time_now(&xfr->end);
1540 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1541 if (msecs == 0) {
1542 msecs = 1;
1543 }
1544 persec = (xfr->nbytes * 1000) / msecs;
1545 xfrin_log(xfr, ISC_LOG_INFO,
1546 "Transfer completed: %d messages, %d records, "
1547 "%" PRIu64 " bytes, "
1548 "%u.%03u secs (%u bytes/sec) (serial %u)",
1549 xfr->nmsg, xfr->nrecs, xfr->nbytes,
1550 (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
1551 (unsigned int)persec, xfr->end_serial);
1552
1553 if (xfr->socket != NULL) {
1554 isc_socket_detach(&xfr->socket);
1555 }
1556
1557 if (xfr->timer != NULL) {
1558 isc_timer_detach(&xfr->timer);
1559 }
1560
1561 if (xfr->task != NULL) {
1562 isc_task_detach(&xfr->task);
1563 }
1564
1565 if (xfr->tsigkey != NULL) {
1566 dns_tsigkey_detach(&xfr->tsigkey);
1567 }
1568
1569 if (xfr->lasttsig != NULL) {
1570 isc_buffer_free(&xfr->lasttsig);
1571 }
1572
1573 dns_diff_clear(&xfr->diff);
1574
1575 if (xfr->ixfr.journal != NULL) {
1576 dns_journal_destroy(&xfr->ixfr.journal);
1577 }
1578
1579 if (xfr->axfr.add_private != NULL) {
1580 (void)dns_db_endload(xfr->db, &xfr->axfr);
1581 }
1582
1583 if (xfr->tcpmsg_valid) {
1584 dns_tcpmsg_invalidate(&xfr->tcpmsg);
1585 }
1586
1587 if (xfr->tsigctx != NULL) {
1588 dst_context_destroy(&xfr->tsigctx);
1589 }
1590
1591 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) {
1592 dns_name_free(&xfr->name, xfr->mctx);
1593 }
1594
1595 if (xfr->ver != NULL) {
1596 dns_db_closeversion(xfr->db, &xfr->ver, false);
1597 }
1598
1599 if (xfr->db != NULL) {
1600 dns_db_detach(&xfr->db);
1601 }
1602
1603 if (xfr->zone != NULL) {
1604 if (!xfr->zone_had_db && xfr->shuttingdown &&
1605 xfr->shutdown_result == ISC_R_SUCCESS &&
1606 dns_zone_gettype(xfr->zone) == dns_zone_mirror)
1607 {
1608 dns_zone_log(xfr->zone, ISC_LOG_INFO,
1609 "mirror zone is now in use");
1610 }
1611 xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context");
1612 /*
1613 * xfr->zone must not be detached before xfrin_log() is called.
1614 */
1615 dns_zone_idetach(&xfr->zone);
1616 }
1617
1618 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1619 }
1620
1621 /*
1622 * Log incoming zone transfer messages in a format like
1623 * transfer of <zone> from <address>: <message>
1624 */
1625 static void
1626 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
1627 const char *fmt, va_list ap) {
1628 char mastertext[ISC_SOCKADDR_FORMATSIZE];
1629 char msgtext[2048];
1630
1631 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
1632 vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
1633
1634 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
1635 level, "transfer of '%s' from %s: %s", zonetext,
1636 mastertext, msgtext);
1637 }
1638
1639 /*
1640 * Logging function for use when a xfrin_ctx_t has not yet been created.
1641 */
1642
1643 static void
1644 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
1645 const char *fmt, ...) {
1646 va_list ap;
1647
1648 if (!isc_log_wouldlog(dns_lctx, level)) {
1649 return;
1650 }
1651
1652 va_start(ap, fmt);
1653 xfrin_logv(level, zonetext, masteraddr, fmt, ap);
1654 va_end(ap);
1655 }
1656
1657 /*
1658 * Logging function for use when there is a xfrin_ctx_t.
1659 */
1660
1661 static void
1662 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) {
1663 va_list ap;
1664 char zonetext[DNS_NAME_MAXTEXT + 32];
1665
1666 if (!isc_log_wouldlog(dns_lctx, level)) {
1667 return;
1668 }
1669
1670 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
1671
1672 va_start(ap, fmt);
1673 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);
1674 va_end(ap);
1675 }
1676