~andreserl/ubuntu/lucid/bind9/bind9-apport-533601

« back to all changes in this revision

Viewing changes to lib/dns/master.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones, LaMont Jones, Internet Software Consortium, Inc, localization folks
  • Date: 2008-08-02 14:20:20 UTC
  • mfrom: (1.2.1 upstream) (6.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080802142020-l1hon9jy8lbbjxmg
[LaMont Jones]

* default to using resolvconf if it is installed
* fix sonames and dependencies.  Closes: #149259, #492418
* Do not build-depend libcap2-dev on non-linux.  Closes: #493392
* drop unused query-loc manpage.  Closes: #492564
* lwresd: Deliver /etc/bind directory.  Closes: #490027
* fix query-source comment in default install

[Internet Software Consortium, Inc]

* 9.5.0-P2.  Closes: #492949

[localization folks]

* l10n: Spanish debconf translation.  Closes: #492425 (Ignacio Mondino)
* l10n: Swedish debconf templates.  Closes: #491369 (Martin Ågren)
* l10n: Japanese debconf translations.  Closes: #492048 (Hideki Yamane
  (Debian-JP))
* l10n: Finnish translation.  Closes: #490630 (Esko Arajärvi)
* l10n: Italian debconf translations.  Closes: #492587 (Alessandro Vietta)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
 
2
 * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
3
3
 * Copyright (C) 1999-2003  Internet Software Consortium.
4
4
 *
5
 
 * Permission to use, copy, modify, and distribute this software for any
 
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
6
 * purpose with or without fee is hereby granted, provided that the above
7
7
 * copyright notice and this permission notice appear in all copies.
8
8
 *
15
15
 * PERFORMANCE OF THIS SOFTWARE.
16
16
 */
17
17
 
18
 
/* $Id: master.c,v 1.122.2.8.2.14 2004/05/05 01:32:16 marka Exp $ */
 
18
/* $Id: master.c,v 1.166.94.3 2008/01/17 23:46:37 tbox Exp $ */
 
19
 
 
20
/*! \file */
19
21
 
20
22
#include <config.h>
21
23
 
25
27
#include <isc/mem.h>
26
28
#include <isc/print.h>
27
29
#include <isc/serial.h>
 
30
#include <isc/stdio.h>
28
31
#include <isc/stdtime.h>
29
32
#include <isc/string.h>
30
33
#include <isc/task.h>
46
49
#include <dns/time.h>
47
50
#include <dns/ttl.h>
48
51
 
49
 
/*
50
 
 * Grow the number of dns_rdatalist_t (RDLSZ) and dns_rdata_t (RDSZ) structures
 
52
/*!
 
53
 * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures
51
54
 * by these sizes when we need to.
52
55
 *
53
 
 * RDLSZ reflects the number of different types with the same name expected.
 
56
 */
 
57
/*% RDLSZ reflects the number of different types with the same name expected. */
 
58
#define RDLSZ 32
 
59
/*%
54
60
 * RDSZ reflects the number of rdata expected at a give name that can fit into
55
61
 * 64k.
56
62
 */
57
 
 
58
 
#define RDLSZ 32
59
63
#define RDSZ 512
60
64
 
61
65
#define NBUFS 4
62
66
#define MAXWIRESZ 255
63
67
 
64
 
/*
 
68
/*%
65
69
 * Target buffer size and minimum target size.
66
70
 * MINTSIZ must be big enough to hold the largest rdata record.
67
 
 *
 
71
 * \brief
68
72
 * TSIZ >= MINTSIZ
69
73
 */
70
74
#define TSIZ (128*1024)
71
 
/*
 
75
/*%
72
76
 * max message size - header - root - type - class - ttl - rdlen
73
77
 */
74
78
#define MINTSIZ (65535 - 12 - 1 - 2 - 2 - 4 - 2)
75
 
/*
 
79
/*%
76
80
 * Size for tokens in the presentation format,
77
81
 * The largest tokens are the base64 blocks in KEY and CERT records,
78
82
 * Largest key allowed is about 1372 bytes but
87
91
 
88
92
typedef struct dns_incctx dns_incctx_t;
89
93
 
90
 
/*
 
94
/*%
91
95
 * Master file load state.
92
96
 */
93
97
 
94
98
struct dns_loadctx {
95
99
        unsigned int            magic;
96
100
        isc_mem_t               *mctx;
97
 
        isc_lex_t               *lex;
98
 
        isc_boolean_t           keep_lex;
 
101
        dns_masterformat_t      format;
 
102
 
99
103
        dns_rdatacallbacks_t    *callbacks;
100
104
        isc_task_t              *task;
101
105
        dns_loaddonefunc_t      done;
102
106
        void                    *done_arg;
 
107
 
 
108
        /* Common methods */
 
109
        isc_result_t            (*openfile)(dns_loadctx_t *lctx,
 
110
                                            const char *filename);
 
111
        isc_result_t            (*load)(dns_loadctx_t *lctx);
 
112
 
 
113
        /* Members specific to the text format: */
 
114
        isc_lex_t               *lex;
 
115
        isc_boolean_t           keep_lex;
103
116
        unsigned int            options;
104
117
        isc_boolean_t           ttl_known;
105
118
        isc_boolean_t           default_ttl_known;
111
124
        isc_uint32_t            default_ttl;
112
125
        dns_rdataclass_t        zclass;
113
126
        dns_fixedname_t         fixed_top;
114
 
        dns_name_t              *top;                   /* top of zone */
 
127
        dns_name_t              *top;                   /*%< top of zone */
 
128
 
 
129
        /* Members specific to the raw format: */
 
130
        FILE                    *f;
 
131
        isc_boolean_t           first;
 
132
 
115
133
        /* Which fixed buffers we are using? */
116
 
