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