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