        unsigned int            loop_cnt;               /* records per quantum,
 
134
        unsigned int            loop_cnt;               /*% records per quantum,
117
135
                                                         * 0 => all. */
118
136
        isc_boolean_t           canceled;
119
137
        isc_mutex_t             lock;
144
162
#define DNS_AS_STR(t) ((t).value.as_textregion.base)
145
163
 
146
164
static isc_result_t
 
165
openfile_text(dns_loadctx_t *lctx, const char *master_file);
 
166
 
 
167
static isc_result_t
 
168
openfile_raw(dns_loadctx_t *lctx, const char *master_file);
 
169
 
 
170
static isc_result_t
 
171
load_text(dns_loadctx_t *lctx);
 
172
 
 
173
static isc_result_t
 
174
load_raw(dns_loadctx_t *lctx);
 
175
 
 
176
static isc_result_t
147
177
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx);
148
178
 
149
179
static isc_result_t
246
276
 
247
277
#define MANYERRS(lctx, result) \
248
278
                ((result != ISC_R_SUCCESS) && \
249
 
                ((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
 
279
                 (result != ISC_R_IOERROR) && \
 
280
                 ((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
250
281
 
251
282
#define SETRESULT(lctx, r) \
252
283
                do { \
405
436
static void
406
437
loadctx_destroy(dns_loadctx_t *lctx) {
407
438
        isc_mem_t *mctx;
 
439
        isc_result_t result;
408
440
 
409
441
        REQUIRE(DNS_LCTX_VALID(lctx));
410
442
 
412
444
        if (lctx->inc != NULL)
413
445
                incctx_destroy(lctx->mctx, lctx->inc);
414
446
 
 
447
        if (lctx->f != NULL) {
 
448
                result = isc_stdio_close(lctx->f);
 
449
                if (result != ISC_R_SUCCESS) {
 
450
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
 
451
                                         "isc_stdio_close() failed: %s",
 
452
                                         isc_result_totext(result));
 
453
                }
 
454
        }
 
455
 
415
456
        /* isc_lex_destroy() will close all open streams */
416
457
        if (lctx->lex != NULL && !lctx->keep_lex)
417
458
                isc_lex_destroy(&lctx->lex);
461
502
}
462
503
 
463
504
static isc_result_t
464
 
loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top,
 
505
loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
 
506
               unsigned int options, dns_name_t *top,
465
507
               dns_rdataclass_t zclass, dns_name_t *origin,
466
508
               dns_rdatacallbacks_t *callbacks, isc_task_t *task,
467
509
               dns_loaddonefunc_t done, void *done_arg, isc_lex_t *lex,
489
531
        result = isc_mutex_init(&lctx->lock);
490
532
        if (result != ISC_R_SUCCESS) {
491
533
                isc_mem_put(mctx, lctx, sizeof(*lctx));
492
 
                UNEXPECTED_ERROR(__FILE__, __LINE__,
493
 
                                 "isc_mutex_init() failed: %s",
494
 
                                 isc_result_totext(result));
495
 
                return (ISC_R_UNEXPECTED);
 
534
                return (result);
496
535
        }
497
536
 
498
537
        lctx->inc = NULL;
499
538
        result = incctx_create(mctx, origin, &lctx->inc);
500
 
        if (result != ISC_R_SUCCESS) 
 
539
        if (result != ISC_R_SUCCESS)
501
540
                goto cleanup_ctx;
502
541
 
 
542
        lctx->format = format;
 
543
        switch (format) {
 
544
        default:
 
545
                INSIST(0);
 
546
        case dns_masterformat_text:
 
547
                lctx->openfile = openfile_text;
 
548
                lctx->load = load_text;
 
549
                break;
 
550
        case dns_masterformat_raw:
 
551
                lctx->openfile = openfile_raw;
 
552
                lctx->load = load_raw;
 
553
                break;
 
554
        }
 
555
 
503
556
        if (lex != NULL) {
504
557
                lctx->lex = lex;
505
558
                lctx->keep_lex = ISC_TRUE;
534
587
        dns_name_toregion(top, &r);
535
588
        dns_name_fromregion(lctx->top, &r);
536
589
 
 
590
        lctx->f = NULL;
 
591
        lctx->first = ISC_TRUE;
 
592
 
537
593
        lctx->loop_cnt = (done != NULL) ? 100 : 0;
538
594
        lctx->callbacks = callbacks;
539
595
        lctx->task = NULL;
640
696
}
641
697
 
642
698
static isc_result_t
 
699
openfile_text(dns_loadctx_t *lctx, const char *master_file) {
 
700
        return (isc_lex_openfile(lctx->lex, master_file));
 
701
}
 
702
 
 
703
static isc_result_t
 
704
openfile_raw(dns_loadctx_t *lctx, const char *master_file) {
 
705
        isc_result_t result;
 
706
 
 
707
        result = isc_stdio_open(master_file, "r", &lctx->f);
 
708
        if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
 
709
                UNEXPECTED_ERROR(__FILE__, __LINE__,
 
710
                                 "isc_stdio_open() failed: %s",
 
711
                                 isc_result_totext(result));
 
712
        }
 
713
 
 
714
        return (result);
 
715
}
 
716
 
 
717
static isc_result_t
643
718
generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
644
719
         const char *source, unsigned int line)
645
720
{
711
786
        case dns_rdatatype_a:
712
787
        case dns_rdatatype_aaaa:
713
788
                if (lctx->zclass == dns_rdataclass_in ||
 
789
                    lctx->zclass == dns_rdataclass_ch ||
714
790
                    lctx->zclass == dns_rdataclass_hs)
715
791
                        break;
716
792
                /* FALLTHROUGH */
836
912
                callback = lctx->callbacks->error;
837
913
        else
838
914
                callback = lctx->callbacks->warn;
839
 
                
 
915
 
840
916
        if (token->type == isc_tokentype_string) {
841
917
                struct in_addr addr;
842
918
                struct in6_addr addr6;
862
938
        return (result);
863
939
}
864
940
 
 
941
static void
 
942
check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line,
 
943
               dns_rdatacallbacks_t *callbacks)
 
944
{
 
945
        dns_name_t *name;
 
946
 
 
947
        name = (ictx->glue != NULL) ? ictx->glue : ictx->current;
 
948
        if (dns_name_internalwildcard(name)) {
 
949
                char namebuf[DNS_NAME_FORMATSIZE];
 
950
 
 
951
                dns_name_format(name, namebuf, sizeof(namebuf));
 
952
                (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername "
 
953
                                   "'%s' contains an non-terminal wildcard",
 
954
                                   source, line, namebuf);
 
955
        }
 
956
}
 
957
 
865
958
static isc_result_t
866
 
load(dns_loadctx_t *lctx) {
 
959
load_text(dns_loadctx_t *lctx) {
867
960
        dns_rdataclass_t rdclass;
868
961
        dns_rdatatype_t type, covers;
869
962
        isc_uint32_t ttl_offset = 0;
939
1032
                options |= DNS_RDATA_CHECKNAMES;
940
1033
        if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0)
941
1034
                options |= DNS_RDATA_CHECKNAMESFAIL;
 
1035
        if ((lctx->options & DNS_MASTER_CHECKMX) != 0)
 
1036
                options |= DNS_RDATA_CHECKMX;
 
1037
        if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0)
 
1038
                options |= DNS_RDATA_CHECKMXFAIL;
942
1039
        source = isc_lex_getsourcename(lctx->lex);
943
1040
        do {
944
1041
                initialws = ISC_FALSE;
945
1042
                line = isc_lex_getsourceline(lctx->lex);
946
 
                GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS, &token, ISC_TRUE);
 
1043
                GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING,
 
1044
                         &token, ISC_TRUE);
947
1045
                line = isc_lex_getsourceline(lctx->lex);
948
1046
 
949
1047
                if (token.type == isc_tokentype_eof) {
979
1077
                         * Still working on the same name.
980
1078
                         */
981
1079
                        initialws = ISC_TRUE;
982
 
                } else if (token.type == isc_tokentype_string) {
 
1080
                } else if (token.type == isc_tokentype_string ||
 
1081
                           token.type == isc_tokentype_qstring) {
983
1082
 
984
1083
                        /*
985
1084
                         * "$" Support.
1117
1216
                                        isc_mem_free(mctx, gtype);
1118
1217
                                if (rhs != NULL)
1119
1218
                                        isc_mem_free(mctx, rhs);
 
1219
                                range = lhs = gtype = rhs = NULL;
1120
1220
                                /* RANGE */
1121
1221
                                GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
1122
1222
                                range = isc_mem_strdup(mctx,
1137
1237
                                /* CLASS? */
1138
1238
                                GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
1139
1239
                                if (dns_rdataclass_fromtext(&rdclass,
1140
 
                                            &token.value.as_textregion)
 
1240
                                            &token.value.as_textregion)
1141
1241
                                                == ISC_R_SUCCESS) {
1142
1242
                                        GETTOKEN(lctx->lex, 0, &token,
1143
1243
                                                 ISC_FALSE);
1321
1421
                                        target_save = target;
1322
1422
                                        ictx->glue = new_name;
1323
1423
                                        ictx->glue_in_use = new_in_use;
1324
 
                                        ictx->in_use[ictx->glue_in_use] = 
 
1424
                                        ictx->in_use[ictx->glue_in_use] =
1325
1425
                                                ISC_TRUE;
1326
1426
                                } else {
1327
1427
                                        result = commit(callbacks, lctx,
1346
1446
                                        isc_buffer_init(&target, target_mem,
1347
1447
                                                        target_size);
1348
1448
                                }
 
1449
                                /*
 
1450
                                 * Check for internal wildcards.
 
1451
                                 */
 
1452
                                if ((lctx->options & DNS_MASTER_CHECKWILDCARD)
 
1453
                                                 != 0)
 
1454
                                        check_wildcard(ictx, source, line,
 
1455
                                                       callbacks);
 
1456
 
1349
1457
                        }
1350
1458
                        if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
1351
1459
                            (lctx->options & DNS_MASTER_SLAVE) == 0 &&
1367
1475
                } else {
1368
1476
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
1369
1477
                                         "%s:%lu: isc_lex_gettoken() returned "
1370
 
                                         "unexpeced token type (%d)",
 
1478
                                         "unexpected token type (%d)",
1371
1479
                                         source, line, token.type);
1372
1480
                        result = ISC_R_UNEXPECTED;
1373
1481
                        if (MANYERRS(lctx, result)) {
1508
1616
                        current_has_delegation = ISC_TRUE;
1509
1617
 
1510
1618
                /*
1511
 
                 * RFC 1123: MD and MF are not allowed to be loaded from
 
1619
                 * RFC1123: MD and MF are not allowed to be loaded from
1512
1620
                 * master files.
1513
1621
                 */
1514
1622
                if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
1571
1679
                        isc_boolean_t ok;
1572
1680
                        dns_name_t *name;
1573
1681
 
1574
 
                        name = (ictx->glue != NULL) ? ictx-> glue :
 
1682
                        name = (ictx->glue != NULL) ? ictx->glue :
1575
1683
                                                      ictx->current;
1576
1684
                        ok = dns_rdata_checkowner(name, lctx->zclass, type,
1577
1685
                                                  ISC_TRUE);
1581
1689
                                dns_name_format(name, namebuf, sizeof(namebuf));
1582
1690
                                result = DNS_R_BADOWNERNAME;
1583
1691
                                desc = dns_result_totext(result);
1584
 
                                if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) {
 
1692
                                if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) {
1585
1693
                                        (*callbacks->error)(callbacks,
1586
1694
                                                            "%s:%lu: %s: %s",
1587
1695
                                                            source, line,
1631
1739
                        dns_name_format(ictx->current, namebuf,
1632
1740
                                        sizeof(namebuf));
1633
1741
                        (*callbacks->error)(callbacks,
1634
 
                                            "%s:%lu: SOA "
1635
 
                                            "record not at top of zone (%s)",
1636
 
                                            source, line, namebuf);
 
1742
                                            "%s:%lu: SOA "
 
1743
                                            "record not at top of zone (%s)",
 
1744
                                            source, line, namebuf);
1637
1745
                        result = DNS_R_NOTZONETOP;
1638
1746
                        if (MANYERRS(lctx, result)) {
1639
1747
                                SETRESULT(lctx, result);
1686
1794
                } else if (!explicit_ttl && lctx->warn_1035) {
1687
1795
                        (*callbacks->warn)(callbacks,
1688
1796
                                           "%s:%lu: "
1689
 
                                           "using RFC 1035 TTL semantics",
 
1797
                                           "using RFC1035 TTL semantics",
1690
1798
                                           source, line);
1691
1799
                        lctx->warn_1035 = ISC_FALSE;
1692
1800
                }
1693
1801
 
1694
1802
                if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) {
1695
1803
                        dns_rdata_rrsig_t sig;
1696
 
                        (void)dns_rdata_tostruct(&rdata[rdcount], &sig, NULL);
 
1804
                        result = dns_rdata_tostruct(&rdata[rdcount], &sig,
 
1805
                                                    NULL);
 
1806
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
1697
1807
                        if (isc_serial_lt(sig.timeexpire, now)) {
1698
1808
                                (*callbacks->warn)(callbacks,
1699
1809
                                                   "%s:%lu: "
1705
1815
 
1706
1816
                if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) &&
1707
1817
                    lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 &&
1708
 
                    (lctx->options & DNS_MASTER_SLAVE) == 0) {
 
1818
                    (lctx->options & DNS_MASTER_SLAVE) == 0) {
1709
1819
                        (*callbacks->warn)(callbacks, "%s:%lu: old style DNSSEC "
1710
1820
                                           " zone detected", source, line);
1711
1821
                        lctx->warn_tcr = ISC_FALSE;
1763
1873
                                ISC_LIST_INITANDPREPEND(glue_list, this, link);
1764
1874
                        else
1765
1875
                                ISC_LIST_INITANDPREPEND(current_list, this,
1766
 
                                                        link);
 
1876
                                                        link);
1767
1877
                } else if (this->ttl != lctx->ttl) {
1768
1878
                        (*callbacks->warn)(callbacks,
1769
1879
                                           "%s:%lu: "
1773
1883
                }
1774
1884
 
1775
1885
                ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link);
1776
 
                if (ictx->glue != NULL) 
 
1886
                if (ictx->glue != NULL)
1777
1887
                        ictx->glue_line = line;
1778
1888
                else
1779
1889
                        ictx->current_line = line;
1879
1989
                new->drop = ictx->drop;
1880
1990
        }
1881
1991
 
1882
 
        result = isc_lex_openfile(lctx->lex, master_file);
 
1992
        result = (lctx->openfile)(lctx, master_file);
1883
1993
        if (result != ISC_R_SUCCESS)
1884
1994
                goto cleanup;
1885
1995
        new->parent = ictx;
1892
2002
        return (result);
1893
2003
}
1894
2004
 
 
2005
static inline isc_result_t
 
