Klaus Demo nginx / af0e284
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. Maxim Dounin 1 year, 4 months ago
3 changed file(s) with 34 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
418418
419419 } while (p != end);
420420
421 h2c->total_bytes += n;
422
423 if (h2c->total_bytes / 8 > h2c->payload_bytes + 1048576) {
424 ngx_log_error(NGX_LOG_INFO, c->log, 0, "http2 flood detected");
425 ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
426 return;
427 }
428
421429 } while (rev->ready);
422430
423431 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
961969 size = h2c->state.length;
962970 stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
963971 }
972
973 h2c->payload_bytes += size;
964974
965975 if (r->request_body) {
966976 rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed);
29082918 "requested control frame is too large: %uz", length);
29092919 return NULL;
29102920 }
2921 #endif
29112922
29122923 frame->length = length;
2913 #endif
29142924
29152925 buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);
29162926
29362946
29372947 frame->next = h2c->free_frames;
29382948 h2c->free_frames = frame;
2949
2950 h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
29392951
29402952 return NGX_OK;
29412953 }
37223734 static void
37233735 ngx_http_v2_run_request(ngx_http_request_t *r)
37243736 {
3725 ngx_connection_t *fc;
3737 ngx_connection_t *fc;
3738 ngx_http_v2_connection_t *h2c;
37263739
37273740 fc = r->connection;
37283741
37533766 if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
37543767 r->headers_in.chunked = 1;
37553768 }
3769
3770 h2c = r->stream->connection;
3771
3772 h2c->payload_bytes += r->request_length;
37563773
37573774 ngx_http_process_request(r);
37583775
117117 struct ngx_http_v2_connection_s {
118118 ngx_connection_t *connection;
119119 ngx_http_connection_t *http_connection;
120
121 off_t total_bytes;
122 off_t payload_bytes;
120123
121124 ngx_uint_t processing;
122125 ngx_uint_t frames;
18761876 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
18771877 + frame->length;
18781878
1879 h2c->payload_bytes += frame->length;
1880
18791881 ngx_http_v2_handle_frame(stream, frame);
18801882
18811883 ngx_http_v2_handle_stream(h2c, stream);
19291931
19301932 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
19311933 + frame->length;
1934
1935 h2c->payload_bytes += frame->length;
19321936
19331937 ngx_http_v2_handle_frame(stream, frame);
19341938
20232027
20242028 stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
20252029
2030 h2c->payload_bytes += frame->length;
2031
20262032 ngx_http_v2_handle_frame(stream, frame);
20272033
20282034 ngx_http_v2_handle_stream(h2c, stream);
20352041 ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
20362042 ngx_http_v2_out_frame_t *frame)
20372043 {
2038 ngx_http_request_t *r;
2044 ngx_http_request_t *r;
2045 ngx_http_v2_connection_t *h2c;
20392046
20402047 r = stream->request;
20412048
20422049 r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
2050
2051 h2c = stream->connection;
2052
2053 h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
20432054
20442055 if (frame->fin) {
20452056 stream->out_closed = 1;