Mercurial > hg > nginx-quic
comparison src/http/ngx_http_upstream.c @ 7042:bd2f97a3aecc
Upstream: introduced ngx_http_upstream_ssl_handshake_handler().
This change reworks 13a5f4765887 to only run posted requests once,
with nothing on stack. Running posted requests with other request
functions on stack may result in use-after-free in case of errors,
similar to the one reported in #788.
To only run posted request once, a separate function was introduced
to be used as ssl handshake handler in c->ssl->handler,
ngx_http_upstream_ssl_handshake_handler(). The ngx_http_run_posted_requests()
is only called in this function, and not in ngx_http_upstream_ssl_handshake()
which may be called directly on stack.
Additionaly, ngx_http_upstream_ssl_handshake_handler() now does appropriate
debug logging of the current subrequest, similar to what is done in other
event handlers.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 22 Jun 2017 21:09:06 +0300 |
parents | 6169dbad37d8 |
children | e3723f2a11b7 |
comparison
equal
deleted
inserted
replaced
7041:6169dbad37d8 | 7042:bd2f97a3aecc |
---|---|
180 static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf); | 180 static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf); |
181 | 181 |
182 #if (NGX_HTTP_SSL) | 182 #if (NGX_HTTP_SSL) |
183 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, | 183 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, |
184 ngx_http_upstream_t *u, ngx_connection_t *c); | 184 ngx_http_upstream_t *u, ngx_connection_t *c); |
185 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); | 185 static void ngx_http_upstream_ssl_handshake_handler(ngx_connection_t *c); |
186 static void ngx_http_upstream_ssl_handshake(ngx_http_request_t *, | |
187 ngx_http_upstream_t *u, ngx_connection_t *c); | |
186 static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r, | 188 static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r, |
187 ngx_http_upstream_t *u, ngx_connection_t *c); | 189 ngx_http_upstream_t *u, ngx_connection_t *c); |
188 #endif | 190 #endif |
189 | 191 |
190 | 192 |
1665 | 1667 |
1666 if (!c->write->timer_set) { | 1668 if (!c->write->timer_set) { |
1667 ngx_add_timer(c->write, u->conf->connect_timeout); | 1669 ngx_add_timer(c->write, u->conf->connect_timeout); |
1668 } | 1670 } |
1669 | 1671 |
1670 c->ssl->handler = ngx_http_upstream_ssl_handshake; | 1672 c->ssl->handler = ngx_http_upstream_ssl_handshake_handler; |
1671 return; | 1673 return; |
1672 } | 1674 } |
1673 | 1675 |
1674 ngx_http_upstream_ssl_handshake(c); | 1676 ngx_http_upstream_ssl_handshake(r, u, c); |
1675 } | 1677 } |
1676 | 1678 |
1677 | 1679 |
1678 static void | 1680 static void |
1679 ngx_http_upstream_ssl_handshake(ngx_connection_t *c) | 1681 ngx_http_upstream_ssl_handshake_handler(ngx_connection_t *c) |
1680 { | 1682 { |
1681 long rc; | |
1682 ngx_http_request_t *r; | 1683 ngx_http_request_t *r; |
1683 ngx_http_upstream_t *u; | 1684 ngx_http_upstream_t *u; |
1684 | 1685 |
1685 r = c->data; | 1686 r = c->data; |
1687 | |
1686 u = r->upstream; | 1688 u = r->upstream; |
1689 c = r->connection; | |
1687 | 1690 |
1688 ngx_http_set_log_request(c->log, r); | 1691 ngx_http_set_log_request(c->log, r); |
1692 | |
1693 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1694 "http upstream ssl handshake: \"%V?%V\"", | |
1695 &r->uri, &r->args); | |
1696 | |
1697 ngx_http_upstream_ssl_handshake(r, u, u->peer.connection); | |
1698 | |
1699 ngx_http_run_posted_requests(c); | |
1700 } | |
1701 | |
1702 | |
1703 static void | |
1704 ngx_http_upstream_ssl_handshake(ngx_http_request_t *r, ngx_http_upstream_t *u, | |
1705 ngx_connection_t *c) | |
1706 { | |
1707 long rc; | |
1689 | 1708 |
1690 if (c->ssl->handshaked) { | 1709 if (c->ssl->handshaked) { |
1691 | 1710 |
1692 if (u->conf->ssl_verify) { | 1711 if (u->conf->ssl_verify) { |
1693 rc = SSL_get_verify_result(c->ssl->connection); | 1712 rc = SSL_get_verify_result(c->ssl->connection); |
1712 } | 1731 } |
1713 | 1732 |
1714 c->write->handler = ngx_http_upstream_handler; | 1733 c->write->handler = ngx_http_upstream_handler; |
1715 c->read->handler = ngx_http_upstream_handler; | 1734 c->read->handler = ngx_http_upstream_handler; |
1716 | 1735 |
1717 c = r->connection; | |
1718 | |
1719 ngx_http_upstream_send_request(r, u, 1); | 1736 ngx_http_upstream_send_request(r, u, 1); |
1720 | 1737 |
1721 ngx_http_run_posted_requests(c); | |
1722 return; | 1738 return; |
1723 } | 1739 } |
1724 | 1740 |
1725 if (c->write->timedout) { | 1741 if (c->write->timedout) { |
1726 c = r->connection; | |
1727 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); | 1742 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); |
1728 ngx_http_run_posted_requests(c); | |
1729 return; | 1743 return; |
1730 } | 1744 } |
1731 | 1745 |
1732 failed: | 1746 failed: |
1733 | 1747 |
1734 c = r->connection; | |
1735 | |
1736 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); | 1748 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
1737 | |
1738 ngx_http_run_posted_requests(c); | |
1739 } | 1749 } |
1740 | 1750 |
1741 | 1751 |
1742 static ngx_int_t | 1752 static ngx_int_t |
1743 ngx_http_upstream_ssl_name(ngx_http_request_t *r, ngx_http_upstream_t *u, | 1753 ngx_http_upstream_ssl_name(ngx_http_request_t *r, ngx_http_upstream_t *u, |