]> git.kaiwu.me - nginx.git/commitdiff
QUIC: handle DATA_BLOCKED frame from client.
authorRoman Arutyunyan <arut@nginx.com>
Wed, 17 Nov 2021 20:07:51 +0000 (23:07 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Wed, 17 Nov 2021 20:07:51 +0000 (23:07 +0300)
Previously the frame was not handled and connection was closed with an error.
Now, after receiving this frame, global flow control is updated and new
flow control credit is sent to client.

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

index 38138a6c1ce0901377c4b02c9113f71e8a174d36..af6f3e69e3d1358a08dec519a72553c97491ca6a 100644 (file)
@@ -1252,6 +1252,17 @@ ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt)
 
             break;
 
+        case NGX_QUIC_FT_DATA_BLOCKED:
+
+            if (ngx_quic_handle_data_blocked_frame(c, pkt,
+                                                   &frame.u.data_blocked)
+                != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
+            break;
+
         case NGX_QUIC_FT_STREAM_DATA_BLOCKED:
 
             if (ngx_quic_handle_stream_data_blocked_frame(c, pkt,
index 534e0608a36a6409a140cc31f49da323540003ac..ced35370b41480fcc7d7fc8b5e25b3e6f10e7823 100644 (file)
@@ -32,6 +32,7 @@ static void ngx_quic_stream_cleanup_handler(void *data);
 static ngx_int_t ngx_quic_control_flow(ngx_connection_t *c, uint64_t last);
 static ngx_int_t ngx_quic_update_flow(ngx_connection_t *c, uint64_t last);
 static ngx_int_t ngx_quic_update_max_stream_data(ngx_connection_t *c);
+static ngx_int_t ngx_quic_update_max_data(ngx_connection_t *c);
 
 
 ngx_connection_t *
@@ -1187,6 +1188,14 @@ ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c,
 }
 
 
+ngx_int_t
+ngx_quic_handle_data_blocked_frame(ngx_connection_t *c,
+    ngx_quic_header_t *pkt, ngx_quic_data_blocked_frame_t *f)
+{
+    return ngx_quic_update_max_data(c);
+}
+
+
 ngx_int_t
 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c,
     ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f)
@@ -1544,7 +1553,6 @@ ngx_quic_update_flow(ngx_connection_t *c, uint64_t last)
     uint64_t                len;
     ngx_event_t            *rev;
     ngx_connection_t       *pc;
-    ngx_quic_frame_t       *frame;
     ngx_quic_stream_t      *qs;
     ngx_quic_connection_t  *qc;
 
@@ -1577,22 +1585,9 @@ ngx_quic_update_flow(ngx_connection_t *c, uint64_t last)
     if (qc->streams.recv_max_data
         <= qc->streams.recv_offset + qc->streams.recv_window / 2)
     {
-        qc->streams.recv_max_data = qc->streams.recv_offset
-                                    + qc->streams.recv_window;
-
-        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0,
-                       "quic flow update md:%uL", qc->streams.recv_max_data);
-
-        frame = ngx_quic_alloc_frame(pc);
-        if (frame == NULL) {
+        if (ngx_quic_update_max_data(pc) != NGX_OK) {
             return NGX_ERROR;
         }
-
-        frame->level = ssl_encryption_application;
-        frame->type = NGX_QUIC_FT_MAX_DATA;
-        frame->u.max_data.max_data = qc->streams.recv_max_data;
-
-        ngx_quic_queue_frame(qc, frame);
     }
 
     return NGX_OK;
@@ -1639,6 +1634,41 @@ ngx_quic_update_max_stream_data(ngx_connection_t *c)
 }
 
 
+static ngx_int_t
+ngx_quic_update_max_data(ngx_connection_t *c)
+{
+    uint64_t                recv_max_data;
+    ngx_quic_frame_t       *frame;
+    ngx_quic_connection_t  *qc;
+
+    qc = ngx_quic_get_connection(c);
+
+    recv_max_data = qc->streams.recv_offset + qc->streams.recv_window;
+
+    if (qc->streams.recv_max_data == recv_max_data) {
+        return NGX_OK;
+    }
+
+    qc->streams.recv_max_data = recv_max_data;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                   "quic flow update md:%uL", qc->streams.recv_max_data);
+
+    frame = ngx_quic_alloc_frame(c);
+    if (frame == NULL) {
+        return NGX_ERROR;
+    }
+
+    frame->level = ssl_encryption_application;
+    frame->type = NGX_QUIC_FT_MAX_DATA;
+    frame->u.max_data.max_data = qc->streams.recv_max_data;
+
+    ngx_quic_queue_frame(qc, frame);
+
+    return NGX_OK;
+}
+
+
 ngx_int_t
 ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
 {
index c914fde24b8c3515bf4d8b6d7e5ca926a11df175..fb6dbbd8f4367586f5850066ca44b51b5e7b60e7 100644 (file)
@@ -20,6 +20,8 @@ ngx_int_t ngx_quic_handle_max_data_frame(ngx_connection_t *c,
     ngx_quic_max_data_frame_t *f);
 ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c,
     ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f);
+ngx_int_t ngx_quic_handle_data_blocked_frame(ngx_connection_t *c,
+    ngx_quic_header_t *pkt, ngx_quic_data_blocked_frame_t *f);
 ngx_int_t ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c,
     ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f);
 ngx_int_t ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c,