aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_upstream_round_robin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_upstream_round_robin.c')
-rw-r--r--src/http/ngx_http_upstream_round_robin.c120
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);