diff --git a/bazel/foreign_cc/nghttp2.patch b/bazel/foreign_cc/nghttp2.patch index bfe51d07dad0..e7b001673a56 100644 --- a/bazel/foreign_cc/nghttp2.patch +++ b/bazel/foreign_cc/nghttp2.patch @@ -15,226 +15,3 @@ index 35c77d1d..47bd63f5 100644 endif() # AC_TYPE_UINT8_T # AC_TYPE_UINT16_T -diff --git a/doc/Makefile.am b/doc/Makefile.am -index c17d93382..4d73cef50 100644 ---- a/doc/Makefile.am -+++ b/doc/Makefile.am -@@ -27,6 +27,7 @@ APIDOCS= \ - macros.rst \ - enums.rst \ - types.rst \ -+ nghttp2_check_authority.rst \ - nghttp2_check_header_name.rst \ - nghttp2_check_header_value.rst \ - nghttp2_hd_deflate_bound.rst \ -diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h -index 313fb23da..e3aeb9fed 100644 ---- a/lib/includes/nghttp2/nghttp2.h -+++ b/lib/includes/nghttp2/nghttp2.h -@@ -4769,6 +4769,19 @@ NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len); - */ - NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len); - -+/** -+ * @function -+ * -+ * Returns nonzero if the |value| which is supposed to the value of -+ * :authority or host header field is valid according to -+ * https://tools.ietf.org/html/rfc3986#section-3.2 -+ * -+ * |value| is valid if it merely consists of the allowed characters. -+ * In particular, it does not check whether |value| follows the syntax -+ * of authority. -+ */ -+NGHTTP2_EXTERN int nghttp2_check_authority(const uint8_t *value, size_t len); -+ - /* HPACK API */ - - struct nghttp2_hd_deflater; -diff --git a/lib/nghttp2_helper.c b/lib/nghttp2_helper.c -index 81a8a0cf9..91136a619 100644 ---- a/lib/nghttp2_helper.c -+++ b/lib/nghttp2_helper.c -@@ -505,6 +505,84 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) { - return 1; - } - -+/* Generated by genauthroitychartbl.py */ -+static char VALID_AUTHORITY_CHARS[] = { -+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, -+ 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, -+ 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, -+ 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, -+ 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, -+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, -+ 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, -+ 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, -+ 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, -+ 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, -+ 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, -+ 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, -+ 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, -+ 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, -+ 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, -+ 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, -+ 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, -+ 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, -+ 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, -+ 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, -+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, -+ 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, -+ 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, -+ 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, -+ 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, -+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, -+ 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, -+ 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, -+ 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, -+ 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, -+ 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, -+ 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, -+ 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, -+ 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, -+ 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, -+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, -+ 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, -+ 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, -+ 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, -+ 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, -+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, -+ 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, -+ 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, -+ 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, -+ 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, -+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, -+ 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, -+ 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, -+ 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, -+ 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, -+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, -+ 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, -+ 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, -+ 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, -+ 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, -+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, -+ 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, -+ 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, -+ 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, -+ 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, -+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, -+ 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, -+ 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, -+ 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ -+}; -+ -+int nghttp2_check_authority(const uint8_t *value, size_t len) { -+ const uint8_t *last; -+ for (last = value + len; value != last; ++value) { -+ if (!VALID_AUTHORITY_CHARS[*value]) { -+ return 0; -+ } -+ } -+ return 1; -+} -+ - uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) { - if (len == 0) { - return dest; -diff --git a/lib/nghttp2_http.c b/lib/nghttp2_http.c -index 8d9902998..62f57b6ae 100644 ---- a/lib/nghttp2_http.c -+++ b/lib/nghttp2_http.c -@@ -305,84 +305,6 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv, - return 0; - } - --/* Generated by genauthroitychartbl.py */ --static char VALID_AUTHORITY_CHARS[] = { -- 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, -- 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, -- 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, -- 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, -- 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, -- 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, -- 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, -- 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, -- 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, -- 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, -- 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, -- 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, -- 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, -- 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, -- 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, -- 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, -- 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, -- 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, -- 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, -- 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, -- 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, -- 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, -- 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, -- 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, -- 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, -- 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, -- 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, -- 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, -- 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, -- 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, -- 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, -- 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, -- 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, -- 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, -- 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, -- 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, -- 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, -- 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, -- 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, -- 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, -- 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, -- 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, -- 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, -- 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, -- 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, -- 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, -- 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, -- 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, -- 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, -- 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, -- 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, -- 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, -- 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, -- 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, -- 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, -- 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, -- 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, -- 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, -- 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, -- 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, -- 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, -- 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, -- 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, -- 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ --}; -- --static int check_authority(const uint8_t *value, size_t len) { -- const uint8_t *last; -- for (last = value + len; value != last; ++value) { -- if (!VALID_AUTHORITY_CHARS[*value]) { -- return 0; -- } -- } -- return 1; --} -- - static int check_scheme(const uint8_t *value, size_t len) { - const uint8_t *last; - if (len == 0) { -@@ -440,7 +362,7 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, - - if (nv->token == NGHTTP2_TOKEN__AUTHORITY || - nv->token == NGHTTP2_TOKEN_HOST) { -- rv = check_authority(nv->value->base, nv->value->len); -+ rv = nghttp2_check_authority(nv->value->base, nv->value->len); - } else if (nv->token == NGHTTP2_TOKEN__SCHEME) { - rv = check_scheme(nv->value->base, nv->value->len); - } else { diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 802e93916135..2b3f009c630d 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -118,9 +118,9 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/nanopb/nanopb/archive/0.3.9.4.tar.gz"], ), com_github_nghttp2_nghttp2 = dict( - sha256 = "25b623cd04dc6a863ca3b34ed6247844effe1aa5458229590b3f56a6d53cd692", - strip_prefix = "nghttp2-1.39.1", - urls = ["https://github.com/nghttp2/nghttp2/releases/download/v1.39.1/nghttp2-1.39.1.tar.gz"], + sha256 = "eacc6f0f8543583ecd659faf0a3f906ed03826f1d4157b536b4b385fe47c5bb8", + strip_prefix = "nghttp2-1.41.0", + urls = ["https://github.com/nghttp2/nghttp2/releases/download/v1.41.0/nghttp2-1.41.0.tar.gz"], ), io_opentracing_cpp = dict( sha256 = "015c4187f7a6426a2b5196f0ccd982aa87f010cf61f507ae3ce5c90523f92301", diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index de3f742478fe..4a756b58bcb2 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -1066,6 +1066,13 @@ ConnectionImpl::Http2Options::Http2Options(const Http2Settings& http2_settings) if (http2_settings.allow_metadata_) { nghttp2_option_set_user_recv_extension_type(options_, METADATA_FRAME_TYPE); } + + // nghttp2 v1.39.2 lowered the internal flood protection limit from 10K to 1K of ACK frames. This + // new limit may cause the internal nghttp2 mitigation to trigger more often (as it requires just + // 9K of incoming bytes for smallest 9 byte SETTINGS frame), bypassing the same mitigation and its + // associated behavior in the envoy HTTP/2 codec. Since envoy does not rely on this mitigation, + // set back to the old 10K number to avoid any changes in the HTTP/2 codec behavior. + nghttp2_option_set_max_outbound_ack(options_, 10000); } ConnectionImpl::Http2Options::~Http2Options() { nghttp2_option_del(options_); } diff --git a/test/integration/http2_integration_test.cc b/test/integration/http2_integration_test.cc index c52ae65656b9..80b03bd88ad2 100644 --- a/test/integration/http2_integration_test.cc +++ b/test/integration/http2_integration_test.cc @@ -1440,16 +1440,19 @@ const int64_t TransmitThreshold = 100 * 1024 * 1024; } // namespace void Http2FloodMitigationTest::setNetworkConnectionBufferSize() { - // nghttp2 library has its own internal mitigation for outbound control frames. The mitigation is - // triggered when there are more than 10000 PING or SETTINGS frames with ACK flag in the nghttp2 - // internal outbound queue. It is possible to trigger this mitigation in nghttp2 before triggering - // Envoy's own flood mitigation. This can happen when a buffer larger enough to contain over 10K - // PING or SETTINGS frames is dispatched to the nghttp2 library. To prevent this from happening - // the network connection receive buffer needs to be smaller than 90Kb (which is 10K SETTINGS - // frames). Set it to the arbitrarily chosen value of 32K. + // nghttp2 library has its own internal mitigation for outbound control frames (see + // NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM). The default nghttp2 mitigation threshold of 1K is modified + // to 10K in the ConnectionImpl::Http2Options::Http2Options. The mitigation is triggered when + // there are more than 10000 PING or SETTINGS frames with ACK flag in the nghttp2 internal + // outbound queue. It is possible to trigger this mitigation in nghttp2 before triggering Envoy's + // own flood mitigation. This can happen when a buffer large enough to contain over 10K PING or + // SETTINGS frames is dispatched to the nghttp2 library. To prevent this from happening the + // network connection receive buffer needs to be smaller than 90Kb (which is 10K SETTINGS frames). + // Set it to the arbitrarily chosen value of 32K. Note that this buffer has 16K lower bound. config_helper_.addConfigModifier([](envoy::config::bootstrap::v2::Bootstrap& bootstrap) -> void { RELEASE_ASSERT(bootstrap.mutable_static_resources()->listeners_size() >= 1, ""); auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0); + listener->mutable_per_connection_buffer_limit_bytes()->set_value(32 * 1024); }); } diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index 76a9f05aadc1..13fa984dcb9c 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -1123,3 +1123,4 @@ zag zig zipkin zlib +OBQ