]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/http: write correct packet buffer
authorTomas Krizek <tomas.krizek@nic.cz>
Thu, 20 Aug 2020 13:03:05 +0000 (15:03 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Tue, 13 Oct 2020 10:55:25 +0000 (12:55 +0200)
task->pktbuf isn't the same as the passed in pkt in qr_task_send().
pkt must be used and it must also stay valid as long as the task
lives. This seems to be the case for request answers, as they aren't
freed until there are no more tasks that reference them.

daemon/http.c
daemon/http.h
daemon/worker.c

index 69712ceb944fcbd8c080c058f20f48ef2061790f..3a0f48dcb393dfd76f16b9755484d9fac802ee04 100644 (file)
@@ -437,15 +437,14 @@ static int http_write_pkt(nghttp2_session *h2, knot_pkt_t *pkt, int32_t stream_i
  *
  * Packet wire buffer must stay valid until the on_write callback.
  */
-int http_write(uv_write_t *req, uv_handle_t *handle, int32_t stream_id, uv_write_cb on_write)
+int http_write(uv_write_t *req, uv_handle_t *handle, knot_pkt_t *pkt, int32_t stream_id,
+              uv_write_cb on_write)
 {
        struct session *session;
        struct http_ctx *ctx;
-       struct qr_task *task;
-       knot_pkt_t *pkt;
        int ret;
 
-       if (!req || !req->data || !handle || !handle->data || stream_id < 0)
+       if (!req || !pkt || !handle || !handle->data || stream_id < 0)
                return kr_error(EINVAL);
 
        session = handle->data;
@@ -456,8 +455,6 @@ int http_write(uv_write_t *req, uv_handle_t *handle, int32_t stream_id, uv_write
        if (!ctx || !ctx->h2)
                return kr_error(EINVAL);
 
-       task = (struct qr_task *)req->data;
-       pkt = worker_task_get_pktbuf(task);
        req->handle = (uv_stream_t *)handle;  // TODO does this have side effects when write fails?
        ret = http_write_pkt(ctx->h2, pkt, stream_id, req, on_write);
        if (ret < 0)
index 31d416e4036c88a6f6a8b617405f37d1bbffed3e..2ae1d59c829286234c9479a37a462786cf80d04c 100644 (file)
@@ -37,5 +37,6 @@ struct http_ctx {
 
 struct http_ctx* http_new(struct session *session, http_send_callback send_cb);
 ssize_t http_process_input_data(struct session *session, const uint8_t *buf, ssize_t nread);
-int http_write(uv_write_t *req, uv_handle_t *handle, int32_t stream_id, uv_write_cb on_write);
+int http_write(uv_write_t *req, uv_handle_t *handle, knot_pkt_t* pkt, int32_t stream_id,
+              uv_write_cb on_write);
 void http_free(struct http_ctx *ctx);
index a58c7c32544e9b7ac668b720778610772adaf4b4..ee9646bfbf2e0c2583c326f16ba46bb41cbf0890 100644 (file)
@@ -621,7 +621,7 @@ static int qr_task_send(struct qr_task *task, struct session *session,
        if (session_flags(session)->has_http) {
                uv_write_t *write_req = (uv_write_t *)ioreq;
                write_req->data = task;
-               ret = http_write(write_req, handle, ctx->req.qsource.stream_id, &on_write);
+               ret = http_write(write_req, handle, pkt, ctx->req.qsource.stream_id, &on_write);
        } else if (session_flags(session)->has_tls) {
                uv_write_t *write_req = (uv_write_t *)ioreq;
                write_req->data = task;