Commit 05acfa5b authored by Marek Vavruša's avatar Marek Vavruša

daemon/worker: track ipv4/ipv6 requests

parent b6d0dba1
......@@ -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:
......
......@@ -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;
}
......
......@@ -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) {
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment