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