2006
read_and_check(isc_boolean_t do_read, isc_buffer_t *buffer,
 
2007
               size_t len, FILE *f)
 
2008
{
 
2009
        isc_result_t result;
 
2010
 
 
2011
        if (do_read) {
 
2012
                INSIST(isc_buffer_availablelength(buffer) >= len);
 
2013
                result = isc_stdio_read(isc_buffer_used(buffer), 1, len,
 
2014
                                        f, NULL);
 
2015
                if (result != ISC_R_SUCCESS)
 
2016
                        return (result);
 
2017
                isc_buffer_add(buffer, len);
 
2018
        } else if (isc_buffer_remaininglength(buffer) < len)
 
2019
                return (ISC_R_RANGE);
 
2020
 
 
2021
        return (ISC_R_SUCCESS);
 
2022
}
 
2023
 
 
2024
static isc_result_t
 
2025
load_raw(dns_loadctx_t *lctx) {
 
2026
        isc_result_t result = ISC_R_SUCCESS;
 
2027
        isc_boolean_t done = ISC_FALSE;
 
2028
        unsigned int loop_cnt = 0;
 
2029
        dns_rdatacallbacks_t *callbacks;
 
2030
        unsigned char namebuf[DNS_NAME_MAXWIRE];
 
2031
        isc_region_t r;
 
2032
        dns_name_t name;
 
2033
        rdatalist_head_t head, dummy;
 
2034
        dns_rdatalist_t rdatalist;
 
2035
        isc_mem_t *mctx = lctx->mctx;
 
2036
        dns_rdata_t *rdata = NULL;
 
2037
        unsigned int rdata_size = 0;
 
2038
        int target_size = TSIZ;
 
2039
        isc_buffer_t target;
 
2040
        unsigned char *target_mem = NULL;
 
2041
 
 
2042
        REQUIRE(DNS_LCTX_VALID(lctx));
 
2043
        callbacks = lctx->callbacks;
 
2044
 
 
2045
        if (lctx->first) {
 
2046
                dns_masterrawheader_t header;
 
2047
                isc_uint32_t format, version, dumptime;
 
2048
                size_t hdrlen = sizeof(format) + sizeof(version) +
 
2049
                        sizeof(dumptime);
 
2050
 
 
2051
                INSIST(hdrlen <= sizeof(header));
 
2052
                isc_buffer_init(&target, &header, sizeof(header));
 
2053
 
 
2054
                result = isc_stdio_read(&header, 1, hdrlen, lctx->f, NULL);
 
2055
                if (result != ISC_R_SUCCESS) {
 
2056
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
 
2057
                                         "isc_stdio_read failed: %s",
 
2058
                                         isc_result_totext(result));
 
2059
                        return (result);
 
2060
                }
 
2061
                isc_buffer_add(&target, hdrlen);
 
2062
                format = isc_buffer_getuint32(&target);
 
2063
                if (format != dns_masterformat_raw) {
 
2064
                        (*callbacks->error)(callbacks,
 
2065
                                            "dns_master_load: "
 
2066
                                            "file format mismatch");
 
2067
                        return (ISC_R_NOTIMPLEMENTED);
 
2068
                }
 
2069
 
 
2070
                version = isc_buffer_getuint32(&target);
 
2071
                if (version > DNS_RAWFORMAT_VERSION) {
 
2072
                        (*callbacks->error)(callbacks,
 
2073
                                            "dns_master_load: "
 
2074
                                            "unsupported file format version");
 
2075
                        return (ISC_R_NOTIMPLEMENTED);
 
2076
                }
 
2077
 
 
2078
                /* Empty read: currently, we do not use dumptime */
 
2079
                dumptime = isc_buffer_getuint32(&target);
 
2080
 
 
2081
                lctx->first = ISC_FALSE;
 
2082
        }
 
