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