- tune.quic.max-frame-loss
- tune.quic.retry-threshold
- tune.quic.socket-owner
+ - tune.rcvbuf.backend
- tune.rcvbuf.client
+ - tune.rcvbuf.frontend
- tune.rcvbuf.server
- tune.recv_enough
- tune.runqueue-depth
- tune.sched.low-latency
+ - tune.sndbuf.backend
- tune.sndbuf.client
+ - tune.sndbuf.frontend
- tune.sndbuf.server
- tune.stick-counters
- tune.ssl.cachesize
is used globally, it will be forced on every listener instance, regardless of
their individual configuration.
+tune.rcvbuf.backend <number>
+tune.rcvbuf.frontend <number>
+ For the kernel socket receive buffer size on non-connected sockets to this
+ size. This can be used QUIC in listener mode and log-forward on the frontend.
+ The default system buffers might sometimes be too small for sockets receiving
+ lots of aggregated traffic, causing some losses and possibly retransmits (in
+ case of QUIC), possibly slowing down connection establishment under heavy
+ traffic. The value is expressed in bytes, applied to each socket. In listener
+ mode, sockets are shared between all connections, and the total number of
+ sockets depends on the "shards" value of the "bind" line. There's no good
+ value, a good one corresponds to an expected size per connection multiplied
+ by the expected number of connections. The kernel may trim large values. See
+ also "tune.rcvbuf.client" and "tune.rcvbuf.server" for their connected socket
+ counter parts, as well as "tune.sndbuf.backend" and "tune.sndbuf.frontend"
+ for the send setting.
+
tune.rcvbuf.client <number>
tune.rcvbuf.server <number>
Forces the kernel socket receive buffer size on the client or the server side
massive traffic, at the expense of a higher impact on this large traffic.
For regular usage it is better to leave this off. The default value is off.
+tune.sndbuf.backend <number>
+tune.sndbuf.frontend <number>
+ For the kernel socket send buffer size on non-connected sockets to this size.
+ This can be used for UNIX socket and UDP logging on the backend side, and for
+ QUIC in listener mode on the frontend. The default system buffers might
+ sometimes be too small for sockets shared between many connections (or log
+ senders), causing some losses and possibly retransmits, slowing down new
+ connection establishment under high traffic. The value is expressed in bytes,
+ applied to each socket. In listener mode, sockets are shared between all
+ connections, and the total number of sockets depends on the "shards" value of
+ the "bind" line. There's no good value, a good one corresponds to an expected
+ size per connection multiplied by the expected number of connections. The
+ kernel may trim large values. See also "tune.sndbuf.client" and
+ "tune.sndbuf.server" for their connected socket counter parts, as well as
+ "tune.rcvbuf.backend" and "tune.rcvbuf.frontend" for the receive setting.
+
tune.sndbuf.client <number>
tune.sndbuf.server <number>
Forces the kernel socket send buffer size on the client or the server side to
int client_rcvbuf; /* set client rcvbuf to this value if not null */
int server_sndbuf; /* set server sndbuf to this value if not null */
int server_rcvbuf; /* set server rcvbuf to this value if not null */
+ int frontend_sndbuf; /* set frontend dgram sndbuf to this value if not null */
+ int frontend_rcvbuf; /* set frontend dgram rcvbuf to this value if not null */
+ int backend_sndbuf; /* set backend dgram sndbuf to this value if not null */
+ int backend_rcvbuf; /* set backend dgram rcvbuf to this value if not null */
int pipesize; /* pipe size in bytes, system defaults if zero */
int max_http_hdr; /* max number of HTTP headers, use MAX_HTTP_HDR if zero */
int requri_len; /* max len of request URI, use REQURI_LEN if zero */
*/
#include <haproxy/fd.h>
+#include <haproxy/cfgparse.h>
#include <haproxy/dgram.h>
+#include <haproxy/errors.h>
+#include <haproxy/tools.h>
/* datagram handler callback */
void dgram_fd_handler(int fd)
return;
}
+
+/* config parser for global "tune.{rcv,snd}buf.{frontend,backend}" */
+static int dgram_parse_tune_bufs(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ int *valptr;
+ int val;
+
+ if (too_many_args(1, args, err, NULL))
+ return -1;
+
+ /* "tune.rcvbuf.frontend", "tune.rcvbuf.backend",
+ * "tune.sndbuf.frontend", "tune.sndbuf.backend"
+ */
+ valptr = (args[0][5] == 'r' && args[0][12] == 'f') ? &global.tune.frontend_rcvbuf :
+ (args[0][5] == 'r' && args[0][12] == 'b') ? &global.tune.backend_rcvbuf :
+ (args[0][5] == 's' && args[0][12] == 'f') ? &global.tune.frontend_sndbuf :
+ &global.tune.backend_sndbuf;
+
+ if (*valptr != 0) {
+ memprintf(err, "parsing [%s:%d] : ignoring '%s' which was already specified.\n", file, line, args[0]);
+ return 1;
+ }
+
+ val = atoi(args[1]);
+
+ if (*(args[1]) == 0 || val <= 0) {
+ memprintf(err, "parsing [%s:%d] : '%s' expects a strictly positive integer argument.\n", file, line, args[0]);
+ return -1;
+ }
+
+ *valptr = val;
+ return 0;
+}
+
+/* register "global" section keywords */
+static struct cfg_kw_list dgram_cfg_kws = {ILH, {
+ { CFG_GLOBAL, "tune.rcvbuf.backend", dgram_parse_tune_bufs },
+ { CFG_GLOBAL, "tune.rcvbuf.frontend", dgram_parse_tune_bufs },
+ { CFG_GLOBAL, "tune.sndbuf.backend", dgram_parse_tune_bufs },
+ { CFG_GLOBAL, "tune.sndbuf.frontend", dgram_parse_tune_bufs },
+ { 0, NULL, NULL }
+}};
+
+INITCALL1(STG_REGISTER, cfg_register_keywords, &dgram_cfg_kws);
} else {
/* we don't want to receive anything on this socket */
setsockopt(*plogfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
+ /* we may want to adjust the output buffer (tune.sndbuf.backend) */
+ if (global.tune.backend_sndbuf)
+ setsockopt(*plogfd, SOL_SOCKET, SO_SNDBUF, &global.tune.backend_sndbuf, sizeof(global.tune.backend_sndbuf));
/* does nothing under Linux, maybe needed for others */
shutdown(*plogfd, SHUT_RD);
fd_set_cloexec(*plogfd);
global.tune.options &= ~GTUNE_QUIC_SOCK_PER_CONN;
}
+ if (global.tune.frontend_rcvbuf)
+ setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.frontend_rcvbuf, sizeof(global.tune.frontend_rcvbuf));
+
+ if (global.tune.frontend_sndbuf)
+ setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &global.tune.frontend_sndbuf, sizeof(global.tune.frontend_sndbuf));
+
listener_set_state(listener, LI_LISTEN);
udp_return:
goto udp_return;
}
+ /* we may want to adjust the output buffer (tune.sndbuf.backend) */
+ if (global.tune.frontend_rcvbuf)
+ setsockopt(listener->rx.fd, SOL_SOCKET, SO_RCVBUF, &global.tune.frontend_rcvbuf, sizeof(global.tune.frontend_rcvbuf));
+
+ if (global.tune.frontend_sndbuf)
+ setsockopt(listener->rx.fd, SOL_SOCKET, SO_SNDBUF, &global.tune.frontend_sndbuf, sizeof(global.tune.frontend_sndbuf));
+
listener_set_state(listener, LI_LISTEN);
udp_return: