]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: define config option for socket per conn
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 18 Nov 2022 16:42:16 +0000 (17:42 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 2 Dec 2022 13:45:43 +0000 (14:45 +0100)
Define global configuration option "tune.quic.socket-owner". This option
can be used to activate or not socket per QUIC connection mode. The
default value is "listener" which disable this feature. It can be
activated with the option "connection".

This change is part of quic-conn owned socket implementation.
It may be backported to 2.7 after a period of observation.

doc/configuration.txt
src/cfgparse-quic.c

index 4eee5944bd80bea3d982277d3f8f63fe1702f58e..f27d38f3c342be18802da8851e9337bb84dd11c4 100644 (file)
@@ -1135,6 +1135,7 @@ The following keywords are supported in the "global" section :
    - tune.quic.frontend.max-idle-timeout
    - tune.quic.frontend.max-streams-bidi
    - tune.quic.retry-threshold
+   - tune.quic.socket-owner
    - tune.rcvbuf.client
    - tune.rcvbuf.server
    - tune.recv_enough
@@ -3086,6 +3087,26 @@ tune.quic.retry-threshold <number>
   See https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 for more
   information about QUIC retry.
 
+tune.quic.socket-owner { listener | connection }
+  Warning: QUIC support in HAProxy is currently experimental. Configuration may
+  change without deprecation in the future.
+
+  Specifies how QUIC connections will use socket for receive/send operations.
+  Connections can share listener socket or each connection can allocate its
+  own socket.
+
+  Default "listener" value indicates that QUIC transfers will occur on the
+  shared listener socket. This option can be a good compromise for small
+  traffic as it allows to reduce FD consumption. However, performance won't be
+  optimal due to a higher CPU usage if listeners are shared accross a lot of
+  threads or a large number of QUIC connections can be used simultaneously.
+
+  If "connection" value is set, a dedicated socket will be allocated by every
+  QUIC connections. This option is the preferred one to achieve the best
+  performance with a large QUIC traffic. However, this relies on some advanced
+  features from the UDP network stack. If your platform is deemed not
+  compatible, haproxy will automatically revert to "listener" mode on startup.
+
 tune.rcvbuf.client <number>
 tune.rcvbuf.server <number>
   Forces the kernel socket receive buffer size on the client or the server side
@@ -4601,12 +4622,13 @@ bind /<path> [, ...] [param*]
                       to receive a FD over the unix socket and uses it as if it
                       was the FD of an accept(). Should be used carefully.
                     - 'quic4@' -> address is resolved as IPv4 and protocol UDP
-                      is used. Note that QUIC connections attached to a
-                      listener will be multiplexed over the listener socket.
-                      With a large traffic this has a noticeable impact on
-                      performance and CPU consumption. To improve this, you
-                      should duplicate QUIC listener instances over several
-                      threads, for example using "shards" keyword.
+                      is used. Note that by default QUIC connections attached
+                      to a listener will be multiplexed over the listener
+                      socket. With a large traffic this has a noticeable impact
+                      on performance and CPU consumption. To improve this, you
+                      can change default settings of "tune.quic.conn-owner" to
+                      connection or at least duplicate QUIC listener instances
+                      over several threads, for example using "shards" keyword.
                     - 'quic6@' -> address is resolved as IPv6 and protocol UDP
                       is used. The performance note for QUIC over IPv4 applies
                       as well.
index 8be054512b849724b0d9c434c1db610411bcbecc..21aaac2e2d5d016d366a1e94b8351e407e061300 100644 (file)
@@ -47,6 +47,29 @@ static struct bind_kw_list bind_kws = { "QUIC", { }, {
 
 INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
 
+/* parse "tune.quic.socket-owner", accepts "listener" or "connection" */
+static int cfg_parse_quic_tune_socket_owner(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], "connection") == 0) {
+               global.tune.options |= GTUNE_QUIC_SOCK_PER_CONN;
+       }
+       else if (strcmp(args[1], "listener") == 0) {
+               global.tune.options &= ~GTUNE_QUIC_SOCK_PER_CONN;
+       }
+       else {
+               memprintf(err, "'%s' expects either 'listener' or 'connection' but got '%s'.", args[0], args[1]);
+               return -1;
+       }
+
+       return 0;
+}
+
 /* Must be used to parse tune.quic.* setting which requires a time
  * as value.
  * Return -1 on alert, or 0 if succeeded.
@@ -132,6 +155,7 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
 }
 
 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 },
        { CFG_GLOBAL, "tune.quic.frontend.conn-tx-buffers.limit", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.frontend.max-streams-bidi", cfg_parse_quic_tune_setting },