mirror of
https://github.com/nginx/nginx.git
synced 2024-12-27 17:31:35 -06:00
HTTP/2: traffic-based flood detection.
With this patch, all traffic over an HTTP/2 connection is counted in the h2c->total_bytes field, and payload traffic is counted in the h2c->payload_bytes field. As long as total traffic is many times larger than payload traffic, we consider this to be a flood.
This commit is contained in:
parent
4d4201fafd
commit
af0e284b96
@ -419,6 +419,14 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
|
||||
|
||||
} while (p != end);
|
||||
|
||||
h2c->total_bytes += n;
|
||||
|
||||
if (h2c->total_bytes / 8 > h2c->payload_bytes + 1048576) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "http2 flood detected");
|
||||
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
} while (rev->ready);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
@ -963,6 +971,8 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
|
||||
}
|
||||
|
||||
h2c->payload_bytes += size;
|
||||
|
||||
if (r->request_body) {
|
||||
rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed);
|
||||
|
||||
@ -2909,9 +2919,9 @@ ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length,
|
||||
"requested control frame is too large: %uz", length);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
frame->length = length;
|
||||
#endif
|
||||
|
||||
buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);
|
||||
|
||||
@ -2938,6 +2948,8 @@ ngx_http_v2_frame_handler(ngx_http_v2_connection_t *h2c,
|
||||
frame->next = h2c->free_frames;
|
||||
h2c->free_frames = frame;
|
||||
|
||||
h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -3723,7 +3735,8 @@ ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
|
||||
static void
|
||||
ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_connection_t *fc;
|
||||
ngx_connection_t *fc;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
|
||||
fc = r->connection;
|
||||
|
||||
@ -3755,6 +3768,10 @@ ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||
r->headers_in.chunked = 1;
|
||||
}
|
||||
|
||||
h2c = r->stream->connection;
|
||||
|
||||
h2c->payload_bytes += r->request_length;
|
||||
|
||||
ngx_http_process_request(r);
|
||||
|
||||
failed:
|
||||
|
@ -119,6 +119,9 @@ struct ngx_http_v2_connection_s {
|
||||
ngx_connection_t *connection;
|
||||
ngx_http_connection_t *http_connection;
|
||||
|
||||
off_t total_bytes;
|
||||
off_t payload_bytes;
|
||||
|
||||
ngx_uint_t processing;
|
||||
ngx_uint_t frames;
|
||||
ngx_uint_t idle;
|
||||
|
@ -1877,6 +1877,8 @@ ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c,
|
||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
||||
+ frame->length;
|
||||
|
||||
h2c->payload_bytes += frame->length;
|
||||
|
||||
ngx_http_v2_handle_frame(stream, frame);
|
||||
|
||||
ngx_http_v2_handle_stream(h2c, stream);
|
||||
@ -1931,6 +1933,8 @@ ngx_http_v2_push_frame_handler(ngx_http_v2_connection_t *h2c,
|
||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
||||
+ frame->length;
|
||||
|
||||
h2c->payload_bytes += frame->length;
|
||||
|
||||
ngx_http_v2_handle_frame(stream, frame);
|
||||
|
||||
ngx_http_v2_handle_stream(h2c, stream);
|
||||
@ -2024,6 +2028,8 @@ done:
|
||||
|
||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
|
||||
|
||||
h2c->payload_bytes += frame->length;
|
||||
|
||||
ngx_http_v2_handle_frame(stream, frame);
|
||||
|
||||
ngx_http_v2_handle_stream(h2c, stream);
|
||||
@ -2036,12 +2042,17 @@ static ngx_inline void
|
||||
ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
|
||||
ngx_http_v2_out_frame_t *frame)
|
||||
{
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
|
||||
r = stream->request;
|
||||
|
||||
r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
||||
|
||||
h2c = stream->connection;
|
||||
|
||||
h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
||||
|
||||
if (frame->fin) {
|
||||
stream->out_closed = 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user