comparison src/event/ngx_event_quic.c @ 8354:d11bc25fc4c3 quic

Refactored ngx_quic_close_connection(). The function is split into three: ngx_quic_close_connection() itself cleans up all core nginx things ngx_quic_close_quic() deals with everything inside c->quic ngx_quic_close_streams() deals with streams cleanup The quic and streams cleanup functions may return NGX_AGAIN, thus signalling that cleanup is not ready yet, and the close cannot continue to next step.
author Vladimir Homutov <vl@nginx.com>
date Thu, 23 Apr 2020 11:15:44 +0300
parents 47dac6e0521a
children ad3a6f069498
comparison
equal deleted inserted replaced
8353:036164360fa9 8354:d11bc25fc4c3
139 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 139 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
140 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt, 140 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt,
141 ngx_connection_handler_pt handler); 141 ngx_connection_handler_pt handler);
142 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); 142 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c);
143 static void ngx_quic_input_handler(ngx_event_t *rev); 143 static void ngx_quic_input_handler(ngx_event_t *rev);
144
144 static void ngx_quic_close_connection(ngx_connection_t *c); 145 static void ngx_quic_close_connection(ngx_connection_t *c);
146 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c);
147 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c,
148 ngx_quic_connection_t *qc);
145 149
146 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); 150 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b);
147 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, 151 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c,
148 ngx_quic_header_t *pkt); 152 ngx_quic_header_t *pkt);
149 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c, 153 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c,
758 762
759 763
760 static void 764 static void
761 ngx_quic_close_connection(ngx_connection_t *c) 765 ngx_quic_close_connection(ngx_connection_t *c)
762 { 766 {
763 #if (NGX_DEBUG) 767 ngx_pool_t *pool;
764 ngx_uint_t ns;
765 #endif
766 ngx_uint_t i;
767 ngx_pool_t *pool;
768 ngx_event_t *rev;
769 ngx_rbtree_t *tree;
770 ngx_rbtree_node_t *node;
771 ngx_quic_stream_t *qs;
772 ngx_quic_connection_t *qc;
773 768
774 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "close quic connection"); 769 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "close quic connection");
775 770
776 qc = c->quic; 771 if (c->quic && ngx_quic_close_quic(c) == NGX_AGAIN) {
777 772 return;
778 if (qc) {
779
780 qc->closing = 1;
781 tree = &qc->streams.tree;
782
783 if (tree->root != tree->sentinel) {
784 if (c->read->timer_set) {
785 ngx_del_timer(c->read);
786 }
787
788 #if (NGX_DEBUG)
789 ns = 0;
790 #endif
791
792 for (node = ngx_rbtree_min(tree->root, tree->sentinel);
793 node;
794 node = ngx_rbtree_next(tree, node))
795 {
796 qs = (ngx_quic_stream_t *) node;
797
798 rev = qs->c->read;
799 rev->ready = 1;
800 rev->pending_eof = 1;
801
802 ngx_post_event(rev, &ngx_posted_events);
803
804 if (rev->timer_set) {
805 ngx_del_timer(rev);
806 }
807
808 #if (NGX_DEBUG)
809 ns++;
810 #endif
811 }
812
813 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
814 "quic connection has %ui active streams", ns);
815
816 return;
817 }
818
819 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) {
820 ngx_quic_free_frames(c, &qc->crypto[i].frames);
821 }
822
823 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
824 ngx_quic_free_frames(c, &qc->send_ctx[i].frames);
825 ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
826 }
827
828 if (qc->push.timer_set) {
829 ngx_del_timer(&qc->push);
830 }
831
832 if (qc->retry.timer_set) {
833 ngx_del_timer(&qc->retry);
834 }
835 } 773 }
836 774
837 if (c->ssl) { 775 if (c->ssl) {
838 (void) ngx_ssl_shutdown(c); 776 (void) ngx_ssl_shutdown(c);
777 }
778
779 if (c->read->timer_set) {
780 ngx_del_timer(c->read);
839 } 781 }
840 782
841 #if (NGX_STAT_STUB) 783 #if (NGX_STAT_STUB)
842 (void) ngx_atomic_fetch_add(ngx_stat_active, -1); 784 (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
843 #endif 785 #endif
847 pool = c->pool; 789 pool = c->pool;
848 790
849 ngx_close_connection(c); 791 ngx_close_connection(c);
850 792
851 ngx_destroy_pool(pool); 793 ngx_destroy_pool(pool);
794 }
795
796
797 static ngx_int_t
798 ngx_quic_close_quic(ngx_connection_t *c)
799 {
800 ngx_uint_t i;
801 ngx_quic_connection_t *qc;
802
803 qc = c->quic;
804
805 qc->closing = 1;
806
807 if (ngx_quic_close_streams(c, qc) == NGX_AGAIN) {
808 return NGX_AGAIN;
809 }
810
811 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) {
812 ngx_quic_free_frames(c, &qc->crypto[i].frames);
813 }
814
815 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
816 ngx_quic_free_frames(c, &qc->send_ctx[i].frames);
817 ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
818 }
819
820 if (qc->push.timer_set) {
821 ngx_del_timer(&qc->push);
822 }
823
824 if (qc->retry.timer_set) {
825 ngx_del_timer(&qc->retry);
826 }
827
828 return NGX_OK;
829 }
830
831
832 static ngx_int_t
833 ngx_quic_close_streams(ngx_connection_t *c, ngx_quic_connection_t *qc)
834 {
835 ngx_event_t *rev;
836 ngx_rbtree_t *tree;
837 ngx_rbtree_node_t *node;
838 ngx_quic_stream_t *qs;
839
840 #if (NGX_DEBUG)
841 ngx_uint_t ns;
842 #endif
843
844 tree = &qc->streams.tree;
845
846 if (tree->root == tree->sentinel) {
847 return NGX_OK;
848 }
849
850 #if (NGX_DEBUG)
851 ns = 0;
852 #endif
853
854 for (node = ngx_rbtree_min(tree->root, tree->sentinel);
855 node;
856 node = ngx_rbtree_next(tree, node))
857 {
858 qs = (ngx_quic_stream_t *) node;
859
860 rev = qs->c->read;
861 rev->ready = 1;
862 rev->pending_eof = 1;
863
864 ngx_post_event(rev, &ngx_posted_events);
865
866 if (rev->timer_set) {
867 ngx_del_timer(rev);
868 }
869
870 #if (NGX_DEBUG)
871 ns++;
872 #endif
873 }
874
875 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
876 "quic connection has %ui active streams", ns);
877
878 return NGX_AGAIN;
852 } 879 }
853 880
854 881
855 static ngx_int_t 882 static ngx_int_t
856 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b) 883 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b)