1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * SPDX-License-Identifier: MPL-2.0
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14 #include <inttypes.h>
15 #include <stdbool.h>
16
17 #include <isc/formatcheck.h>
18 #include <isc/mem.h>
19 #include <isc/netmgr.h>
20 #include <isc/print.h>
21 #include <isc/stats.h>
22 #include <isc/util.h>
23
24 #include <dns/db.h>
25 #include <dns/dbiterator.h>
26 #include <dns/dlz.h>
27 #include <dns/fixedname.h>
28 #include <dns/journal.h>
29 #include <dns/message.h>
30 #include <dns/peer.h>
31 #include <dns/rdataclass.h>
32 #include <dns/rdatalist.h>
33 #include <dns/rdataset.h>
34 #include <dns/rdatasetiter.h>
35 #include <dns/result.h>
36 #include <dns/rriterator.h>
37 #include <dns/soa.h>
38 #include <dns/stats.h>
39 #include <dns/tsig.h>
40 #include <dns/view.h>
41 #include <dns/zone.h>
42 #include <dns/zt.h>
43
44 #include <ns/client.h>
45 #include <ns/log.h>
46 #include <ns/server.h>
47 #include <ns/stats.h>
48 #include <ns/xfrout.h>
49
50 /*! \file
51 * \brief
52 * Outgoing AXFR and IXFR.
53 */
54
55 /*
56 * TODO:
57 * - IXFR over UDP
58 */
59
60 #define XFROUT_COMMON_LOGARGS \
61 ns_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT
62
63 #define XFROUT_PROTOCOL_LOGARGS XFROUT_COMMON_LOGARGS, ISC_LOG_INFO
64
65 #define XFROUT_DEBUG_LOGARGS(n) XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n)
66
67 #define XFROUT_RR_LOGARGS XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL
68
69 #define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8)
70
71 /*%
72 * Fail unconditionally and log as a client error.
73 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
74 * from complaining about "end-of-loop code not reached".
75 */
76 #define FAILC(code, msg) \
77 do { \
78 result = (code); \
79 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
80 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
81 "bad zone transfer request: %s (%s)", msg, \
82 isc_result_totext(code)); \
83 if (result != ISC_R_SUCCESS) \
84 goto failure; \
85 } while (0)
86
87 #define FAILQ(code, msg, question, rdclass) \
88 do { \
89 char _buf1[DNS_NAME_FORMATSIZE]; \
90 char _buf2[DNS_RDATACLASS_FORMATSIZE]; \
91 result = (code); \
92 dns_name_format(question, _buf1, sizeof(_buf1)); \
93 dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \
94 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
95 NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
96 "bad zone transfer request: '%s/%s': %s (%s)", \
97 _buf1, _buf2, msg, isc_result_totext(code)); \
98 if (result != ISC_R_SUCCESS) \
99 goto failure; \
100 } while (0)
101
102 #define CHECK(op) \
103 do { \
104 result = (op); \
105 if (result != ISC_R_SUCCESS) \
106 goto failure; \
107 } while (0)
108
109 /**************************************************************************/
110
111 static inline void
inc_stats(ns_client_t * client,dns_zone_t * zone,isc_statscounter_t counter)112 inc_stats(ns_client_t *client, dns_zone_t *zone, isc_statscounter_t counter) {
113 ns_stats_increment(client->sctx->nsstats, counter);
114 if (zone != NULL) {
115 isc_stats_t *zonestats = dns_zone_getrequeststats(zone);
116 if (zonestats != NULL) {
117 isc_stats_increment(zonestats, counter);
118 }
119 }
120 }
121
122 /**************************************************************************/
123
124 /*% Log an RR (for debugging) */
125
126 static void
log_rr(dns_name_t * name,dns_rdata_t * rdata,uint32_t ttl)127 log_rr(dns_name_t *name, dns_rdata_t *rdata, uint32_t ttl) {
128 isc_result_t result;
129 isc_buffer_t buf;
130 char mem[2000];
131 dns_rdatalist_t rdl;
132 dns_rdataset_t rds;
133 dns_rdata_t rd = DNS_RDATA_INIT;
134
135 dns_rdatalist_init(&rdl);
136 rdl.type = rdata->type;
137 rdl.rdclass = rdata->rdclass;
138 rdl.ttl = ttl;
139 if (rdata->type == dns_rdatatype_sig ||
140 rdata->type == dns_rdatatype_rrsig) {
141 rdl.covers = dns_rdata_covers(rdata);
142 } else {
143 rdl.covers = dns_rdatatype_none;
144 }
145 dns_rdataset_init(&rds);
146 dns_rdata_init(&rd);
147 dns_rdata_clone(rdata, &rd);
148 ISC_LIST_APPEND(rdl.rdata, &rd, link);
149 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS);
150
151 isc_buffer_init(&buf, mem, sizeof(mem));
152 result = dns_rdataset_totext(&rds, name, false, false, &buf);
153
154 /*
155 * We could use xfrout_log(), but that would produce
156 * very long lines with a repetitive prefix.
157 */
158 if (result == ISC_R_SUCCESS) {
159 /*
160 * Get rid of final newline.
161 */
162 INSIST(buf.used >= 1 &&
163 ((char *)buf.base)[buf.used - 1] == '\n');
164 buf.used--;
165
166 isc_log_write(XFROUT_RR_LOGARGS, "%.*s",
167 (int)isc_buffer_usedlength(&buf),
168 (char *)isc_buffer_base(&buf));
169 } else {
170 isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>");
171 }
172 }
173
174 /**************************************************************************/
175 /*
176 * An 'rrstream_t' is a polymorphic iterator that returns
177 * a stream of resource records. There are multiple implementations,
178 * e.g. for generating AXFR and IXFR records streams.
179 */
180
181 typedef struct rrstream_methods rrstream_methods_t;
182
183 typedef struct rrstream {
184 isc_mem_t *mctx;
185 rrstream_methods_t *methods;
186 } rrstream_t;
187
188 struct rrstream_methods {
189 isc_result_t (*first)(rrstream_t *);
190 isc_result_t (*next)(rrstream_t *);
191 void (*current)(rrstream_t *, dns_name_t **, uint32_t *,
192 dns_rdata_t **);
193 void (*pause)(rrstream_t *);
194 void (*destroy)(rrstream_t **);
195 };
196
197 static void
rrstream_noop_pause(rrstream_t * rs)198 rrstream_noop_pause(rrstream_t *rs) {
199 UNUSED(rs);
200 }
201
202 /**************************************************************************/
203 /*
204 * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
205 * an IXFR-like RR stream from a journal file.
206 *
207 * The SOA at the beginning of each sequence of additions
208 * or deletions are included in the stream, but the extra
209 * SOAs at the beginning and end of the entire transfer are
210 * not included.
211 */
212
213 typedef struct ixfr_rrstream {
214 rrstream_t common;
215 dns_journal_t *journal;
216 } ixfr_rrstream_t;
217
218 /* Forward declarations. */
219 static void
220 ixfr_rrstream_destroy(rrstream_t **sp);
221
222 static rrstream_methods_t ixfr_rrstream_methods;
223
224 /*
225 * Returns: anything dns_journal_open() or dns_journal_iter_init()
226 * may return.
227 */
228
229 static isc_result_t
ixfr_rrstream_create(isc_mem_t * mctx,const char * journal_filename,uint32_t begin_serial,uint32_t end_serial,size_t * sizep,rrstream_t ** sp)230 ixfr_rrstream_create(isc_mem_t *mctx, const char *journal_filename,
231 uint32_t begin_serial, uint32_t end_serial, size_t *sizep,
232 rrstream_t **sp) {
233 isc_result_t result;
234 ixfr_rrstream_t *s = NULL;
235
236 INSIST(sp != NULL && *sp == NULL);
237
238 s = isc_mem_get(mctx, sizeof(*s));
239 s->common.mctx = NULL;
240 isc_mem_attach(mctx, &s->common.mctx);
241 s->common.methods = &ixfr_rrstream_methods;
242 s->journal = NULL;
243
244 CHECK(dns_journal_open(mctx, journal_filename, DNS_JOURNAL_READ,
245 &s->journal));
246 CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial,
247 sizep));
248
249 *sp = (rrstream_t *)s;
250 return (ISC_R_SUCCESS);
251
252 failure:
253 ixfr_rrstream_destroy((rrstream_t **)(void *)&s);
254 return (result);
255 }
256
257 static isc_result_t
ixfr_rrstream_first(rrstream_t * rs)258 ixfr_rrstream_first(rrstream_t *rs) {
259 ixfr_rrstream_t *s = (ixfr_rrstream_t *)rs;
260 return (dns_journal_first_rr(s->journal));
261 }
262
263 static isc_result_t
ixfr_rrstream_next(rrstream_t * rs)264 ixfr_rrstream_next(rrstream_t *rs) {
265 ixfr_rrstream_t *s = (ixfr_rrstream_t *)rs;
266 return (dns_journal_next_rr(s->journal));
267 }
268
269 static void
ixfr_rrstream_current(rrstream_t * rs,dns_name_t ** name,uint32_t * ttl,dns_rdata_t ** rdata)270 ixfr_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
271 dns_rdata_t **rdata) {
272 ixfr_rrstream_t *s = (ixfr_rrstream_t *)rs;
273 dns_journal_current_rr(s->journal, name, ttl, rdata);
274 }
275
276 static void
ixfr_rrstream_destroy(rrstream_t ** rsp)277 ixfr_rrstream_destroy(rrstream_t **rsp) {
278 ixfr_rrstream_t *s = (ixfr_rrstream_t *)*rsp;
279 if (s->journal != NULL) {
280 dns_journal_destroy(&s->journal);
281 }
282 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
283 }
284
285 static rrstream_methods_t ixfr_rrstream_methods = {
286 ixfr_rrstream_first, ixfr_rrstream_next, ixfr_rrstream_current,
287 rrstream_noop_pause, ixfr_rrstream_destroy
288 };
289
290 /**************************************************************************/
291 /*
292 * An 'axfr_rrstream_t' is an 'rrstream_t' that returns
293 * an AXFR-like RR stream from a database.
294 *
295 * The SOAs at the beginning and end of the transfer are
296 * not included in the stream.
297 */
298
299 typedef struct axfr_rrstream {
300 rrstream_t common;
301 dns_rriterator_t it;
302 bool it_valid;
303 } axfr_rrstream_t;
304
305 /*
306 * Forward declarations.
307 */
308 static void
309 axfr_rrstream_destroy(rrstream_t **rsp);
310
311 static rrstream_methods_t axfr_rrstream_methods;
312
313 static isc_result_t
axfr_rrstream_create(isc_mem_t * mctx,dns_db_t * db,dns_dbversion_t * ver,rrstream_t ** sp)314 axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
315 rrstream_t **sp) {
316 axfr_rrstream_t *s;
317 isc_result_t result;
318
319 INSIST(sp != NULL && *sp == NULL);
320
321 s = isc_mem_get(mctx, sizeof(*s));
322 s->common.mctx = NULL;
323 isc_mem_attach(mctx, &s->common.mctx);
324 s->common.methods = &axfr_rrstream_methods;
325 s->it_valid = false;
326
327 CHECK(dns_rriterator_init(&s->it, db, ver, 0));
328 s->it_valid = true;
329
330 *sp = (rrstream_t *)s;
331 return (ISC_R_SUCCESS);
332
333 failure:
334 axfr_rrstream_destroy((rrstream_t **)(void *)&s);
335 return (result);
336 }
337
338 static isc_result_t
axfr_rrstream_first(rrstream_t * rs)339 axfr_rrstream_first(rrstream_t *rs) {
340 axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
341 isc_result_t result;
342 result = dns_rriterator_first(&s->it);
343 if (result != ISC_R_SUCCESS) {
344 return (result);
345 }
346 /* Skip SOA records. */
347 for (;;) {
348 dns_name_t *name_dummy = NULL;
349 uint32_t ttl_dummy;
350 dns_rdata_t *rdata = NULL;
351 dns_rriterator_current(&s->it, &name_dummy, &ttl_dummy, NULL,
352 &rdata);
353 if (rdata->type != dns_rdatatype_soa) {
354 break;
355 }
356 result = dns_rriterator_next(&s->it);
357 if (result != ISC_R_SUCCESS) {
358 break;
359 }
360 }
361 return (result);
362 }
363
364 static isc_result_t
axfr_rrstream_next(rrstream_t * rs)365 axfr_rrstream_next(rrstream_t *rs) {
366 axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
367 isc_result_t result;
368
369 /* Skip SOA records. */
370 for (;;) {
371 dns_name_t *name_dummy = NULL;
372 uint32_t ttl_dummy;
373 dns_rdata_t *rdata = NULL;
374 result = dns_rriterator_next(&s->it);
375 if (result != ISC_R_SUCCESS) {
376 break;
377 }
378 dns_rriterator_current(&s->it, &name_dummy, &ttl_dummy, NULL,
379 &rdata);
380 if (rdata->type != dns_rdatatype_soa) {
381 break;
382 }
383 }
384 return (result);
385 }
386
387 static void
axfr_rrstream_current(rrstream_t * rs,dns_name_t ** name,uint32_t * ttl,dns_rdata_t ** rdata)388 axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
389 dns_rdata_t **rdata) {
390 axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
391 dns_rriterator_current(&s->it, name, ttl, NULL, rdata);
392 }
393
394 static void
axfr_rrstream_pause(rrstream_t * rs)395 axfr_rrstream_pause(rrstream_t *rs) {
396 axfr_rrstream_t *s = (axfr_rrstream_t *)rs;
397 dns_rriterator_pause(&s->it);
398 }
399
400 static void
axfr_rrstream_destroy(rrstream_t ** rsp)401 axfr_rrstream_destroy(rrstream_t **rsp) {
402 axfr_rrstream_t *s = (axfr_rrstream_t *)*rsp;
403 if (s->it_valid) {
404 dns_rriterator_destroy(&s->it);
405 }
406 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
407 }
408
409 static rrstream_methods_t axfr_rrstream_methods = {
410 axfr_rrstream_first, axfr_rrstream_next, axfr_rrstream_current,
411 axfr_rrstream_pause, axfr_rrstream_destroy
412 };
413
414 /**************************************************************************/
415 /*
416 * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns
417 * a single SOA record.
418 */
419
420 typedef struct soa_rrstream {
421 rrstream_t common;
422 dns_difftuple_t *soa_tuple;
423 } soa_rrstream_t;
424
425 /*
426 * Forward declarations.
427 */
428 static void
429 soa_rrstream_destroy(rrstream_t **rsp);
430
431 static rrstream_methods_t soa_rrstream_methods;
432
433 static isc_result_t
soa_rrstream_create(isc_mem_t * mctx,dns_db_t * db,dns_dbversion_t * ver,rrstream_t ** sp)434 soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
435 rrstream_t **sp) {
436 soa_rrstream_t *s;
437 isc_result_t result;
438
439 INSIST(sp != NULL && *sp == NULL);
440
441 s = isc_mem_get(mctx, sizeof(*s));
442 s->common.mctx = NULL;
443 isc_mem_attach(mctx, &s->common.mctx);
444 s->common.methods = &soa_rrstream_methods;
445 s->soa_tuple = NULL;
446
447 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
448 &s->soa_tuple));
449
450 *sp = (rrstream_t *)s;
451 return (ISC_R_SUCCESS);
452
453 failure:
454 soa_rrstream_destroy((rrstream_t **)(void *)&s);
455 return (result);
456 }
457
458 static isc_result_t
soa_rrstream_first(rrstream_t * rs)459 soa_rrstream_first(rrstream_t *rs) {
460 UNUSED(rs);
461 return (ISC_R_SUCCESS);
462 }
463
464 static isc_result_t
soa_rrstream_next(rrstream_t * rs)465 soa_rrstream_next(rrstream_t *rs) {
466 UNUSED(rs);
467 return (ISC_R_NOMORE);
468 }
469
470 static void
soa_rrstream_current(rrstream_t * rs,dns_name_t ** name,uint32_t * ttl,dns_rdata_t ** rdata)471 soa_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
472 dns_rdata_t **rdata) {
473 soa_rrstream_t *s = (soa_rrstream_t *)rs;
474 *name = &s->soa_tuple->name;
475 *ttl = s->soa_tuple->ttl;
476 *rdata = &s->soa_tuple->rdata;
477 }
478
479 static void
soa_rrstream_destroy(rrstream_t ** rsp)480 soa_rrstream_destroy(rrstream_t **rsp) {
481 soa_rrstream_t *s = (soa_rrstream_t *)*rsp;
482 if (s->soa_tuple != NULL) {
483 dns_difftuple_free(&s->soa_tuple);
484 }
485 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
486 }
487
488 static rrstream_methods_t soa_rrstream_methods = {
489 soa_rrstream_first, soa_rrstream_next, soa_rrstream_current,
490 rrstream_noop_pause, soa_rrstream_destroy
491 };
492
493 /**************************************************************************/
494 /*
495 * A 'compound_rrstream_t' objects owns a soa_rrstream
496 * and another rrstream, the "data stream". It returns
497 * a concatenated stream consisting of the soa_rrstream, then
498 * the data stream, then the soa_rrstream again.
499 *
500 * The component streams are owned by the compound_rrstream_t
501 * and are destroyed with it.
502 */
503
504 typedef struct compound_rrstream {
505 rrstream_t common;
506 rrstream_t *components[3];
507 int state;
508 isc_result_t result;
509 } compound_rrstream_t;
510
511 /*
512 * Forward declarations.
513 */
514 static void
515 compound_rrstream_destroy(rrstream_t **rsp);
516
517 static isc_result_t
518 compound_rrstream_next(rrstream_t *rs);
519
520 static rrstream_methods_t compound_rrstream_methods;
521
522 /*
523 * Requires:
524 * soa_stream != NULL && *soa_stream != NULL
525 * data_stream != NULL && *data_stream != NULL
526 * sp != NULL && *sp == NULL
527 *
528 * Ensures:
529 * *soa_stream == NULL
530 * *data_stream == NULL
531 * *sp points to a valid compound_rrstream_t
532 * The soa and data streams will be destroyed
533 * when the compound_rrstream_t is destroyed.
534 */
535 static isc_result_t
compound_rrstream_create(isc_mem_t * mctx,rrstream_t ** soa_stream,rrstream_t ** data_stream,rrstream_t ** sp)536 compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream,
537 rrstream_t **data_stream, rrstream_t **sp) {
538 compound_rrstream_t *s;
539
540 INSIST(sp != NULL && *sp == NULL);
541
542 s = isc_mem_get(mctx, sizeof(*s));
543 s->common.mctx = NULL;
544 isc_mem_attach(mctx, &s->common.mctx);
545 s->common.methods = &compound_rrstream_methods;
546 s->components[0] = *soa_stream;
547 s->components[1] = *data_stream;
548 s->components[2] = *soa_stream;
549 s->state = -1;
550 s->result = ISC_R_FAILURE;
551
552 *data_stream = NULL;
553 *soa_stream = NULL;
554 *sp = (rrstream_t *)s;
555 return (ISC_R_SUCCESS);
556 }
557
558 static isc_result_t
compound_rrstream_first(rrstream_t * rs)559 compound_rrstream_first(rrstream_t *rs) {
560 compound_rrstream_t *s = (compound_rrstream_t *)rs;
561 s->state = 0;
562 do {
563 rrstream_t *curstream = s->components[s->state];
564 s->result = curstream->methods->first(curstream);
565 } while (s->result == ISC_R_NOMORE && s->state < 2);
566 return (s->result);
567 }
568
569 static isc_result_t
compound_rrstream_next(rrstream_t * rs)570 compound_rrstream_next(rrstream_t *rs) {
571 compound_rrstream_t *s = (compound_rrstream_t *)rs;
572 rrstream_t *curstream = s->components[s->state];
573 s->result = curstream->methods->next(curstream);
574 while (s->result == ISC_R_NOMORE) {
575 /*
576 * Make sure locks held by the current stream
577 * are released before we switch streams.
578 */
579 curstream->methods->pause(curstream);
580 if (s->state == 2) {
581 return (ISC_R_NOMORE);
582 }
583 s->state++;
584 curstream = s->components[s->state];
585 s->result = curstream->methods->first(curstream);
586 }
587 return (s->result);
588 }
589
590 static void
compound_rrstream_current(rrstream_t * rs,dns_name_t ** name,uint32_t * ttl,dns_rdata_t ** rdata)591 compound_rrstream_current(rrstream_t *rs, dns_name_t **name, uint32_t *ttl,
592 dns_rdata_t **rdata) {
593 compound_rrstream_t *s = (compound_rrstream_t *)rs;
594 rrstream_t *curstream;
595 INSIST(0 <= s->state && s->state < 3);
596 INSIST(s->result == ISC_R_SUCCESS);
597 curstream = s->components[s->state];
598 curstream->methods->current(curstream, name, ttl, rdata);
599 }
600
601 static void
compound_rrstream_pause(rrstream_t * rs)602 compound_rrstream_pause(rrstream_t *rs) {
603 compound_rrstream_t *s = (compound_rrstream_t *)rs;
604 rrstream_t *curstream;
605 INSIST(0 <= s->state && s->state < 3);
606 curstream = s->components[s->state];
607 curstream->methods->pause(curstream);
608 }
609
610 static void
compound_rrstream_destroy(rrstream_t ** rsp)611 compound_rrstream_destroy(rrstream_t **rsp) {
612 compound_rrstream_t *s = (compound_rrstream_t *)*rsp;
613 s->components[0]->methods->destroy(&s->components[0]);
614 s->components[1]->methods->destroy(&s->components[1]);
615 s->components[2] = NULL; /* Copy of components[0]. */
616 isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
617 }
618
619 static rrstream_methods_t compound_rrstream_methods = {
620 compound_rrstream_first, compound_rrstream_next,
621 compound_rrstream_current, compound_rrstream_pause,
622 compound_rrstream_destroy
623 };
624
625 /**************************************************************************/
626
627 /*%
628 * Structure holding outgoing transfer statistics
629 */
630 struct xfr_stats {
631 uint64_t nmsg; /*%< Number of messages sent */
632 uint64_t nrecs; /*%< Number of records sent */
633 uint64_t nbytes; /*%< Number of bytes sent */
634 isc_time_t start; /*%< Start time of the transfer */
635 isc_time_t end; /*%< End time of the transfer */
636 };
637
638 /*%
639 * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR
640 * in progress.
641 */
642 typedef struct {
643 isc_mem_t *mctx;
644 ns_client_t *client;
645 unsigned int id; /* ID of request */
646 dns_name_t *qname; /* Question name of request */
647 dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */
648 dns_rdataclass_t qclass;
649 dns_zone_t *zone; /* (necessary for stats) */
650 dns_db_t *db;
651 dns_dbversion_t *ver;
652 isc_quota_t *quota;
653 rrstream_t *stream; /* The XFR RR stream */
654 bool question_added; /* QUESTION section sent? */
655 bool end_of_stream; /* EOS has been reached */
656 isc_buffer_t buf; /* Buffer for message owner
657 * names and rdatas */
658 isc_buffer_t txbuf; /* Transmit message buffer */
659 size_t cbytes; /* Length of current message */
660 void *txmem;
661 unsigned int txmemlen;
662 dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
663 isc_buffer_t *lasttsig; /* the last TSIG */
664 bool verified_tsig; /* verified request MAC */
665 bool many_answers;
666 int sends; /* Send in progress */
667 bool shuttingdown;
668 bool poll;
669 const char *mnemonic; /* Style of transfer */
670 uint32_t end_serial; /* Serial number after XFR is done */
671 struct xfr_stats stats; /*%< Transfer statistics */
672
673 /* Timeouts */
674 uint64_t maxtime; /*%< Maximum XFR timeout (in ms) */
675 isc_nm_timer_t *maxtime_timer;
676
677 uint64_t idletime; /*%< XFR idle timeout (in ms) */
678 } xfrout_ctx_t;
679
680 static void
681 xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
682 dns_name_t *qname, dns_rdatatype_t qtype,
683 dns_rdataclass_t qclass, dns_zone_t *zone, dns_db_t *db,
684 dns_dbversion_t *ver, isc_quota_t *quota, rrstream_t *stream,
685 dns_tsigkey_t *tsigkey, isc_buffer_t *lasttsig,
686 bool verified_tsig, unsigned int maxtime,
687 unsigned int idletime, bool many_answers,
688 xfrout_ctx_t **xfrp);
689
690 static void
691 sendstream(xfrout_ctx_t *xfr);
692
693 static void
694 xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg);
695
696 static void
697 xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg);
698
699 static void
700 xfrout_maybe_destroy(xfrout_ctx_t *xfr);
701
702 static void
703 xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
704
705 static void
706 xfrout_client_timeout(void *arg, isc_result_t result);
707
708 static void
709 xfrout_log1(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
710 int level, const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
711
712 static void
713 xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...)
714 ISC_FORMAT_PRINTF(3, 4);
715
716 /**************************************************************************/
717
718 void
ns_xfr_start(ns_client_t * client,dns_rdatatype_t reqtype)719 ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
720 isc_result_t result;
721 dns_name_t *question_name;
722 dns_rdataset_t *question_rdataset;
723 dns_zone_t *zone = NULL, *raw = NULL, *mayberaw;
724 dns_db_t *db = NULL;
725 dns_dbversion_t *ver = NULL;
726 dns_rdataclass_t question_class;
727 rrstream_t *soa_stream = NULL;
728 rrstream_t *data_stream = NULL;
729 rrstream_t *stream = NULL;
730 dns_difftuple_t *current_soa_tuple = NULL;
731 dns_name_t *soa_name;
732 dns_rdataset_t *soa_rdataset;
733 dns_rdata_t soa_rdata = DNS_RDATA_INIT;
734 bool have_soa = false;
735 const char *mnemonic = NULL;
736 isc_mem_t *mctx = client->mctx;
737 dns_message_t *request = client->message;
738 xfrout_ctx_t *xfr = NULL;
739 isc_quota_t *quota = NULL;
740 dns_transfer_format_t format = client->view->transfer_format;
741 isc_netaddr_t na;
742 dns_peer_t *peer = NULL;
743 isc_buffer_t *tsigbuf = NULL;
744 char *journalfile;
745 char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")];
746 char keyname[DNS_NAME_FORMATSIZE];
747 bool is_poll = false;
748 bool is_dlz = false;
749 bool is_ixfr = false;
750 bool useviewacl = false;
751 uint32_t begin_serial = 0, current_serial;
752
753 switch (reqtype) {
754 case dns_rdatatype_axfr:
755 mnemonic = "AXFR";
756 break;
757 case dns_rdatatype_ixfr:
758 mnemonic = "IXFR";
759 break;
760 default:
761 INSIST(0);
762 ISC_UNREACHABLE();
763 }
764
765 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT,
766 ISC_LOG_DEBUG(6), "%s request", mnemonic);
767 /*
768 * Apply quota.
769 */
770 result = isc_quota_attach(&client->sctx->xfroutquota, "a);
771 if (result != ISC_R_SUCCESS) {
772 isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING,
773 "%s request denied: %s", mnemonic,
774 isc_result_totext(result));
775 goto failure;
776 }
777
778 /*
779 * Interpret the question section.
780 */
781 result = dns_message_firstname(request, DNS_SECTION_QUESTION);
782 INSIST(result == ISC_R_SUCCESS);
783
784 /*
785 * The question section must contain exactly one question, and
786 * it must be for AXFR/IXFR as appropriate.
787 */
788 question_name = NULL;
789 dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name);
790 question_rdataset = ISC_LIST_HEAD(question_name->list);
791 question_class = question_rdataset->rdclass;
792 INSIST(question_rdataset->type == reqtype);
793 if (ISC_LIST_NEXT(question_rdataset, link) != NULL) {
794 FAILC(DNS_R_FORMERR, "multiple questions");
795 }
796 result = dns_message_nextname(request, DNS_SECTION_QUESTION);
797 if (result != ISC_R_NOMORE) {
798 FAILC(DNS_R_FORMERR, "multiple questions");
799 }
800
801 result = dns_zt_find(client->view->zonetable, question_name, 0, NULL,
802 &zone);
803
804 if (result != ISC_R_SUCCESS || dns_zone_gettype(zone) == dns_zone_dlz) {
805 /*
806 * The normal zone table does not have a match, or this is
807 * marked in the zone table as a DLZ zone. Check the DLZ
808 * databases for a match.
809 */
810 if (!ISC_LIST_EMPTY(client->view->dlz_searched)) {
811 result = dns_dlzallowzonexfr(client->view,
812 question_name,
813 &client->peeraddr, &db);
814 if (result == ISC_R_DEFAULT) {
815 useviewacl = true;
816 result = ISC_R_SUCCESS;
817 }
818 if (result == ISC_R_NOPERM) {
819 char _buf1[DNS_NAME_FORMATSIZE];
820 char _buf2[DNS_RDATACLASS_FORMATSIZE];
821
822 result = DNS_R_REFUSED;
823 dns_name_format(question_name, _buf1,
824 sizeof(_buf1));
825 dns_rdataclass_format(question_class, _buf2,
826 sizeof(_buf2));
827 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
828 NS_LOGMODULE_XFER_OUT,
829 ISC_LOG_ERROR,
830 "zone transfer '%s/%s' denied",
831 _buf1, _buf2);
832 goto failure;
833 }
834 if (result != ISC_R_SUCCESS) {
835 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
836 question_name, question_class);
837 }
838 is_dlz = true;
839 } else {
840 /*
841 * not DLZ and not in normal zone table, we are
842 * not authoritative
843 */
844 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
845 question_name, question_class);
846 }
847 } else {
848 /* zone table has a match */
849 switch (dns_zone_gettype(zone)) {
850 /*
851 * Master, slave, and mirror zones are OK for transfer.
852 */
853 case dns_zone_primary:
854 case dns_zone_secondary:
855 case dns_zone_mirror:
856 case dns_zone_dlz:
857 break;
858 default:
859 FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
860 question_name, question_class);
861 }
862 CHECK(dns_zone_getdb(zone, &db));
863 dns_db_currentversion(db, &ver);
864 }
865
866 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6),
867 "%s question section OK", mnemonic);
868
869 /*
870 * Check the authority section. Look for a SOA record with
871 * the same name and class as the question.
872 */
873 for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY);
874 result == ISC_R_SUCCESS;
875 result = dns_message_nextname(request, DNS_SECTION_AUTHORITY))
876 {
877 soa_name = NULL;
878 dns_message_currentname(request, DNS_SECTION_AUTHORITY,
879 &soa_name);
880
881 /*
882 * Ignore data whose owner name is not the zone apex.
883 */
884 if (!dns_name_equal(soa_name, question_name)) {
885 continue;
886 }
887
888 for (soa_rdataset = ISC_LIST_HEAD(soa_name->list);
889 soa_rdataset != NULL;
890 soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link))
891 {
892 /*
893 * Ignore non-SOA data.
894 */
895 if (soa_rdataset->type != dns_rdatatype_soa) {
896 continue;
897 }
898 if (soa_rdataset->rdclass != question_class) {
899 continue;
900 }
901
902 CHECK(dns_rdataset_first(soa_rdataset));
903 dns_rdataset_current(soa_rdataset, &soa_rdata);
904 result = dns_rdataset_next(soa_rdataset);
905 if (result == ISC_R_SUCCESS) {
906 FAILC(DNS_R_FORMERR, "IXFR authority section "
907 "has multiple SOAs");
908 }
909 have_soa = true;
910 goto got_soa;
911 }
912 }
913 got_soa:
914 if (result != ISC_R_NOMORE) {
915 CHECK(result);
916 }
917
918 xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6),
919 "%s authority section OK", mnemonic);
920
921 /*
922 * If not a DLZ zone or we are falling back to the view's transfer
923 * ACL, decide whether to allow this transfer.
924 */
925 if (!is_dlz || useviewacl) {
926 dns_acl_t *acl;
927
928 ns_client_aclmsg("zone transfer", question_name, reqtype,
929 client->view->rdclass, msg, sizeof(msg));
930 if (useviewacl) {
931 acl = client->view->transferacl;
932 } else {
933 acl = dns_zone_getxfracl(zone);
934 }
935 CHECK(ns_client_checkacl(client, NULL, msg, acl, true,
936 ISC_LOG_ERROR));
937 }
938
939 /*
940 * AXFR over UDP is not possible.
941 */
942 if (reqtype == dns_rdatatype_axfr &&
943 (client->attributes & NS_CLIENTATTR_TCP) == 0)
944 {
945 FAILC(DNS_R_FORMERR, "attempted AXFR over UDP");
946 }
947
948 /*
949 * Look up the requesting server in the peer table.
950 */
951 isc_netaddr_fromsockaddr(&na, &client->peeraddr);
952 (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer);
953
954 /*
955 * Decide on the transfer format (one-answer or many-answers).
956 */
957 if (peer != NULL) {
958 (void)dns_peer_gettransferformat(peer, &format);
959 }
960
961 /*
962 * Get a dynamically allocated copy of the current SOA.
963 */
964 if (is_dlz) {
965 dns_db_currentversion(db, &ver);
966 }
967
968 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
969 ¤t_soa_tuple));
970
971 current_serial = dns_soa_getserial(¤t_soa_tuple->rdata);
972 if (reqtype == dns_rdatatype_ixfr) {
973 size_t jsize;
974 uint64_t dbsize;
975
976 /*
977 * Outgoing IXFR may have been disabled for this peer
978 * or globally.
979 */
980 if ((client->attributes & NS_CLIENTATTR_TCP) != 0) {
981 bool provide_ixfr;
982
983 provide_ixfr = client->view->provideixfr;
984 if (peer != NULL) {
985 (void)dns_peer_getprovideixfr(peer,
986 &provide_ixfr);
987 }
988 if (provide_ixfr == false) {
989 goto axfr_fallback;
990 }
991 }
992
993 if (!have_soa) {
994 FAILC(DNS_R_FORMERR, "IXFR request missing SOA");
995 }
996
997 begin_serial = dns_soa_getserial(&soa_rdata);
998
999 /*
1000 * RFC1995 says "If an IXFR query with the same or
1001 * newer version number than that of the server
1002 * is received, it is replied to with a single SOA
1003 * record of the server's current version, just as
1004 * in AXFR". The claim about AXFR is incorrect,
1005 * but other than that, we do as the RFC says.
1006 *
1007 * Sending a single SOA record is also how we refuse
1008 * IXFR over UDP (currently, we always do).
1009 */
1010 if (DNS_SERIAL_GE(begin_serial, current_serial) ||
1011 (client->attributes & NS_CLIENTATTR_TCP) == 0)
1012 {
1013 CHECK(soa_rrstream_create(mctx, db, ver, &stream));
1014 is_poll = true;
1015 goto have_stream;
1016 }
1017
1018 /*
1019 * Outgoing IXFR may have been disabled for this peer
1020 * or globally.
1021 */
1022 if ((client->attributes & NS_CLIENTATTR_TCP) != 0) {
1023 bool provide_ixfr;
1024
1025 provide_ixfr = client->view->provideixfr;
1026 if (peer != NULL) {
1027 (void)dns_peer_getprovideixfr(peer,
1028 &provide_ixfr);
1029 }
1030 if (!provide_ixfr) {
1031 xfrout_log1(client, question_name,
1032 question_class, ISC_LOG_DEBUG(4),
1033 "IXFR delta response disabled due "
1034 "to 'provide-ixfr no;' being set");
1035 mnemonic = "AXFR-style IXFR";
1036 goto axfr_fallback;
1037 }
1038 }
1039
1040 journalfile = is_dlz ? NULL : dns_zone_getjournal(zone);
1041 if (journalfile != NULL) {
1042 result = ixfr_rrstream_create(
1043 mctx, journalfile, begin_serial, current_serial,
1044 &jsize, &data_stream);
1045 } else {
1046 result = ISC_R_NOTFOUND;
1047 }
1048 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
1049 xfrout_log1(client, question_name, question_class,
1050 ISC_LOG_DEBUG(4),
1051 "IXFR version not in journal, "
1052 "falling back to AXFR");
1053 mnemonic = "AXFR-style IXFR";
1054 goto axfr_fallback;
1055 }
1056 CHECK(result);
1057
1058 result = dns_db_getsize(db, ver, NULL, &dbsize);
1059 if (result == ISC_R_SUCCESS) {
1060 uint32_t ratio = dns_zone_getixfrratio(zone);
1061 if (ratio != 0 && ((100 * jsize) / dbsize) > ratio) {
1062 data_stream->methods->destroy(&data_stream);
1063 data_stream = NULL;
1064 xfrout_log1(client, question_name,
1065 question_class, ISC_LOG_DEBUG(4),
1066 "IXFR delta size (%zu bytes) "
1067 "exceeds the maximum ratio to "
1068 "database size "
1069 "(%" PRIu64 " bytes), "
1070 "falling back to AXFR",
1071 jsize, dbsize);
1072 mnemonic = "AXFR-style IXFR";
1073 goto axfr_fallback;
1074 } else {
1075 xfrout_log1(client, question_name,
1076 question_class, ISC_LOG_DEBUG(4),
1077 "IXFR delta size (%zu bytes); "
1078 "database size "
1079 "(%" PRIu64 " bytes)",
1080 jsize, dbsize);
1081 }
1082 }
1083 is_ixfr = true;
1084 } else {
1085 axfr_fallback:
1086 CHECK(axfr_rrstream_create(mctx, db, ver, &data_stream));
1087 }
1088
1089 /*
1090 * Bracket the data stream with SOAs.
1091 */
1092 CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream));
1093 CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream,
1094 &stream));
1095 soa_stream = NULL;
1096 data_stream = NULL;
1097
1098 have_stream:
1099 CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf));
1100 /*
1101 * Create the xfrout context object. This transfers the ownership
1102 * of "stream", "db", "ver", and "quota" to the xfrout context object.
1103 */
1104
1105 if (is_dlz) {
1106 xfrout_ctx_create(mctx, client, request->id, question_name,
1107 reqtype, question_class, zone, db, ver, quota,
1108 stream, dns_message_gettsigkey(request),
1109 tsigbuf, request->verified_sig, 3600, 3600,
1110 (format == dns_many_answers) ? true : false,
1111 &xfr);
1112 } else {
1113 xfrout_ctx_create(
1114 mctx, client, request->id, question_name, reqtype,
1115 question_class, zone, db, ver, quota, stream,
1116 dns_message_gettsigkey(request), tsigbuf,
1117 request->verified_sig, dns_zone_getmaxxfrout(zone),
1118 dns_zone_getidleout(zone),
1119 (format == dns_many_answers) ? true : false, &xfr);
1120 }
1121
1122 xfr->end_serial = current_serial;
1123 xfr->mnemonic = mnemonic;
1124 stream = NULL;
1125 quota = NULL;
1126
1127 CHECK(xfr->stream->methods->first(xfr->stream));
1128
1129 if (xfr->tsigkey != NULL) {
1130 dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname));
1131 } else {
1132 keyname[0] = '\0';
1133 }
1134 xfr->poll = is_poll;
1135 if (is_poll) {
1136 xfr->mnemonic = "IXFR poll response";
1137 xfrout_log1(client, question_name, question_class,
1138 ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s",
1139 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname);
1140 } else if (is_ixfr) {
1141 xfrout_log1(client, question_name, question_class, ISC_LOG_INFO,
1142 "%s started%s%s (serial %u -> %u)", mnemonic,
1143 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname,
1144 begin_serial, current_serial);
1145 } else {
1146 xfrout_log1(client, question_name, question_class, ISC_LOG_INFO,
1147 "%s started%s%s (serial %u)", mnemonic,
1148 (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname,
1149 current_serial);
1150 }
1151
1152 if (zone != NULL) {
1153 dns_zone_getraw(zone, &raw);
1154 mayberaw = (raw != NULL) ? raw : zone;
1155 if ((client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 &&
1156 (dns_zone_gettype(mayberaw) == dns_zone_secondary ||
1157 dns_zone_gettype(mayberaw) == dns_zone_mirror))
1158 {
1159 isc_time_t expiretime;
1160 uint32_t secs;
1161 dns_zone_getexpiretime(zone, &expiretime);
1162 secs = isc_time_seconds(&expiretime);
1163 if (secs >= client->now && result == ISC_R_SUCCESS) {
1164 client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
1165 client->expire = secs - client->now;
1166 }
1167 }
1168 if (raw != NULL) {
1169 dns_zone_detach(&raw);
1170 }
1171 }
1172
1173 /* Start the timers */
1174 if (xfr->maxtime > 0) {
1175 xfrout_log(xfr, ISC_LOG_ERROR,
1176 "starting maxtime timer %" PRIu64 " ms",
1177 xfr->maxtime);
1178 isc_nm_timer_start(xfr->maxtime_timer, xfr->maxtime);
1179 }
1180
1181 /*
1182 * Hand the context over to sendstream(). Set xfr to NULL;
1183 * sendstream() is responsible for either passing the
1184 * context on to a later event handler or destroying it.
1185 */
1186 sendstream(xfr);
1187 xfr = NULL;
1188
1189 result = ISC_R_SUCCESS;
1190
1191 failure:
1192 if (result == DNS_R_REFUSED) {
1193 inc_stats(client, zone, ns_statscounter_xfrrej);
1194 }
1195 if (quota != NULL) {
1196 isc_quota_detach("a);
1197 }
1198 if (current_soa_tuple != NULL) {
1199 dns_difftuple_free(¤t_soa_tuple);
1200 }
1201 if (stream != NULL) {
1202 stream->methods->destroy(&stream);
1203 }
1204 if (soa_stream != NULL) {
1205 soa_stream->methods->destroy(&soa_stream);
1206 }
1207 if (data_stream != NULL) {
1208 data_stream->methods->destroy(&data_stream);
1209 }
1210 if (ver != NULL) {
1211 dns_db_closeversion(db, &ver, false);
1212 }
1213 if (db != NULL) {
1214 dns_db_detach(&db);
1215 }
1216 if (zone != NULL) {
1217 dns_zone_detach(&zone);
1218 }
1219 /* XXX kludge */
1220 if (xfr != NULL) {
1221 xfrout_fail(xfr, result, "setting up zone transfer");
1222 } else if (result != ISC_R_SUCCESS) {
1223 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,
1224 NS_LOGMODULE_XFER_OUT, ISC_LOG_DEBUG(3),
1225 "zone transfer setup failed");
1226 ns_client_error(client, result);
1227 isc_nmhandle_detach(&client->reqhandle);
1228 }
1229 }
1230
1231 static void
xfrout_ctx_create(isc_mem_t * mctx,ns_client_t * client,unsigned int id,dns_name_t * qname,dns_rdatatype_t qtype,dns_rdataclass_t qclass,dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,isc_quota_t * quota,rrstream_t * stream,dns_tsigkey_t * tsigkey,isc_buffer_t * lasttsig,bool verified_tsig,unsigned int maxtime,unsigned int idletime,bool many_answers,xfrout_ctx_t ** xfrp)1232 xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
1233 dns_name_t *qname, dns_rdatatype_t qtype,
1234 dns_rdataclass_t qclass, dns_zone_t *zone, dns_db_t *db,
1235 dns_dbversion_t *ver, isc_quota_t *quota, rrstream_t *stream,
1236 dns_tsigkey_t *tsigkey, isc_buffer_t *lasttsig,
1237 bool verified_tsig, unsigned int maxtime,
1238 unsigned int idletime, bool many_answers,
1239 xfrout_ctx_t **xfrp) {
1240 xfrout_ctx_t *xfr = NULL;
1241 unsigned int len = NS_CLIENT_TCP_BUFFER_SIZE;
1242 void *mem = NULL;
1243
1244 REQUIRE(xfrp != NULL && *xfrp == NULL);
1245
1246 xfr = isc_mem_get(mctx, sizeof(*xfr));
1247 *xfr = (xfrout_ctx_t){
1248 .client = client,
1249 .id = id,
1250 .qname = qname,
1251 .qtype = qtype,
1252 .qclass = qclass,
1253 .maxtime = maxtime * 1000, /* in milliseconds */
1254 .idletime = idletime * 1000, /* In milliseconds */
1255 .tsigkey = tsigkey,
1256 .lasttsig = lasttsig,
1257 .verified_tsig = verified_tsig,
1258 .many_answers = many_answers,
1259 };
1260
1261 isc_mem_attach(mctx, &xfr->mctx);
1262
1263 if (zone != NULL) { /* zone will be NULL if it's DLZ */
1264 dns_zone_attach(zone, &xfr->zone);
1265 }
1266 dns_db_attach(db, &xfr->db);
1267 dns_db_attachversion(db, ver, &xfr->ver);
1268
1269 isc_time_now(&xfr->stats.start);
1270
1271 isc_nm_timer_create(xfr->client->handle, xfrout_client_timeout, xfr,
1272 &xfr->maxtime_timer);
1273
1274 /*
1275 * Allocate a temporary buffer for the uncompressed response
1276 * message data. The buffer size must be 65535 bytes
1277 * (NS_CLIENT_TCP_BUFFER_SIZE): small enough that compressed
1278 * data will fit in a single TCP message, and big enough to
1279 * hold a maximum-sized RR.
1280 *
1281 * Note that although 65535-byte RRs are allowed in principle, they
1282 * cannot be zone-transferred (at least not if uncompressible),
1283 * because the message and RR headers would push the size of the
1284 * TCP message over the 65536 byte limit.
1285 */
1286 mem = isc_mem_get(mctx, len);
1287 isc_buffer_init(&xfr->buf, mem, len);
1288
1289 /*
1290 * Allocate another temporary buffer for the compressed
1291 * response message.
1292 */
1293 mem = isc_mem_get(mctx, len);
1294 isc_buffer_init(&xfr->txbuf, (char *)mem, len);
1295 xfr->txmem = mem;
1296 xfr->txmemlen = len;
1297
1298 /*
1299 * These MUST be after the last "goto failure;" / CHECK to
1300 * prevent a double free by the caller.
1301 */
1302 xfr->quota = quota;
1303 xfr->stream = stream;
1304
1305 *xfrp = xfr;
1306 }
1307
1308 /*
1309 * Arrange to send as much as we can of "stream" without blocking.
1310 *
1311 * Requires:
1312 * The stream iterator is initialized and points at an RR,
1313 * or possibly at the end of the stream (that is, the
1314 * _first method of the iterator has been called).
1315 */
1316 static void
sendstream(xfrout_ctx_t * xfr)1317 sendstream(xfrout_ctx_t *xfr) {
1318 dns_message_t *tcpmsg = NULL;
1319 dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */
1320 isc_result_t result;
1321 dns_rdataset_t *qrdataset;
1322 dns_name_t *msgname = NULL;
1323 dns_rdata_t *msgrdata = NULL;
1324 dns_rdatalist_t *msgrdl = NULL;
1325 dns_rdataset_t *msgrds = NULL;
1326 dns_compress_t cctx;
1327 bool cleanup_cctx = false;
1328 bool is_tcp;
1329 int n_rrs;
1330
1331 isc_buffer_clear(&xfr->buf);
1332 isc_buffer_clear(&xfr->txbuf);
1333
1334 is_tcp = ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0);
1335 if (!is_tcp) {
1336 /*
1337 * In the UDP case, we put the response data directly into
1338 * the client message.
1339 */
1340 msg = xfr->client->message;
1341 CHECK(dns_message_reply(msg, true));
1342 } else {
1343 /*
1344 * TCP. Build a response dns_message_t, temporarily storing
1345 * the raw, uncompressed owner names and RR data contiguously
1346 * in xfr->buf. We know that if the uncompressed data fits
1347 * in xfr->buf, the compressed data will surely fit in a TCP
1348 * message.
1349 */
1350
1351 dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER,
1352 &tcpmsg);
1353 msg = tcpmsg;
1354
1355 msg->id = xfr->id;
1356 msg->rcode = dns_rcode_noerror;
1357 msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
1358 if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) {
1359 msg->flags |= DNS_MESSAGEFLAG_RA;
1360 }
1361 CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1362 CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1363 if (xfr->lasttsig != NULL) {
1364 isc_buffer_free(&xfr->lasttsig);
1365 }
1366 msg->verified_sig = xfr->verified_tsig;
1367
1368 /*
1369 * Add a EDNS option to the message?
1370 */
1371 if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
1372 dns_rdataset_t *opt = NULL;
1373
1374 CHECK(ns_client_addopt(xfr->client, msg, &opt));
1375 CHECK(dns_message_setopt(msg, opt));
1376 /*
1377 * Add to first message only.
1378 */
1379 xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID;
1380 xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE;
1381 }
1382
1383 /*
1384 * Account for reserved space.
1385 */
1386 if (xfr->tsigkey != NULL) {
1387 INSIST(msg->reserved != 0U);
1388 }
1389 isc_buffer_add(&xfr->buf, msg->reserved);
1390
1391 /*
1392 * Include a question section in the first message only.
1393 * BIND 8.2.1 will not recognize an IXFR if it does not
1394 * have a question section.
1395 */
1396 if (!xfr->question_added) {
1397 dns_name_t *qname = NULL;
1398 isc_region_t r;
1399
1400 /*
1401 * Reserve space for the 12-byte message header
1402 * and 4 bytes of question.
1403 */
1404 isc_buffer_add(&xfr->buf, 12 + 4);
1405
1406 qrdataset = NULL;
1407 result = dns_message_gettemprdataset(msg, &qrdataset);
1408 if (result != ISC_R_SUCCESS) {
1409 goto failure;
1410 }
1411 dns_rdataset_makequestion(qrdataset,
1412 xfr->client->message->rdclass,
1413 xfr->qtype);
1414
1415 result = dns_message_gettempname(msg, &qname);
1416 if (result != ISC_R_SUCCESS) {
1417 goto failure;
1418 }
1419 isc_buffer_availableregion(&xfr->buf, &r);
1420 INSIST(r.length >= xfr->qname->length);
1421 r.length = xfr->qname->length;
1422 isc_buffer_putmem(&xfr->buf, xfr->qname->ndata,
1423 xfr->qname->length);
1424 dns_name_fromregion(qname, &r);
1425 ISC_LIST_INIT(qname->list);
1426 ISC_LIST_APPEND(qname->list, qrdataset, link);
1427
1428 dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1429 xfr->question_added = true;
1430 } else {
1431 /*
1432 * Reserve space for the 12-byte message header
1433 */
1434 isc_buffer_add(&xfr->buf, 12);
1435 msg->tcp_continuation = 1;
1436 }
1437 }
1438
1439 /*
1440 * Try to fit in as many RRs as possible, unless "one-answer"
1441 * format has been requested.
1442 */
1443 for (n_rrs = 0;; n_rrs++) {
1444 dns_name_t *name = NULL;
1445 uint32_t ttl;
1446 dns_rdata_t *rdata = NULL;
1447
1448 unsigned int size;
1449 isc_region_t r;
1450
1451 msgname = NULL;
1452 msgrdata = NULL;
1453 msgrdl = NULL;
1454 msgrds = NULL;
1455
1456 xfr->stream->methods->current(xfr->stream, &name, &ttl, &rdata);
1457 size = name->length + 10 + rdata->length;
1458 isc_buffer_availableregion(&xfr->buf, &r);
1459 if (size >= r.length) {
1460 /*
1461 * RR would not fit. If there are other RRs in the
1462 * buffer, send them now and leave this RR to the
1463 * next message. If this RR overflows the buffer
1464 * all by itself, fail.
1465 *
1466 * In theory some RRs might fit in a TCP message
1467 * when compressed even if they do not fit when
1468 * uncompressed, but surely we don't want
1469 * to send such monstrosities to an unsuspecting
1470 * slave.
1471 */
1472 if (n_rrs == 0) {
1473 xfrout_log(xfr, ISC_LOG_WARNING,
1474 "RR too large for zone transfer "
1475 "(%d bytes)",
1476 size);
1477 /* XXX DNS_R_RRTOOLARGE? */
1478 result = ISC_R_NOSPACE;
1479 goto failure;
1480 }
1481 break;
1482 }
1483
1484 if (isc_log_wouldlog(ns_lctx, XFROUT_RR_LOGLEVEL)) {
1485 log_rr(name, rdata, ttl); /* XXX */
1486 }
1487
1488 result = dns_message_gettempname(msg, &msgname);
1489 if (result != ISC_R_SUCCESS) {
1490 goto failure;
1491 }
1492 isc_buffer_availableregion(&xfr->buf, &r);
1493 INSIST(r.length >= name->length);
1494 r.length = name->length;
1495 isc_buffer_putmem(&xfr->buf, name->ndata, name->length);
1496 dns_name_fromregion(msgname, &r);
1497
1498 /* Reserve space for RR header. */
1499 isc_buffer_add(&xfr->buf, 10);
1500
1501 result = dns_message_gettemprdata(msg, &msgrdata);
1502 if (result != ISC_R_SUCCESS) {
1503 goto failure;
1504 }
1505 isc_buffer_availableregion(&xfr->buf, &r);
1506 r.length = rdata->length;
1507 isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length);
1508 dns_rdata_init(msgrdata);
1509 dns_rdata_fromregion(msgrdata, rdata->rdclass, rdata->type, &r);
1510
1511 result = dns_message_gettemprdatalist(msg, &msgrdl);
1512 if (result != ISC_R_SUCCESS) {
1513 goto failure;
1514 }
1515 msgrdl->type = rdata->type;
1516 msgrdl->rdclass = rdata->rdclass;
1517 msgrdl->ttl = ttl;
1518 if (rdata->type == dns_rdatatype_sig ||
1519 rdata->type == dns_rdatatype_rrsig) {
1520 msgrdl->covers = dns_rdata_covers(rdata);
1521 } else {
1522 msgrdl->covers = dns_rdatatype_none;
1523 }
1524 ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link);
1525
1526 result = dns_message_gettemprdataset(msg, &msgrds);
1527 if (result != ISC_R_SUCCESS) {
1528 goto failure;
1529 }
1530 result = dns_rdatalist_tordataset(msgrdl, msgrds);
1531 INSIST(result == ISC_R_SUCCESS);
1532
1533 ISC_LIST_APPEND(msgname->list, msgrds, link);
1534
1535 dns_message_addname(msg, msgname, DNS_SECTION_ANSWER);
1536 msgname = NULL;
1537
1538 xfr->stats.nrecs++;
1539
1540 result = xfr->stream->methods->next(xfr->stream);
1541 if (result == ISC_R_NOMORE) {
1542 xfr->end_of_stream = true;
1543 break;
1544 }
1545 CHECK(result);
1546
1547 if (!xfr->many_answers) {
1548 break;
1549 }
1550 /*
1551 * At this stage, at least 1 RR has been rendered into
1552 * the message. Check if we want to clamp this message
1553 * here (TCP only).
1554 */
1555 if ((isc_buffer_usedlength(&xfr->buf) >=
1556 xfr->client->sctx->transfer_tcp_message_size) &&
1557 is_tcp)
1558 {
1559 break;
1560 }
1561 }
1562
1563 if (is_tcp) {
1564 isc_region_t used;
1565 CHECK(dns_compress_init(&cctx, -1, xfr->mctx));
1566 dns_compress_setsensitive(&cctx, true);
1567 cleanup_cctx = true;
1568 CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf));
1569 CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
1570 CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
1571 CHECK(dns_message_renderend(msg));
1572 dns_compress_invalidate(&cctx);
1573 cleanup_cctx = false;
1574
1575 isc_buffer_usedregion(&xfr->txbuf, &used);
1576
1577 xfrout_log(xfr, ISC_LOG_DEBUG(8),
1578 "sending TCP message of %d bytes", used.length);
1579
1580 isc_nmhandle_attach(xfr->client->handle,
1581 &xfr->client->sendhandle);
1582 if (xfr->idletime > 0) {
1583 isc_nmhandle_setwritetimeout(xfr->client->sendhandle,
1584 xfr->idletime);
1585 }
1586 isc_nm_send(xfr->client->sendhandle, &used, xfrout_senddone,
1587 xfr);
1588 xfr->sends++;
1589 xfr->cbytes = used.length;
1590 } else {
1591 xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
1592 ns_client_send(xfr->client);
1593 xfr->stream->methods->pause(xfr->stream);
1594 isc_nmhandle_detach(&xfr->client->reqhandle);
1595 xfrout_ctx_destroy(&xfr);
1596 return;
1597 }
1598
1599 /* Advance lasttsig to be the last TSIG generated */
1600 CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1601
1602 failure:
1603 if (msgname != NULL) {
1604 if (msgrds != NULL) {
1605 if (dns_rdataset_isassociated(msgrds)) {
1606 dns_rdataset_disassociate(msgrds);
1607 }
1608 dns_message_puttemprdataset(msg, &msgrds);
1609 }
1610 if (msgrdl != NULL) {
1611 ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link);
1612 dns_message_puttemprdatalist(msg, &msgrdl);
1613 }
1614 if (msgrdata != NULL) {
1615 dns_message_puttemprdata(msg, &msgrdata);
1616 }
1617 dns_message_puttempname(msg, &msgname);
1618 }
1619
1620 if (tcpmsg != NULL) {
1621 dns_message_detach(&tcpmsg);
1622 }
1623
1624 if (cleanup_cctx) {
1625 dns_compress_invalidate(&cctx);
1626 }
1627 /*
1628 * Make sure to release any locks held by database
1629 * iterators before returning from the event handler.
1630 */
1631 xfr->stream->methods->pause(xfr->stream);
1632
1633 if (result == ISC_R_SUCCESS) {
1634 return;
1635 }
1636
1637 if (xfr->client->sendhandle != NULL) {
1638 isc_nmhandle_detach(&xfr->client->sendhandle);
1639 }
1640
1641 xfrout_fail(xfr, result, "sending zone data");
1642 }
1643
1644 static void
xfrout_ctx_destroy(xfrout_ctx_t ** xfrp)1645 xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
1646 xfrout_ctx_t *xfr = *xfrp;
1647 *xfrp = NULL;
1648
1649 INSIST(xfr->sends == 0);
1650
1651 isc_nm_timer_stop(xfr->maxtime_timer);
1652 isc_nm_timer_detach(&xfr->maxtime_timer);
1653
1654 if (xfr->stream != NULL) {
1655 xfr->stream->methods->destroy(&xfr->stream);
1656 }
1657 if (xfr->buf.base != NULL) {
1658 isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length);
1659 }
1660 if (xfr->txmem != NULL) {
1661 isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen);
1662 }
1663 if (xfr->lasttsig != NULL) {
1664 isc_buffer_free(&xfr->lasttsig);
1665 }
1666 if (xfr->quota != NULL) {
1667 isc_quota_detach(&xfr->quota);
1668 }
1669 if (xfr->ver != NULL) {
1670 dns_db_closeversion(xfr->db, &xfr->ver, false);
1671 }
1672 if (xfr->zone != NULL) {
1673 dns_zone_detach(&xfr->zone);
1674 }
1675 if (xfr->db != NULL) {
1676 dns_db_detach(&xfr->db);
1677 }
1678
1679 isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1680 }
1681
1682 static void
xfrout_senddone(isc_nmhandle_t * handle,isc_result_t result,void * arg)1683 xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
1684 xfrout_ctx_t *xfr = (xfrout_ctx_t *)arg;
1685
1686 REQUIRE((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0);
1687
1688 INSIST(handle == xfr->client->handle);
1689
1690 xfr->sends--;
1691 INSIST(xfr->sends == 0);
1692
1693 isc_nmhandle_detach(&xfr->client->sendhandle);
1694
1695 /*
1696 * Update transfer statistics if sending succeeded, accounting for the
1697 * two-byte TCP length prefix included in the number of bytes sent.
1698 */
1699 if (result == ISC_R_SUCCESS) {
1700 xfr->stats.nmsg++;
1701 xfr->stats.nbytes += xfr->cbytes;
1702 }
1703
1704 if (xfr->shuttingdown) {
1705 xfrout_maybe_destroy(xfr);
1706 } else if (result != ISC_R_SUCCESS) {
1707 xfrout_fail(xfr, result, "send");
1708 } else if (!xfr->end_of_stream) {
1709 sendstream(xfr);
1710 } else {
1711 /* End of zone transfer stream. */
1712 uint64_t msecs, persec;
1713
1714 inc_stats(xfr->client, xfr->zone, ns_statscounter_xfrdone);
1715 isc_time_now(&xfr->stats.end);
1716 msecs = isc_time_microdiff(&xfr->stats.end, &xfr->stats.start);
1717 msecs /= 1000;
1718 if (msecs == 0) {
1719 msecs = 1;
1720 }
1721 persec = (xfr->stats.nbytes * 1000) / msecs;
1722 xfrout_log(xfr, xfr->poll ? ISC_LOG_DEBUG(1) : ISC_LOG_INFO,
1723 "%s ended: "
1724 "%" PRIu64 " messages, %" PRIu64 " records, "
1725 "%" PRIu64 " bytes, "
1726 "%u.%03u secs (%u bytes/sec) (serial %u)",
1727 xfr->mnemonic, xfr->stats.nmsg, xfr->stats.nrecs,
1728 xfr->stats.nbytes, (unsigned int)(msecs / 1000),
1729 (unsigned int)(msecs % 1000), (unsigned int)persec,
1730 xfr->end_serial);
1731
1732 /*
1733 * We're done, unreference the handle and destroy the xfr
1734 * context.
1735 */
1736 isc_nmhandle_detach(&xfr->client->reqhandle);
1737 xfrout_ctx_destroy(&xfr);
1738 }
1739 }
1740
1741 static void
xfrout_fail(xfrout_ctx_t * xfr,isc_result_t result,const char * msg)1742 xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) {
1743 xfr->shuttingdown = true;
1744 xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", msg,
1745 isc_result_totext(result));
1746 xfrout_maybe_destroy(xfr);
1747 }
1748
1749 static void
xfrout_maybe_destroy(xfrout_ctx_t * xfr)1750 xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
1751 REQUIRE(xfr->shuttingdown);
1752
1753 ns_client_drop(xfr->client, ISC_R_CANCELED);
1754 isc_nmhandle_detach(&xfr->client->reqhandle);
1755 xfrout_ctx_destroy(&xfr);
1756 }
1757
1758 static void
xfrout_client_timeout(void * arg,isc_result_t result)1759 xfrout_client_timeout(void *arg, isc_result_t result) {
1760 xfrout_ctx_t *xfr = (xfrout_ctx_t *)arg;
1761
1762 xfr->shuttingdown = true;
1763 xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", "aborted",
1764 isc_result_totext(result));
1765 }
1766
1767 /*
1768 * Log outgoing zone transfer messages in a format like
1769 * <client>: transfer of <zone>: <message>
1770 */
1771
1772 static void
1773 xfrout_logv(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
1774 int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0);
1775
1776 static void
xfrout_logv(ns_client_t * client,dns_name_t * zonename,dns_rdataclass_t rdclass,int level,const char * fmt,va_list ap)1777 xfrout_logv(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
1778 int level, const char *fmt, va_list ap) {
1779 char msgbuf[2048];
1780 char namebuf[DNS_NAME_FORMATSIZE];
1781 char classbuf[DNS_RDATACLASS_FORMATSIZE];
1782
1783 dns_name_format(zonename, namebuf, sizeof(namebuf));
1784 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
1785 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
1786 ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT,
1787 level, "transfer of '%s/%s': %s", namebuf, classbuf,
1788 msgbuf);
1789 }
1790
1791 /*
1792 * Logging function for use when a xfrout_ctx_t has not yet been created.
1793 */
1794 static void
xfrout_log1(ns_client_t * client,dns_name_t * zonename,dns_rdataclass_t rdclass,int level,const char * fmt,...)1795 xfrout_log1(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
1796 int level, const char *fmt, ...) {
1797 va_list ap;
1798 va_start(ap, fmt);
1799 xfrout_logv(client, zonename, rdclass, level, fmt, ap);
1800 va_end(ap);
1801 }
1802
1803 /*
1804 * Logging function for use when there is a xfrout_ctx_t.
1805 */
1806 static void
xfrout_log(xfrout_ctx_t * xfr,int level,const char * fmt,...)1807 xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) {
1808 va_list ap;
1809 va_start(ap, fmt);
1810 xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap);
1811 va_end(ap);
1812 }
1813