Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7d37bce

Browse filesBrowse files
lundibundiaddaleax
authored andcommitted
http2: make maximum tolerated rejected streams configurable
PR-URL: #30534 Fixes: #30505 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 5ecfd94 commit 7d37bce
Copy full SHA for 7d37bce

File tree

Expand file treeCollapse file tree

6 files changed

+70
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+70
-2
lines changed
Open diff view settings
Collapse file

‎doc/api/http2.md‎

Copy file name to clipboardExpand all lines: doc/api/http2.md
+18Lines changed: 18 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,9 @@ error will be thrown.
19411941
<!-- YAML
19421942
added: v8.4.0
19431943
changes:
1944+
- version: REPLACEME
1945+
pr-url: https://github.com/nodejs/node/pull/30534
1946+
description: Added `maxSessionRejectedStreams` option with a default of 100.
19441947
- version: REPLACEME
19451948
pr-url: https://github.com/nodejs/node/pull/30534
19461949
description: Added `maxSessionInvalidFrames` option with a default of 1000.
@@ -2007,6 +2010,12 @@ changes:
20072010
* `maxSessionInvalidFrames` {integer} Sets the maximum number of invalid
20082011
frames that will be tolerated before the session is closed.
20092012
**Default:** `1000`.
2013+
* `maxSessionRejectedStreams` {integer} Sets the maximum number of rejected
2014+
upon creation streams that will be tolerated before the session is closed.
2015+
Each rejection is associated with an `NGHTTP2_ENHANCE_YOUR_CALM`
2016+
error that should tell the peer to not open any more streams, continuing
2017+
to open streams is therefore regarded as a sign of a misbehaving peer.
2018+
**Default:** `100`.
20102019
* `settings` {HTTP/2 Settings Object} The initial settings to send to the
20112020
remote peer upon connection.
20122021
* `Http1IncomingMessage` {http.IncomingMessage} Specifies the
@@ -2059,6 +2068,9 @@ server.listen(80);
20592068
<!-- YAML
20602069
added: v8.4.0
20612070
changes:
2071+
- version: REPLACEME
2072+
pr-url: https://github.com/nodejs/node/pull/30534
2073+
description: Added `maxSessionRejectedStreams` option with a default of 100.
20622074
- version: REPLACEME
20632075
pr-url: https://github.com/nodejs/node/pull/30534
20642076
description: Added `maxSessionInvalidFrames` option with a default of 1000.
@@ -2125,6 +2137,12 @@ changes:
21252137
* `maxSessionInvalidFrames` {integer} Sets the maximum number of invalid
21262138
frames that will be tolerated before the session is closed.
21272139
**Default:** `1000`.
2140+
* `maxSessionRejectedStreams` {integer} Sets the maximum number of rejected
2141+
upon creation streams that will be tolerated before the session is closed.
2142+
Each rejection is associated with an `NGHTTP2_ENHANCE_YOUR_CALM`
2143+
error that should tell the peer to not open any more streams, continuing
2144+
to open streams is therefore regarded as a sign of a misbehaving peer.
2145+
**Default:** `100`.
21282146
* `settings` {HTTP/2 Settings Object} The initial settings to send to the
21292147
remote peer upon connection.
21302148
* ...: Any [`tls.createServer()`][] options can be provided. For
Collapse file

‎lib/internal/http2/core.js‎

