MEDIUM: stconn: Nofify requested size during zero-copy forwarding nego is exact

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.
This commit is contained in:
Christopher Faulet 2024-01-25 14:52:08 +01:00
parent fe506d7aaa
commit 1c18d32a0d
3 changed files with 16 additions and 4 deletions

View 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 {

View 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) {

View 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;