]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stconn: Nofify requested size during zero-copy forwarding nego is exact
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 25 Jan 2024 13:52:08 +0000 (14:52 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 7 Feb 2024 14:04:38 +0000 (15:04 +0100)
It is now possible to use a flag during zero-copy forwarding negotiation to
specify the requested size is exact, it means the producer really expect to
receive at least this amount of data.

It can be used by consumer to prepare some processing at this stage, based
on the requested size. For instance, in the H1 mux, it is used to write the
next chunk size.

include/haproxy/stconn-t.h
src/applet.c
src/mux_h1.c

index 223956058d4e3149235dc6f1fa76924283b6f4fd..f55472398edc1704fb7594cfe5db7cd263f91ed6 100644 (file)
@@ -44,6 +44,7 @@ enum iobuf_flags {
 enum nego_ff_flags {
        NEGO_FF_FL_NONE           = 0x00000000, /* For initialization purposes */
        NEGO_FF_FL_MAY_SPLICE     = 0x00000001, /* Consumer may choose to use kernel splicing if it supports it */
+       NEGO_FF_FL_EXACT_SIZE     = 0x00000002, /* Size passed for the nego is the expected exact size to forwarded */
 };
 
 struct iobuf {
index ba3af6a5fc4fee964127d98a2f07990fb6bfd1a6..7b302f97683319fa123671bf094cb492a708a8c8 100644 (file)
@@ -619,8 +619,10 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
        sdo = container_of(peer, struct sedesc, xref);
        xref_unlock(&appctx->sedesc->xref, peer);
 
-       if (appctx->to_forward && count > appctx->to_forward)
+       if (appctx->to_forward && count > appctx->to_forward) {
                count = appctx->to_forward;
+               nego_flags |= NEGO_FF_FL_EXACT_SIZE;
+       }
 
        len = se_nego_ff(sdo, &BUF_NULL, count, nego_flags);
        if (sdo->iobuf.flags & IOBUF_FL_NO_FF) {
index 0db232934f5018fa0df734f5ced2e6a332698c2e..a08d08520f89e6093bba9d57b9697edc2a2ea0a4 100644 (file)
@@ -4470,9 +4470,16 @@ static size_t h1_nego_ff(struct stconn *sc, struct buffer *input, size_t count,
                }
                else {
                        BUG_ON(h1m->state != H1_MSG_CHUNK_CRLF && h1m->state != H1_MSG_CHUNK_SIZE);
-                       if (!h1_make_chunk(h1s, h1m, count))
+                       if (flags & NEGO_FF_FL_EXACT_SIZE) {
+                               if (!h1_make_chunk(h1s, h1m, count))
+                                       goto out;
+                               h1m->curr_len = count;
+                       }
+                       else {
+                               /* XXX: Unsupported for now but will be added soon ! */
+                               h1s->sd->iobuf.flags |= IOBUF_FL_NO_FF;
                                goto out;
-                       h1m->curr_len = count;
+                       }
                }
        }
 
@@ -4655,8 +4662,10 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
   retry:
        ret = 0;
 
-       if (h1m->state == H1_MSG_DATA && (h1m->flags & (H1_MF_CHNK|H1_MF_CLEN)) &&  count > h1m->curr_len)
+       if (h1m->state == H1_MSG_DATA && (h1m->flags & (H1_MF_CHNK|H1_MF_CLEN)) &&  count > h1m->curr_len) {
+               flags |= NEGO_FF_FL_EXACT_SIZE;
                count = h1m->curr_len;
+       }
 
        if (h1c->conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING))
                nego_flags |= NEGO_FF_FL_MAY_SPLICE;