diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/event/ngx_event_quic.c | 151 |
1 files changed, 89 insertions, 62 deletions
diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c index 1965ed907..5ef9cf47e 100644 --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -141,7 +141,11 @@ static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_connection_handler_pt handler); static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); static void ngx_quic_input_handler(ngx_event_t *rev); + static void ngx_quic_close_connection(ngx_connection_t *c); +static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c); +static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c, + ngx_quic_connection_t *qc); static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, @@ -760,95 +764,118 @@ ngx_quic_input_handler(ngx_event_t *rev) static void ngx_quic_close_connection(ngx_connection_t *c) { -#if (NGX_DEBUG) - ngx_uint_t ns; -#endif - ngx_uint_t i; - ngx_pool_t *pool; - ngx_event_t *rev; - ngx_rbtree_t *tree; - ngx_rbtree_node_t *node; - ngx_quic_stream_t *qs; - ngx_quic_connection_t *qc; + ngx_pool_t *pool; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "close quic connection"); - qc = c->quic; - - if (qc) { + if (c->quic && ngx_quic_close_quic(c) == NGX_AGAIN) { + return; + } - qc->closing = 1; - tree = &qc->streams.tree; + if (c->ssl) { + (void) ngx_ssl_shutdown(c); + } - if (tree->root != tree->sentinel) { - if (c->read->timer_set) { - ngx_del_timer(c->read); - } + if (c->read->timer_set) { + ngx_del_timer(c->read); + } -#if (NGX_DEBUG) - ns = 0; +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_active, -1); #endif - for (node = ngx_rbtree_min(tree->root, tree->sentinel); - node; - node = ngx_rbtree_next(tree, node)) - { - qs = (ngx_quic_stream_t *) node; + c->destroyed = 1; - rev = qs->c->read; - rev->ready = 1; - rev->pending_eof = 1; + pool = c->pool; - ngx_post_event(rev, &ngx_posted_events); + ngx_close_connection(c); - if (rev->timer_set) { - ngx_del_timer(rev); - } + ngx_destroy_pool(pool); +} -#if (NGX_DEBUG) - ns++; -#endif - } - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic connection has %ui active streams", ns); +static ngx_int_t +ngx_quic_close_quic(ngx_connection_t *c) +{ + ngx_uint_t i; + ngx_quic_connection_t *qc; - return; - } + qc = c->quic; - for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { - ngx_quic_free_frames(c, &qc->crypto[i].frames); - } + qc->closing = 1; - for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { - ngx_quic_free_frames(c, &qc->send_ctx[i].frames); - ngx_quic_free_frames(c, &qc->send_ctx[i].sent); - } + if (ngx_quic_close_streams(c, qc) == NGX_AGAIN) { + return NGX_AGAIN; + } - if (qc->push.timer_set) { - ngx_del_timer(&qc->push); - } + for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { + ngx_quic_free_frames(c, &qc->crypto[i].frames); + } - if (qc->retry.timer_set) { - ngx_del_timer(&qc->retry); - } + for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { + ngx_quic_free_frames(c, &qc->send_ctx[i].frames); + ngx_quic_free_frames(c, &qc->send_ctx[i].sent); } - if (c->ssl) { - (void) ngx_ssl_shutdown(c); + if (qc->push.timer_set) { + ngx_del_timer(&qc->push); } -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, -1); + if (qc->retry.timer_set) { + ngx_del_timer(&qc->retry); + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_quic_close_streams(ngx_connection_t *c, ngx_quic_connection_t *qc) +{ + ngx_event_t *rev; + ngx_rbtree_t *tree; + ngx_rbtree_node_t *node; + ngx_quic_stream_t *qs; + +#if (NGX_DEBUG) + ngx_uint_t ns; #endif - c->destroyed = 1; + tree = &qc->streams.tree; - pool = c->pool; + if (tree->root == tree->sentinel) { + return NGX_OK; + } - ngx_close_connection(c); +#if (NGX_DEBUG) + ns = 0; +#endif - ngx_destroy_pool(pool); + for (node = ngx_rbtree_min(tree->root, tree->sentinel); + node; + node = ngx_rbtree_next(tree, node)) + { + qs = (ngx_quic_stream_t *) node; + + rev = qs->c->read; + rev->ready = 1; + rev->pending_eof = 1; + + ngx_post_event(rev, &ngx_posted_events); + + if (rev->timer_set) { + ngx_del_timer(rev); + } + +#if (NGX_DEBUG) + ns++; +#endif + } + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "quic connection has %ui active streams", ns); + + return NGX_AGAIN; } |
