]> git.kaiwu.me - nginx.git/commitdiff
QUIC: traffic-based flood detection.
authorRoman Arutyunyan <arut@nginx.com>
Wed, 13 Oct 2021 11:41:46 +0000 (14:41 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Wed, 13 Oct 2021 11:41:46 +0000 (14:41 +0300)
With this patch, all traffic over a QUIC connection is compared to traffic
over QUIC streams.  As long as total traffic is many times larger than stream
traffic, we consider this to be a flood.

src/event/quic/ngx_event_quic.c
src/event/quic/ngx_event_quic_connection.h

index 8741b83e6578d12c4c564847b1a3fc7c086d64cc..38138a6c1ce0901377c4b02c9113f71e8a174d36 100644 (file)
@@ -665,13 +665,17 @@ ngx_quic_close_timer_handler(ngx_event_t *ev)
 static ngx_int_t
 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf)
 {
-    u_char             *p;
-    ngx_int_t           rc;
-    ngx_uint_t          good;
-    ngx_quic_header_t   pkt;
+    size_t                  size;
+    u_char                 *p;
+    ngx_int_t               rc;
+    ngx_uint_t              good;
+    ngx_quic_header_t       pkt;
+    ngx_quic_connection_t  *qc;
 
     good = 0;
 
+    size = b->last - b->pos;
+
     p = b->pos;
 
     while (p < b->last) {
@@ -736,7 +740,27 @@ ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf)
         p = b->pos;
     }
 
-    return good ? NGX_OK : NGX_DECLINED;
+    if (!good) {
+        return NGX_DECLINED;
+    }
+
+    qc = ngx_quic_get_connection(c);
+
+    if (qc) {
+        qc->received += size;
+
+        if ((uint64_t) (c->sent + qc->received) / 8 >
+            (qc->streams.sent + qc->streams.recv_last) + 1048576)
+        {
+            ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic flood detected");
+
+            qc->error = NGX_QUIC_ERR_NO_ERROR;
+            qc->error_reason = "QUIC flood detected";
+            return NGX_ERROR;
+        }
+    }
+
+    return NGX_OK;
 }
 
 
index f3de5b136fa54a7337b40f722df8ac3fab1928da..b58e9f5869c61ff102a1e2034c27f8cca809dfc2 100644 (file)
@@ -236,6 +236,8 @@ struct ngx_quic_connection_s {
     ngx_quic_streams_t                streams;
     ngx_quic_congestion_t             congestion;
 
+    off_t                             received;
+
     ngx_uint_t                        error;
     enum ssl_encryption_level_t       error_level;
     ngx_uint_t                        error_ftype;