changeset 8617:69dc750cf66f quic

QUIC: handle more frames in ngx_quic_resend_frames(). When a packet is declared lost, its frames are handled differently according to 13.3. Retransmission of Information.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 29 Oct 2020 14:25:02 +0000
parents 64405f970f6f
children 71b7453fb11f
files src/event/ngx_event_quic.c
diffstat 1 files changed, 58 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -4832,8 +4832,11 @@ ngx_quic_detect_lost(ngx_connection_t *c
 static void
 ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
 {
+    size_t                  n;
+    ngx_buf_t              *b;
     ngx_queue_t            *q;
     ngx_quic_frame_t       *f, *start;
+    ngx_quic_stream_t      *sn;
     ngx_quic_connection_t  *qc;
 
     qc = c->quic;
@@ -4864,6 +4867,61 @@ ngx_quic_resend_frames(ngx_connection_t 
             ngx_quic_free_frame(c, f);
             break;
 
+        case NGX_QUIC_FT_PING:
+        case NGX_QUIC_FT_PATH_RESPONSE:
+        case NGX_QUIC_FT_CONNECTION_CLOSE:
+            ngx_quic_free_frame(c, f);
+            break;
+
+        case NGX_QUIC_FT_MAX_DATA:
+            f->u.max_data.max_data = qc->streams.recv_max_data;
+            ngx_quic_queue_frame(qc, f);
+            break;
+
+        case NGX_QUIC_FT_MAX_STREAMS:
+        case NGX_QUIC_FT_MAX_STREAMS2:
+            f->u.max_streams.limit = f->u.max_streams.bidi
+                                     ? qc->streams.client_max_streams_bidi
+                                     : qc->streams.client_max_streams_uni;
+            ngx_quic_queue_frame(qc, f);
+            break;
+
+        case NGX_QUIC_FT_MAX_STREAM_DATA:
+            sn = ngx_quic_find_stream(&qc->streams.tree,
+                                      f->u.max_stream_data.id);
+            if (sn == NULL) {
+                ngx_quic_free_frame(c, f);
+                break;
+            }
+
+            b = sn->b;
+            n = sn->fs.received + (b->pos - b->start) + (b->end - b->last);
+
+            if (f->u.max_stream_data.limit < n) {
+                f->u.max_stream_data.limit = n;
+            }
+
+            ngx_quic_queue_frame(qc, f);
+            break;
+
+        case NGX_QUIC_FT_STREAM0:
+        case NGX_QUIC_FT_STREAM1:
+        case NGX_QUIC_FT_STREAM2:
+        case NGX_QUIC_FT_STREAM3:
+        case NGX_QUIC_FT_STREAM4:
+        case NGX_QUIC_FT_STREAM5:
+        case NGX_QUIC_FT_STREAM6:
+        case NGX_QUIC_FT_STREAM7:
+            sn = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
+
+            if (sn && sn->c->write->error) {
+                /* RESET_STREAM was sent */
+                ngx_quic_free_frame(c, f);
+                break;
+            }
+
+            /* fall through */
+
         default:
             ngx_queue_insert_tail(&ctx->frames, &f->queue);
         }