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,