Copy file name to clipboardExpand all lines: lib/internal/http2/core.js
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ const {
204204
kSessionPriorityListenerCount,
205205
kSessionFrameErrorListenerCount,
206206
kSessionMaxInvalidFrames,
207+
kSessionMaxRejectedStreams,
207208
kSessionUint8FieldCount,
208209
kSessionHasRemoteSettingsListeners,
209210
kSessionRemoteSettingsIsUpToDate,
@@ -948,6 +949,12 @@ function setupHandle(socket, type, options) {
948949
uint32[0] = options.maxSessionInvalidFrames;
949950
}
950951

952+
if (isUint32(options.maxSessionRejectedStreams)) {
953+
const uint32 = new Uint32Array(
954+
this[kNativeFields].buffer, kSessionMaxRejectedStreams, 1);
955+
uint32[0] = options.maxSessionRejectedStreams;
956+
}
957+
951958
const settings = typeof options.settings === 'object' ?
952959
options.settings : {};
953960

@@ -2782,6 +2789,13 @@ function initializeOptions(options) {
27822789
if (options.maxSessionInvalidFrames !== undefined)
27832790
validateUint32(options.maxSessionInvalidFrames, 'maxSessionInvalidFrames');
27842791

2792+
if (options.maxSessionRejectedStreams !== undefined) {
2793+
validateUint32(
2794+
options.maxSessionRejectedStreams,
2795+
'maxSessionRejectedStreams'
2796+
);
2797+
}
2798+
27852799
// Used only with allowHTTP1
27862800
options.Http1IncomingMessage = options.Http1IncomingMessage ||
27872801
http.IncomingMessage;
Collapse file

‎src/node_http2.cc‎

Copy file name to clipboardExpand all lines: src/node_http2.cc
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,8 @@ int Http2Session::OnBeginHeadersCallback(nghttp2_session* handle,
920920
if (UNLIKELY(!session->CanAddStream() ||
921921
Http2Stream::New(session, id, frame->headers.cat) ==
922922
nullptr)) {
923-
if (session->rejected_stream_count_++ > 100)
923+
if (session->rejected_stream_count_++ >
924+
session->js_fields_.max_rejected_streams)
924925
return NGHTTP2_ERR_CALLBACK_FAILURE;
925926
// Too many concurrent streams being opened
926927
nghttp2_submit_rst_stream(**session, NGHTTP2_FLAG_NONE, id,
@@ -3062,6 +3063,7 @@ void Initialize(Local<Object> target,
30623063
NODE_DEFINE_CONSTANT(target, kSessionPriorityListenerCount);
30633064
NODE_DEFINE_CONSTANT(target, kSessionFrameErrorListenerCount);
30643065
NODE_DEFINE_CONSTANT(target, kSessionMaxInvalidFrames);
3066+
NODE_DEFINE_CONSTANT(target, kSessionMaxRejectedStreams);
30653067
NODE_DEFINE_CONSTANT(target, kSessionUint8FieldCount);
30663068

30673069
NODE_DEFINE_CONSTANT(target, kSessionHasRemoteSettingsListeners);
Collapse file

‎src/node_http2.h‎

Copy file name to clipboardExpand all lines: src/node_http2.h
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ typedef struct {
678678
uint8_t priority_listener_count;
679679
uint8_t frame_error_listener_count;
680680
uint32_t max_invalid_frames = 1000;
681+
uint32_t max_rejected_streams = 100;
681682
} SessionJSFields;
682683

683684
// Indices for js_fields_, which serves as a way to communicate data with JS
@@ -691,6 +692,7 @@ enum SessionUint8Fields {
691692
kSessionFrameErrorListenerCount =
692693
offsetof(SessionJSFields, frame_error_listener_count),
693694
kSessionMaxInvalidFrames = offsetof(SessionJSFields, max_invalid_frames),
695+
kSessionMaxRejectedStreams = offsetof(SessionJSFields, max_rejected_streams),
694696
kSessionUint8FieldCount = sizeof(SessionJSFields)
695697
};
696698

@@ -1024,7 +1026,7 @@ class Http2Session : public AsyncWrap, public StreamListener {
10241026
// limit will result in the session being destroyed, as an indication of a
10251027
// misbehaving peer. This counter is reset once new streams are being
10261028
// accepted again.
1027-
int32_t rejected_stream_count_ = 0;
1029+
uint32_t rejected_stream_count_ = 0;
10281030
// Also use the invalid frame count as a measure for rejecting input frames.
10291031
uint32_t invalid_frame_count_ = 0;
10301032

Collapse file

‎test/parallel/test-http2-createsecureserver-options.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-http2-createsecureserver-options.js
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ Object.entries({
5252
},
5353
},
5454
],
55+
maxSessionRejectedStreams: [
56+
{
57+
val: -1,
58+
err: {
59+
name: 'RangeError',
60+
code: 'ERR_OUT_OF_RANGE',
61+
},
62+
},
63+
{
64+
val: Number.NEGATIVE_INFINITY,
65+
err: {
66+
name: 'RangeError',
67+
code: 'ERR_OUT_OF_RANGE',
68+
},
69+
},
70+
],
5571
}).forEach(([opt, tests]) => {
5672
tests.forEach(({ val, err }) => {
5773
assert.throws(
Collapse file

‎test/parallel/test-http2-createserver-options.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-http2-createserver-options.js
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ Object.entries({
5252
},
5353
},
5454
],
55+
maxSessionRejectedStreams: [
56+
{
57+
val: -1,
58+
err: {
59+
name: 'RangeError',
60+
code: 'ERR_OUT_OF_RANGE',
61+
},
62+
},
63+
{
64+
val: Number.NEGATIVE_INFINITY,
65+
err: {
66+
name: 'RangeError',
67+
code: 'ERR_OUT_OF_RANGE',
68+
},
69+
},
70+
]
5571
}).forEach(([opt, tests]) => {
5672
tests.forEach(({ val, err }) => {
5773
assert.throws(

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.