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