]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/worker: less aggresssive packet error detection
authorOto Šťáva <oto.stava@nic.cz>
Wed, 8 Feb 2023 07:15:36 +0000 (08:15 +0100)
committerOto Šťáva <oto.stava@nic.cz>
Wed, 8 Feb 2023 07:15:36 +0000 (08:15 +0100)
daemon/session2.c
daemon/worker.c

index 4000a1b0980358575371c787ac9e0b5dfc8133ef..c9e9e5945d710ffc3b6c4d38649fc749fc280ed9 100644 (file)
@@ -665,8 +665,12 @@ int wire_buf_movestart(struct wire_buf *wb)
                return kr_ok();
 
        size_t len = wire_buf_data_length(wb);
-       if (len)
-               memmove(wb->buf, wire_buf_data(wb), len);
+       if (len) {
+               if (wb->start < len)
+                       memmove(wb->buf, wire_buf_data(wb), len);
+               else
+                       memcpy(wb->buf, wire_buf_data(wb), len);
+       }
        wb->start = 0;
        wb->end = len;
        return kr_ok();
index 65754fc08d2e79d419e271f5ab99f96c89a73dfe..eb301cd0b64536460fb5b458ae90fd51f94d7555 100644 (file)
@@ -2044,8 +2044,10 @@ static enum protolayer_event_cb_result pl_dns_stream_event_unwrap(
 static knot_pkt_t *produce_stream_packet(struct wire_buf *wb)
 {
        uint16_t pkt_len = knot_wire_read_u16(wire_buf_data(wb));
-       if (wire_buf_data_length(wb) < pkt_len + sizeof(uint16_t))
+       if (wire_buf_data_length(wb) < pkt_len + sizeof(uint16_t)) {
+               wire_buf_reset(wb);
                return NULL;
+       }
 
        wire_buf_trim(wb, sizeof(uint16_t));
        knot_pkt_t *pkt = produce_packet(wire_buf_data(wb), pkt_len);
@@ -2065,28 +2067,28 @@ static enum protolayer_iter_cb_result pl_dns_stream_unwrap(
        struct session2 *session = ctx->manager->session;
        struct pl_dns_stream_sess_data *stream_sess = sess_data;
        struct wire_buf *wb = ctx->payload.wire_buf;
+
+       if (wire_buf_data_length(wb) == 0)
+               return protolayer_break(ctx, status);
+
        const uint32_t max_iters = (wire_buf_data_length(wb) /
                (KNOT_WIRE_HEADER_SIZE + KNOT_WIRE_QUESTION_MIN_SIZE)) + 1;
        int iters = 0;
 
        knot_pkt_t *pkt;
        while ((pkt = produce_stream_packet(wb)) && iters < max_iters) {
-               session->was_useful = true;
                if (stream_sess->single && stream_sess->produced) {
                        if (kr_log_is_debug(WORKER, NULL)) {
                                kr_log_debug(WORKER, "Unexpected extra data from %s\n",
                                                kr_straddr(ctx->comm.src_addr));
                        }
-                       worker_end_tcp(session);
                        status = KNOT_EMALF;
                        goto exit;
                }
 
                stream_sess->produced = true;
-               if (!pkt) {
-                       status = KNOT_EMALF;
-                       goto exit;
-               }
+               if (pkt)
+                       session->was_useful = true;
 
                int ret = worker_submit(session, &ctx->comm, pkt);
                wire_buf_movestart(wb);
@@ -2095,8 +2097,6 @@ static enum protolayer_iter_cb_result pl_dns_stream_unwrap(
                }
        }
 
-
-
        /* worker_submit() may cause the session to close (e.g. due to IO
         * write error when the packet triggers an immediate answer). This is
         * an error state, as well as any wirebuf error. */
@@ -2106,6 +2106,8 @@ static enum protolayer_iter_cb_result pl_dns_stream_unwrap(
 exit:
        wire_buf_movestart(wb);
        mp_flush(the_worker->pkt_pool.ctx);
+       if (status < 0)
+               worker_end_tcp(session);
        return protolayer_break(ctx, status);
 }