]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: hq-interop: use zero-copy to transfer single HTX data block
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 8 Dec 2023 14:52:00 +0000 (15:52 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 12 Dec 2023 09:31:22 +0000 (10:31 +0100)
Similarly to H3, hq-interop now uses zero-copy when dealing with a HTX
message with only a single data block. Exchange HTX and QCS buffer, and
use the HTX data block for HTTP payload. This is only possible if QCS
buffer is empty. Contrary to HTTP/3, no extra frame header is needed
before transferring HTTP payload.

hq-interop is only implemented for testing purpose so this change should
not be noticeable by users. However, it will be useful to be able to
test zero-copy transfer on QUIC interop testing.

src/hq_interop.c

index 0bbf44c5adcfaf8fd7ad9e7a9e37ba41ae85153f..690c13bad0911dd2129a89e0fa7c0821196f8150 100644 (file)
@@ -8,6 +8,8 @@
 #include <haproxy/http.h>
 #include <haproxy/mux_quic.h>
 #include <haproxy/qmux_http.h>
+#include <haproxy/qmux_trace.h>
+#include <haproxy/trace.h>
 
 static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
 {
@@ -110,6 +112,28 @@ static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf,
 
                switch (btype) {
                case HTX_BLK_DATA:
+                       if (unlikely(fsize == count &&
+                                    !b_data(res) &&
+                                    htx_nbblks(htx) == 1 && btype == HTX_BLK_DATA)) {
+                               void *old_area = res->area;
+
+                               TRACE_DATA("perform zero-copy DATA transfer", QMUX_EV_STRM_SEND,
+                                          qcs->qcc->conn, qcs);
+
+                               /* remap MUX buffer to HTX area */
+                               *res = b_make(buf->area, buf->size,
+                                             sizeof(struct htx) + blk->addr, fsize);
+
+                               /* assign old MUX area to HTX buffer. */
+                               buf->area = old_area;
+                               buf->data = buf->head = 0;
+                               total += fsize;
+
+                               /* reload HTX with empty buffer. */
+                               *htx = *htx_from_buf(buf);
+                               goto end;
+                       }
+
                        if (fsize > count)
                                fsize = count;