From 9db6bf201a535ab6893889937d18afeb1f9b9f00 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Vavru=C5=A1a?= Date: Sun, 19 Jul 2015 00:55:29 +0200 Subject: [PATCH] lib/resolve: per-request options, worker.resolve() support --- daemon/README.rst | 3 ++- daemon/bindings.c | 13 ++++++++++++- daemon/worker.c | 5 +++-- daemon/worker.h | 2 +- lib/resolve.c | 3 ++- lib/resolve.h | 1 + lib/rplan.c | 6 +++--- lib/rplan.h | 6 +++--- tests/test_rplan.c | 5 +++-- 9 files changed, 30 insertions(+), 14 deletions(-) diff --git a/daemon/README.rst b/daemon/README.rst index c6c495f11..c9a0309e8 100644 --- a/daemon/README.rst +++ b/daemon/README.rst @@ -521,11 +521,12 @@ you can see the statistics or schedule new queries. print(worker.stats().concurrent) -.. function:: worker.resolve(qname, qtype[, qclass = kres.class.IN]) +.. function:: worker.resolve(qname, qtype[, qclass = kres.class.IN, options = 0]) :param string qname: Query name (e.g. 'com.') :param number qtype: Query type (e.g. ``kres.type.NS``) :param number qclass: Query class *(optional)* (e.g. ``kres.class.IN``) + :param number options: Resolution options (see query flags) :return: boolean Resolve a query, there is currently no callback when its finished, but you can track the query diff --git a/daemon/bindings.c b/daemon/bindings.c index 419703dfe..29af9e62d 100644 --- a/daemon/bindings.c +++ b/daemon/bindings.c @@ -578,8 +578,19 @@ static int wrk_resolve(lua_State *L) } knot_pkt_put_question(pkt, dname, rrclass, rrtype); knot_wire_set_rd(pkt->wire); + /* Add OPT RR */ + pkt->opt_rr = mm_alloc(&pkt->mm, sizeof(*pkt->opt_rr)); + if (!pkt->opt_rr) { + return kr_error(ENOMEM); + } + int ret = knot_edns_init(pkt->opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, &pkt->mm); + if (ret != 0) { + knot_pkt_free(&pkt); + return 0; + } /* Resolve it */ - int ret = worker_resolve(worker, pkt); + unsigned options = lua_tointeger(L, 4); + ret = worker_resolve(worker, pkt, options); knot_pkt_free(&pkt); lua_pushboolean(L, ret == 0); return 1; diff --git a/daemon/worker.c b/daemon/worker.c index 85cffe386..31586bd29 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -93,7 +93,7 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha { /* How much can client handle? */ size_t answer_max = KNOT_WIRE_MIN_PKTSIZE; - if (!addr) { /* TCP */ + if (!addr && handle) { /* TCP */ answer_max = KNOT_WIRE_MAX_PKTSIZE; } else if (knot_pkt_has_edns(query)) { /* EDNS */ answer_max = MAX(knot_edns_get_payload(query->opt_rr), KNOT_WIRE_MIN_PKTSIZE); @@ -404,7 +404,7 @@ int worker_exec(struct worker_ctx *worker, uv_handle_t *handle, knot_pkt_t *quer return qr_task_step(task, query); } -int worker_resolve(struct worker_ctx *worker, knot_pkt_t *query) +int worker_resolve(struct worker_ctx *worker, knot_pkt_t *query, unsigned options) { if (!worker) { return kr_error(EINVAL); @@ -415,6 +415,7 @@ int worker_resolve(struct worker_ctx *worker, knot_pkt_t *query) if (!task) { return kr_error(ENOMEM); } + task->req.options |= options; return qr_task_step(task, query); } diff --git a/daemon/worker.h b/daemon/worker.h index 6364761d6..21cc0b97a 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -58,7 +58,7 @@ int worker_exec(struct worker_ctx *worker, uv_handle_t *handle, knot_pkt_t *quer * Schedule query for resolution. * @return 0 or an error code */ -int worker_resolve(struct worker_ctx *worker, knot_pkt_t *query); +int worker_resolve(struct worker_ctx *worker, knot_pkt_t *query, unsigned options); /** Reserve worker buffers */ int worker_reserve(struct worker_ctx *worker, size_t ring_maxlen); diff --git a/lib/resolve.c b/lib/resolve.c index bc51b1784..84ef95baf 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -345,13 +345,14 @@ int kr_resolve(struct kr_context* ctx, knot_pkt_t *answer, int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pkt_t *answer) { /* Initialize request */ - kr_rplan_init(&request->rplan, ctx, &request->pool); knot_overlay_init(&request->overlay, &request->pool); request->ctx = ctx; request->answer = answer; + request->options = ctx->options; prepare_layers(request); /* Expect first query */ + kr_rplan_init(&request->rplan, request, &request->pool); return KNOT_STATE_CONSUME; } diff --git a/lib/resolve.h b/lib/resolve.h index 8a976229d..fbc207b86 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -128,6 +128,7 @@ struct kr_request { struct knot_overlay overlay; knot_pkt_t *answer; mm_ctx_t pool; + uint32_t options; }; /** diff --git a/lib/rplan.c b/lib/rplan.c index cbf3a130d..11760a99a 100644 --- a/lib/rplan.c +++ b/lib/rplan.c @@ -65,7 +65,7 @@ static void query_free(mm_ctx_t *pool, struct kr_query *qry) mm_free(pool, qry); } -int kr_rplan_init(struct kr_rplan *rplan, struct kr_context *context, mm_ctx_t *pool) +int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, mm_ctx_t *pool) { if (rplan == NULL) { return KNOT_EINVAL; @@ -74,7 +74,7 @@ int kr_rplan_init(struct kr_rplan *rplan, struct kr_context *context, mm_ctx_t * memset(rplan, 0, sizeof(struct kr_rplan)); rplan->pool = pool; - rplan->context = context; + rplan->request = request; init_list(&rplan->pending); init_list(&rplan->resolved); return KNOT_EOK; @@ -117,7 +117,7 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent, } qry->sclass = cls; qry->stype = type; - qry->flags = rplan->context->options; + qry->flags = rplan->request->options; qry->parent = parent; gettimeofday(&qry->timestamp, NULL); add_tail(&rplan->pending, &qry->node); diff --git a/lib/rplan.h b/lib/rplan.h index ccf300a1b..a459f4c5b 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -75,17 +75,17 @@ struct kr_query { struct kr_rplan { list_t pending; /**< List of pending queries. */ list_t resolved; /**< List of resolved queries. */ - struct kr_context *context; /**< Parent resolution context. */ + struct kr_request *request; /**< Parent resolution request. */ mm_ctx_t *pool; /**< Temporary memory pool. */ }; /** * Initialize resolution plan (empty). * @param rplan plan instance - * @param context resolution context + * @param request resolution request * @param pool ephemeral memory pool for whole resolution */ -int kr_rplan_init(struct kr_rplan *rplan, struct kr_context *context, mm_ctx_t *pool); +int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, mm_ctx_t *pool); /** * Deinitialize resolution plan, aborting any uncommited transactions. diff --git a/tests/test_rplan.c b/tests/test_rplan.c index d5eb1faba..5a8eb3ed6 100644 --- a/tests/test_rplan.c +++ b/tests/test_rplan.c @@ -44,8 +44,9 @@ static void test_rplan_push(void **state) { mm_ctx_t mm; test_mm_ctx_init(&mm); - struct kr_context context = { - .pool = &mm, + struct kr_request request = { + .pool = mm, + .flags = 0, }; struct kr_rplan rplan; -- 2.47.2