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