comparison src/http/v2/ngx_http_v2.c @ 7738:554c6ae25ffc

SSL: fixed non-working SSL shutdown on lingering close. When doing lingering close, the socket was first shut down for writing, so SSL shutdown initiated after lingering close was not able to send the close_notify alerts (ticket #2056). The fix is to call ngx_ssl_shutdown() before shutting down the socket.
author Ruslan Ermilov <ru@nginx.com>
date Fri, 06 Nov 2020 23:44:54 +0300
parents 526dddf637bb
children 7efae6b4cfb0
comparison
equal deleted inserted replaced
7737:ed17a2a95c8d 7738:554c6ae25ffc
58 58
59 59
60 static void ngx_http_v2_read_handler(ngx_event_t *rev); 60 static void ngx_http_v2_read_handler(ngx_event_t *rev);
61 static void ngx_http_v2_write_handler(ngx_event_t *wev); 61 static void ngx_http_v2_write_handler(ngx_event_t *wev);
62 static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c); 62 static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
63 static void ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c); 63 static void ngx_http_v2_lingering_close(ngx_connection_t *c);
64 static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev); 64 static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);
65 65
66 static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, 66 static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c,
67 u_char *pos, u_char *end); 67 u_char *pos, u_char *end);
68 static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, 68 static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c,
662 662
663 /* rc == NGX_OK */ 663 /* rc == NGX_OK */
664 } 664 }
665 665
666 if (h2c->goaway) { 666 if (h2c->goaway) {
667 ngx_http_v2_lingering_close(h2c); 667 ngx_http_v2_lingering_close(c);
668 return; 668 return;
669 } 669 }
670 670
671 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, 671 h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
672 ngx_http_v2_module); 672 ngx_http_v2_module);
701 ngx_add_timer(c->read, h2scf->idle_timeout); 701 ngx_add_timer(c->read, h2scf->idle_timeout);
702 } 702 }
703 703
704 704
705 static void 705 static void
706 ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c) 706 ngx_http_v2_lingering_close(ngx_connection_t *c)
707 { 707 {
708 ngx_event_t *rev, *wev; 708 ngx_event_t *rev, *wev;
709 ngx_connection_t *c; 709 ngx_http_v2_connection_t *h2c;
710 ngx_http_core_loc_conf_t *clcf; 710 ngx_http_core_loc_conf_t *clcf;
711 711
712 c = h2c->connection; 712 h2c = c->data;
713 713
714 clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx, 714 clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
715 ngx_http_core_module); 715 ngx_http_core_module);
716 716
717 if (clcf->lingering_close == NGX_HTTP_LINGERING_OFF) { 717 if (clcf->lingering_close == NGX_HTTP_LINGERING_OFF) {
718 ngx_http_close_connection(c); 718 ngx_http_close_connection(c);
719 return; 719 return;
720 } 720 }
721 721
722 if (h2c->lingering_time == 0) {
723 h2c->lingering_time = ngx_time()
724 + (time_t) (clcf->lingering_time / 1000);
725 }
726
727 #if (NGX_HTTP_SSL)
728 if (c->ssl) {
729 ngx_int_t rc;
730
731 rc = ngx_ssl_shutdown(c);
732
733 if (rc == NGX_ERROR) {
734 ngx_http_close_connection(c);
735 return;
736 }
737
738 if (rc == NGX_AGAIN) {
739 c->ssl->handler = ngx_http_v2_lingering_close;
740 return;
741 }
742
743 c->recv = ngx_recv;
744 }
745 #endif
746
722 rev = c->read; 747 rev = c->read;
723 rev->handler = ngx_http_v2_lingering_close_handler; 748 rev->handler = ngx_http_v2_lingering_close_handler;
724
725 h2c->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
726 ngx_add_timer(rev, clcf->lingering_timeout);
727 749
728 if (ngx_handle_read_event(rev, 0) != NGX_OK) { 750 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
729 ngx_http_close_connection(c); 751 ngx_http_close_connection(c);
730 return; 752 return;
731 } 753 }
744 ngx_connection_error(c, ngx_socket_errno, 766 ngx_connection_error(c, ngx_socket_errno,
745 ngx_shutdown_socket_n " failed"); 767 ngx_shutdown_socket_n " failed");
746 ngx_http_close_connection(c); 768 ngx_http_close_connection(c);
747 return; 769 return;
748 } 770 }
771
772 ngx_add_timer(rev, clcf->lingering_timeout);
749 773
750 if (rev->ready) { 774 if (rev->ready) {
751 ngx_http_v2_lingering_close_handler(rev); 775 ngx_http_v2_lingering_close_handler(rev);
752 } 776 }
753 } 777 }
4755 if (c->error) { 4779 if (c->error) {
4756 ngx_http_close_connection(c); 4780 ngx_http_close_connection(c);
4757 return; 4781 return;
4758 } 4782 }
4759 4783
4760 ngx_http_v2_lingering_close(h2c); 4784 ngx_http_v2_lingering_close(c);
4761 } 4785 }
4762 4786
4763 4787
4764 static ngx_int_t 4788 static ngx_int_t
4765 ngx_http_v2_adjust_windows(ngx_http_v2_connection_t *h2c, ssize_t delta) 4789 ngx_http_v2_adjust_windows(ngx_http_v2_connection_t *h2c, ssize_t delta)