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