2083
 
 
2084
        ISC_LIST_INIT(head);
 
2085
        ISC_LIST_INIT(dummy);
 
2086
        dns_rdatalist_init(&rdatalist);
 
2087
 
 
2088
        /*
 
2089
         * Allocate target_size of buffer space.  This is greater than twice
 
2090
         * the maximum individual RR data size.
 
2091
         */
 
2092
        target_mem = isc_mem_get(mctx, target_size);
 
2093
        if (target_mem == NULL) {
 
2094
                result = ISC_R_NOMEMORY;
 
2095
                goto cleanup;
 
2096
        }
 
2097
        isc_buffer_init(&target, target_mem, target_size);
 
2098
 
 
2099
        /*
 
2100
         * In the following loop, we regard any error fatal regardless of
 
2101
         * whether "MANYERRORS" is set in the context option.  This is because
 
2102
         * normal errors should already have been checked at creation time.
 
2103
         * Besides, it is very unlikely that we can recover from an error
 
2104
         * in this format, and so trying to continue parsing erroneous data
 
2105
         * does not really make sense.
 
2106
         */
 
2107
        for (loop_cnt = 0;
 
2108
             (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt);
 
2109
             loop_cnt++) {
 
2110
                unsigned int i, rdcount, consumed_name;
 
2111
                isc_uint16_t namelen;
 
2112
                isc_uint32_t totallen;
 
2113
                size_t minlen, readlen;
 
2114
                isc_boolean_t sequential_read = ISC_FALSE;
 
2115
 
 
2116
                /* Read the data length */
 
2117
                isc_buffer_clear(&target);
 
2118
                INSIST(isc_buffer_availablelength(&target) >=
 
2119
                       sizeof(totallen));
 
2120
                result = isc_stdio_read(target.base, 1, sizeof(totallen),
 
2121
                                        lctx->f, NULL);
 
2122
                if (result == ISC_R_EOF) {
 
2123
                        result = ISC_R_SUCCESS;
 
2124
                        done = ISC_TRUE;
 
2125
                        break;
 
2126
                }
 
2127
                if (result != ISC_R_SUCCESS)
 
2128
                        goto cleanup;
 
2129
                isc_buffer_add(&target, sizeof(totallen));
 
2130
                totallen = isc_buffer_getuint32(&target);
 
2131
                /*
 
2132
                 * Validation: the input data must at least contain the common
 
2133
                 * header.
 
2134
                 */
 
2135
                minlen = sizeof(totallen) + sizeof(isc_uint16_t) +
 
2136
                        sizeof(isc_uint16_t) + sizeof(isc_uint16_t) +
 
2137
                        sizeof(isc_uint32_t) + sizeof(isc_uint32_t);
 
2138
                if (totallen < minlen) {
 
2139
                        result = ISC_R_RANGE;
 
2140
                        goto cleanup;
 
2141
                }
 
2142
                totallen -= sizeof(totallen);
 
2143
 
 
2144
                isc_buffer_clear(&target);
 
2145
                if (totallen > isc_buffer_availablelength(&target)) {
 
2146
                        /*
 
2147
                         * The default buffer size should typically be large
 
2148
                         * enough to store the entire RRset.  We could try to
 
2149
                         * allocate enough space if this is not the case, but
 
2150
                         * it might cause a hazardous result when "totallen"
 
2151
                         * is forged.  Thus, we'd rather take an inefficient
 
2152
                         * but robust approach in this atypical case: read
 
2153
                         * data step by step, and commit partial data when
 
2154
                         * necessary.  Note that the buffer must be large
 
2155
                         * enough to store the "header part", owner name, and
 
2156
                         * at least one rdata (however large it is).
 
2157
                         */
 
2158
                        sequential_read = ISC_TRUE;
 
2159
                        readlen = minlen - sizeof(totallen);
 
2160
                } else {
 
2161
                        /*
 
2162
                         * Typical case.  We can read the whole RRset at once
 
2163
                         * with the default buffer.
 
2164
                         */
 
2165
                        readlen = totallen;
 
2166
                }
 
2167
                result = isc_stdio_read(target.base, 1, readlen,
 
2168
                                        lctx->f, NULL);
 
2169
                if (result != ISC_R_SUCCESS)
 
2170
                        goto cleanup;
 
2171
                isc_buffer_add(&target, readlen);
 
2172
 
 
2173
                /* Construct RRset headers */
 
2174
                rdatalist.rdclass = isc_buffer_getuint16(&target);
 
2175
                rdatalist.type = isc_buffer_getuint16(&target);
 
2176
                rdatalist.covers = isc_buffer_getuint16(&target);
 
2177
                rdatalist.ttl =  isc_buffer_getuint32(&target);
 
2178
                rdcount = isc_buffer_getuint32(&target);
 
2179
                if (rdcount == 0) {
 
2180
                        result = ISC_R_RANGE;
 
2181
                        goto cleanup;
 
2182
                }
 
2183
                INSIST(isc_buffer_consumedlength(&target) <= readlen);
 
2184
 
 
2185
                /* Owner name: length followed by name */
 
2186
                result = read_and_check(sequential_read, &target,
 
2187
                                        sizeof(namelen), lctx->f);
 
2188
                if (result != ISC_R_SUCCESS)
 
2189
                        goto cleanup;
 
2190
                namelen = isc_buffer_getuint16(&target);
 
2191
                if (namelen > sizeof(namebuf)) {
 
2192
                        result = ISC_R_RANGE;
 
2193
                        goto cleanup;
 
2194
                }
 
2195
 
 
2196
                result = read_and_check(sequential_read, &target, namelen,
 
2197
                                        lctx->f);
 
2198
                if (result != ISC_R_SUCCESS)
 
2199
                        goto cleanup;
 
2200
                isc_buffer_setactive(&target, (unsigned int)namelen);
 
2201
                isc_buffer_activeregion(&target, &r);
 
2202
                dns_name_init(&name, NULL);
 
2203
                dns_name_fromregion(&name, &r);
 
2204
                isc_buffer_forward(&target, (unsigned int)namelen);
 
2205
                consumed_name = isc_buffer_consumedlength(&target);
 
2206
 
 
2207
                /* Rdata contents. */
 
2208
                if (rdcount > rdata_size) {
 
2209
                        dns_rdata_t *new_rdata = NULL;
 
2210
 
 
2211
                        new_rdata = grow_rdata(rdata_size + RDSZ, rdata,
 
2212
                                               rdata_size, &head,
 
2213
                                               &dummy, mctx);
 
2214
                        if (new_rdata == NULL) {
 
2215
                                result = ISC_R_NOMEMORY;
 
2216
                                goto cleanup;
 
2217
                        }
 
2218
                        rdata_size += RDSZ;
 
2219
                        rdata = new_rdata;
 
2220
                }
 
2221
 
 
2222
        continue_read:
 
2223
                for (i = 0; i < rdcount; i++) {
 
2224
                        isc_uint16_t rdlen;
 
2225
 
 
2226
                        dns_rdata_init(&rdata[i]);
 
2227
 
 
2228
                        if (sequential_read &&
 
2229
                            isc_buffer_availablelength(&target) < MINTSIZ) {
 
2230
                                unsigned int j;
 
2231
 
 
2232
                                INSIST(i > 0); /* detect an infinite loop */
 
2233
 
 
2234
                                /* Partial Commit. */
 
2235
                                ISC_LIST_APPEND(head, &rdatalist, link);
 
2236
                                result = commit(callbacks, lctx, &head, &name,
 
2237
                                                NULL, 0);
 
2238
                                for (j = 0; j < i; j++) {
 
2239
                                        ISC_LIST_UNLINK(rdatalist.rdata,
 
2240
                                                        &rdata[j], link);
 
2241
                                        dns_rdata_reset(&rdata[j]);
 
2242
                                }
 
2243
                                if (result != ISC_R_SUCCESS)
 
2244
                                        goto cleanup;
 
2245
 
 
2246
                                /* Rewind the buffer and continue */
 
2247
                                isc_buffer_clear(&target);
 
2248
                                isc_buffer_add(&target, consumed_name);
 
2249
                                isc_buffer_forward(&target, consumed_name);
 
2250
 
 
2251
                                rdcount -= i;
 
2252
                                i = 0;
 
2253
 
 
2254
                                goto continue_read;
 
2255
                        }
 
2256
 
 
2257
                        /* rdata length */
 
2258
                        result = read_and_check(sequential_read, &target,
 
2259
                                                sizeof(rdlen), lctx->f);
 
2260
                        if (result != ISC_R_SUCCESS)
 
2261
                                goto cleanup;
 
2262
                        rdlen = isc_buffer_getuint16(&target);
 
2263
 
 
2264
                        /* rdata */
 
2265
                        result = read_and_check(sequential_read, &target,
 
2266
                                                rdlen, lctx->f);
 
2267
                        if (result != ISC_R_SUCCESS)
 
2268
                                goto cleanup;
 
2269
                        isc_buffer_setactive(&target, (unsigned int)rdlen);
 
2270
                        isc_buffer_activeregion(&target, &r);
 
2271
                        isc_buffer_forward(&target, (unsigned int)rdlen);
 
2272
                        dns_rdata_fromregion(&rdata[i], rdatalist.rdclass,
 
2273
                                             rdatalist.type, &r);
 
2274
 
 
2275
                        ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link);
 
2276
                }
 
