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