Mercurial > hg > nginx
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) |