changeset 8505:240931629995 quic

QUIC: handle client RESET_STREAM and STOP_SENDING. For RESET_STREAM the c->read->error flag is set. For STOP_SENDING the c->write->error flag is set.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 03 Aug 2020 13:31:48 +0300
parents d277e25e37fc
children 03ec6ab67752
files src/event/ngx_event_quic.c
diffstat 1 files changed, 66 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -3180,16 +3180,52 @@ static ngx_int_t
 ngx_quic_handle_reset_stream_frame(ngx_connection_t *c,
     ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f)
 {
-    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                   "quic frame handler not implemented");
+    ngx_event_t            *rev;
+    ngx_connection_t       *sc;
+    ngx_quic_stream_t      *sn;
+    ngx_quic_connection_t  *qc;
+
+    qc = c->quic;
 
     if ((f->id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
         && (f->id & NGX_QUIC_STREAM_SERVER_INITIATED))
     {
-        c->quic->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
+        qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
         return NGX_ERROR;
     }
 
+    sn = ngx_quic_find_stream(&qc->streams.tree, f->id);
+
+    if (sn == NULL) {
+        sn = ngx_quic_create_client_stream(c, f->id);
+
+        if (sn == NULL) {
+            return NGX_ERROR;
+        }
+
+        if (sn == NGX_QUIC_STREAM_GONE) {
+            return NGX_OK;
+        }
+
+        sc = sn->c;
+
+        rev = sc->read;
+        rev->error = 1;
+        rev->ready = 1;
+
+        sc->listening->handler(sc);
+
+        return NGX_OK;
+    }
+
+    rev = sn->c->read;
+    rev->error = 1;
+    rev->ready = 1;
+
+    if (rev->active) {
+        rev->handler(rev);
+    }
+
     return NGX_OK;
 }
 
@@ -3198,12 +3234,11 @@ static ngx_int_t
 ngx_quic_handle_stop_sending_frame(ngx_connection_t *c,
     ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f)
 {
+    ngx_event_t            *wev;
+    ngx_connection_t       *sc;
     ngx_quic_stream_t      *sn;
     ngx_quic_connection_t  *qc;
 
-    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                   "quic frame handler not implemented");
-
     qc = c->quic;
 
     if ((f->id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
@@ -3216,13 +3251,33 @@ ngx_quic_handle_stop_sending_frame(ngx_c
     sn = ngx_quic_find_stream(&qc->streams.tree, f->id);
 
     if (sn == NULL) {
-        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                       "quic stream id 0x%xL is new", f->id);
-
-        if (f->id & NGX_QUIC_STREAM_SERVER_INITIATED) {
-            qc->error = NGX_QUIC_ERR_STREAM_STATE_ERROR;
+        sn = ngx_quic_create_client_stream(c, f->id);
+
+        if (sn == NULL) {
             return NGX_ERROR;
         }
+
+        if (sn == NGX_QUIC_STREAM_GONE) {
+            return NGX_OK;
+        }
+
+        sc = sn->c;
+
+        wev = sc->write;
+        wev->error = 1;
+        wev->ready = 1;
+
+        sc->listening->handler(sc);
+
+        return NGX_OK;
+    }
+
+    wev = sn->c->write;
+    wev->error = 1;
+    wev->ready = 1;
+
+    if (wev->active) {
+        wev->handler(wev);
     }
 
     return NGX_OK;