]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: add a new global option "tune.ssl.hard-maxrecord"
authorThomas Prückl <plt@hainzl.at>
Wed, 27 Apr 2022 11:04:54 +0000 (13:04 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 27 Apr 2022 14:53:43 +0000 (16:53 +0200)
Low footprint client machines may not have enough memory to download a
complete 16KB TLS record at once. With the new option the maximum
record size can be defined on the server side.

Note: Before limiting the the record size on the server side, a client should
consider using the TLS Maximum Fragment Length Negotiation Extension defined
in RFC6066.

This patch fixes GitHub issue #1679.

doc/configuration.txt
include/haproxy/ssl_sock-t.h
src/cfgparse-ssl.c
src/ssl_sock.c

index 4f7fc4afb441ad5cdeac2316cc7dd306ecdbb487..aa422f0f5e80874d567f8fa3920a76c66d646bda 100644 (file)
@@ -1118,9 +1118,10 @@ The following keywords are supported in the "global" section :
    - tune.sndbuf.client
    - tune.sndbuf.server
    - tune.ssl.cachesize
+   - tune.ssl.force-private-cache
+   - tune.ssl.hard-maxrecord
    - tune.ssl.keylog
    - tune.ssl.lifetime
-   - tune.ssl.force-private-cache
    - tune.ssl.maxrecord
    - tune.ssl.default-dh-param
    - tune.ssl.ssl-ctx-cache-size
@@ -2903,6 +2904,12 @@ tune.ssl.force-private-cache
   this case, adding a first layer of hash-based load balancing before the SSL
   layer might limit the impact of the lack of session sharing.
 
+tune.ssl.hard-maxrecord <number>
+  Sets the maximum amount of bytes passed to SSL_write() at any time. Default
+  value 0 means there is no limit. In contrast to tune.ssl.maxrecord this
+  settings will not be adjusted dynamically. Smaller records may decrease
+  throughput, but may be required when dealing with low-footprint clients.
+
 tune.ssl.keylog { on | off }
   This option activates the logging of the TLS keys. It should be used with
   care as it will consume more memory per SSL session and could decrease
@@ -2950,18 +2957,19 @@ tune.ssl.lifetime <timeout>
   being used for too long.
 
 tune.ssl.maxrecord <number>
-  Sets the maximum amount of bytes passed to SSL_write() at a time. Default
-  value 0 means there is no limit. Over SSL/TLS, the client can decipher the
-  data only once it has received a full record. With large records, it means
-  that clients might have to download up to 16kB of data before starting to
-  process them. Limiting the value can improve page load times on browsers
-  located over high latency or low bandwidth networks. It is suggested to find
-  optimal values which fit into 1 or 2 TCP segments (generally 1448 bytes over
-  Ethernet with TCP timestamps enabled, or 1460 when timestamps are disabled),
-  keeping in mind that SSL/TLS add some overhead. Typical values of 1419 and
-  2859 gave good results during tests. Use "strace -e trace=write" to find the
-  best value. HAProxy will automatically switch to this setting after an idle
-  stream has been detected (see tune.idletimer above).
+  Sets the maximum amount of bytes passed to SSL_write() at the beginning of
+  the data transfer. Default value 0 means there is no limit. Over SSL/TLS,
+  the client can decipher the data only once it has received a full record.
+  With large records, it means that clients might have to download up to 16kB
+  of data before starting to process them. Limiting the value can improve page
+  load times on browsers located over high latency or low bandwidth networks.
+  It is suggested to find optimal values which fit into 1 or 2 TCP segments
+  (generally 1448 bytes over Ethernet with TCP timestamps enabled, or 1460 when
+  timestamps are disabled), keeping in mind that SSL/TLS add some overhead.
+  Typical values of 1419 and 2859 gave good results during tests. Use
+  "strace -e trace=write" to find the best value. HAProxy will automatically
+  switch to this setting after an idle stream has been detected (see
+  tune.idletimer above). See also tune.ssl.hard-maxrecord.
 
 tune.ssl.default-dh-param <number>
   Sets the maximum size of the Diffie-Hellman parameters used for generating
index fab8decbff5ca2c01038f284d1f9df37737798bb..b404defdb2b3840a5cfc4d6e3b3926fe594a4b3b 100644 (file)
@@ -275,6 +275,7 @@ struct global_ssl {
        int private_cache; /* Force to use a private session cache even if nbproc > 1 */
        unsigned int life_time;   /* SSL session lifetime in seconds */
        unsigned int max_record; /* SSL max record size */
+       unsigned int hard_max_record; /* SSL max record size hard limit */
        unsigned int default_dh_param; /* SSL maximum DH parameter size */
        int ctx_cache; /* max number of entries in the ssl_ctx cache. */
        int capture_buffer_size; /* Size of the capture buffer. */
index 831a3ca5e1b72a09391cd43b27e0e927181bf91f..7acd135ddc8abe427b04ff7f180bb84743e5eaef 100644 (file)
@@ -268,6 +268,8 @@ static int ssl_parse_global_int(char **args, int section_type, struct proxy *cur
                target = &global.tune.sslcachesize;
        else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
                target = (int *)&global_ssl.max_record;
+       else if (strcmp(args[0], "tune.ssl.hard-maxrecord") == 0)
+               target = (int *)&global_ssl.hard_max_record;
        else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
                target = &global_ssl.ctx_cache;
        else if (strcmp(args[0], "maxsslconn") == 0)
@@ -1942,6 +1944,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_GLOBAL, "tune.ssl.force-private-cache",  ssl_parse_global_private_cache },
        { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
        { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
+       { CFG_GLOBAL, "tune.ssl.hard-maxrecord", ssl_parse_global_int },
        { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
        { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_buffer },
        { CFG_GLOBAL, "tune.ssl.capture-buffer-size", ssl_parse_global_capture_buffer },
index 19e41fd877ac12df808daaee2c714ddeb168536a..f88f2415edb52acc1abfe69c33f3bfc18e1a254d 100644 (file)
@@ -122,6 +122,7 @@ struct global_ssl global_ssl = {
 #ifdef DEFAULT_SSL_MAX_RECORD
        .max_record = DEFAULT_SSL_MAX_RECORD,
 #endif
+       .hard_max_record = 0,
        .default_dh_param = SSL_DEFAULT_DH_PARAM,
        .ctx_cache = DEFAULT_SSL_CTX_CACHE,
        .capture_buffer_size = 0,
@@ -6568,6 +6569,9 @@ static size_t ssl_sock_from_buf(struct connection *conn, void *xprt_ctx, const s
                if (try > count)
                        try = count;
 
+               if (global_ssl.hard_max_record && try > global_ssl.hard_max_record)
+                       try = global_ssl.hard_max_record;
+
                if (!(flags & CO_SFL_STREAMER) &&
                    !(ctx->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
                    global_ssl.max_record && try > global_ssl.max_record) {