From: Grigorii Demidov Date: Wed, 15 Nov 2017 09:56:09 +0000 (+0100) Subject: daemon: TCP - for now session source address is queried at tcp_accept(). AF_UNSPEC... X-Git-Tag: v2.0.0~43^2~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6208de5c4d232fb515d6ec9c8ecafba7696f0565;p=thirdparty%2Fknot-resolver.git daemon: TCP - for now session source address is queried at tcp_accept(). AF_UNSPEC is treated as error for both of udp&tcp. --- diff --git a/daemon/io.c b/daemon/io.c index 18232aea3..efce48d67 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -167,7 +167,9 @@ void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, } /* nread == 0 is for freeing buffers, we don't need to do this */ return; } - + if (addr->sa_family == AF_UNSPEC) { + return; + } knot_pkt_t *query = knot_pkt_new(buf->base, nread, &worker->pkt_pool); if (query) { query->max_size = KNOT_WIRE_MAX_PKTSIZE; @@ -267,6 +269,7 @@ static void _tcp_accept(uv_stream_t *master, int status, bool tls) if (status != 0) { return; } + uv_stream_t *client = handle_borrow(master->loop); if (!client) { return; @@ -283,6 +286,15 @@ static void _tcp_accept(uv_stream_t *master, int status, bool tls) * is idle and should be terminated, this is an educated guess. */ struct session *session = client->data; assert(session->outgoing == false); + + struct sockaddr *addr = &(session->peer.ip); + int addr_len = sizeof(union inaddr); + int ret = uv_tcp_getpeername((uv_tcp_t *)client, addr, &addr_len); + if (ret || addr->sa_family == AF_UNSPEC) { + worker_session_close(session); + return; + } + session->has_tls = tls; if (tls && !session->tls_ctx) { session->tls_ctx = tls_new(master->loop->data); diff --git a/daemon/worker.c b/daemon/worker.c index 603be8e73..d651939da 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -962,7 +962,7 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad worker->stats.tcp += 1; if (addr->sa_family == AF_INET6) worker->stats.ipv6 += 1; - else + else if (addr->sa_family == AF_INET) worker->stats.ipv4 += 1; } return ret; @@ -1313,7 +1313,6 @@ static int qr_task_finalize(struct qr_task *task, int state) uv_handle_t *handle = ctx->source.session->handle; assert(ctx->source.session->closing == false); assert(handle->data == ctx->source.session); - assert(!uv_is_closing(handle)); assert(ctx->source.addr.ip.sa_family != AF_UNSPEC); (void) qr_task_send(task, handle, (struct sockaddr *)&ctx->source.addr, @@ -1911,13 +1910,8 @@ int worker_process_tcp(struct worker_ctx *worker, uv_stream_t *handle, if (!session->outgoing) { /* This is a new query, create a new task that we can use * to buffer incoming message until it's complete. */ - struct sockaddr_storage addr_storage; - struct sockaddr *addr = (struct sockaddr *)&addr_storage; - int addr_len = sizeof(addr_storage); - int ret = uv_tcp_getpeername((uv_tcp_t *)handle, addr, &addr_len); - if (ret) { - addr = NULL; /* fallback */ - } + struct sockaddr *addr = &(session->peer.ip); + assert(addr->sa_family != AF_UNSPEC); struct request_ctx *ctx = request_create(worker, (uv_handle_t *)handle, addr);