diff options
| author | Ruslan Ermilov <ru@nginx.com> | 2015-04-14 19:01:25 +0300 |
|---|---|---|
| committer | Ruslan Ermilov <ru@nginx.com> | 2015-04-14 19:01:25 +0300 |
| commit | cf31347ee84fdaa02f768e641d1a2f1352b6a56a (patch) | |
| tree | 95fa2e6267ffddd5d3ace7bf8108964e7c68fed8 /src/http/ngx_http_upstream_round_robin.c | |
| parent | b0b7b5a356c7dedf4a1867e94d8a36cbb6dc3da1 (diff) | |
| download | nginx-cf31347ee84fdaa02f768e641d1a2f1352b6a56a.tar.gz nginx-cf31347ee84fdaa02f768e641d1a2f1352b6a56a.tar.bz2 | |
Upstream: the "zone" directive.
Upstreams with the "zone" directive are kept in shared memory,
with a consistent view of all worker processes.
Diffstat (limited to 'src/http/ngx_http_upstream_round_robin.c')
| -rw-r--r-- | src/http/ngx_http_upstream_round_robin.c | 120 |
1 files changed, 115 insertions, 5 deletions
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c index 9a970dcba..52da545a1 100644 --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -657,12 +657,55 @@ ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc, { ngx_http_upstream_rr_peer_data_t *rrp = data; - ngx_int_t rc; - ngx_ssl_session_t *ssl_session; - ngx_http_upstream_rr_peer_t *peer; + ngx_int_t rc; + ngx_ssl_session_t *ssl_session; + ngx_http_upstream_rr_peer_t *peer; +#if (NGX_HTTP_UPSTREAM_ZONE) + int len; +#if OPENSSL_VERSION_NUMBER >= 0x0090707fL + const +#endif + u_char *p; + ngx_http_upstream_rr_peers_t *peers; + u_char buf[NGX_SSL_MAX_SESSION_SIZE]; +#endif peer = rrp->current; +#if (NGX_HTTP_UPSTREAM_ZONE) + peers = rrp->peers; + + if (peers->shpool) { + ngx_http_upstream_rr_peers_rlock(peers); + ngx_http_upstream_rr_peer_lock(peers, peer); + + if (peer->ssl_session == NULL) { + ngx_http_upstream_rr_peer_unlock(peers, peer); + ngx_http_upstream_rr_peers_unlock(peers); + return NGX_OK; + } + + len = peer->ssl_session_len; + + ngx_memcpy(buf, peer->ssl_session, len); + + ngx_http_upstream_rr_peer_unlock(peers, peer); + ngx_http_upstream_rr_peers_unlock(peers); + + p = buf; + ssl_session = d2i_SSL_SESSION(NULL, &p, len); + + rc = ngx_ssl_set_session(pc->connection, ssl_session); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "set session: %p", ssl_session); + + ngx_ssl_free_session(ssl_session); + + return rc; + } +#endif + ssl_session = peer->ssl_session; rc = ngx_ssl_set_session(pc->connection, ssl_session); @@ -680,8 +723,75 @@ ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc, { ngx_http_upstream_rr_peer_data_t *rrp = data; - ngx_ssl_session_t *old_ssl_session, *ssl_session; - ngx_http_upstream_rr_peer_t *peer; + ngx_ssl_session_t *old_ssl_session, *ssl_session; + ngx_http_upstream_rr_peer_t *peer; +#if (NGX_HTTP_UPSTREAM_ZONE) + int len; + u_char *p; + ngx_http_upstream_rr_peers_t *peers; + u_char buf[NGX_SSL_MAX_SESSION_SIZE]; +#endif + +#if (NGX_HTTP_UPSTREAM_ZONE) + peers = rrp->peers; + + if (peers->shpool) { + + ssl_session = SSL_get0_session(pc->connection->ssl->connection); + + if (ssl_session == NULL) { + return; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "save session: %p", ssl_session); + + len = i2d_SSL_SESSION(ssl_session, NULL); + + /* do not cache too big session */ + + if (len > NGX_SSL_MAX_SESSION_SIZE) { + return; + } + + p = buf; + (void) i2d_SSL_SESSION(ssl_session, &p); + + peer = rrp->current; + + ngx_http_upstream_rr_peers_rlock(peers); + ngx_http_upstream_rr_peer_lock(peers, peer); + + if (len > peer->ssl_session_len) { + ngx_shmtx_lock(&peers->shpool->mutex); + + if (peer->ssl_session) { + ngx_slab_free_locked(peers->shpool, peer->ssl_session); + } + + peer->ssl_session = ngx_slab_alloc_locked(peers->shpool, len); + + ngx_shmtx_unlock(&peers->shpool->mutex); + + if (peer->ssl_session == NULL) { + peer->ssl_session_len = 0; + + ngx_http_upstream_rr_peer_unlock(peers, peer); + ngx_http_upstream_rr_peers_unlock(peers); + return; + } + + peer->ssl_session_len = len; + } + + ngx_memcpy(peer->ssl_session, buf, len); + + ngx_http_upstream_rr_peer_unlock(peers, peer); + ngx_http_upstream_rr_peers_unlock(peers); + + return; + } +#endif ssl_session = ngx_ssl_get_session(pc->connection); |
