]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: config: ensure that tune.bufsize is at least 16384 when using HTTP/2
authorWilly Tarreau <w@1wt.eu>
Fri, 24 Nov 2017 10:28:00 +0000 (11:28 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 24 Nov 2017 10:28:00 +0000 (11:28 +0100)
HTTP/2 mandates the support of 16384 bytes frames by default, so we need
a large enough buffer to process them. Till now if tune.bufsize was too
small, H2 connections were simply rejected during their establishment,
making it quite hard to troubleshoot the issue.

Now we detect when HTTP/2 is enabled on an HTTP frontend and emit an
error if tune.bufsize is not large enough, with the appropriate
recommendation.

doc/configuration.txt
src/cfgparse.c

index 27e370230510326bc3463a7eed19cd1b2a9ff0c0..4940b33e9104f4bab2803f01417ec48aebc5d300 100644 (file)
@@ -1353,8 +1353,9 @@ tune.bufsize <number>
   from the default value, as very low values will break some services such as
   statistics, and values larger than default size will increase memory usage,
   possibly causing the system to run out of memory. At least the global maxconn
-  parameter should be decreased by the same factor as this one is increased.
-  If HTTP request is larger than (tune.bufsize - tune.maxrewrite), haproxy will
+  parameter should be decreased by the same factor as this one is increased. In
+  addition, use of HTTP/2 mandates that this value must be 16384 or more. If an
+  HTTP request is larger than (tune.bufsize - tune.maxrewrite), haproxy will
   return HTTP 400 (Bad Request) error. Similarly if an HTTP response is larger
   than this size, haproxy will return HTTP 502 (Bad Gateway).
 
index 57f25fac79f52cebbca85cea21695ede020aa14f..bf8139ca0e087afa35e432a2a0a04484bb81c255 100644 (file)
@@ -7583,6 +7583,30 @@ int check_config_validity()
                list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
                        unsigned long mask;
 
+                       /* HTTP frontends with "h2" as ALPN/NPN will work in
+                        * HTTP/2 and absolutely require buffers 16kB or larger.
+                        */
+#ifdef USE_OPENSSL
+                       if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
+#ifdef OPENSSL_NPN_NEGOTIATED
+                               /* check NPN */
+                               if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
+                                       Alert("config : HTTP frontend '%s' enables HTTP/2 via NPN at [%s:%d], so global.tune.bufsize must be at least 16384 bytes (%d now).\n",
+                                             curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
+                                       cfgerr++;
+                               }
+#endif
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
+                               /* check ALPN */
+                               if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
+                                       Alert("config : HTTP frontend '%s' enables HTTP/2 via ALPN at [%s:%d], so global.tune.bufsize must be at least 16384 bytes (%d now).\n",
+                                             curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
+                                       cfgerr++;
+                               }
+#endif
+                       } /* HTTP && bufsize < 16384 */
+#endif
+
                        if (!bind_conf->bind_proc)
                                continue;