Skip to content

Commit

Permalink
move MAX_QUEUED_CONTROL_FRAMES to configuration file
Browse files Browse the repository at this point in the history
  • Loading branch information
kingluo committed May 6, 2024
1 parent 985bb62 commit 1effa31
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
13 changes: 13 additions & 0 deletions etc/tempesta_fw.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,19 @@
# http_max_header_list_size 4096;
#

# TAG: max_queued_control_frames
#
# Maximum number of control frames allowed to wait in
# the client connection's write queue, to mitigate control frames flooding
# (PING/SETTINGS/RESET_STREAM).
#
# Syntax:
# max_queued_control_frames SIZE
#
# Example:
# max_queued_control_frames 10000;
#

#
# Health monitoring configuration.
#
Expand Down
35 changes: 35 additions & 0 deletions fw/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -7530,6 +7530,34 @@ tfw_cfgop_cleanup_max_header_list_size(TfwCfgSpec *cs)
max_header_list_size = 0;
}

static int
tfw_cfgop_max_queued_control_frames(TfwCfgSpec *cs, TfwCfgEntry *ce)
{
int r;

if (tfw_cfg_check_val_n(ce, 1))
return -EINVAL;
if (ce->attr_n) {
T_ERR_NL("Unexpected attributes\n");
return -EINVAL;
}

r = tfw_cfg_parse_uint(ce->vals[0], &max_queued_control_frames);
if (unlikely(r)) {
T_ERR_NL("Unable to parse 'max_queued_control_frames' value: '%s'\n",
ce->vals[0]);
return -EINVAL;
}

return 0;
}

static void
tfw_cfgop_cleanup_max_queued_control_frames(TfwCfgSpec *cs)
{
max_queued_control_frames = 0;
}

static TfwCfgSpec tfw_http_specs[] = {
{
.name = "block_action",
Expand Down Expand Up @@ -7617,6 +7645,13 @@ static TfwCfgSpec tfw_http_specs[] = {
.allow_none = true,
.cleanup = tfw_cfgop_cleanup_max_header_list_size,
},
{
.name = "max_queued_control_frames",
.deflt = "10000",
.handler = tfw_cfgop_max_queued_control_frames,
.allow_none = true,
.cleanup = tfw_cfgop_cleanup_max_queued_control_frames,
},
{ 0 }
};

Expand Down
13 changes: 9 additions & 4 deletions fw/http_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "http_msg.h"
#include "tcp.h"

unsigned int max_queued_control_frames = 0;

#define FRAME_PREFACE_CLI_MAGIC "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
#define FRAME_PREFACE_CLI_MAGIC_LEN 24
#define FRAME_WND_UPDATE_SIZE 4
Expand Down Expand Up @@ -282,11 +284,14 @@ __tfw_h2_send_frame(TfwH2Ctx *ctx, TfwFrameHdr *hdr, TfwStr *data,
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
bool is_control_frame = !hdr->stream_id || hdr->type == HTTP2_RST_STREAM;

// If the peer is causing us to generate a lot of control frames,
// but not reading them from us, assume they are trying to make us
// run out of memory.
/*
* If the peer is causing us to generate a lot of control frames,
* but not reading them from us, assume they are trying to make us
* run out of memory.
*/
if (is_control_frame &&
atomic_read(&ctx->queued_control_frames) > MAX_QUEUED_CONTROL_FRAMES) {
atomic_read(&ctx->queued_control_frames)
> max_queued_control_frames) {
T_ERR("Too many control frames in send queue, closing connection");
r = SS_BLOCK_WITH_RST;
goto err;
Expand Down
2 changes: 2 additions & 0 deletions fw/http_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "http_stream.h"
#include "hpack.h"

extern unsigned int max_queued_control_frames;

/* RFC 7540 Section 4.1 frame header constants. */
#define FRAME_HEADER_SIZE 9
#define FRAME_STREAM_ID_MASK ((1U << 31) - 1)
Expand Down

0 comments on commit 1effa31

Please sign in to comment.