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