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