0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Increase the default max_received_frame_rate

Allow 10000 frames every 10 seconds instead of just 1000,
as the limit was too quickly reached in some deployments.
This commit is contained in:
Loïc Hoguin 2020-03-29 13:51:21 +02:00
parent f8e94c3315
commit 6ad842a742
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764
3 changed files with 10 additions and 8 deletions

View file

@ -161,7 +161,7 @@ following the client's advertised maximum.
Note that actual frame sizes may be lower than the limit when Note that actual frame sizes may be lower than the limit when
there is not enough space left in the flow control window. there is not enough space left in the flow control window.
max_received_frame_rate ({1000, 10000}):: max_received_frame_rate ({10000, 10000})::
Maximum frame rate allowed per connection. The rate is expressed Maximum frame rate allowed per connection. The rate is expressed
as a tuple `{NumFrames, TimeMs}` indicating how many frames are as a tuple `{NumFrames, TimeMs}` indicating how many frames are
@ -236,6 +236,8 @@ too many `WINDOW_UPDATE` frames.
== Changelog == Changelog
* *2.8*: The `active_n` option was added. * *2.8*: The `active_n` option was added.
* *2.8*: The `max_received_frame_rate` default value has
been multiplied by 10 as the default was too low.
* *2.7*: Add the options `connection_window_margin_size`, * *2.7*: Add the options `connection_window_margin_size`,
`connection_window_update_threshold`, `connection_window_update_threshold`,
`max_connection_window_size`, `max_stream_window_size`, `max_connection_window_size`, `max_stream_window_size`,

View file

