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