comparison src/http/v2/ngx_http_v2.c @ 7377:d4448892a294

HTTP/2: flood detection. 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.
author Ruslan Ermilov <ru@nginx.com>
date Tue, 06 Nov 2018 16:29:35 +0300
parents 1812f1d79d84
children e7f19d268c72
comparison
equal deleted inserted replaced
7376:e5069816039b 7377:d4448892a294
660 660
661 ngx_destroy_pool(h2c->pool); 661 ngx_destroy_pool(h2c->pool);
662 662
663 h2c->pool = NULL; 663 h2c->pool = NULL;
664 h2c->free_frames = NULL; 664 h2c->free_frames = NULL;
665 h2c->frames = 0;
665 h2c->free_fake_connections = NULL; 666 h2c->free_fake_connections = NULL;
666 667
667 #if (NGX_HTTP_SSL) 668 #if (NGX_HTTP_SSL)
668 if (c->ssl) { 669 if (c->ssl) {
669 ngx_ssl_free_buffer(c); 670 ngx_ssl_free_buffer(c);
2893 buf = frame->first->buf; 2894 buf = frame->first->buf;
2894 buf->pos = buf->start; 2895 buf->pos = buf->start;
2895 2896
2896 frame->blocked = 0; 2897 frame->blocked = 0;
2897 2898
2898 } else { 2899 } else if (h2c->frames < 10000) {
2899 pool = h2c->pool ? h2c->pool : h2c->connection->pool; 2900 pool = h2c->pool ? h2c->pool : h2c->connection->pool;
2900 2901
2901 frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t)); 2902 frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t));
2902 if (frame == NULL) { 2903 if (frame == NULL) {
2903 return NULL; 2904 return NULL;
2917 2918
2918 frame->first->buf = buf; 2919 frame->first->buf = buf;
2919 frame->last = frame->first; 2920 frame->last = frame->first;
2920 2921
2921 frame->handler = ngx_http_v2_frame_handler; 2922 frame->handler = ngx_http_v2_frame_handler;
2923
2924 h2c->frames++;
2925
2926 } else {
2927 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
2928 "http2 flood detected");
2929
2930 h2c->connection->error = 1;
2931 return NULL;
2922 } 2932 }
2923 2933
2924 #if (NGX_DEBUG) 2934 #if (NGX_DEBUG)
2925 if (length > NGX_HTTP_V2_FRAME_BUFFER_SIZE - NGX_HTTP_V2_FRAME_HEADER_SIZE) 2935 if (length > NGX_HTTP_V2_FRAME_BUFFER_SIZE - NGX_HTTP_V2_FRAME_HEADER_SIZE)
2926 { 2936 {