2277
 
 
2278
                /*
 
2279
                 * Sanity check.  Still having remaining space is not
 
2280
                 * necessarily critical, but it very likely indicates broken
 
2281
                 * or malformed data.
 
2282
                 */
 
2283
                if (isc_buffer_remaininglength(&target) != 0) {
 
2284
                        result = ISC_R_RANGE;
 
2285
                        goto cleanup;
 
2286
                }
 
2287
 
 
2288
                ISC_LIST_APPEND(head, &rdatalist, link);
 
2289
 
 
2290
                /* Commit this RRset.  rdatalist will be unlinked. */
 
2291
                result = commit(callbacks, lctx, &head, &name, NULL, 0);
 
2292
 
 
2293
                for (i = 0; i < rdcount; i++) {
 
2294
                        ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link);
 
2295
                        dns_rdata_reset(&rdata[i]);
 
2296
                }
 
2297
 
 
2298
                if (result != ISC_R_SUCCESS)
 
2299
                        goto cleanup;
 
2300
        }
 
2301
 
 
2302
        if (!done) {
 
2303
                INSIST(lctx->done != NULL && lctx->task != NULL);
 
2304
                result = DNS_R_CONTINUE;
 
2305
        } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS)
 
2306
                result = lctx->result;
 
2307
 
 
2308
 cleanup:
 
