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