diff --git a/doc/configuration.txt b/doc/configuration.txt index bcdaae1fa..10faa8613 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1221,6 +1221,7 @@ The following keywords are supported in the "global" section : - tune.quic.max-frame-loss - tune.quic.retry-threshold - tune.quic.socket-owner + - tune.quic.zero-copy-fwd-send - tune.rcvbuf.backend - tune.rcvbuf.client - tune.rcvbuf.frontend @@ -2927,7 +2928,7 @@ tune.disable-zero-copy-forwarding See also: tune.pt.zero-copy-forwarding, tune.h1.zero-copy-fwd-recv, tune.h1.zero-copy-fwd-send, - tune.h2.zero-copy-fwd-send + tune.h2.zero-copy-fwd-send, tune.quic.zero-copy-fwd-send tune.events.max-events-at-once Sets the number of events that may be processed at once by an asynchronous @@ -3456,6 +3457,12 @@ tune.quic.socket-owner { connection | listener } is used globally, it will be forced on every listener instance, regardless of their individual configuration. +tune.quit.zero-copy-fwd-send { on | off } + Enables ('on') of disabled ('off') the zero-copy sends of data for the QUIC + multiplexer. It is enabled by default. + + See also: tune.disable-zero-copy-forwarding + tune.rcvbuf.backend tune.rcvbuf.frontend For the kernel socket receive buffer size on non-connected sockets to this diff --git a/src/cfgparse-quic.c b/src/cfgparse-quic.c index 802940850..ec2dedacf 100644 --- a/src/cfgparse-quic.c +++ b/src/cfgparse-quic.c @@ -248,6 +248,25 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type, return 0; } +/* config parser for global "tune.quic.zero-copy-fwd-send" */ +static int cfg_parse_quic_zero_copy_fwd_snd(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (too_many_args(1, args, err, NULL)) + return -1; + + if (strcmp(args[1], "on") == 0) + global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_QUIC_SND; + else if (strcmp(args[1], "off") == 0) + global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_QUIC_SND; + else { + memprintf(err, "'%s' expects 'on' or 'off'.", args[0]); + return -1; + } + return 0; +} + static struct cfg_kw_list cfg_kws = {ILH, { { CFG_GLOBAL, "tune.quic.socket-owner", cfg_parse_quic_tune_socket_owner }, { CFG_GLOBAL, "tune.quic.backend.max-idle-timeou", cfg_parse_quic_time }, @@ -256,6 +275,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { { CFG_GLOBAL, "tune.quic.frontend.max-idle-timeout", cfg_parse_quic_time }, { CFG_GLOBAL, "tune.quic.max-frame-loss", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.retry-threshold", cfg_parse_quic_tune_setting }, + { CFG_GLOBAL, "tune.quic.zero-copy-fwd-send", cfg_parse_quic_zero_copy_fwd_snd }, { 0, NULL, NULL } }}; diff --git a/src/mux_quic.c b/src/mux_quic.c index 714bc32f9..a4afe9b27 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -2819,6 +2819,11 @@ static size_t qmux_nego_ff(struct stconn *sc, struct buffer *input, size_t count /* stream layer has been detached so no transfer must occur after. */ BUG_ON_HOT(qcs->flags & QC_SF_DETACH); + if (global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_QUIC_SND) { + qcs->sd->iobuf.flags |= IOBUF_FL_NO_FF; + goto end; + } + if (!qcs->qcc->app_ops->nego_ff || !qcs->qcc->app_ops->done_ff) { /* Fast forwading is not supported by the QUIC application layer */ qcs->sd->iobuf.flags |= IOBUF_FL_NO_FF;