2309
        if (rdata != NULL)
 
2310
                isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
 
2311
        if (target_mem != NULL)
 
2312
                isc_mem_put(mctx, target_mem, target_size);
 
2313
        if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) {
 
2314
                (*callbacks->error)(callbacks, "dns_master_load: %s",
 
2315
                                    dns_result_totext(result));
 
2316
        }
 
2317
 
 
2318
        return (result);
 
2319
}
 
2320
 
1895
2321
isc_result_t
1896
2322
dns_master_loadfile(const char *master_file, dns_name_t *top,
1897
2323
                    dns_name_t *origin,
1898
2324
                    dns_rdataclass_t zclass, unsigned int options,
1899
2325
                    dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
1900
2326
{
 
2327
        return (dns_master_loadfile2(master_file, top, origin, zclass, options,
 
2328
                                     callbacks, mctx, dns_masterformat_text));
 
2329
}
 
2330
 
 
2331
isc_result_t
 
2332
dns_master_loadfile2(const char *master_file, dns_name_t *top,
 
2333
                     dns_name_t *origin,
 
2334
                     dns_rdataclass_t zclass, unsigned int options,
 
2335
                     dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
 
2336
                     dns_masterformat_t format)
 
2337
{
1901
2338
        dns_loadctx_t *lctx = NULL;
1902
2339
        isc_result_t result;
1903
2340
 
1904
 
        result = loadctx_create(mctx, options, top, zclass, origin,
 
2341
        result = loadctx_create(format, mctx, options, top, zclass, origin,
1905
2342
                                callbacks, NULL, NULL, NULL, NULL, &lctx);
1906
2343
        if (result != ISC_R_SUCCESS)
1907
2344
                return (result);
1908
2345
 
1909
 
        result = isc_lex_openfile(lctx->lex, master_file);
 
2346
        result = (lctx->openfile)(lctx, master_file);
1910
2347
        if (result != ISC_R_SUCCESS)
1911
2348
                goto cleanup;
1912
2349
 
1913
 
        result = load(lctx);
 
2350
        result = (lctx->load)(lctx);
1914
2351
        INSIST(result != DNS_R_CONTINUE);
1915
2352
 
1916
2353
 cleanup:
1917
 
        if (lctx != NULL)
1918
 
                dns_loadctx_detach(&lctx);
 
2354
        dns_loadctx_detach(&lctx);
1919
2355
        return (result);
1920
2356
}
1921
2357
 
1926
2362
                       isc_task_t *task, dns_loaddonefunc_t done,
1927
2363
                       void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx)
1928
2364
{
 
2365
        return (dns_master_loadfileinc2(master_file, top, origin, zclass,
 
2366
                                        options, callbacks, task, done,
 
2367
                                        done_arg, lctxp, mctx,
 
2368
                                        dns_masterformat_text));
 
2369
}
 
2370
 
 
2371
isc_result_t
 
2372
dns_master_loadfileinc2(const char *master_file, dns_name_t *top,
 
2373
                        dns_name_t *origin, dns_rdataclass_t zclass,
 
2374
                        unsigned int options, dns_rdatacallbacks_t *callbacks,
 
2375
                        isc_task_t *task, dns_loaddonefunc_t done,
 
2376
                        void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx,
 
2377
                        dns_masterformat_t format)
 
2378
{
1929
2379
        dns_loadctx_t *lctx = NULL;
1930
2380
        isc_result_t result;
1931
 
        
 
2381
 
1932
2382
        REQUIRE(task != NULL);
1933
2383
        REQUIRE(done != NULL);
1934
2384
 
1935
 
        result = loadctx_create(mctx, options, top, zclass, origin,
 
2385
        result = loadctx_create(format, mctx, options, top, zclass, origin,
1936
2386
                                callbacks, task, done, done_arg, NULL, &lctx);
1937
2387
        if (result != ISC_R_SUCCESS)
1938
2388
                return (result);
1939
2389
 
1940
 
        result = isc_lex_openfile(lctx->lex, master_file);
 
2390
        result = (lctx->openfile)(lctx, master_file);
1941
2391
        if (result != ISC_R_SUCCESS)
1942
2392
                goto cleanup;
1943
2393
 
1948
2398
        }
1949
2399
 
1950
2400
 cleanup:
1951
 
        if (lctx != NULL)
1952
 
                dns_loadctx_detach(&lctx);
 
2401
        dns_loadctx_detach(&lctx);
1953
2402
        return (result);
1954
2403
}
1955
2404
 
1963
2412
 
1964
2413
        REQUIRE(stream != NULL);
1965
2414
 
1966
 
        result = loadctx_create(mctx, options, top, zclass, origin,
1967
 
                                callbacks, NULL, NULL, NULL, NULL, &lctx);
 
2415
        result = loadctx_create(dns_masterformat_text, mctx, options, top,
 
2416
                                zclass, origin, callbacks, NULL, NULL, NULL,
 
2417
                                NULL, &lctx);
1968
2418
        if (result != ISC_R_SUCCESS)
1969
2419
                goto cleanup;
1970
2420
 
1972
2422
        if (result != ISC_R_SUCCESS)
1973
2423
                goto cleanup;
1974
2424
 
1975
 
        result = load(lctx);
 
2425
        result = (lctx->load)(lctx);
1976
2426
        INSIST(result != DNS_R_CONTINUE);
1977
2427
 
1978
2428
 cleanup:
1995
2445
        REQUIRE(task != NULL);
1996
2446
        REQUIRE(done != NULL);
1997
2447
 
1998
 
        result = loadctx_create(mctx, options, top, zclass, origin,
1999
 
                                callbacks, task, done, done_arg, NULL, &lctx);
 
2448
        result = loadctx_create(dns_masterformat_text, mctx, options, top,
 
2449
                                zclass, origin, callbacks, task, done,
 
2450
                                done_arg, NULL, &lctx);
2000
2451
        if (result != ISC_R_SUCCESS)
2001
2452
                goto cleanup;
2002
2453
 
2027
2478
 
2028
2479
        REQUIRE(buffer != NULL);
2029
2480
 
2030
 
        result = loadctx_create(mctx, options, top, zclass, origin,
2031
 
                                callbacks, NULL, NULL, NULL, NULL, &lctx);
 
2481
        result = loadctx_create(dns_masterformat_text, mctx, options, top,
 
2482
                                zclass, origin, callbacks, NULL, NULL, NULL,
 
2483
                                NULL, &lctx);
2032
2484
        if (result != ISC_R_SUCCESS)
2033
2485
                return (result);
2034
2486
 
2036
2488
        if (result != ISC_R_SUCCESS)
2037
2489
                goto cleanup;
2038
2490
 
2039
 
        result = load(lctx);
 
2491
        result = (lctx->load)(lctx);
2040
2492
        INSIST(result != DNS_R_CONTINUE);
2041
2493
 
2042
2494
 cleanup:
2043
 
        if (lctx != NULL)
2044
 
                dns_loadctx_detach(&lctx);
 
2495
        dns_loadctx_detach(&lctx);
2045
2496
        return (result);
2046
2497
}
2047
2498
 