@ -171,7 +171,7 @@ init(Parent, Ref, Socket, Transport, ProxyHeader, Opts, Peer, Sock, Cert, Buffer
end. end.
init_rate_limiting(State=#state{opts=Opts}) -> init_rate_limiting(State=#state{opts=Opts}) ->
{FrameRateNum, FrameRatePeriod} = maps:get(max_received_frame_rate, Opts, {1000, 10000}), {FrameRateNum, FrameRatePeriod} = maps:get(max_received_frame_rate, Opts, {10000, 10000}),
{ResetRateNum, ResetRatePeriod} = maps:get(max_reset_stream_rate, Opts, {10, 10000}), {ResetRateNum, ResetRatePeriod} = maps:get(max_reset_stream_rate, Opts, {10, 10000}),
CurrentTime = erlang:monotonic_time(millisecond), CurrentTime = erlang:monotonic_time(millisecond),
State#state{ State#state{

View file

@ -116,7 +116,7 @@ http2_empty_frame_flooding_data(Config) ->
{<<":path">>, <<"/echo/read_body">>} {<<":path">>, <<"/echo/read_body">>}
]), ]),
ok = gen_tcp:send(Socket, cow_http2:headers(1, nofin, HeadersBlock)), ok = gen_tcp:send(Socket, cow_http2:headers(1, nofin, HeadersBlock)),
_ = [gen_tcp:send(Socket, cow_http2:data(1, nofin, <<>>)) || _ <- lists:seq(1, 2000)], _ = [gen_tcp:send(Socket, cow_http2:data(1, nofin, <<>>)) || _ <- lists:seq(1, 20000)],
%% When Cowboy detects a flood it must close the connection. %% When Cowboy detects a flood it must close the connection.
%% We skip WINDOW_UPDATE frames sent when Cowboy starts to read the body. %% We skip WINDOW_UPDATE frames sent when Cowboy starts to read the body.
case gen_tcp:recv(Socket, 43, 6000) of case gen_tcp:recv(Socket, 43, 6000) of
@ -133,7 +133,7 @@ http2_empty_frame_flooding_headers_continuation(Config) ->
{ok, Socket} = rfc7540_SUITE:do_handshake(Config), {ok, Socket} = rfc7540_SUITE:do_handshake(Config),
%% Send many empty HEADERS/CONTINUATION frames before the headers. %% Send many empty HEADERS/CONTINUATION frames before the headers.
ok = gen_tcp:send(Socket, <<0:24, 1:8, 0:9, 1:31>>), ok = gen_tcp:send(Socket, <<0:24, 1:8, 0:9, 1:31>>),
_ = [gen_tcp:send(Socket, <<0:24, 9:8, 0:9, 1:31>>) || _ <- lists:seq(1, 2000)], _ = [gen_tcp:send(Socket, <<0:24, 9:8, 0:9, 1:31>>) || _ <- lists:seq(1, 20000)],
{HeadersBlock, _} = cow_hpack:encode([ {HeadersBlock, _} = cow_hpack:encode([
{<<":method">>, <<"POST">>}, {<<":method">>, <<"POST">>},
{<<":scheme">>, <<"http">>}, {<<":scheme">>, <<"http">>},
@ -181,7 +181,7 @@ http2_ping_flood(Config) ->
doc("Confirm that Cowboy detects PING floods. (CVE-2019-9512)"), doc("Confirm that Cowboy detects PING floods. (CVE-2019-9512)"),
{ok, Socket} = rfc7540_SUITE:do_handshake(Config), {ok, Socket} = rfc7540_SUITE:do_handshake(Config),
%% Flood the server with PING frames. %% Flood the server with PING frames.
_ = [gen_tcp:send(Socket, cow_http2:ping(0)) || _ <- lists:seq(1, 2000)], _ = [gen_tcp:send(Socket, cow_http2:ping(0)) || _ <- lists:seq(1, 20000)],
%% Receive a number of PING ACK frames in return, following by the closing of the connection. %% Receive a number of PING ACK frames in return, following by the closing of the connection.
try try
[case gen_tcp:recv(Socket, 17, 6000) of [case gen_tcp:recv(Socket, 17, 6000) of
@ -190,7 +190,7 @@ http2_ping_flood(Config) ->
%% We also accept the connection being closed immediately, %% We also accept the connection being closed immediately,
%% which may happen because we send the GOAWAY right before closing. %% which may happen because we send the GOAWAY right before closing.
{error, closed} -> throw(goaway) {error, closed} -> throw(goaway)
end || _ <- lists:seq(1, 2000)], end || _ <- lists:seq(1, 20000)],
error(flood_successful) error(flood_successful)
catch throw:goaway -> catch throw:goaway ->
ok ok
@ -231,7 +231,7 @@ http2_settings_flood(Config) ->
doc("Confirm that Cowboy detects SETTINGS floods. (CVE-2019-9515)"), doc("Confirm that Cowboy detects SETTINGS floods. (CVE-2019-9515)"),
{ok, Socket} = rfc7540_SUITE:do_handshake(Config), {ok, Socket} = rfc7540_SUITE:do_handshake(Config),
%% Flood the server with empty SETTINGS frames. %% Flood the server with empty SETTINGS frames.
_ = [gen_tcp:send(Socket, cow_http2:settings(#{})) || _ <- lists:seq(1, 2000)], _ = [gen_tcp:send(Socket, cow_http2:settings(#{})) || _ <- lists:seq(1, 20000)],
%% Receive a number of SETTINGS ACK frames in return, following by the closing of the connection. %% Receive a number of SETTINGS ACK frames in return, following by the closing of the connection.
try try
[case gen_tcp:recv(Socket, 9, 6000) of [case gen_tcp:recv(Socket, 9, 6000) of
@ -243,7 +243,7 @@ http2_settings_flood(Config) ->
%% which may happen because we send the GOAWAY right before closing. %% which may happen because we send the GOAWAY right before closing.
{error, closed} -> {error, closed} ->
throw(goaway) throw(goaway)
end || _ <- lists:seq(1, 2000)], end || _ <- lists:seq(1, 20000)],
error(flood_successful) error(flood_successful)
catch throw:goaway -> catch throw:goaway ->
ok ok