]> git.kaiwu.me - nginx.git/commitdiff
HTTP/2: flood detection.
authorRuslan Ermilov <ru@nginx.com>
Tue, 6 Nov 2018 13:29:35 +0000 (16:29 +0300)
committerRuslan Ermilov <ru@nginx.com>
Tue, 6 Nov 2018 13:29:35 +0000 (16:29 +0300)
Fixed uncontrolled memory growth in case peer is flooding us with
some frames (e.g., SETTINGS and PING) and doesn't read data.  Fix
is to limit the number of allocated control frames.

src/http/v2/ngx_http_v2.c
src/http/v2/ngx_http_v2.h

index b916ebdf6d37e277b371f8dd91b359986f8a605d..8089ddd58492a545c5bdabfe41517bfe8cfb2568 100644 (file)
@@ -662,6 +662,7 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
 
     h2c->pool = NULL;
     h2c->free_frames = NULL;
+    h2c->frames = 0;
     h2c->free_fake_connections = NULL;
 
 #if (NGX_HTTP_SSL)
@@ -2895,7 +2896,7 @@ ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length,
 
         frame->blocked = 0;
 
-    } else {
+    } else if (h2c->frames < 10000) {
         pool = h2c->pool ? h2c->pool : h2c->connection->pool;
 
         frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t));
@@ -2919,6 +2920,15 @@ ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length,
         frame->last = frame->first;
 
         frame->handler = ngx_http_v2_frame_handler;
+
+        h2c->frames++;
+
+    } else {
+        ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
+                      "http2 flood detected");
+
+        h2c->connection->error = 1;
+        return NULL;
     }
 
 #if (NGX_DEBUG)
index ebd0e77c0fd6ce24225188506e369b9b6e030037..e8eaebb25553e7666029d1cd3e42b5fbed9efb73 100644 (file)
@@ -120,6 +120,7 @@ struct ngx_http_v2_connection_s {
     ngx_http_connection_t           *http_connection;
 
     ngx_uint_t                       processing;
+    ngx_uint_t                       frames;
 
     ngx_uint_t                       pushing;
     ngx_uint_t                       concurrent_pushes;