From: Marek VavruĊĦa Date: Mon, 13 Jul 2015 22:48:01 +0000 (+0200) Subject: daemon/worker: track ipv4/ipv6 requests X-Git-Tag: v1.0.0-beta1~77^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05acfa5bc13fa1ab742fad3956b05189fd3930e7;p=thirdparty%2Fknot-resolver.git daemon/worker: track ipv4/ipv6 requests --- diff --git a/daemon/README.rst b/daemon/README.rst index 019dc5056..c6c495f11 100644 --- a/daemon/README.rst +++ b/daemon/README.rst @@ -511,6 +511,8 @@ you can see the statistics or schedule new queries. * ``udp`` - number of outbound queries over UDP * ``tcp`` - number of outbound queries over TCP + * ``ipv6`` - number of outbound queries over IPv6 + * ``ipv4`` - number of outbound queries over IPv4 * ``concurrent`` - number of concurrent queries at the moment Example: diff --git a/daemon/bindings.c b/daemon/bindings.c index c223cfe9f..419703dfe 100644 --- a/daemon/bindings.c +++ b/daemon/bindings.c @@ -599,6 +599,10 @@ static int wrk_stats(lua_State *L) lua_setfield(L, -2, "udp"); lua_pushnumber(L, worker->stats.tcp); lua_setfield(L, -2, "tcp"); + lua_pushnumber(L, worker->stats.ipv6); + lua_setfield(L, -2, "ipv6"); + lua_pushnumber(L, worker->stats.ipv4); + lua_setfield(L, -2, "ipv4"); return 1; } diff --git a/daemon/worker.c b/daemon/worker.c index 58ab23e19..8b446875a 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -233,12 +233,11 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad if (!req) { return qr_task_on_send(task, kr_error(ENOMEM)); } + /* Send using given protocol */ if (handle->type == UV_UDP) { uv_buf_t buf = { (char *)pkt->wire, pkt->size }; req->as.send.data = task; ret = uv_udp_send(&req->as.send, (uv_udp_t *)handle, &buf, 1, addr, &on_send); - if (handle != task->source.handle) - task->worker->stats.udp += 1; } else { uint16_t pkt_size = htons(pkt->size); uv_buf_t buf[2] = { @@ -247,8 +246,15 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad }; req->as.write.data = task; ret = uv_write(&req->as.write, (uv_stream_t *)handle, buf, 2, &on_write); - if (handle != task->source.handle) - task->worker->stats.tcp += 1; + } + /* Update statistics */ + if (handle != task->source.handle && addr) { + if (handle->type == UV_UDP) + task->worker->stats.udp += 1; + else task->worker->stats.tcp += 1; + if (addr->sa_family == AF_INET6) + task->worker->stats.ipv6 += 1; + else task->worker->stats.ipv4 += 1; } if (ret != 0) { ioreq_release(task->worker, req); @@ -260,7 +266,11 @@ static void on_connect(uv_connect_t *req, int status) { struct qr_task *task = req->data; if (status == 0) { - qr_task_send(task, (uv_handle_t *)req->handle, NULL, task->next_query); + /* Retrieve endpoint IP for statistics */ + struct sockaddr_in6 addr; + int addrlen = sizeof(addr); + uv_tcp_getpeername((uv_tcp_t *)req->handle, (struct sockaddr *)&addr, &addrlen); + qr_task_send(task, (uv_handle_t *)req->handle, (struct sockaddr *)&addr, task->next_query); ioreq_release(task->worker, (struct ioreq *)req); } else { /* Must not recycle, as 'task' may be freed. */ free(req); @@ -304,6 +314,11 @@ static int qr_task_step(struct qr_task *task, knot_pkt_t *packet) return qr_task_finalize(task, state); } + /* Not done, but no next address given. */ + if (!addr || sock_type < 0) { + return qr_task_step(task, NULL); + } + /* Create connection for iterative query */ task->next_handle = io_create(task->worker->loop, sock_type); if (task->next_handle == NULL) { diff --git a/daemon/worker.h b/daemon/worker.h index 233c865b7..6364761d6 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -41,6 +41,8 @@ struct worker_ctx { size_t concurrent; size_t udp; size_t tcp; + size_t ipv4; + size_t ipv6; } stats; mp_freelist_t pools; mp_freelist_t ioreqs;