]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon: TCP - for now session source address is queried at tcp_accept(). AF_UNSPEC...
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Wed, 15 Nov 2017 09:56:09 +0000 (10:56 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Mon, 8 Jan 2018 11:00:59 +0000 (12:00 +0100)
daemon/io.c
daemon/worker.c

index 18232aea30775e01bc5b615db7ec221ff8523a11..efce48d67c00a2e74b2378af6e7f2f5a2a694fcb 100644 (file)
@@ -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);
index 603be8e7350440390d828e6f2badbc79408f9200..d651939dae4f34eea5c3f1f430e2fe21083ce5f3 100644 (file)
@@ -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);