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