#include <isc/stdtime.h>
#include <isc/string.h>
#include <isc/util.h>
+#include <isc/work.h>
#include <dns/callbacks.h>
#include <dns/events.h>
dns_masterformat_t format;
dns_rdatacallbacks_t *callbacks;
- isc_loop_t *loop;
dns_loaddonefunc_t done;
void *done_arg;
dns_masterrawheader_t header;
/* Which fixed buffers we are using? */
- unsigned int loop_cnt; /*% records per quantum,
- * 0 => all. */
isc_result_t result;
/* Atomic */
grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
isc_mem_t *);
-static void
-load_quantum(void *arg);
-
static void
loadctx_destroy(dns_loadctx_t *lctx);
((result != ISC_R_SUCCESS) && (result != ISC_R_IOERROR) && \
((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
-#define SETRESULT(lctx, r) \
- do { \
- if ((lctx)->result == ISC_R_SUCCESS) \
- (lctx)->result = r; \
- } while (0)
+#define SETRESULT(lctx, r) \
+ if ((lctx)->result == ISC_R_SUCCESS) { \
+ (lctx)->result = r; \
+ }
#define LOGITFILE(result, filename) \
if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \
isc_lex_destroy(&lctx->lex);
}
- if (lctx->loop != NULL) {
- isc_loop_detach(&lctx->loop);
- }
-
isc_mem_putanddetach(&lctx->mctx, lctx, sizeof(*lctx));
}
-static isc_result_t
+static void
incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) {
dns_incctx_t *ictx;
isc_region_t r;
ictx->origin_changed = true;
*ictxp = ictx;
- return (ISC_R_SUCCESS);
}
-static isc_result_t
+static void
loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options,
uint32_t resign, dns_name_t *top, dns_rdataclass_t zclass,
dns_name_t *origin, dns_rdatacallbacks_t *callbacks,
- isc_loop_t *loop, dns_loaddonefunc_t done, void *done_arg,
+ dns_loaddonefunc_t done, void *done_arg,
dns_masterincludecb_t include_cb, void *include_arg,
isc_lex_t *lex, dns_loadctx_t **lctxp) {
dns_loadctx_t *lctx = NULL;
- isc_result_t result;
isc_region_t r;
- isc_lexspecials_t specials;
REQUIRE(lctxp != NULL && *lctxp == NULL);
REQUIRE(callbacks != NULL);
REQUIRE(mctx != NULL);
REQUIRE(dns_name_isabsolute(top));
REQUIRE(dns_name_isabsolute(origin));
- REQUIRE((loop == NULL && done == NULL) ||
- (loop != NULL && done != NULL));
lctx = isc_mem_get(mctx, sizeof(*lctx));
*lctx = (dns_loadctx_t){
.done = done,
.callbacks = callbacks,
.done_arg = done_arg,
- .loop_cnt = (done != NULL) ? 100 : 0,
-
};
- result = incctx_create(mctx, origin, &lctx->inc);
- if (result != ISC_R_SUCCESS) {
- goto cleanup_ctx;
- }
+ incctx_create(mctx, origin, &lctx->inc);
switch (format) {
case dns_masterformat_text:
lctx->lex = lex;
lctx->keep_lex = true;
} else {
+ isc_lexspecials_t specials;
lctx->lex = NULL;
isc_lex_create(mctx, TOKENSIZ, &lctx->lex);
lctx->keep_lex = false;
dns_master_initrawheader(&lctx->header);
- if (loop != NULL) {
- isc_loop_attach(loop, &lctx->loop);
- }
-
isc_refcount_init(&lctx->references, 1); /* Implicit attach. */
isc_mem_attach(mctx, &lctx->mctx);
lctx->magic = DNS_LCTX_MAGIC;
*lctxp = lctx;
- return (ISC_R_SUCCESS);
-
-cleanup_ctx:
- isc_mem_put(mctx, lctx, sizeof(*lctx));
- return (result);
+ return;
}
static const char *hex = "0123456789abcdef0123456789ABCDEF";
uint32_t ttl_offset = 0;
dns_name_t *new_name;
bool current_has_delegation = false;
- bool done = false;
bool finish_origin = false;
bool finish_include = false;
bool read_till_eol = false;
unsigned char *target_mem = NULL;
int target_size = TSIZ;
int new_in_use;
- unsigned int loop_cnt = 0;
isc_mem_t *mctx;
dns_rdatacallbacks_t *callbacks;
dns_incctx_t *ictx;
options |= DNS_RDATA_CHECKMXFAIL;
}
source = isc_lex_getsourcename(lctx->lex);
- do {
+ while (true) {
+ if (atomic_load_acquire(&lctx->canceled)) {
+ result = ISC_R_CANCELED;
+ goto log_and_cleanup;
+ }
+
initialws = false;
line = isc_lex_getsourceline(lctx->lex);
GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING,
ictx = lctx->inc;
continue;
}
- done = true;
- continue;
+ break;
}
if (token.type == isc_tokentype_eol) {
SETRESULT(lctx, result);
read_till_eol = true;
continue;
- } else if (result != ISC_R_SUCCESS) {
+ } else {
goto insist_and_cleanup;
}
}
COMMITALL;
}
next_line:;
- } while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt));
+ }
/*
* Commit what has not yet been committed.
SETRESULT(lctx, result);
} else if (result != ISC_R_SUCCESS) {
goto insist_and_cleanup;
- }
-
- if (!done) {
- INSIST(lctx->done != NULL && lctx->loop != NULL);
- result = DNS_R_CONTINUE;
- } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
+ } else if (lctx->result != ISC_R_SUCCESS) {
result = lctx->result;
- } else if (result == ISC_R_SUCCESS && lctx->seen_include) {
+ } else if (lctx->seen_include) {
result = DNS_R_SEENINCLUDE;
}
+
goto cleanup;
log_and_cleanup:
if (rhs != NULL) {
isc_mem_free(mctx, rhs);
}
+
return (result);
}
ictx = lctx->inc;
lctx->seen_include = true;
- result = incctx_create(lctx->mctx, origin, &newctx);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
+ incctx_create(lctx->mctx, origin, &newctx);
/*
* Push origin_changed.
static isc_result_t
load_raw(dns_loadctx_t *lctx) {
isc_result_t result = ISC_R_SUCCESS;
- bool done = false;
- unsigned int loop_cnt = 0;
dns_rdatacallbacks_t *callbacks;
unsigned char namebuf[DNS_NAME_MAXWIRE];
dns_fixedname_t fixed;
* in this format, and so trying to continue parsing erroneous data
* does not really make sense.
*/
- for (loop_cnt = 0; (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt);
- loop_cnt++)
- {
+ while (true) {
unsigned int i, rdcount;
uint16_t namelen;
uint32_t totallen;
lctx->f, NULL);
if (result == ISC_R_EOF) {
result = ISC_R_SUCCESS;
- done = true;
break;
}
if (result != ISC_R_SUCCESS) {
}
}
- if (!done) {
- INSIST(lctx->done != NULL && lctx->loop != NULL);
- result = DNS_R_CONTINUE;
- } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
+ if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
result = lctx->result;
}
if (target_mem != NULL) {
isc_mem_put(mctx, target_mem, target_size);
}
- if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) {
+ if (result != ISC_R_SUCCESS) {
(*callbacks->error)(callbacks, "dns_master_load: %s",
isc_result_totext(result));
}
dns_loadctx_t *lctx = NULL;
isc_result_t result;
- result = loadctx_create(format, mctx, options, resign, top, zclass,
- origin, callbacks, NULL, NULL, NULL, include_cb,
- include_arg, NULL, &lctx);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
+ loadctx_create(format, mctx, options, resign, top, zclass, origin,
+ callbacks, NULL, NULL, include_cb, include_arg, NULL,
+ &lctx);
lctx->maxttl = maxttl;
return (result);
}
+static void
+load(void *arg) {
+ dns_loadctx_t *lctx = arg;
+ lctx->result = (lctx->load)(lctx);
+}
+
+static void
+load_done(void *arg) {
+ dns_loadctx_t *lctx = arg;
+
+ (lctx->done)(lctx->done_arg, lctx->result);
+ dns_loadctx_detach(&lctx);
+}
+
isc_result_t
-dns_master_loadfileinc(const char *master_file, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options, uint32_t resign,
- dns_rdatacallbacks_t *callbacks, isc_loop_t *loop,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **lctxp, dns_masterincludecb_t include_cb,
- void *include_arg, isc_mem_t *mctx,
- dns_masterformat_t format, uint32_t maxttl) {
+dns_master_loadfileasync(const char *master_file, dns_name_t *top,
+ dns_name_t *origin, dns_rdataclass_t zclass,
+ unsigned int options, uint32_t resign,
+ dns_rdatacallbacks_t *callbacks, isc_loop_t *loop,
+ dns_loaddonefunc_t done, void *done_arg,
+ dns_loadctx_t **lctxp,
+ dns_masterincludecb_t include_cb, void *include_arg,
+ isc_mem_t *mctx, dns_masterformat_t format,
+ uint32_t maxttl) {
dns_loadctx_t *lctx = NULL;
isc_result_t result;
REQUIRE(loop != NULL);
REQUIRE(done != NULL);
- result = loadctx_create(format, mctx, options, resign, top, zclass,
- origin, callbacks, loop, done, done_arg,
- include_cb, include_arg, NULL, &lctx);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
+ loadctx_create(format, mctx, options, resign, top, zclass, origin,
+ callbacks, done, done_arg, include_cb, include_arg, NULL,
+ &lctx);
lctx->maxttl = maxttl;
return (result);
}
- isc_async_run(loop, load_quantum, lctx);
dns_loadctx_attach(lctx, lctxp);
- return (DNS_R_CONTINUE);
+ isc_work_enqueue(loop, load, load_done, lctx);
+
+ return (ISC_R_SUCCESS);
}
isc_result_t
REQUIRE(stream != NULL);
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, NULL, NULL, NULL,
- NULL, NULL, NULL, &lctx);
- if (result != ISC_R_SUCCESS) {
- goto cleanup;
- }
+ loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass,
+ origin, callbacks, NULL, NULL, NULL, NULL, NULL, &lctx);
result = isc_lex_openstream(lctx->lex, stream);
if (result != ISC_R_SUCCESS) {
- dns_loadctx_detach(&lctx);
- return (result);
+ goto cleanup;
}
result = (lctx->load)(lctx);
INSIST(result != DNS_R_CONTINUE);
cleanup:
- if (lctx != NULL) {
- dns_loadctx_detach(&lctx);
- }
+ dns_loadctx_detach(&lctx);
return (result);
}
REQUIRE(buffer != NULL);
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, NULL, NULL, NULL,
- NULL, NULL, NULL, &lctx);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
+ loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass,
+ origin, callbacks, NULL, NULL, NULL, NULL, NULL, &lctx);
result = isc_lex_openbuffer(lctx->lex, buffer);
if (result != ISC_R_SUCCESS) {
return (false);
}
-static void
-load_quantum(void *arg) {
- isc_result_t result;
- dns_loadctx_t *lctx = (dns_loadctx_t *)arg;
-
- REQUIRE(DNS_LCTX_VALID(lctx));
-
- if (atomic_load_acquire(&lctx->canceled)) {
- result = ISC_R_CANCELED;
- } else {
- result = (lctx->load)(lctx);
- }
- if (result == DNS_R_CONTINUE) {
- isc_async_run(lctx->loop, load_quantum, lctx);
- } else {
- (lctx->done)(lctx->done_arg, result);
- dns_loadctx_detach(&lctx);
- }
-}
-
void
dns_loadctx_cancel(dns_loadctx_t *lctx) {
REQUIRE(DNS_LCTX_VALID(lctx));