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