]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/xfrin.c
Fix BIND remote denial of service vulnerability. [SA-15:27]
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / xfrin.c
1 /*
2  * Copyright (C) 2004-2008, 2011-2013  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id$ */
19
20 /*! \file */
21
22 #include <config.h>
23
24 #include <isc/mem.h>
25 #include <isc/print.h>
26 #include <isc/random.h>
27 #include <isc/string.h>         /* Required for HP/UX (and others?) */
28 #include <isc/task.h>
29 #include <isc/timer.h>
30 #include <isc/util.h>
31
32 #include <dns/db.h>
33 #include <dns/diff.h>
34 #include <dns/events.h>
35 #include <dns/journal.h>
36 #include <dns/log.h>
37 #include <dns/message.h>
38 #include <dns/rdataclass.h>
39 #include <dns/rdatalist.h>
40 #include <dns/rdataset.h>
41 #include <dns/result.h>
42 #include <dns/soa.h>
43 #include <dns/tcpmsg.h>
44 #include <dns/timer.h>
45 #include <dns/tsig.h>
46 #include <dns/view.h>
47 #include <dns/xfrin.h>
48 #include <dns/zone.h>
49
50 #include <dst/dst.h>
51
52 /*
53  * Incoming AXFR and IXFR.
54  */
55
56 /*%
57  * It would be non-sensical (or at least obtuse) to use FAIL() with an
58  * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
59  * from complaining about "end-of-loop code not reached".
60  */
61 #define FAIL(code) \
62         do { result = (code);                                   \
63                 if (result != ISC_R_SUCCESS) goto failure;      \
64         } while (0)
65
66 #define CHECK(op) \
67         do { result = (op);                                     \
68                 if (result != ISC_R_SUCCESS) goto failure;      \
69         } while (0)
70
71 /*%
72  * The states of the *XFR state machine.  We handle both IXFR and AXFR
73  * with a single integrated state machine because they cannot be distinguished
74  * immediately - an AXFR response to an IXFR request can only be detected
75  * when the first two (2) response RRs have already been received.
76  */
77 typedef enum {
78         XFRST_SOAQUERY,
79         XFRST_GOTSOA,
80         XFRST_INITIALSOA,
81         XFRST_FIRSTDATA,
82         XFRST_IXFR_DELSOA,
83         XFRST_IXFR_DEL,
84         XFRST_IXFR_ADDSOA,
85         XFRST_IXFR_ADD,
86         XFRST_IXFR_END,
87         XFRST_AXFR,
88         XFRST_AXFR_END
89 } xfrin_state_t;
90
91 /*%
92  * Incoming zone transfer context.
93  */
94
95 struct dns_xfrin_ctx {
96         unsigned int            magic;
97         isc_mem_t               *mctx;
98         dns_zone_t              *zone;
99
100         int                     refcount;
101
102         isc_task_t              *task;
103         isc_timer_t             *timer;
104         isc_socketmgr_t         *socketmgr;
105
106         int                     connects;       /*%< Connect in progress */
107         int                     sends;          /*%< Send in progress */
108         int                     recvs;          /*%< Receive in progress */
109         isc_boolean_t           shuttingdown;
110
111         dns_name_t              name;           /*%< Name of zone to transfer */
112         dns_rdataclass_t        rdclass;
113
114         isc_boolean_t           checkid;
115         dns_messageid_t         id;
116
117         /*%
118          * Requested transfer type (dns_rdatatype_axfr or
119          * dns_rdatatype_ixfr).  The actual transfer type
120          * may differ due to IXFR->AXFR fallback.
121          */
122         dns_rdatatype_t         reqtype;
123
124         isc_sockaddr_t          masteraddr;
125         isc_sockaddr_t          sourceaddr;
126         isc_socket_t            *socket;
127
128         /*% Buffer for IXFR/AXFR request message */
129         isc_buffer_t            qbuffer;
130         unsigned char           qbuffer_data[512];
131
132         /*% Incoming reply TCP message */
133         dns_tcpmsg_t            tcpmsg;
134         isc_boolean_t           tcpmsg_valid;
135
136         dns_db_t                *db;
137         dns_dbversion_t         *ver;
138         dns_diff_t              diff;           /*%< Pending database changes */
139         int                     difflen;        /*%< Number of pending tuples */
140
141         xfrin_state_t           state;
142         isc_uint32_t            end_serial;
143         isc_boolean_t           is_ixfr;
144
145         unsigned int            nmsg;           /*%< Number of messages recvd */
146         unsigned int            nrecs;          /*%< Number of records recvd */
147         isc_uint64_t            nbytes;         /*%< Number of bytes received */
148
149         isc_time_t              start;          /*%< Start time of the transfer */
150         isc_time_t              end;            /*%< End time of the transfer */
151
152         dns_tsigkey_t           *tsigkey;       /*%< Key used to create TSIG */
153         isc_buffer_t            *lasttsig;      /*%< The last TSIG */
154         dst_context_t           *tsigctx;       /*%< TSIG verification context */
155         unsigned int            sincetsig;      /*%< recvd since the last TSIG */
156         dns_xfrindone_t         done;
157
158         /*%
159          * AXFR- and IXFR-specific data.  Only one is used at a time
160          * according to the is_ixfr flag, so this could be a union,
161          * but keeping them separate makes it a bit simpler to clean
162          * things up when destroying the context.
163          */
164         struct {
165                 dns_addrdatasetfunc_t add_func;
166                 dns_dbload_t          *add_private;
167         } axfr;
168
169         struct {
170                 isc_uint32_t    request_serial;
171                 isc_uint32_t    current_serial;
172                 dns_journal_t   *journal;
173
174         } ixfr;
175 };
176
177 #define XFRIN_MAGIC               ISC_MAGIC('X', 'f', 'r', 'I')
178 #define VALID_XFRIN(x)            ISC_MAGIC_VALID(x, XFRIN_MAGIC)
179
180 /**************************************************************************/
181 /*
182  * Forward declarations.
183  */
184
185 static isc_result_t
186 xfrin_create(isc_mem_t *mctx,
187              dns_zone_t *zone,
188              dns_db_t *db,
189              isc_task_t *task,
190              isc_timermgr_t *timermgr,
191              isc_socketmgr_t *socketmgr,
192              dns_name_t *zonename,
193              dns_rdataclass_t rdclass,
194              dns_rdatatype_t reqtype,
195              isc_sockaddr_t *masteraddr,
196              isc_sockaddr_t *sourceaddr,
197              dns_tsigkey_t *tsigkey,
198              dns_xfrin_ctx_t **xfrp);
199
200 static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
201 static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
202 static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
203                                    dns_name_t *name, dns_ttl_t ttl,
204                                    dns_rdata_t *rdata);
205 static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
206 static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
207 static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr);
208
209 static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
210 static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
211 static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
212                                  dns_name_t *name, dns_ttl_t ttl,
213                                  dns_rdata_t *rdata);
214 static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
215
216 static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
217                            isc_uint32_t ttl, dns_rdata_t *rdata);
218
219 static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
220
221 static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
222 static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
223 static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
224 static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
225 static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
226
227 static void maybe_free(dns_xfrin_ctx_t *xfr);
228
229 static void
230 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
231 static isc_result_t
232 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
233
234 static void
235 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
236            const char *fmt, va_list ap)
237      ISC_FORMAT_PRINTF(4, 0);
238
239 static void
240 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
241            const char *fmt, ...)
242      ISC_FORMAT_PRINTF(4, 5);
243
244 static void
245 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
246      ISC_FORMAT_PRINTF(3, 4);
247
248 /**************************************************************************/
249 /*
250  * AXFR handling
251  */
252
253 static isc_result_t
254 axfr_init(dns_xfrin_ctx_t *xfr) {
255         isc_result_t result;
256
257         xfr->is_ixfr = ISC_FALSE;
258
259         if (xfr->db != NULL)
260                 dns_db_detach(&xfr->db);
261
262         CHECK(axfr_makedb(xfr, &xfr->db));
263         CHECK(dns_db_beginload(xfr->db, &xfr->axfr.add_func,
264                                &xfr->axfr.add_private));
265         result = ISC_R_SUCCESS;
266  failure:
267         return (result);
268 }
269
270 static isc_result_t
271 axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
272         isc_result_t result;
273
274         result = dns_db_create(xfr->mctx, /* XXX */
275                                "rbt",   /* XXX guess */
276                                &xfr->name,
277                                dns_dbtype_zone,
278                                xfr->rdclass,
279                                0, NULL, /* XXX guess */
280                                dbp);
281         if (result == ISC_R_SUCCESS)
282                 result = dns_zone_rpz_enable_db(xfr->zone, *dbp);
283         return (result);
284 }
285
286 static isc_result_t
287 axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
288              dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
289 {
290         isc_result_t result;
291
292         dns_difftuple_t *tuple = NULL;
293
294         CHECK(dns_zone_checknames(xfr->zone, name, rdata));
295         CHECK(dns_difftuple_create(xfr->diff.mctx, op,
296                                    name, ttl, rdata, &tuple));
297         dns_diff_append(&xfr->diff, &tuple);
298         if (++xfr->difflen > 100)
299                 CHECK(axfr_apply(xfr));
300         result = ISC_R_SUCCESS;
301  failure:
302         return (result);
303 }
304
305 /*
306  * Store a set of AXFR RRs in the database.
307  */
308 static isc_result_t
309 axfr_apply(dns_xfrin_ctx_t *xfr) {
310         isc_result_t result;
311
312         CHECK(dns_diff_load(&xfr->diff,
313                             xfr->axfr.add_func, xfr->axfr.add_private));
314         xfr->difflen = 0;
315         dns_diff_clear(&xfr->diff);
316         result = ISC_R_SUCCESS;
317  failure:
318         return (result);
319 }
320
321 static isc_result_t
322 axfr_commit(dns_xfrin_ctx_t *xfr) {
323         isc_result_t result;
324
325         CHECK(axfr_apply(xfr));
326         CHECK(dns_db_endload(xfr->db, &xfr->axfr.add_private));
327
328         result = ISC_R_SUCCESS;
329  failure:
330         return (result);
331 }
332
333 static isc_result_t
334 axfr_finalize(dns_xfrin_ctx_t *xfr) {
335         isc_result_t result;
336
337         CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE));
338
339         result = ISC_R_SUCCESS;
340  failure:
341         return (result);
342 }
343
344 /**************************************************************************/
345 /*
346  * IXFR handling
347  */
348
349 static isc_result_t
350 ixfr_init(dns_xfrin_ctx_t *xfr) {
351         isc_result_t result;
352         char *journalfile;
353
354         if (xfr->reqtype != dns_rdatatype_ixfr) {
355                 xfrin_log(xfr, ISC_LOG_ERROR,
356                           "got incremental response to AXFR request");
357                 return (DNS_R_FORMERR);
358         }
359
360         xfr->is_ixfr = ISC_TRUE;
361         INSIST(xfr->db != NULL);
362         xfr->difflen = 0;
363
364         journalfile = dns_zone_getjournal(xfr->zone);
365         if (journalfile != NULL)
366                 CHECK(dns_journal_open(xfr->mctx, journalfile,
367                                        DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
368
369         result = ISC_R_SUCCESS;
370  failure:
371         return (result);
372 }
373
374 static isc_result_t
375 ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
376              dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
377 {
378         isc_result_t result;
379
380         dns_difftuple_t *tuple = NULL;
381         if (op == DNS_DIFFOP_ADD)
382                 CHECK(dns_zone_checknames(xfr->zone, name, rdata));
383         CHECK(dns_difftuple_create(xfr->diff.mctx, op,
384                                    name, ttl, rdata, &tuple));
385         dns_diff_append(&xfr->diff, &tuple);
386         if (++xfr->difflen > 100)
387                 CHECK(ixfr_apply(xfr));
388         result = ISC_R_SUCCESS;
389  failure:
390         return (result);
391 }
392
393 /*
394  * Apply a set of IXFR changes to the database.
395  */
396 static isc_result_t
397 ixfr_apply(dns_xfrin_ctx_t *xfr) {
398         isc_result_t result;
399
400         if (xfr->ver == NULL) {
401                 CHECK(dns_db_newversion(xfr->db, &xfr->ver));
402                 if (xfr->ixfr.journal != NULL)
403                         CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
404         }
405         CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
406         if (xfr->ixfr.journal != NULL) {
407                 result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
408                 if (result != ISC_R_SUCCESS)
409                         goto failure;
410         }
411         dns_diff_clear(&xfr->diff);
412         xfr->difflen = 0;
413         result = ISC_R_SUCCESS;
414  failure:
415         return (result);
416 }
417
418 static isc_result_t
419 ixfr_commit(dns_xfrin_ctx_t *xfr) {
420         isc_result_t result;
421
422         CHECK(ixfr_apply(xfr));
423         if (xfr->ver != NULL) {
424                 /* XXX enter ready-to-commit state here */
425                 if (xfr->ixfr.journal != NULL)
426                         CHECK(dns_journal_commit(xfr->ixfr.journal));
427                 dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE);
428                 dns_zone_markdirty(xfr->zone);
429         }
430         result = ISC_R_SUCCESS;
431  failure:
432         return (result);
433 }
434
435 /**************************************************************************/
436 /*
437  * Common AXFR/IXFR protocol code
438  */
439
440 /*
441  * Handle a single incoming resource record according to the current
442  * state.
443  */
444 static isc_result_t
445 xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
446        dns_rdata_t *rdata)
447 {
448         isc_result_t result;
449
450         xfr->nrecs++;
451
452         if (rdata->type == dns_rdatatype_none ||
453             dns_rdatatype_ismeta(rdata->type))
454                 FAIL(DNS_R_FORMERR);
455
456  redo:
457         switch (xfr->state) {
458         case XFRST_SOAQUERY:
459                 if (rdata->type != dns_rdatatype_soa) {
460                         xfrin_log(xfr, ISC_LOG_ERROR,
461                                   "non-SOA response to SOA query");
462                         FAIL(DNS_R_FORMERR);
463                 }
464                 xfr->end_serial = dns_soa_getserial(rdata);
465                 if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
466                     !dns_zone_isforced(xfr->zone)) {
467                         xfrin_log(xfr, ISC_LOG_DEBUG(3),
468                                   "requested serial %u, "
469                                   "master has %u, not updating",
470                                   xfr->ixfr.request_serial, xfr->end_serial);
471                         FAIL(DNS_R_UPTODATE);
472                 }
473                 xfr->state = XFRST_GOTSOA;
474                 break;
475
476         case XFRST_GOTSOA:
477                 /*
478                  * Skip other records in the answer section.
479                  */
480                 break;
481
482         case XFRST_INITIALSOA:
483                 if (rdata->type != dns_rdatatype_soa) {
484                         xfrin_log(xfr, ISC_LOG_ERROR,
485                                   "first RR in zone transfer must be SOA");
486                         FAIL(DNS_R_FORMERR);
487                 }
488                 /*
489                  * Remember the serial number in the initial SOA.
490                  * We need it to recognize the end of an IXFR.
491                  */
492                 xfr->end_serial = dns_soa_getserial(rdata);
493                 if (xfr->reqtype == dns_rdatatype_ixfr &&
494                     ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial)
495                     && !dns_zone_isforced(xfr->zone))
496                 {
497                         /*
498                          * This must be the single SOA record that is
499                          * sent when the current version on the master
500                          * is not newer than the version in the request.
501                          */
502                         xfrin_log(xfr, ISC_LOG_DEBUG(3),
503                                   "requested serial %u, "
504                                   "master has %u, not updating",
505                                   xfr->ixfr.request_serial, xfr->end_serial);
506                         FAIL(DNS_R_UPTODATE);
507                 }
508                 if (xfr->reqtype == dns_rdatatype_axfr)
509                         xfr->checkid = ISC_FALSE;
510                 xfr->state = XFRST_FIRSTDATA;
511                 break;
512
513         case XFRST_FIRSTDATA:
514                 /*
515                  * If the transfer begins with one SOA record, it is an AXFR,
516                  * if it begins with two SOAs, it is an IXFR.
517                  */
518                 if (xfr->reqtype == dns_rdatatype_ixfr &&
519                     rdata->type == dns_rdatatype_soa &&
520                     xfr->ixfr.request_serial == dns_soa_getserial(rdata)) {
521                         xfrin_log(xfr, ISC_LOG_DEBUG(3),
522                                   "got incremental response");
523                         CHECK(ixfr_init(xfr));
524                         xfr->state = XFRST_IXFR_DELSOA;
525                 } else {
526                         xfrin_log(xfr, ISC_LOG_DEBUG(3),
527                                   "got nonincremental response");
528                         CHECK(axfr_init(xfr));
529                         xfr->state = XFRST_AXFR;
530                 }
531                 goto redo;
532
533         case XFRST_IXFR_DELSOA:
534                 INSIST(rdata->type == dns_rdatatype_soa);
535                 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
536                 xfr->state = XFRST_IXFR_DEL;
537                 break;
538
539         case XFRST_IXFR_DEL:
540                 if (rdata->type == dns_rdatatype_soa) {
541                         isc_uint32_t soa_serial = dns_soa_getserial(rdata);
542                         xfr->state = XFRST_IXFR_ADDSOA;
543                         xfr->ixfr.current_serial = soa_serial;
544                         goto redo;
545                 }
546                 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
547                 break;
548
549         case XFRST_IXFR_ADDSOA:
550                 INSIST(rdata->type == dns_rdatatype_soa);
551                 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
552                 xfr->state = XFRST_IXFR_ADD;
553                 break;
554
555         case XFRST_IXFR_ADD:
556                 if (rdata->type == dns_rdatatype_soa) {
557                         isc_uint32_t soa_serial = dns_soa_getserial(rdata);
558                         if (soa_serial == xfr->end_serial) {
559                                 CHECK(ixfr_commit(xfr));
560                                 xfr->state = XFRST_IXFR_END;
561                                 break;
562                         } else if (soa_serial != xfr->ixfr.current_serial) {
563                                 xfrin_log(xfr, ISC_LOG_ERROR,
564                                           "IXFR out of sync: "
565                                           "expected serial %u, got %u",
566                                           xfr->ixfr.current_serial, soa_serial);
567                                 FAIL(DNS_R_FORMERR);
568                         } else {
569                                 CHECK(ixfr_commit(xfr));
570                                 xfr->state = XFRST_IXFR_DELSOA;
571                                 goto redo;
572                         }
573                 }
574                 if (rdata->type == dns_rdatatype_ns &&
575                     dns_name_iswildcard(name))
576                         FAIL(DNS_R_INVALIDNS);
577                 CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
578                 break;
579
580         case XFRST_AXFR:
581                 /*
582                  * Old BINDs sent cross class A records for non IN classes.
583                  */
584                 if (rdata->type == dns_rdatatype_a &&
585                     rdata->rdclass != xfr->rdclass &&
586                     xfr->rdclass != dns_rdataclass_in)
587                         break;
588                 CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
589                 if (rdata->type == dns_rdatatype_soa) {
590                         CHECK(axfr_commit(xfr));
591                         xfr->state = XFRST_AXFR_END;
592                         break;
593                 }
594                 break;
595         case XFRST_AXFR_END:
596         case XFRST_IXFR_END:
597                 FAIL(DNS_R_EXTRADATA);
598                 /* NOTREACHED */
599         default:
600                 INSIST(0);
601                 break;
602         }
603         result = ISC_R_SUCCESS;
604  failure:
605         return (result);
606 }
607
608 isc_result_t
609 dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
610                  isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
611                  isc_mem_t *mctx, isc_timermgr_t *timermgr,
612                  isc_socketmgr_t *socketmgr, isc_task_t *task,
613                  dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
614 {
615         isc_sockaddr_t sourceaddr;
616
617         switch (isc_sockaddr_pf(masteraddr)) {
618         case PF_INET:
619                 sourceaddr = *dns_zone_getxfrsource4(zone);
620                 break;
621         case PF_INET6:
622                 sourceaddr = *dns_zone_getxfrsource6(zone);
623                 break;
624         default:
625                 INSIST(0);
626         }
627
628         return(dns_xfrin_create2(zone, xfrtype, masteraddr, &sourceaddr,
629                                  tsigkey, mctx, timermgr, socketmgr,
630                                  task, done, xfrp));
631 }
632
633 isc_result_t
634 dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
635                   isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
636                   dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
637                   isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
638                   isc_task_t *task, dns_xfrindone_t done,
639                   dns_xfrin_ctx_t **xfrp)
640 {
641         dns_name_t *zonename = dns_zone_getorigin(zone);
642         dns_xfrin_ctx_t *xfr = NULL;
643         isc_result_t result;
644         dns_db_t *db = NULL;
645
646         REQUIRE(xfrp != NULL && *xfrp == NULL);
647
648         (void)dns_zone_getdb(zone, &db);
649
650         if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
651                 REQUIRE(db != NULL);
652
653         CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
654                            dns_zone_getclass(zone), xfrtype, masteraddr,
655                            sourceaddr, tsigkey, &xfr));
656
657         CHECK(xfrin_start(xfr));
658
659         xfr->done = done;
660         xfr->refcount++;
661         *xfrp = xfr;
662
663  failure:
664         if (db != NULL)
665                 dns_db_detach(&db);
666         if (result != ISC_R_SUCCESS) {
667                 char zonetext[DNS_NAME_MAXTEXT+32];
668                 dns_zone_name(zone, zonetext, sizeof(zonetext));
669                 xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
670                            "zone transfer setup failed");
671         }
672         return (result);
673 }
674
675 void
676 dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
677         if (! xfr->shuttingdown)
678                 xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
679 }
680
681 void
682 dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
683         REQUIRE(target != NULL && *target == NULL);
684         source->refcount++;
685         *target = source;
686 }
687
688 void
689 dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
690         dns_xfrin_ctx_t *xfr = *xfrp;
691         INSIST(xfr->refcount > 0);
692         xfr->refcount--;
693         maybe_free(xfr);
694         *xfrp = NULL;
695 }
696
697 static void
698 xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
699         if (xfr->connects > 0) {
700                 isc_socket_cancel(xfr->socket, xfr->task,
701                                   ISC_SOCKCANCEL_CONNECT);
702         } else if (xfr->recvs > 0) {
703                 dns_tcpmsg_cancelread(&xfr->tcpmsg);
704         } else if (xfr->sends > 0) {
705                 isc_socket_cancel(xfr->socket, xfr->task,
706                                   ISC_SOCKCANCEL_SEND);
707         }
708 }
709
710 static void
711 xfrin_reset(dns_xfrin_ctx_t *xfr) {
712         REQUIRE(VALID_XFRIN(xfr));
713
714         xfrin_log(xfr, ISC_LOG_INFO, "resetting");
715
716         xfrin_cancelio(xfr);
717
718         if (xfr->socket != NULL)
719                 isc_socket_detach(&xfr->socket);
720
721         if (xfr->lasttsig != NULL)
722                 isc_buffer_free(&xfr->lasttsig);
723
724         dns_diff_clear(&xfr->diff);
725         xfr->difflen = 0;
726
727         if (xfr->ixfr.journal != NULL)
728                 dns_journal_destroy(&xfr->ixfr.journal);
729
730         if (xfr->axfr.add_private != NULL) {
731                 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
732                 xfr->axfr.add_func = NULL;
733         }
734
735         if (xfr->tcpmsg_valid) {
736                 dns_tcpmsg_invalidate(&xfr->tcpmsg);
737                 xfr->tcpmsg_valid = ISC_FALSE;
738         }
739
740         if (xfr->ver != NULL)
741                 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
742 }
743
744
745 static void
746 xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
747         if (result != DNS_R_UPTODATE) {
748                 xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
749                           msg, isc_result_totext(result));
750                 if (xfr->is_ixfr)
751                         /* Pass special result code to force AXFR retry */
752                         result = DNS_R_BADIXFR;
753         }
754         xfrin_cancelio(xfr);
755         /*
756          * Close the journal.
757          */
758         if (xfr->ixfr.journal != NULL)
759                 dns_journal_destroy(&xfr->ixfr.journal);
760         if (xfr->done != NULL) {
761                 (xfr->done)(xfr->zone, result);
762                 xfr->done = NULL;
763         }
764         xfr->shuttingdown = ISC_TRUE;
765         maybe_free(xfr);
766 }
767
768 static isc_result_t
769 xfrin_create(isc_mem_t *mctx,
770              dns_zone_t *zone,
771              dns_db_t *db,
772              isc_task_t *task,
773              isc_timermgr_t *timermgr,
774              isc_socketmgr_t *socketmgr,
775              dns_name_t *zonename,
776              dns_rdataclass_t rdclass,
777              dns_rdatatype_t reqtype,
778              isc_sockaddr_t *masteraddr,
779              isc_sockaddr_t *sourceaddr,
780              dns_tsigkey_t *tsigkey,
781              dns_xfrin_ctx_t **xfrp)
782 {
783         dns_xfrin_ctx_t *xfr = NULL;
784         isc_result_t result;
785         isc_uint32_t tmp;
786
787         xfr = isc_mem_get(mctx, sizeof(*xfr));
788         if (xfr == NULL)
789                 return (ISC_R_NOMEMORY);
790         xfr->mctx = NULL;
791         isc_mem_attach(mctx, &xfr->mctx);
792         xfr->refcount = 0;
793         xfr->zone = NULL;
794         dns_zone_iattach(zone, &xfr->zone);
795         xfr->task = NULL;
796         isc_task_attach(task, &xfr->task);
797         xfr->timer = NULL;
798         xfr->socketmgr = socketmgr;
799         xfr->done = NULL;
800
801         xfr->connects = 0;
802         xfr->sends = 0;
803         xfr->recvs = 0;
804         xfr->shuttingdown = ISC_FALSE;
805
806         dns_name_init(&xfr->name, NULL);
807         xfr->rdclass = rdclass;
808         isc_random_get(&tmp);
809         xfr->checkid = ISC_TRUE;
810         xfr->id = (isc_uint16_t)(tmp & 0xffff);
811         xfr->reqtype = reqtype;
812
813         /* sockaddr */
814         xfr->socket = NULL;
815         /* qbuffer */
816         /* qbuffer_data */
817         /* tcpmsg */
818         xfr->tcpmsg_valid = ISC_FALSE;
819
820         xfr->db = NULL;
821         if (db != NULL)
822                 dns_db_attach(db, &xfr->db);
823         xfr->ver = NULL;
824         dns_diff_init(xfr->mctx, &xfr->diff);
825         xfr->difflen = 0;
826
827         if (reqtype == dns_rdatatype_soa)
828                 xfr->state = XFRST_SOAQUERY;
829         else
830                 xfr->state = XFRST_INITIALSOA;
831         /* end_serial */
832
833         xfr->nmsg = 0;
834         xfr->nrecs = 0;
835         xfr->nbytes = 0;
836         isc_time_now(&xfr->start);
837
838         xfr->tsigkey = NULL;
839         if (tsigkey != NULL)
840                 dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
841         xfr->lasttsig = NULL;
842         xfr->tsigctx = NULL;
843         xfr->sincetsig = 0;
844         xfr->is_ixfr = ISC_FALSE;
845
846         /* ixfr.request_serial */
847         /* ixfr.current_serial */
848         xfr->ixfr.journal = NULL;
849
850         xfr->axfr.add_func = NULL;
851         xfr->axfr.add_private = NULL;
852
853         CHECK(dns_name_dup(zonename, mctx, &xfr->name));
854
855         CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
856                                task, xfrin_timeout, xfr, &xfr->timer));
857         CHECK(dns_timer_setidle(xfr->timer,
858                                 dns_zone_getmaxxfrin(xfr->zone),
859                                 dns_zone_getidlein(xfr->zone),
860                                 ISC_FALSE));
861
862         xfr->masteraddr = *masteraddr;
863
864         INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
865         xfr->sourceaddr = *sourceaddr;
866         isc_sockaddr_setport(&xfr->sourceaddr, 0);
867
868         /*
869          * Reserve 2 bytes for TCP length at the begining of the buffer.
870          */
871         isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2],
872                         sizeof(xfr->qbuffer_data) - 2);
873
874         xfr->magic = XFRIN_MAGIC;
875         *xfrp = xfr;
876         return (ISC_R_SUCCESS);
877
878  failure:
879         if (xfr->timer != NULL)
880                 isc_timer_detach(&xfr->timer);
881         if (dns_name_dynamic(&xfr->name))
882                 dns_name_free(&xfr->name, xfr->mctx);
883         if (xfr->tsigkey != NULL)
884                 dns_tsigkey_detach(&xfr->tsigkey);
885         if (xfr->db != NULL)
886                 dns_db_detach(&xfr->db);
887         isc_task_detach(&xfr->task);
888         dns_zone_idetach(&xfr->zone);
889         isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
890
891         return (result);
892 }
893
894 static isc_result_t
895 xfrin_start(dns_xfrin_ctx_t *xfr) {
896         isc_result_t result;
897         CHECK(isc_socket_create(xfr->socketmgr,
898                                 isc_sockaddr_pf(&xfr->sourceaddr),
899                                 isc_sockettype_tcp,
900                                 &xfr->socket));
901         isc_socket_setname(xfr->socket, "xfrin", NULL);
902 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
903         CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
904                               ISC_SOCKET_REUSEADDRESS));
905 #endif
906         CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
907                                  xfrin_connect_done, xfr));
908         xfr->connects++;
909         return (ISC_R_SUCCESS);
910  failure:
911         xfrin_fail(xfr, result, "failed setting up socket");
912         return (result);
913 }
914
915 /* XXX the resolver could use this, too */
916
917 static isc_result_t
918 render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
919         dns_compress_t cctx;
920         isc_boolean_t cleanup_cctx = ISC_FALSE;
921         isc_result_t result;
922
923         CHECK(dns_compress_init(&cctx, -1, mctx));
924         cleanup_cctx = ISC_TRUE;
925         CHECK(dns_message_renderbegin(msg, &cctx, buf));
926         CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
927         CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
928         CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
929         CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
930         CHECK(dns_message_renderend(msg));
931         result = ISC_R_SUCCESS;
932  failure:
933         if (cleanup_cctx)
934                 dns_compress_invalidate(&cctx);
935         return (result);
936 }
937
938 /*
939  * A connection has been established.
940  */
941 static void
942 xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
943         isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
944         dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
945         isc_result_t result = cev->result;
946         char sourcetext[ISC_SOCKADDR_FORMATSIZE];
947         isc_sockaddr_t sockaddr;
948         dns_zonemgr_t * zmgr;
949         isc_time_t now;
950
951         REQUIRE(VALID_XFRIN(xfr));
952
953         UNUSED(task);
954
955         INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
956         isc_event_free(&event);
957
958         xfr->connects--;
959         if (xfr->shuttingdown) {
960                 maybe_free(xfr);
961                 return;
962         }
963
964         zmgr = dns_zone_getmgr(xfr->zone);
965         if (zmgr != NULL) {
966                 if (result != ISC_R_SUCCESS) {
967                         TIME_NOW(&now);
968                         dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
969                                                    &xfr->sourceaddr, &now);
970                         goto failure;
971                 } else
972                         dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr,
973                                                    &xfr->sourceaddr);
974         }
975
976         result = isc_socket_getsockname(xfr->socket, &sockaddr);
977         if (result == ISC_R_SUCCESS) {
978                 isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
979         } else
980                 strcpy(sourcetext, "<UNKNOWN>");
981         xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext);
982
983         dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
984         xfr->tcpmsg_valid = ISC_TRUE;
985
986         CHECK(xfrin_send_request(xfr));
987  failure:
988         if (result != ISC_R_SUCCESS)
989                 xfrin_fail(xfr, result, "failed to connect");
990 }
991
992 /*
993  * Convert a tuple into a dns_name_t suitable for inserting
994  * into the given dns_message_t.
995  */
996 static isc_result_t
997 tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
998 {
999         isc_result_t result;
1000         dns_rdata_t *rdata = NULL;
1001         dns_rdatalist_t *rdl = NULL;
1002         dns_rdataset_t *rds = NULL;
1003         dns_name_t *name = NULL;
1004
1005         REQUIRE(target != NULL && *target == NULL);
1006
1007         CHECK(dns_message_gettemprdata(msg, &rdata));
1008         dns_rdata_init(rdata);
1009         dns_rdata_clone(&tuple->rdata, rdata);
1010
1011         CHECK(dns_message_gettemprdatalist(msg, &rdl));
1012         dns_rdatalist_init(rdl);
1013         rdl->type = tuple->rdata.type;
1014         rdl->rdclass = tuple->rdata.rdclass;
1015         rdl->ttl = tuple->ttl;
1016         ISC_LIST_APPEND(rdl->rdata, rdata, link);
1017
1018         CHECK(dns_message_gettemprdataset(msg, &rds));
1019         dns_rdataset_init(rds);
1020         CHECK(dns_rdatalist_tordataset(rdl, rds));
1021
1022         CHECK(dns_message_gettempname(msg, &name));
1023         dns_name_init(name, NULL);
1024         dns_name_clone(&tuple->name, name);
1025         ISC_LIST_APPEND(name->list, rds, link);
1026
1027         *target = name;
1028         return (ISC_R_SUCCESS);
1029
1030  failure:
1031
1032         if (rds != NULL) {
1033                 dns_rdataset_disassociate(rds);
1034                 dns_message_puttemprdataset(msg, &rds);
1035         }
1036         if (rdl != NULL) {
1037                 ISC_LIST_UNLINK(rdl->rdata, rdata, link);
1038                 dns_message_puttemprdatalist(msg, &rdl);
1039         }
1040         if (rdata != NULL)
1041                 dns_message_puttemprdata(msg, &rdata);
1042
1043         return (result);
1044 }
1045
1046
1047 /*
1048  * Build an *XFR request and send its length prefix.
1049  */
1050 static isc_result_t
1051 xfrin_send_request(dns_xfrin_ctx_t *xfr) {
1052         isc_result_t result;
1053         isc_region_t region;
1054         dns_rdataset_t *qrdataset = NULL;
1055         dns_message_t *msg = NULL;
1056         dns_difftuple_t *soatuple = NULL;
1057         dns_name_t *qname = NULL;
1058         dns_dbversion_t *ver = NULL;
1059         dns_name_t *msgsoaname = NULL;
1060
1061         /* Create the request message */
1062         CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
1063         CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1064
1065         /* Create a name for the question section. */
1066         CHECK(dns_message_gettempname(msg, &qname));
1067         dns_name_init(qname, NULL);
1068         dns_name_clone(&xfr->name, qname);
1069
1070         /* Formulate the question and attach it to the question name. */
1071         CHECK(dns_message_gettemprdataset(msg, &qrdataset));
1072         dns_rdataset_init(qrdataset);
1073         dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
1074         ISC_LIST_APPEND(qname->list, qrdataset, link);
1075         qrdataset = NULL;
1076
1077         dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
1078         qname = NULL;
1079
1080         if (xfr->reqtype == dns_rdatatype_ixfr) {
1081                 /* Get the SOA and add it to the authority section. */
1082                 /* XXX is using the current version the right thing? */
1083                 dns_db_currentversion(xfr->db, &ver);
1084                 CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
1085                                             DNS_DIFFOP_EXISTS, &soatuple));
1086                 xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
1087                 xfr->ixfr.current_serial = xfr->ixfr.request_serial;
1088                 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1089                           "requesting IXFR for serial %u",
1090                           xfr->ixfr.request_serial);
1091
1092                 CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
1093                 dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
1094         } else if (xfr->reqtype == dns_rdatatype_soa)
1095                 CHECK(dns_db_getsoaserial(xfr->db, NULL,
1096                                           &xfr->ixfr.request_serial));
1097
1098         xfr->checkid = ISC_TRUE;
1099         xfr->id++;
1100         xfr->nmsg = 0;
1101         xfr->nrecs = 0;
1102         xfr->nbytes = 0;
1103         isc_time_now(&xfr->start);
1104         msg->id = xfr->id;
1105         if (xfr->tsigctx != NULL)
1106                 dst_context_destroy(&xfr->tsigctx);
1107
1108         CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
1109
1110         /*
1111          * Free the last tsig, if there is one.
1112          */
1113         if (xfr->lasttsig != NULL)
1114                 isc_buffer_free(&xfr->lasttsig);
1115
1116         /*
1117          * Save the query TSIG and don't let message_destroy free it.
1118          */
1119         CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
1120
1121         isc_buffer_usedregion(&xfr->qbuffer, &region);
1122         INSIST(region.length <= 65535);
1123
1124         /*
1125          * Record message length and adjust region to include TCP
1126          * length field.
1127          */
1128         xfr->qbuffer_data[0] = (region.length >> 8) & 0xff;
1129         xfr->qbuffer_data[1] = region.length & 0xff;
1130         region.base -= 2;
1131         region.length += 2;
1132         CHECK(isc_socket_send(xfr->socket, &region, xfr->task,
1133                               xfrin_send_done, xfr));
1134         xfr->sends++;
1135
1136  failure:
1137         if (qname != NULL)
1138                 dns_message_puttempname(msg, &qname);
1139         if (qrdataset != NULL)
1140                 dns_message_puttemprdataset(msg, &qrdataset);
1141         if (msg != NULL)
1142                 dns_message_destroy(&msg);
1143         if (soatuple != NULL)
1144                 dns_difftuple_free(&soatuple);
1145         if (ver != NULL)
1146                 dns_db_closeversion(xfr->db, &ver, ISC_FALSE);
1147         return (result);
1148 }
1149
1150 static void
1151 xfrin_send_done(isc_task_t *task, isc_event_t *event) {
1152         isc_socketevent_t *sev = (isc_socketevent_t *) event;
1153         dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1154         isc_result_t result;
1155
1156         REQUIRE(VALID_XFRIN(xfr));
1157
1158         UNUSED(task);
1159
1160         INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1161
1162         xfr->sends--;
1163         xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
1164         CHECK(sev->result);
1165
1166         CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1167                                      xfrin_recv_done, xfr));
1168         xfr->recvs++;
1169  failure:
1170         isc_event_free(&event);
1171         if (result != ISC_R_SUCCESS)
1172                 xfrin_fail(xfr, result, "failed sending request data");
1173 }
1174
1175
1176 static void
1177 xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
1178         dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
1179         isc_result_t result;
1180         dns_message_t *msg = NULL;
1181         dns_name_t *name;
1182         dns_tcpmsg_t *tcpmsg;
1183         dns_name_t *tsigowner = NULL;
1184
1185         REQUIRE(VALID_XFRIN(xfr));
1186
1187         UNUSED(task);
1188
1189         INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
1190         tcpmsg = ev->ev_sender;
1191         isc_event_free(&ev);
1192
1193         xfr->recvs--;
1194         if (xfr->shuttingdown) {
1195                 maybe_free(xfr);
1196                 return;
1197         }
1198
1199         CHECK(tcpmsg->result);
1200
1201         xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
1202                   tcpmsg->buffer.used);
1203
1204         CHECK(isc_timer_touch(xfr->timer));
1205
1206         CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
1207
1208         CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
1209         CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
1210
1211         msg->tsigctx = xfr->tsigctx;
1212         xfr->tsigctx = NULL;
1213
1214         dns_message_setclass(msg, xfr->rdclass);
1215
1216         if (xfr->nmsg > 0)
1217                 msg->tcp_continuation = 1;
1218
1219         result = dns_message_parse(msg, &tcpmsg->buffer,
1220                                    DNS_MESSAGEPARSE_PRESERVEORDER);
1221
1222         if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
1223             (xfr->checkid && msg->id != xfr->id)) {
1224                 if (result == ISC_R_SUCCESS)
1225                         result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
1226                 if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
1227                         result = DNS_R_UNEXPECTEDID;
1228                 if (xfr->reqtype == dns_rdatatype_axfr ||
1229                     xfr->reqtype == dns_rdatatype_soa)
1230                         goto failure;
1231                 xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
1232                        isc_result_totext(result));
1233  try_axfr:
1234                 dns_message_destroy(&msg);
1235                 xfrin_reset(xfr);
1236                 xfr->reqtype = dns_rdatatype_soa;
1237                 xfr->state = XFRST_SOAQUERY;
1238                 (void)xfrin_start(xfr);
1239                 return;
1240         }
1241
1242         /*
1243          * Does the server know about IXFR?  If it doesn't we will get
1244          * a message with a empty answer section or a potentially a CNAME /
1245          * DNAME, the later is handled by xfr_rr() which will return FORMERR
1246          * if the first RR in the answer section is not a SOA record.
1247          */
1248         if (xfr->reqtype == dns_rdatatype_ixfr &&
1249             xfr->state == XFRST_INITIALSOA &&
1250             msg->counts[DNS_SECTION_ANSWER] == 0) {
1251                 xfrin_log(xfr, ISC_LOG_DEBUG(3),
1252                           "empty answer section, retrying with AXFR");
1253                 goto try_axfr;
1254         }
1255
1256         if (xfr->reqtype == dns_rdatatype_soa &&
1257             (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
1258                 FAIL(DNS_R_NOTAUTHORITATIVE);
1259         }
1260
1261
1262         result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
1263         if (result != ISC_R_SUCCESS) {
1264                 xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
1265                        isc_result_totext(result));
1266                 goto failure;
1267         }
1268
1269         for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
1270              result == ISC_R_SUCCESS;
1271              result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
1272         {
1273                 dns_rdataset_t *rds;
1274
1275                 name = NULL;
1276                 dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
1277                 for (rds = ISC_LIST_HEAD(name->list);
1278                      rds != NULL;
1279                      rds = ISC_LIST_NEXT(rds, link))
1280                 {
1281                         for (result = dns_rdataset_first(rds);
1282                              result == ISC_R_SUCCESS;
1283                              result = dns_rdataset_next(rds))
1284                         {
1285                                 dns_rdata_t rdata = DNS_RDATA_INIT;
1286                                 dns_rdataset_current(rds, &rdata);
1287                                 CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
1288                         }
1289                 }
1290         }
1291         if (result != ISC_R_NOMORE)
1292                 goto failure;
1293
1294         if (dns_message_gettsig(msg, &tsigowner) != NULL) {
1295                 /*
1296                  * Reset the counter.
1297                  */
1298                 xfr->sincetsig = 0;
1299
1300                 /*
1301                  * Free the last tsig, if there is one.
1302                  */
1303                 if (xfr->lasttsig != NULL)
1304                         isc_buffer_free(&xfr->lasttsig);
1305
1306                 /*
1307                  * Update the last tsig pointer.
1308                  */
1309                 CHECK(dns_message_getquerytsig(msg, xfr->mctx,
1310                                                &xfr->lasttsig));
1311
1312         } else if (dns_message_gettsigkey(msg) != NULL) {
1313                 xfr->sincetsig++;
1314                 if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
1315                     xfr->state == XFRST_AXFR_END ||
1316                     xfr->state == XFRST_IXFR_END)
1317                 {
1318                         result = DNS_R_EXPECTEDTSIG;
1319                         goto failure;
1320                 }
1321         }
1322
1323         /*
1324          * Update the number of messages received.
1325          */
1326         xfr->nmsg++;
1327
1328         /*
1329          * Update the number of bytes received.
1330          */
1331         xfr->nbytes += tcpmsg->buffer.used;
1332
1333         /*
1334          * Take the context back.
1335          */
1336         INSIST(xfr->tsigctx == NULL);
1337         xfr->tsigctx = msg->tsigctx;
1338         msg->tsigctx = NULL;
1339
1340         dns_message_destroy(&msg);
1341
1342         switch (xfr->state) {
1343         case XFRST_GOTSOA:
1344                 xfr->reqtype = dns_rdatatype_axfr;
1345                 xfr->state = XFRST_INITIALSOA;
1346                 CHECK(xfrin_send_request(xfr));
1347                 break;
1348         case XFRST_AXFR_END:
1349                 CHECK(axfr_finalize(xfr));
1350                 /* FALLTHROUGH */
1351         case XFRST_IXFR_END:
1352                 /*
1353                  * Close the journal.
1354                  */
1355                 if (xfr->ixfr.journal != NULL)
1356                         dns_journal_destroy(&xfr->ixfr.journal);
1357
1358                 /*
1359                  * Inform the caller we succeeded.
1360                  */
1361                 if (xfr->done != NULL) {
1362                         (xfr->done)(xfr->zone, ISC_R_SUCCESS);
1363                         xfr->done = NULL;
1364                 }
1365                 /*
1366                  * We should have no outstanding events at this
1367                  * point, thus maybe_free() should succeed.
1368                  */
1369                 xfr->shuttingdown = ISC_TRUE;
1370                 maybe_free(xfr);
1371                 break;
1372         default:
1373                 /*
1374                  * Read the next message.
1375                  */
1376                 CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
1377                                              xfrin_recv_done, xfr));
1378                 xfr->recvs++;
1379         }
1380         return;
1381
1382  failure:
1383         if (msg != NULL)
1384                 dns_message_destroy(&msg);
1385         if (result != ISC_R_SUCCESS)
1386                 xfrin_fail(xfr, result, "failed while receiving responses");
1387 }
1388
1389 static void
1390 xfrin_timeout(isc_task_t *task, isc_event_t *event) {
1391         dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
1392
1393         REQUIRE(VALID_XFRIN(xfr));
1394
1395         UNUSED(task);
1396
1397         isc_event_free(&event);
1398         /*
1399          * This will log "giving up: timeout".
1400          */
1401         xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
1402 }
1403
1404 static void
1405 maybe_free(dns_xfrin_ctx_t *xfr) {
1406         isc_uint64_t msecs;
1407         isc_uint64_t persec;
1408
1409         REQUIRE(VALID_XFRIN(xfr));
1410
1411         if (! xfr->shuttingdown || xfr->refcount != 0 ||
1412             xfr->connects != 0 || xfr->sends != 0 ||
1413             xfr->recvs != 0)
1414                 return;
1415
1416         /*
1417          * Calculate the length of time the transfer took,
1418          * and print a log message with the bytes and rate.
1419          */
1420         isc_time_now(&xfr->end);
1421         msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
1422         if (msecs == 0)
1423                 msecs = 1;
1424         persec = (xfr->nbytes * 1000) / msecs;
1425         xfrin_log(xfr, ISC_LOG_INFO,
1426                   "Transfer completed: %d messages, %d records, "
1427                   "%" ISC_PRINT_QUADFORMAT "u bytes, "
1428                   "%u.%03u secs (%u bytes/sec)",
1429                   xfr->nmsg, xfr->nrecs, xfr->nbytes,
1430                   (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000),
1431                   (unsigned int) persec);
1432
1433         if (xfr->socket != NULL)
1434                 isc_socket_detach(&xfr->socket);
1435
1436         if (xfr->timer != NULL)
1437                 isc_timer_detach(&xfr->timer);
1438
1439         if (xfr->task != NULL)
1440                 isc_task_detach(&xfr->task);
1441
1442         if (xfr->tsigkey != NULL)
1443                 dns_tsigkey_detach(&xfr->tsigkey);
1444
1445         if (xfr->lasttsig != NULL)
1446                 isc_buffer_free(&xfr->lasttsig);
1447
1448         dns_diff_clear(&xfr->diff);
1449
1450         if (xfr->ixfr.journal != NULL)
1451                 dns_journal_destroy(&xfr->ixfr.journal);
1452
1453         if (xfr->axfr.add_private != NULL)
1454                 (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
1455
1456         if (xfr->tcpmsg_valid)
1457                 dns_tcpmsg_invalidate(&xfr->tcpmsg);
1458
1459         if (xfr->tsigctx != NULL)
1460                 dst_context_destroy(&xfr->tsigctx);
1461
1462         if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
1463                 dns_name_free(&xfr->name, xfr->mctx);
1464
1465         if (xfr->ver != NULL)
1466                 dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
1467
1468         if (xfr->db != NULL)
1469                 dns_db_detach(&xfr->db);
1470
1471         if (xfr->zone != NULL)
1472                 dns_zone_idetach(&xfr->zone);
1473
1474         isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
1475 }
1476
1477 /*
1478  * Log incoming zone transfer messages in a format like
1479  * transfer of <zone> from <address>: <message>
1480  */
1481 static void
1482 xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1483            const char *fmt, va_list ap)
1484 {
1485         char mastertext[ISC_SOCKADDR_FORMATSIZE];
1486         char msgtext[2048];
1487
1488         isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
1489         vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
1490
1491         isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
1492                       DNS_LOGMODULE_XFER_IN, level,
1493                       "transfer of '%s' from %s: %s",
1494                       zonetext, mastertext, msgtext);
1495 }
1496
1497 /*
1498  * Logging function for use when a xfrin_ctx_t has not yet been created.
1499  */
1500
1501 static void
1502 xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
1503            const char *fmt, ...)
1504 {
1505         va_list ap;
1506
1507         if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1508                 return;
1509
1510         va_start(ap, fmt);
1511         xfrin_logv(level, zonetext, masteraddr, fmt, ap);
1512         va_end(ap);
1513 }
1514
1515 /*
1516  * Logging function for use when there is a xfrin_ctx_t.
1517  */
1518
1519 static void
1520 xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
1521 {
1522         va_list ap;
1523         char zonetext[DNS_NAME_MAXTEXT+32];
1524
1525         if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
1526                 return;
1527
1528         dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
1529
1530         va_start(ap, fmt);
1531         xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);
1532         va_end(ap);
1533 }