From: Marek Vavrusa Date: Thu, 16 Jun 2016 17:39:07 +0000 (-0700) Subject: daemon/worker: track query in BEGIN and dst addr X-Git-Tag: v1.1.0~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4747066ac53db908fb925fcf48a4b9e872b34b2;p=thirdparty%2Fknot-resolver.git daemon/worker: track query in BEGIN and dst addr * in the begin() layer, the incoming query is exposed as req->qsource.packet, it is invalidated after begin() and should not be modified * the destination address (local interface) is also tracked for filtering purposes --- diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index e568172ff..5c6fd505a 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -212,6 +212,8 @@ struct kr_request { struct { const knot_rrset_t *key; const struct sockaddr *addr; + const struct sockaddr *dst_addr; + const knot_pkt_t *packet; } qsource; struct { unsigned rtt; @@ -467,7 +469,6 @@ local function rr2str(rr) dname2str(rr.owner), rr.ttl, rr.type, #rr.rdata, rdata) end - -- Module API local kres = { -- Constants diff --git a/daemon/worker.c b/daemon/worker.c index 00de593cc..30cce8342 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -254,6 +254,7 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha task->on_complete = NULL; task->req.qsource.key = NULL; task->req.qsource.addr = NULL; + task->req.qsource.dst_addr = NULL; /* Remember query source addr */ if (addr) { size_t addr_len = sizeof(struct sockaddr_in); @@ -264,6 +265,21 @@ static struct qr_task *qr_task_create(struct worker_ctx *worker, uv_handle_t *ha } else { task->source.addr.ip4.sin_family = AF_UNSPEC; } + /* Remember the destination address. */ + if (handle) { + int addr_len = sizeof(task->source.dst_addr); + struct sockaddr *dst_addr = (struct sockaddr *)&task->source.dst_addr; + task->source.dst_addr.ip4.sin_family = AF_UNSPEC; + if (handle->type == UV_UDP) { + if (uv_udp_getsockname((uv_udp_t *)handle, dst_addr, &addr_len) == 0) { + task->req.qsource.dst_addr = dst_addr; + } + } else if (handle->type == UV_TCP) { + if (uv_tcp_getsockname((uv_tcp_t *)handle, dst_addr, &addr_len) == 0) { + task->req.qsource.dst_addr = dst_addr; + } + } + } worker->stats.concurrent += 1; return task; } diff --git a/daemon/worker.h b/daemon/worker.h index 27d6c184d..e5527486e 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -85,6 +85,10 @@ struct qr_task struct sockaddr_in ip4; struct sockaddr_in6 ip6; } addr; + union { + struct sockaddr_in ip4; + struct sockaddr_in6 ip6; + } dst_addr; uv_handle_t *handle; } source; uint32_t refs; diff --git a/lib/resolve.c b/lib/resolve.c index bd9fce5f4..9ad5205d7 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -410,7 +410,9 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet) } /* Expect answer, pop if satisfied immediately */ + request->qsource.packet = packet; ITERATE_LAYERS(request, qry, begin, request); + request->qsource.packet = NULL; if (request->state == KNOT_STATE_DONE) { kr_rplan_pop(rplan, qry); } diff --git a/lib/resolve.h b/lib/resolve.h index 2896d54f2..563d85219 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -112,6 +112,8 @@ struct kr_request { struct { const knot_rrset_t *key; const struct sockaddr *addr; + const struct sockaddr *dst_addr; + const knot_pkt_t *packet; } qsource; struct { unsigned rtt; /**< Current upstream RTT */