#include "daemon/worker.h"
+/** resolve_pkt(pkt, options, init_cb) */
static int wrk_resolve_pkt(lua_State *L)
{
struct worker_ctx *worker = wrk_luaget(L);
return 0;
}
- // FIXME: merge with wrk_resolve
- const struct kr_qflags options = {};
knot_pkt_t *pkt = *(knot_pkt_t **)lua_topointer(L, 1);
if (!pkt)
lua_error_maybe(L, ENOMEM);
- /* Create task and start with a first question */
+ /* Add query options */
+ const struct kr_qflags *options = lua_topointer(L, 2);
+ if (!options) /* but we rely on the lua wrapper when dereferencing non-NULL */
+ lua_error_p(L, "invalid options");
- struct qr_task *task = worker_resolve_start(worker, pkt, options);
+ /* Create task and start with a first question */
+ struct qr_task *task = worker_resolve_start(worker, pkt, *options);
if (!task) {
lua_error_p(L, "couldn't create a resolution request");
}
/* Add initialisation callback */
- if (lua_isfunction(L, 2)) {
- lua_pushvalue(L, 2);
+ if (lua_isfunction(L, 3)) {
+ lua_pushvalue(L, 3);
lua_pushlightuserdata(L, worker_task_request(task));
(void) execute_callback(L, 1);
}
return 1;
}
+/** resolve(qname, qtype, qclass, options, init_cb) */
static int wrk_resolve(lua_State *L)
{
struct worker_ctx *worker = wrk_luaget(L);
knot_wire_set_cd(pkt->wire);
}
- /* Create task and start with a first question */
- struct qr_task *task = worker_resolve_start(worker, pkt, *options);
- if (!task) {
- knot_rrset_free(pkt->opt_rr, NULL);
- knot_pkt_free(pkt);
- lua_error_p(L, "couldn't create a resolution request");
- }
-
- /* Add initialisation callback */
- if (lua_isfunction(L, 5)) {
- lua_pushvalue(L, 5);
- lua_pushlightuserdata(L, worker_task_request(task));
- (void) execute_callback(L, 1);
- }
+ lua_pushcfunction(L, wrk_resolve_pkt);
+ lua_pushlightuserdata(L, &pkt);
+ lua_pushvalue(L, 4); /* options */
+ lua_pushvalue(L, 5); /* init_cb */
+ lua_call(L, 3, 1); /* leaves return value on stack */
- /* Start execution */
- int ret = worker_resolve_exec(task, pkt);
- lua_pushboolean(L, ret == 0);
knot_rrset_free(pkt->opt_rr, NULL);
knot_pkt_free(pkt);
return 1;
todname = kres.str2dname
end
--- Compatibility wrapper for query flags.
-worker.resolve = function (qname, qtype, qclass, options, finish, init)
- -- Alternatively use named arguments
- if type(qname) == 'table' then
- local t = qname
- qname = t.name
- qtype = t.type or kres.type.A
- qclass = t.class or kres.class.IN
- options = t.options
- finish = t.finish
- init = t.init
- end
-
+local function prep_resolve_cb(finish, init)
local init_cb, finish_cb = init, nil
if finish then
-- Create callback for finalization
req.trace_finish = finish_cb
end
end
-
- -- Translate options and resolve
- options = kres.mk_qflags(options)
- return worker.resolve_unwrapped(qname, qtype, qclass, options, init_cb)
+ return init_cb
end
-worker.resolve_pkt = function (pkt, finish, init)
- local init_cb, finish_cb = init, nil
- if finish then
- -- Create callback for finalization
- finish_cb = ffi.cast('trace_callback_f', function (req)
- req = kres.request_t(req)
- finish(req.answer, req)
- finish_cb:free()
- end)
- -- Wrap initialiser to install finish callback
- init_cb = function (req)
- req = kres.request_t(req)
- if init then init(req) end
- req.trace_finish = finish_cb
- end
+-- Compatibility wrapper for query flags.
+worker.resolve = function (qname, qtype, qclass, options, finish, init)
+ -- Alternatively use named arguments
+ if type(qname) == 'table' then
+ local t = qname
+ qname = t.name
+ qtype = t.type or kres.type.A
+ qclass = t.class or kres.class.IN
+ options = t.options
+ finish = t.finish
+ init = t.init
end
+ local init_cb = prep_resolve_cb(finish, init)
-- Translate options and resolve
- return worker.resolve_unwrapped_pkt(pkt, init_cb)
+ options = kres.mk_qflags(options)
+ return worker.resolve_unwrapped(qname, qtype, qclass, options, init_cb)
end
+worker.resolve_pkt = function (pkt, options, finish, init)
+ local init_cb = prep_resolve_cb(finish, init)
+ options = kres.mk_qflags(options)
+ return worker.resolve_unwrapped_pkt(pkt, options, init_cb)
+end
resolve = worker.resolve