xfrin.c revision 1.1.1.5 1 /* $NetBSD: xfrin.c,v 1.1.1.5 2020/08/03 17:07: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 http://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 redo:
504 switch (xfr->state) {
505 case XFRST_SOAQUERY:
506 if (rdata->type != dns_rdatatype_soa) {
507 xfrin_log(xfr, ISC_LOG_ERROR,
508 "non-SOA response to SOA query");
509 FAIL(DNS_R_FORMERR);
510 }
511 xfr->end_serial = dns_soa_getserial(rdata);
512 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
513 !dns_zone_isforced(xfr->zone))
514 {
515 xfrin_log(xfr, ISC_LOG_DEBUG(3),
516 "requested serial %u, "
517 "master has %u, not updating",
518 xfr->ixfr.request_serial, xfr->end_serial);
519 FAIL(DNS_R_UPTODATE);
520 }
521 xfr->state = XFRST_GOTSOA;
522 break;
523
524 case XFRST_GOTSOA:
525 /*
526 * Skip other records in the answer section.
527 */
528 break;
529
530 case XFRST_INITIALSOA:
531 if (rdata->type != dns_rdatatype_soa) {
532 xfrin_log(xfr, ISC_LOG_ERROR,
533 "first RR in zone transfer must be SOA");
534 FAIL(DNS_R_FORMERR);
535 }
536 /*
537 * Remember the serial number in the initial SOA.
538 * We need it to recognize the end of an IXFR.
539 */
540 xfr->end_serial = dns_soa_getserial(rdata);
541 if (xfr->reqtype == dns_rdatatype_ixfr &&
542 !DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
543 !dns_zone_isforced(xfr->zone))
544 {
545 /*
546 * This must be the single SOA record that is
547 * sent when the current version on the master
548 * is not newer than the version in the request.
549 */
550 xfrin_log(xfr, ISC_LOG_DEBUG(3),
551 "requested serial %u, "
552 "master has %u, not updating",
553 xfr->ixfr.request_serial, xfr->end_serial);
554 FAIL(DNS_R_UPTODATE);
555 }
556 if (xfr->reqtype == dns_rdatatype_axfr) {
557 xfr->checkid = false;
558 }
559 xfr->state = XFRST_FIRSTDATA;
560 break;
561
562 case XFRST_FIRSTDATA:
563 /*
564 * If the transfer begins with one SOA record, it is an AXFR,
565 * if it begins with two SOAs, it is an IXFR.
566 */
567 if (xfr->reqtype == dns_rdatatype_ixfr &&
568 rdata->type == dns_rdatatype_soa &&
569 xfr->ixfr.request_serial == dns_soa_getserial(rdata))
570 {
571 xfrin_log(xfr, ISC_LOG_DEBUG(3),
572 "got incremental response");
573 CHECK(ixfr_init(xfr));
574 xfr->state = XFRST_IXFR_DELSOA;
575 } else {
576 xfrin_log(xfr, ISC_LOG_DEBUG(3),
577 "got nonincremental response");
578 CHECK(axfr_init(xfr));
579 xfr->state = XFRST_AXFR;
580 }
581 goto redo;
582
583 case XFRST_IXFR_DELSOA:
584 INSIST(rdata->type == dns_rdatatype_soa);
585 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
586 xfr->state = XFRST_IXFR_DEL;
587 break;
588
589 case XFRST_IXFR_DEL:
590 if (rdata->type == dns_rdatatype_soa) {
591 uint32_t soa_serial = dns_soa_getserial(rdata);
592 xfr->state = XFRST_IXFR_ADDSOA;
593 xfr->ixfr.current_serial = soa_serial;
594 goto redo;
595 }
596 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
597 break;
598
599 case XFRST_IXFR_ADDSOA:
600 INSIST(rdata->type == dns_rdatatype_soa);
601 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
602 xfr->state = XFRST_IXFR_ADD;
603 break;
604
605 case XFRST_IXFR_ADD:
606 if (rdata->type == dns_rdatatype_soa) {
607 uint32_t soa_serial = dns_soa_getserial(rdata);
608 if (soa_serial == xfr->end_serial) {
609 CHECK(ixfr_commit(xfr));
610 xfr->state = XFRST_IXFR_END;
611 break;
612 } else if (soa_serial != xfr->ixfr.current_serial) {
613 xfrin_log(xfr, ISC_LOG_ERROR,
614 "IXFR out of sync: "
615 "expected serial %u, got %u",
616 xfr->ixfr.current_serial, soa_serial);
617 FAIL(DNS_R_FORMERR);
618 } else {
619 CHECK(ixfr_commit(xfr));
620 xfr->state = XFRST_IXFR_DELSOA;
621 goto redo;
622 }
623 }
624 if (rdata->type == dns_rdatatype_ns &&
625 dns_name_iswildcard(name)) {
626 FAIL(DNS_R_INVALIDNS);
627 }
628 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
629 break;
630
631 case XFRST_AXFR:
632 /*
633 * Old BINDs sent cross class A records for non IN classes.
634 */
635 if (rdata->type == dns_rdatatype_a &&
636 rdata->rdclass != xfr->rdclass &&
637 xfr->rdclass != dns_rdataclass_in)
638 {
639 break;
640 }
641 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
642 if (rdata->type == dns_rdatatype_soa) {
643 CHECK(axfr_commit(xfr));
644 xfr->state = XFRST_AXFR_END;
645 break;
646 }
647 break;
648 case XFRST_AXFR_END:
649 case XFRST_IXFR_END:
650 FAIL(DNS_R_EXTRADATA);
651 /* NOTREACHED */
652 /* FALLTHROUGH */
653 default:
654 INSIST(0);
655 ISC_UNREACHABLE();
656 }
657 result = ISC_R_SUCCESS;
658 failure:
659 return (result);
660 }
661
662 isc_result_t
663 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
664 const isc_sockaddr_t *masteraddr,
665 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
666 dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
667 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
668 isc_task_t *task, dns_xfrindone_t done,
669 dns_xfrin_ctx_t **xfrp) {
670 dns_name_t *zonename = dns_zone_getorigin(zone);
671 dns_xfrin_ctx_t *xfr = NULL;
672 isc_result_t result;
673 dns_db_t *db = NULL;
674
675 REQUIRE(xfrp != NULL && *xfrp == NULL);
676
677 (void)dns_zone_getdb(zone, &db);
678
679 if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) {
680 REQUIRE(db != NULL);
681 }
682
683 CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
684 dns_zone_getclass(zone), xfrtype, masteraddr,
685 sourceaddr, dscp, tsigkey, &xfr));
686
687 if (db != NULL) {
688 xfr->zone_had_db = true;
689 }
690
691 CHECK(xfrin_start(xfr));
692
693 xfr->done = done;
694 if (xfr->done != NULL) {
695 xfr->refcount++;
696 }
697 *xfrp = xfr;
698
699 failure:
700 if (db != NULL) {
701 dns_db_detach(&db);
702 }
703 if (result != ISC_R_SUCCESS) {
704 char zonetext[DNS_NAME_MAXTEXT + 32];
705 dns_zone_name(zone, zonetext, sizeof(zonetext));
706 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
707 "zone transfer setup failed");
708 }
709 return (result);
710 }
711
712 void
713 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
714 if (!xfr->shuttingdown) {
715 xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
716 }
717 }
718
719 void
720 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
721 REQUIRE(target != NULL && *target == NULL);
722 source->refcount++;
723 *target = source;
724 }
725
726 void
727 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
728 dns_xfrin_ctx_t *xfr = *xfrp;
729 *xfrp = NULL;
730 INSIST(xfr->refcount > 0);
731 xfr->refcount--;
732 maybe_free(xfr);
733 }
734
735 static void
736 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
737 if (xfr->connects > 0) {
738 isc_socket_cancel(xfr->socket, xfr->task,
739 ISC_SOCKCANCEL_CONNECT);
740 } else if (xfr->recvs > 0) {
741 dns_tcpmsg_cancelread(&xfr->tcpmsg);
742 } else if (xfr->sends > 0) {
743 isc_socket_cancel(xfr->socket, xfr->task, ISC_SOCKCANCEL_SEND);
744 }
745 }
746
747 static void
748 xfrin_reset(dns_xfrin_ctx_t *xfr) {
749 REQUIRE(VALID_XFRIN(xfr));
750
751 xfrin_log(xfr, ISC_LOG_INFO, "resetting");
752
753 xfrin_cancelio(xfr);
754
755 if (xfr->socket != NULL) {
756 isc_socket_detach(&xfr->socket);
757 }
758
759 if (xfr->lasttsig != NULL) {
760 isc_buffer_free(&xfr->lasttsig);
761 }
762
763 dns_diff_clear(&xfr->diff);
764 xfr->difflen = 0;
765
766 if (xfr->ixfr.journal != NULL) {
767 dns_journal_destroy(&xfr->ixfr.journal);
768 }
769
770 if (xfr->axfr.add_private != NULL) {
771 (void)dns_db_endload(xfr->db, &xfr->axfr);
772 }
773
774 if (xfr->tcpmsg_valid) {
775 dns_tcpmsg_invalidate(&xfr->tcpmsg);
776 xfr->tcpmsg_valid = false;
777 }
778
779 if (xfr->ver != NULL) {
780 dns_db_closeversion(xfr->db, &xfr->ver, false);
781 }
782 }
783
784 static void
785 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
786 if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) {
787 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
788 isc_result_totext(result));
789 if (xfr->is_ixfr) {
790 /* Pass special result code to force AXFR retry */
791 result = DNS_R_BADIXFR;
792 }
793 }
794 xfrin_cancelio(xfr);
795 /*
796 * Close the journal.
797 */
798 if (xfr->ixfr.journal != NULL) {
799 dns_journal_destroy(&xfr->ixfr.journal);
800 }
801 if (xfr->done != NULL) {
802 (xfr->done)(xfr->zone, result);
803 xfr->done = NULL;
804 }
805 xfr->shuttingdown = true;
806 xfr->shutdown_result = result;
807 maybe_free(xfr);
808 }
809
810 static isc_result_t
811 xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
812 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
813 dns_name_t *zonename, dns_rdataclass_t rdclass,
814 dns_rdatatype_t reqtype, const isc_sockaddr_t *masteraddr,
815 const isc_sockaddr_t *sourceaddr, isc_dscp_t dscp,
816 dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp) {
817 dns_xfrin_ctx_t *xfr = NULL;
818 isc_result_t result;
819
820 xfr = isc_mem_get(mctx, sizeof(*xfr));
821 xfr->mctx = NULL;
822 isc_mem_attach(mctx, &xfr->mctx);
823 xfr->refcount = 0;
824 xfr->zone = NULL;
825 dns_zone_iattach(zone, &xfr->zone);
826 xfr->task = NULL;
827 isc_task_attach(task, &xfr->task);
828 xfr->timer = NULL;
829 xfr->socketmgr = socketmgr;
830 xfr->done = NULL;
831
832 xfr->connects = 0;
833 xfr->sends = 0;
834 xfr->recvs = 0;
835 xfr->shuttingdown = false;
836 xfr->shutdown_result = ISC_R_UNSET;
837
838 dns_name_init(&xfr->name, NULL);
839 xfr->rdclass = rdclass;
840 xfr->checkid = true;
841 xfr->logit = true;
842 xfr->id = (dns_messageid_t)isc_random16();
843 xfr->reqtype = reqtype;
844 xfr->dscp = dscp;
845
846 /* sockaddr */
847 xfr->socket = NULL;
848 /* qbuffer */
849 /* qbuffer_data */
850 /* tcpmsg */
851 xfr->tcpmsg_valid = false;
852
853 xfr->zone_had_db = false;
854 xfr->db = NULL;
855 if (db != NULL) {
856 dns_db_attach(db, &xfr->db);
857 }
858 xfr->ver = NULL;
859 dns_diff_init(xfr->mctx, &xfr->diff);
860 xfr->difflen = 0;
861
862 if (reqtype == dns_rdatatype_soa) {
863 xfr->state = XFRST_SOAQUERY;
864 } else {
865 xfr->state = XFRST_INITIALSOA;
866 }
867 /* end_serial */
868
869 xfr->nmsg = 0;
870 xfr->nrecs = 0;
871 xfr->nbytes = 0;
872 xfr->maxrecords = dns_zone_getmaxrecords(zone);
873 isc_time_now(&xfr->start);
874
875 xfr->tsigkey = NULL;
876 if (tsigkey != NULL) {
877 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
878 }
879 xfr->lasttsig = NULL;
880 xfr->tsigctx = NULL;
881 xfr->sincetsig = 0;
882 xfr->is_ixfr = false;
883
884 /* ixfr.request_serial */
885 /* ixfr.current_serial */
886 xfr->ixfr.journal = NULL;
887
888 xfr->axfr.add = NULL;
889 xfr->axfr.add_private = NULL;
890
891 dns_name_dup(zonename, mctx, &xfr->name);
892
893 CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
894 task, xfrin_timeout, xfr, &xfr->timer));
895 CHECK(dns_timer_setidle(xfr->timer, dns_zone_getmaxxfrin(xfr->zone),
896 dns_zone_getidlein(xfr->zone), false));
897
898 xfr->masteraddr = *masteraddr;
899
900 INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
901 xfr->sourceaddr = *sourceaddr;
902 isc_sockaddr_setport(&xfr->sourceaddr, 0);
903
904 /*
905 * Reserve 2 bytes for TCP length at the beginning of the buffer.
906 */
907 isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
908 sizeof(xfr->qbuffer_data) - 2);
909
910 xfr->magic = XFRIN_MAGIC;
911 *xfrp = xfr;
912 return (ISC_R_SUCCESS);
913
914 failure:
915 if (xfr->timer != NULL) {
916 isc_timer_detach(&xfr->timer);
917 }
918 if (dns_name_dynamic(&xfr->name)) {
919 dns_name_free(&xfr->name, xfr->mctx);
920 }
921 if (xfr->tsigkey != NULL) {
922 dns_tsigkey_detach(&xfr->tsigkey);
923 }
924 if (xfr->db != NULL) {
925 dns_db_detach(&xfr->db);
926 }
927 isc_task_detach(&xfr->task);
928 dns_zone_idetach(&xfr->zone);
929 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
930
931 return (result);
932 }
933
934 static isc_result_t
935 xfrin_start(dns_xfrin_ctx_t *xfr) {
936 isc_result_t result;
937 CHECK(isc_socket_create(xfr->socketmgr,
938 isc_sockaddr_pf(&xfr->sourceaddr),
939 isc_sockettype_tcp, &xfr->socket));
940 isc_socket_setname(xfr->socket, "xfrin", NULL);
941 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
942 CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
943 ISC_SOCKET_REUSEADDRESS));
944 #endif /* ifndef BROKEN_TCP_BIND_BEFORE_CONNECT */
945 isc_socket_dscp(xfr->socket, xfr->dscp);
946 CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
947 xfrin_connect_done, xfr));
948 xfr->connects++;
949 return (ISC_R_SUCCESS);
950 failure:
951 xfrin_fail(xfr, result, "failed setting up socket");
952 return (result);
953 }
954
955 /* XXX the resolver could use this, too */
956
957 static isc_result_t
958 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
959 dns_compress_t cctx;
960 bool cleanup_cctx = false;
961 isc_result_t result;
962
963 CHECK(dns_compress_init(&cctx, -1, mctx));
964 cleanup_cctx = true;
965 CHECK(dns_message_renderbegin(msg, &cctx, buf));
966 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
967 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
968 CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
969 CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
970 CHECK(dns_message_renderend(msg));
971 result = ISC_R_SUCCESS;
972 failure:
973 if (cleanup_cctx) {
974 dns_compress_invalidate(&cctx);
975 }
976 return (result);
977 }
978
979 /*
980 * A connection has been established.
981 */
982 static void
983 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
984 isc_socket_connev_t *cev = (isc_socket_connev_t *)event;
985 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
986 isc_result_t result = cev->result;
987 char sourcetext[ISC_SOCKADDR_FORMATSIZE];
988 char signerbuf[DNS_NAME_FORMATSIZE];
989 const char *signer = "", *sep = "";
990 isc_sockaddr_t sockaddr;
991 dns_zonemgr_t *zmgr;
992 isc_time_t now;
993
994 REQUIRE(VALID_XFRIN(xfr));
995
996 UNUSED(task);
997
998 INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
999 isc_event_free(&event);
1000
1001 xfr->connects--;
1002 if (xfr->shuttingdown) {
1003 maybe_free(xfr);
1004 return;
1005 }
1006
1007 zmgr = dns_zone_getmgr(xfr->zone);
1008 if (zmgr != NULL) {
1009 if (result != ISC_R_SUCCESS) {
1010 TIME_NOW(&now);
1011 dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
1012 &xfr->sourceaddr, &now);
1013 goto failure;
1014 } else {
1015 dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
1016 &xfr->sourceaddr);
1017 }
1018 }
1019
1020 result = isc_socket_getsockname(xfr->socket, &sockaddr);
1021 if (result == ISC_R_SUCCESS) {
1022 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
1023 } else {
1024 strlcpy(sourcetext, "<UNKNOWN>", sizeof(sourcetext));
1025 }
1026
1027 if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
1028 dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,
1029 sizeof(signerbuf));
1030 sep = " TSIG ";
1031 signer = signerbuf;
1032 }
1033
1034 xfrin_log(xfr, ISC_LOG_INFO, "connected using %s%s%s", sourcetext, sep,
1035 signer);
1036
1037 dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
1038 xfr->tcpmsg_valid = true;
1039
1040 CHECK(xfrin_send_request(xfr));
1041 failure:
1042 if (result != ISC_R_SUCCESS) {
1043 xfrin_fail(xfr, result, "failed to connect");
1044 }
1045 }
1046
1047 /*
1048 * Convert a tuple into a dns_name_t suitable for inserting
1049 * into the given dns_message_t.
1050 */
1051 static isc_result_t
1052 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) {
1053 isc_result_t result;
1054 dns_rdata_t *rdata = NULL;
1055 dns_rdatalist_t *rdl = NULL;
1056 dns_rdataset_t *rds = NULL;
1057 dns_name_t *name = NULL;
1058
1059 REQUIRE(target != NULL && *target == NULL);
1060
1061 CHECK(dns_message_gettemprdata(msg, &rdata));
1062 dns_rdata_init(rdata);
1063 dns_rdata_clone(&tuple->rdata, rdata);
1064
1065 CHECK(dns_message_gettemprdatalist(msg, &rdl));
1066 dns_rdatalist_init(rdl);
1067 rdl->type = tuple->rdata.type;
1068 rdl->rdclass = tuple->rdata.rdclass;
1069 rdl->ttl = tuple->ttl;
1070 ISC_LIST_APPEND(rdl->rdata, rdata, link);
1071
1072 CHECK(dns_message_gettemprdataset(msg, &rds));
1073 CHECK(dns_rdatalist_tordataset(rdl, rds));
1074
1075 CHECK(dns_message_gettempname(msg, &name));
1076 dns_name_init(name, NULL);
1077 dns_name_clone(&tuple->name, name);
1078 ISC_LIST_APPEND(name->list, rds, link);
1079
1080 *target = name;
1081 return (ISC_R_SUCCESS);
1082
1083 failure:
1084
1085 if (rds != NULL) {
1086 dns_rdataset_disassociate(rds);
1087 dns_message_puttemprdataset(msg, &rds);
1088 }
1089 if (rdl != NULL) {
1090 ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1091 dns_message_puttemprdatalist(msg, &rdl);
1092 }
1093 if (rdata != NULL) {
1094 dns_message_puttemprdata(msg, &rdata);
1095 }
1096
1097 return (result);
1098 }
1099
1100 /*
1101 * Build an *XFR request and send its length prefix.
1102 */
1103 static isc_result_t
1104 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1105 isc_result_t result;
1106 isc_region_t region;
1107 dns_rdataset_t *qrdataset = NULL;
1108 dns_message_t *msg = NULL;
1109 dns_difftuple_t *soatuple = NULL;
1110 dns_name_t *qname = NULL;
1111 dns_dbversion_t *ver = NULL;
1112 dns_name_t *msgsoaname = NULL;
1113
1114 /* Create the request message */
1115 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
1116 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1117
1118 /* Create a name for the question section. */
1119 CHECK(dns_message_gettempname(msg, &qname));
1120 dns_name_init(qname, NULL);
1121 dns_name_clone(&xfr->name, qname);
1122
1123 /* Formulate the question and attach it to the question name. */
1124 CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1125 dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1126 ISC_LIST_APPEND(qname->list, qrdataset, link);
1127 qrdataset = NULL;
1128
1129 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1130 qname = NULL;
1131
1132 if (xfr->reqtype == dns_rdatatype_ixfr) {
1133 /* Get the SOA and add it to the authority section. */
1134 /* XXX is using the current version the right thing? */
1135 dns_db_currentversion(xfr->db, &ver);
1136 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1137 DNS_DIFFOP_EXISTS, &soatuple));
1138 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1139 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1140 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1141 "requesting IXFR for serial %u",
1142 xfr->ixfr.request_serial);
1143
1144 CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1145 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1146 } else if (xfr->reqtype == dns_rdatatype_soa) {
1147 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1148 &xfr->ixfr.request_serial));
1149 }
1150
1151 xfr->checkid = true;
1152 xfr->logit = true;
1153 xfr->id++;
1154 xfr->nmsg = 0;
1155 xfr->nrecs = 0;
1156 xfr->nbytes = 0;
1157 isc_time_now(&xfr->start);
1158 msg->id = xfr->id;
1159 if (xfr->tsigctx != NULL) {
1160 dst_context_destroy(&xfr->tsigctx);
1161 }
1162
1163 CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1164
1165 /*
1166 * Free the last tsig, if there is one.
1167 */
1168 if (xfr->lasttsig != NULL) {
1169 isc_buffer_free(&xfr->lasttsig);
1170 }
1171
1172 /*
1173 * Save the query TSIG and don't let message_destroy free it.
1174 */
1175 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1176
1177 isc_buffer_usedregion(&xfr->qbuffer, ®ion);
1178 INSIST(region.length <= 65535);
1179
1180 /*
1181 * Record message length and adjust region to include TCP
1182 * length field.
1183 */
1184 xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
1185 xfr->qbuffer_data[1] = region.length & 0xff;
1186 region.base -= 2;
1187 region.length += 2;
1188 CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task, xfrin_send_done,
1189 xfr));
1190 xfr->sends++;
1191
1192 failure:
1193 if (qname != NULL) {
1194 dns_message_puttempname(msg, &qname);
1195 }
1196 if (qrdataset != NULL) {
1197 dns_message_puttemprdataset(msg, &qrdataset);
1198 }
1199 if (msg != NULL) {
1200 dns_message_destroy(&msg);
1201 }
1202 if (soatuple != NULL) {
1203 dns_difftuple_free(&soatuple);
1204 }
1205 if (ver != NULL) {
1206 dns_db_closeversion(xfr->db, &ver, false);
1207 }
1208 return (result);
1209 }
1210
1211 static void
1212 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
1213 isc_socketevent_t *sev = (isc_socketevent_t *)event;
1214 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
1215 isc_result_t result;
1216
1217 REQUIRE(VALID_XFRIN(xfr));
1218
1219 UNUSED(task);
1220
1221 INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1222
1223 xfr->sends--;
1224 xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1225 CHECK(sev->result);
1226
1227 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, xfrin_recv_done,
1228 xfr));
1229 xfr->recvs++;
1230 failure:
1231 isc_event_free(&event);
1232 if (result != ISC_R_SUCCESS) {
1233 xfrin_fail(xfr, result, "failed sending request data");
1234 }
1235 }
1236
1237 static void
1238 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
1239 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)ev->ev_arg;
1240 isc_result_t result;
1241 dns_message_t *msg = NULL;
1242 dns_name_t *name;
1243 dns_tcpmsg_t *tcpmsg;
1244 const dns_name_t *tsigowner = NULL;
1245
1246 REQUIRE(VALID_XFRIN(xfr));
1247
1248 UNUSED(task);
1249
1250 INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
1251 tcpmsg = ev->ev_sender;
1252 isc_event_free(&ev);
1253
1254 xfr->recvs--;
1255 if (xfr->shuttingdown) {
1256 maybe_free(xfr);
1257 return;
1258 }
1259
1260 CHECK(tcpmsg->result);
1261
1262 xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
1263 tcpmsg->buffer.used);
1264
1265 CHECK(isc_timer_touch(xfr->timer));
1266
1267 CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
1268
1269 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1270 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1271
1272 msg->tsigctx = xfr->tsigctx;
1273 xfr->tsigctx = NULL;
1274
1275 dns_message_setclass(msg, xfr->rdclass);
1276
1277 if (xfr->nmsg > 0) {
1278 msg->tcp_continuation = 1;
1279 }
1280
1281 result = dns_message_parse(msg, &tcpmsg->buffer,
1282 DNS_MESSAGEPARSE_PRESERVEORDER);
1283
1284 if (result == ISC_R_SUCCESS) {
1285 dns_message_logpacket(msg, "received message from",
1286 &tcpmsg->address, DNS_LOGCATEGORY_XFER_IN,
1287 DNS_LOGMODULE_XFER_IN, ISC_LOG_DEBUG(10),
1288 xfr->mctx);
1289 } else {
1290 xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s",
1291 dns_result_totext(result));
1292 }
1293
1294 if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1295 msg->opcode != dns_opcode_query || msg->rdclass != xfr->rdclass ||
1296 (xfr->checkid && msg->id != xfr->id))
1297 {
1298 if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
1299 {
1300 result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
1301 } else if (result == ISC_R_SUCCESS &&
1302 msg->opcode != dns_opcode_query) {
1303 result = DNS_R_UNEXPECTEDOPCODE;
1304 } else if (result == ISC_R_SUCCESS &&
1305 msg->rdclass != xfr->rdclass) {
1306 result = DNS_R_BADCLASS;
1307 } else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) {
1308 result = DNS_R_UNEXPECTEDID;
1309 }
1310 if (xfr->reqtype == dns_rdatatype_axfr ||
1311 xfr->reqtype == dns_rdatatype_soa) {
1312 goto failure;
1313 }
1314 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1315 isc_result_totext(result));
1316 try_axfr:
1317 dns_message_destroy(&msg);
1318 xfrin_reset(xfr);
1319 xfr->reqtype = dns_rdatatype_soa;
1320 xfr->state = XFRST_SOAQUERY;
1321 (void)xfrin_start(xfr);
1322 return;
1323 } else if (!xfr->checkid && msg->id != xfr->id && xfr->logit) {
1324 xfrin_log(xfr, ISC_LOG_WARNING,
1325 "detected message ID mismatch on incoming AXFR "
1326 "stream, transfer will fail in BIND 9.17.2 and "
1327 "later if AXFR source is not fixed");
1328 xfr->logit = false;
1329 }
1330
1331 /*
1332 * Does the server know about IXFR? If it doesn't we will get
1333 * a message with a empty answer section or a potentially a CNAME /
1334 * DNAME, the later is handled by xfr_rr() which will return FORMERR
1335 * if the first RR in the answer section is not a SOA record.
1336 */
1337 if (xfr->reqtype == dns_rdatatype_ixfr &&
1338 xfr->state == XFRST_INITIALSOA &&
1339 msg->counts[DNS_SECTION_ANSWER] == 0)
1340 {
1341 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1342 "empty answer section, retrying with AXFR");
1343 goto try_axfr;
1344 }
1345
1346 if (xfr->reqtype == dns_rdatatype_soa &&
1347 (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
1348 FAIL(DNS_R_NOTAUTHORITATIVE);
1349 }
1350
1351 result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1352 if (result != ISC_R_SUCCESS) {
1353 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1354 isc_result_totext(result));
1355 goto failure;
1356 }
1357
1358 for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1359 result == ISC_R_SUCCESS;
1360 result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1361 {
1362 dns_rdataset_t *rds;
1363
1364 name = NULL;
1365 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1366 for (rds = ISC_LIST_HEAD(name->list); rds != NULL;
1367 rds = ISC_LIST_NEXT(rds, link))
1368 {
1369 for (result = dns_rdataset_first(rds);
1370 result == ISC_R_SUCCESS;
1371 result = dns_rdataset_next(rds))
1372 {
1373 dns_rdata_t rdata = DNS_RDATA_INIT;
1374 dns_rdataset_current(rds, &rdata);
1375 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1376 }
1377 }
1378 }
1379 if (result != ISC_R_NOMORE) {
1380 goto failure;
1381 }
1382
1383 if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1384 /*
1385 * Reset the counter.
1386 */
1387 xfr->sincetsig = 0;
1388
1389 /*
1390 * Free the last tsig, if there is one.
1391 */
1392 if (xfr->lasttsig != NULL) {
1393 isc_buffer_free(&xfr->lasttsig);
1394 }
1395
1396 /*
1397 * Update the last tsig pointer.
1398 */
1399 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1400 } else if (dns_message_gettsigkey(msg) != NULL) {
1401 xfr->sincetsig++;
1402 if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1403 xfr->state == XFRST_AXFR_END ||
1404 xfr->state == XFRST_IXFR_END)
1405 {
1406 result = DNS_R_EXPECTEDTSIG;
1407 goto failure;
1408 }
1409 }
1410
1411 /*
1412 * Update the number of messages received.
1413 */
1414 xfr->nmsg++;
1415
1416 /*
1417 * Update the number of bytes received.
1418 */
1419 xfr->nbytes += tcpmsg->buffer.used;
1420
1421 /*
1422 * Take the context back.
1423 */
1424 INSIST(xfr->tsigctx == NULL);
1425 xfr->tsigctx = msg->tsigctx;
1426 msg->tsigctx = NULL;
1427
1428 dns_message_destroy(&msg);
1429
1430 switch (xfr->state) {
1431 case XFRST_GOTSOA:
1432 xfr->reqtype = dns_rdatatype_axfr;
1433 xfr->state = XFRST_INITIALSOA;
1434 CHECK(xfrin_send_request(xfr));
1435 break;
1436 case XFRST_AXFR_END:
1437 CHECK(axfr_finalize(xfr));
1438 /* FALLTHROUGH */
1439 case XFRST_IXFR_END:
1440 /*
1441 * Close the journal.
1442 */
1443 if (xfr->ixfr.journal != NULL) {
1444 dns_journal_destroy(&xfr->ixfr.journal);
1445 }
1446
1447 /*
1448 * Inform the caller we succeeded.
1449 */
1450 if (xfr->done != NULL) {
1451 (xfr->done)(xfr->zone, ISC_R_SUCCESS);
1452 xfr->done = NULL;
1453 }
1454 /*
1455 * We should have no outstanding events at this
1456 * point, thus maybe_free() should succeed.
1457 */
1458 xfr->shuttingdown = true;
1459 xfr->shutdown_result = ISC_R_SUCCESS;
1460 maybe_free(xfr);
1461 break;
1462 default:
1463 /*
1464 * Read the next message.
1465 */
1466 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1467 xfrin_recv_done, xfr));
1468 xfr->recvs++;
1469 }
1470 return;
1471
1472 failure:
1473 if (msg != NULL) {
1474 dns_message_destroy(&msg);
1475 }
1476 if (result != ISC_R_SUCCESS) {
1477 xfrin_fail(xfr, result, "failed while receiving responses");
1478 }
1479 }
1480
1481 static void
1482 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
1483 dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *)event->ev_arg;
1484
1485 REQUIRE(VALID_XFRIN(xfr));
1486
1487 UNUSED(task);
1488
1489 isc_event_free(&event);
1490 /*
1491 * This will log "giving up: timeout".
1492 */
1493 xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
1494 }
1495
1496 static void
1497 maybe_free(dns_xfrin_ctx_t *xfr) {
1498 uint64_t msecs;
1499 uint64_t persec;
1500 const char *result_str;
1501
1502 REQUIRE(VALID_XFRIN(xfr));
1503
1504 if (!xfr->shuttingdown || xfr->refcount != 0 || xfr->connects != 0 ||
1505 xfr->sends != 0 || xfr->recvs != 0)
1506 {
1507 return;
1508 }
1509
1510 INSIST(!xfr->shuttingdown || xfr->shutdown_result != ISC_R_UNSET);
1511
1512 /* If we're called through dns_xfrin_detach() and are not
1513 * shutting down, we can't know what the transfer status is as
1514 * we are only called when the last reference is lost.
1515 */
1516 result_str = (xfr->shuttingdown
1517 ? isc_result_totext(xfr->shutdown_result)
1518 : "unknown");
1519 xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str);
1520
1521 /*
1522 * Calculate the length of time the transfer took,
1523 * and print a log message with the bytes and rate.
1524 */
1525 isc_time_now(&xfr->end);
1526 msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1527 if (msecs == 0) {
1528 msecs = 1;
1529 }
1530 persec = (xfr->nbytes * 1000) / msecs;
1531 xfrin_log(xfr, ISC_LOG_INFO,
1532 "Transfer completed: %d messages, %d records, "
1533 "%" PRIu64 " bytes, "
1534 "%u.%03u secs (%u bytes/sec)",
1535 xfr->nmsg, xfr->nrecs, xfr->nbytes,
1536 (unsigned int)(msecs / 1000), (unsigned int)(msecs % 1000),
1537 (unsigned int)persec);
1538
1539 if (xfr->socket != NULL) {
1540 isc_socket_detach(&xfr->socket);
1541 }
1542
1543 if (xfr->timer != NULL) {
1544 isc_timer_detach(&xfr->timer);
1545 }
1546
1547 if (xfr->task != NULL) {
1548 isc_task_detach(&xfr->task);
1549 }
1550
1551 if (xfr->tsigkey != NULL) {
1552 dns_tsigkey_detach(&xfr->tsigkey);
1553 }
1554
1555 if (xfr->lasttsig != NULL) {
1556 isc_buffer_free(&xfr->lasttsig);
1557 }
1558
1559 dns_diff_clear(&xfr->diff);
1560
1561 if (xfr->ixfr.journal != NULL) {
1562 dns_journal_destroy(&xfr->ixfr.journal);
1563 }
1564
1565 if (xfr->axfr.add_private != NULL) {
1566 (void)dns_db_endload(xfr->db, &xfr->axfr);
1567 }
1568
1569 if (xfr->tcpmsg_valid) {
1570 dns_tcpmsg_invalidate(&xfr->tcpmsg);
1571 }
1572
1573 if (xfr->tsigctx != NULL) {
1574 dst_context_destroy(&xfr->tsigctx);
1575 }
1576
1577 if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) {
1578 dns_name_free(&xfr->name, xfr->mctx);
1579 }
1580
1581 if (xfr->ver != NULL) {
1582 dns_db_closeversion(xfr->db, &xfr->ver, false);
1583 }
1584
1585 if (xfr->db != NULL) {
1586 dns_db_detach(&xfr->db);
1587 }
1588
1589 if (xfr->zone != NULL) {
1590 if (!xfr->zone_had_db && xfr->shuttingdown &&
1591 xfr->shutdown_result == ISC_R_SUCCESS &&
1592 dns_zone_gettype(xfr->zone) == dns_zone_mirror)
1593 {
1594 dns_zone_log(xfr->zone, ISC_LOG_INFO,
1595 "mirror zone is now in use");
1596 }
1597 xfrin_log(xfr, ISC_LOG_DEBUG(99), "freeing transfer context");
1598 /*
1599 * xfr->zone must not be detached before xfrin_log() is called.
1600 */
1601 dns_zone_idetach(&xfr->zone);
1602 }
1603
1604 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1605 }
1606
1607 /*
1608 * Log incoming zone transfer messages in a format like
1609 * transfer of <zone> from <address>: <message>
1610 */
1611 static void
1612 xfrin_logv(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
1613 const char *fmt, va_list ap) {
1614 char mastertext[ISC_SOCKADDR_FORMATSIZE];
1615 char msgtext[2048];
1616
1617 isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
1618 vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
1619
1620 isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN,
1621 level, "transfer of '%s' from %s: %s", zonetext,
1622 mastertext, msgtext);
1623 }
1624
1625 /*
1626 * Logging function for use when a xfrin_ctx_t has not yet been created.
1627 */
1628
1629 static void
1630 xfrin_log1(int level, const char *zonetext, const isc_sockaddr_t *masteraddr,
1631 const char *fmt, ...) {
1632 va_list ap;
1633
1634 if (!isc_log_wouldlog(dns_lctx, level)) {
1635 return;
1636 }
1637
1638 va_start(ap, fmt);
1639 xfrin_logv(level, zonetext, masteraddr, fmt, ap);
1640 va_end(ap);
1641 }
1642
1643 /*
1644 * Logging function for use when there is a xfrin_ctx_t.
1645 */
1646
1647 static void
1648 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) {
1649 va_list ap;
1650 char zonetext[DNS_NAME_MAXTEXT + 32];
1651
1652 if (!isc_log_wouldlog(dns_lctx, level)) {
1653 return;
1654 }
1655
1656 dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
1657
1658 va_start(ap, fmt);
1659 xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);
1660 va_end(ap);
1661 }
1662