2060
2511
        REQUIRE(task != NULL);
2061
2512
        REQUIRE(done != NULL);
2062
2513
 
2063
 
        result = loadctx_create(mctx, options, top, zclass, origin,
2064
 
                                callbacks, task, done, done_arg, NULL, &lctx);
 
2514
        result = loadctx_create(dns_masterformat_text, mctx, options, top,
 
2515
                                zclass, origin, callbacks, task, done,
 
2516
                                done_arg, NULL, &lctx);
2065
2517
        if (result != ISC_R_SUCCESS)
2066
2518
                return (result);
2067
2519
 
2076
2528
        }
2077
2529
 
2078
2530
 cleanup:
2079
 
        if (lctx != NULL)
2080
 
                dns_loadctx_detach(&lctx);
 
2531
        dns_loadctx_detach(&lctx);
2081
2532
        return (result);
2082
2533
}
2083
2534
 
2092
2543
 
2093
2544
        REQUIRE(lex != NULL);
2094
2545
 
2095
 
        result = loadctx_create(mctx, options, top, zclass, origin,
2096
 
                                callbacks, NULL, NULL, NULL, lex, &lctx);
 
2546
        result = loadctx_create(dns_masterformat_text, mctx, options, top,
 
2547
                                zclass, origin, callbacks, NULL, NULL, NULL,
 
2548
                                lex, &lctx);
