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