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