Mercurial > hg > nginx
diff src/event/ngx_event_openssl.c @ 7320:696df3ac27ac
SSL: save sessions for upstream peers using a callback function.
In TLSv1.3, NewSessionTicket messages arrive after the handshake and
can come at any time. Therefore we use a callback to save the session
when we know about it. This approach works for < TLSv1.3 as well.
The callback function is set once per location on merge phase.
Since SSL_get_session() in BoringSSL returns an unresumable session for
TLSv1.3, peer save_session() methods have been updated as well to use a
session supplied within the callback. To preserve API, the session is
cached in c->ssl->session. It is preferably accessed in save_session()
methods by ngx_ssl_get_session() and ngx_ssl_get0_session() wrappers.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 17 Jul 2018 12:53:23 +0300 |
parents | dcab86115261 |
children | 7ad0f4ace359 |
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -24,6 +24,8 @@ static int ngx_ssl_verify_callback(int o static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret); static void ngx_ssl_passwords_cleanup(void *data); +static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, + ngx_ssl_session_t *sess); static void ngx_ssl_handshake_handler(ngx_event_t *ev); static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); static void ngx_ssl_write_handler(ngx_event_t *wev); @@ -1162,6 +1164,42 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_s ngx_int_t +ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable) +{ + if (!enable) { + return NGX_OK; + } + + SSL_CTX_set_session_cache_mode(ssl->ctx, + SSL_SESS_CACHE_CLIENT + |SSL_SESS_CACHE_NO_INTERNAL); + + SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_client_session); + + return NGX_OK; +} + + +static int +ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess) +{ + ngx_connection_t *c; + + c = ngx_ssl_get_connection(ssl_conn); + + if (c->ssl->save_session) { + c->ssl->session = sess; + + c->ssl->save_session(c); + + c->ssl->session = NULL; + } + + return 0; +} + + +ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags) { ngx_ssl_connection_t *sc; @@ -1210,6 +1248,31 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl } +ngx_ssl_session_t * +ngx_ssl_get_session(ngx_connection_t *c) +{ +#ifdef TLS1_3_VERSION + if (c->ssl->session) { + SSL_SESSION_up_ref(c->ssl->session); + return c->ssl->session; + } +#endif + + return SSL_get1_session(c->ssl->connection); +} + + +ngx_ssl_session_t * +ngx_ssl_get0_session(ngx_connection_t *c) +{ + if (c->ssl->session) { + return c->ssl->session; + } + + return SSL_get0_session(c->ssl->connection); +} + + ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session) {