2097
2549
        if (result != ISC_R_SUCCESS)
2098
2550
                return (result);
2099
2551
 
2100
 
        result = load(lctx);
 
2552
        result = (lctx->load)(lctx);
2101
2553
        INSIST(result != DNS_R_CONTINUE);
2102
2554
 
2103
2555
        dns_loadctx_detach(&lctx);
2119
2571
        REQUIRE(task != NULL);
2120
2572
        REQUIRE(done != NULL);
2121
2573
 
2122
 
        result = loadctx_create(mctx, options, top, zclass, origin,
2123
 
                                callbacks, task, done, done_arg, lex, &lctx);
 
2574
        result = loadctx_create(dns_masterformat_text, mctx, options, top,
 
2575
                                zclass, origin, callbacks, task, done,
 
2576
                                done_arg, lex, &lctx);
2124
2577
        if (result != ISC_R_SUCCESS)
2125
2578
                return (result);
2126
2579
 
2281
2734
                } else if (result != ISC_R_SUCCESS) {
2282
2735
                        dns_name_format(owner, namebuf,
2283
2736
                                        sizeof(namebuf));
2284
 
                        (*error)(callbacks, "%s: %s:%lu: %s: %s",
2285
 
                                 "dns_master_load", source, line,
2286
 
                                 namebuf, dns_result_totext(result));
 
2737
                        if (source != NULL) {
 
2738
                                (*error)(callbacks, "%s: %s:%lu: %s: %s",
 
2739
                                         "dns_master_load", source, line,
 
2740
                                         namebuf, dns_result_totext(result));
 
2741
                        } else {
 
2742
                                (*error)(callbacks, "%s: %s: %s",
 
2743
                                         "dns_master_load", namebuf,
 
2744
                                         dns_result_totext(result));
 
2745
                        }
2287
2746
                }
2288
2747
                if (MANYERRS(lctx, result))
2289
2748
                        SETRESULT(lctx, result);
2342
2801
        if (lctx->canceled)
2343
2802
                result = ISC_R_CANCELED;
2344
2803
        else
2345
 
                result = load(lctx);
 
2804
                result = (lctx->load)(lctx);
2346
2805
        if (result == DNS_R_CONTINUE) {
2347
2806
                event->ev_arg = lctx;
2348
2807
                isc_task_send(task, &event);