]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-h2: make the H2 MAX_FRAME_SIZE setting configurable
authorWilly Tarreau <w@1wt.eu>
Thu, 21 Feb 2019 12:24:36 +0000 (13:24 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 21 Feb 2019 16:30:59 +0000 (17:30 +0100)
This creates a new tunable "tune.h2.max-frame-size" to adjust the
advertised max frame size. When not set it still defaults to the buffer
size. It is convenient to advertise sizes lower than the buffer size,
for example when using very large buffers.

doc/configuration.txt
src/mux_h2.c

index d2a49cf11bdfecacfd98855762a2941121c6a378..d1ce793a848f9ed585e563db90ec465d14d83804 100644 (file)
@@ -1580,6 +1580,15 @@ tune.h2.max-concurrent-streams <number>
   client may create as many streams as allocatable by haproxy. It is highly
   recommended not to change this value.
 
+tune.h2.max-frame-size <number>
+  Sets the HTTP/2 maximum frame size that haproxy announces it is willing to
+  receive to its peers. The default value is the largest between 16384 and the
+  buffer size (tune.bufsize). In any case, haproxy will not announce support
+  for frame sizes larger than buffers. The main purpose of this setting is to
+  allow to limit the maximum frame size setting when using large buffers. Too
+  large frame sizes might have performance impact or cause some peers to
+  misbehave. It is highly recommended not to change this value.
+
 tune.http.cookielen <number>
   Sets the maximum length of captured cookies. This is the maximum value that
   the "capture cookie xxx len yyy" will be allowed to take, and any upper value
index 725074ea126f8ef5594db2bef781eb141ed50b42..3855cb280412bf61d4f56797fd5edbb1c7534275 100644 (file)
@@ -226,6 +226,7 @@ DECLARE_STATIC_POOL(pool_head_h2s, "h2s", sizeof(struct h2s));
 static int h2_settings_header_table_size      =  4096; /* initial value */
 static int h2_settings_initial_window_size    = 65535; /* initial value */
 static unsigned int h2_settings_max_concurrent_streams = 100;
+static int h2_settings_max_frame_size         = 0;     /* unset */
 
 /* a dmumy closed stream */
 static const struct h2s *h2_closed_stream = &(const struct h2s){
@@ -1003,6 +1004,7 @@ static int h2c_send_settings(struct h2c *h2c)
        struct buffer *res;
        char buf_data[100]; // enough for 15 settings
        struct buffer buf;
+       int mfs;
        int ret;
 
        if (h2c_mux_busy(h2c, NULL)) {
@@ -1048,14 +1050,21 @@ static int h2c_send_settings(struct h2c *h2c)
                chunk_memcat(&buf, str, 6);
        }
 
-       if (global.tune.bufsize != 16384) {
+       mfs = h2_settings_max_frame_size;
+       if (mfs > global.tune.bufsize)
+               mfs = global.tune.bufsize;
+
+       if (!mfs)
+               mfs = global.tune.bufsize;
+
+       if (mfs != 16384) {
                char str[6] = "\x00\x05"; /* max_frame_size */
 
                /* note: similarly we could also emit MAX_HEADER_LIST_SIZE to
                 * match bufsize - rewrite size, but at the moment it seems
                 * that clients don't take care of it.
                 */
-               write_n32(str + 2, global.tune.bufsize);
+               write_n32(str + 2, mfs);
                chunk_memcat(&buf, str, 6);
        }
 
@@ -5479,6 +5488,22 @@ static int h2_parse_max_concurrent_streams(char **args, int section_type, struct
        return 0;
 }
 
+/* config parser for global "tune.h2.max-frame-size" */
+static int h2_parse_max_frame_size(char **args, int section_type, struct proxy *curpx,
+                                   struct proxy *defpx, const char *file, int line,
+                                   char **err)
+{
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       h2_settings_max_frame_size = atoi(args[1]);
+       if (h2_settings_max_frame_size < 16384 || h2_settings_max_frame_size > 16777215) {
+               memprintf(err, "'%s' expects a numeric value between 16384 and 16777215.", args[0]);
+               return -1;
+       }
+       return 0;
+}
+
 
 /****************************************/
 /* MUX initialization and instanciation */
@@ -5521,6 +5546,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_GLOBAL, "tune.h2.header-table-size",      h2_parse_header_table_size      },
        { CFG_GLOBAL, "tune.h2.initial-window-size",    h2_parse_initial_window_size    },
        { CFG_GLOBAL, "tune.h2.max-concurrent-streams", h2_parse_max_concurrent_streams },
+       { CFG_GLOBAL, "tune.h2.max-frame-size",         h2_parse_max_frame_size         },
        { 0, NULL, NULL }
 }};