1892
2002
return (result);
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)
2009
isc_result_t result;
2012
INSIST(isc_buffer_availablelength(buffer) >= len);
2013
result = isc_stdio_read(isc_buffer_used(buffer), 1, len,
2015
if (result != ISC_R_SUCCESS)
2017
isc_buffer_add(buffer, len);
2018
} else if (isc_buffer_remaininglength(buffer) < len)
2019
return (ISC_R_RANGE);
2021
return (ISC_R_SUCCESS);
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];
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;
2042
REQUIRE(DNS_LCTX_VALID(lctx));
2043
callbacks = lctx->callbacks;
2046
dns_masterrawheader_t header;
2047
isc_uint32_t format, version, dumptime;
2048
size_t hdrlen = sizeof(format) + sizeof(version) +
2051
INSIST(hdrlen <= sizeof(header));
2052
isc_buffer_init(&target, &header, sizeof(header));
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));
2061
isc_buffer_add(&target, hdrlen);
2062
format = isc_buffer_getuint32(&target);
2063
if (format != dns_masterformat_raw) {
2064
(*callbacks->error)(callbacks,
2066
"file format mismatch");
2067
return (ISC_R_NOTIMPLEMENTED);
2070
version = isc_buffer_getuint32(&target);
2071
if (version > DNS_RAWFORMAT_VERSION) {
2072
(*callbacks->error)(callbacks,
2074
"unsupported file format version");
2075
return (ISC_R_NOTIMPLEMENTED);
2078
/* Empty read: currently, we do not use dumptime */
2079
dumptime = isc_buffer_getuint32(&target);
2081
lctx->first = ISC_FALSE;
2084
ISC_LIST_INIT(head);
2085
ISC_LIST_INIT(dummy);
2086
dns_rdatalist_init(&rdatalist);
2089
* Allocate target_size of buffer space. This is greater than twice
2090
* the maximum individual RR data size.
2092
target_mem = isc_mem_get(mctx, target_size);
2093
if (target_mem == NULL) {
2094
result = ISC_R_NOMEMORY;
2097
isc_buffer_init(&target, target_mem, target_size);
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.
2108
(lctx->loop_cnt == 0 || loop_cnt < lctx->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;
2116
/* Read the data length */
2117
isc_buffer_clear(&target);
2118
INSIST(isc_buffer_availablelength(&target) >=
2120
result = isc_stdio_read(target.base, 1, sizeof(totallen),
2122
if (result == ISC_R_EOF) {
2123
result = ISC_R_SUCCESS;
2127
if (result != ISC_R_SUCCESS)
2129
isc_buffer_add(&target, sizeof(totallen));
2130
totallen = isc_buffer_getuint32(&target);
2132
* Validation: the input data must at least contain the common
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;
2142
totallen -= sizeof(totallen);
2144
isc_buffer_clear(&target);
2145
if (totallen > isc_buffer_availablelength(&target)) {
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).
2158
sequential_read = ISC_TRUE;
2159
readlen = minlen - sizeof(totallen);
2162
* Typical case. We can read the whole RRset at once
2163
* with the default buffer.
2167
result = isc_stdio_read(target.base, 1, readlen,
2169
if (result != ISC_R_SUCCESS)
2171
isc_buffer_add(&target, readlen);
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);
2180
result = ISC_R_RANGE;
2183
INSIST(isc_buffer_consumedlength(&target) <= readlen);
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)
2190
namelen = isc_buffer_getuint16(&target);
2191
if (namelen > sizeof(namebuf)) {
2192
result = ISC_R_RANGE;
2196
result = read_and_check(sequential_read, &target, namelen,
2198
if (result != ISC_R_SUCCESS)
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);
2207
/* Rdata contents. */
2208
if (rdcount > rdata_size) {
2209
dns_rdata_t *new_rdata = NULL;
2211
new_rdata = grow_rdata(rdata_size + RDSZ, rdata,
2214
if (new_rdata == NULL) {
2215
result = ISC_R_NOMEMORY;
2223
for (i = 0; i < rdcount; i++) {
2226
dns_rdata_init(&rdata[i]);
2228
if (sequential_read &&
2229
isc_buffer_availablelength(&target) < MINTSIZ) {
2232
INSIST(i > 0); /* detect an infinite loop */
2234
/* Partial Commit. */
2235
ISC_LIST_APPEND(head, &rdatalist, link);
2236
result = commit(callbacks, lctx, &head, &name,
2238
for (j = 0; j < i; j++) {
2239
ISC_LIST_UNLINK(rdatalist.rdata,
2241
dns_rdata_reset(&rdata[j]);
2243
if (result != ISC_R_SUCCESS)
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);
2258
result = read_and_check(sequential_read, &target,
2259
sizeof(rdlen), lctx->f);
2260
if (result != ISC_R_SUCCESS)
2262
rdlen = isc_buffer_getuint16(&target);
2265
result = read_and_check(sequential_read, &target,
2267
if (result != ISC_R_SUCCESS)
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);
2275
ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link);
2279
* Sanity check. Still having remaining space is not
2280
* necessarily critical, but it very likely indicates broken
2281
* or malformed data.
2283
if (isc_buffer_remaininglength(&target) != 0) {
2284
result = ISC_R_RANGE;
2288
ISC_LIST_APPEND(head, &rdatalist, link);
2290
/* Commit this RRset. rdatalist will be unlinked. */
2291
result = commit(callbacks, lctx, &head, &name, NULL, 0);
2293
for (i = 0; i < rdcount; i++) {
2294
ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link);
2295
dns_rdata_reset(&rdata[i]);
2298
if (result != ISC_R_SUCCESS)
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;
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));
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)
2327
return (dns_master_loadfile2(master_file, top, origin, zclass, options,
2328
callbacks, mctx, dns_masterformat_text));
2332
dns_master_loadfile2(const char *master_file, dns_name_t *top,
2334
dns_rdataclass_t zclass, unsigned int options,
2335
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
2336
dns_masterformat_t format)
1901
2338
dns_loadctx_t *lctx = NULL;
1902
2339
isc_result_t result;
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);
1909
result = isc_lex_openfile(lctx->lex, master_file);
2346
result = (lctx->openfile)(lctx, master_file);
1910
2347
if (result != ISC_R_SUCCESS)
1913
result = load(lctx);
2350
result = (lctx->load)(lctx);
1914
2351
INSIST(result != DNS_R_CONTINUE);
1918
dns_loadctx_detach(&lctx);
2354
dns_loadctx_detach(&lctx);
1919
2355
return (result);