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:
parent
f8e94c3315
commit
6ad842a742
3 changed files with 10 additions and 8 deletions
|
@ -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`,
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue