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