Upstream: Yes
Reason: Without this patch proxy ssl session resumptions fails
Url: https://github.com/h2o/h2o/pull/2088
--- a/include/h2o/socket.h
+++ b/include/h2o/socket.h
@@ -71,6 +71,9 @@
 
 #define H2O_SOCKET_INITIAL_INPUT_BUFFER_SIZE 4096
 
+#define H2O_SESSID_CTX ((const uint8_t*)"h2o")
+#define H2O_SESSID_CTX_LEN (sizeof("h2o") - 1)
+
 typedef struct st_h2o_socket_t h2o_socket_t;
 
 typedef void (*h2o_socket_cb)(h2o_socket_t *sock, const char *err);
@@ -266,6 +269,7 @@
 static h2o_iovec_t h2o_socket_log_ssl_cipher(h2o_socket_t *sock, h2o_mem_pool_t *pool);
 h2o_iovec_t h2o_socket_log_ssl_cipher_bits(h2o_socket_t *sock, h2o_mem_pool_t *pool);
 h2o_iovec_t h2o_socket_log_ssl_session_id(h2o_socket_t *sock, h2o_mem_pool_t *pool);
+int h2o_socket_ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
 
 /**
  * compares socket addresses
--- a/lib/common/socket.c
+++ b/lib/common/socket.c
@@ -916,6 +916,8 @@
 static void create_ossl(h2o_socket_t *sock)
 {
     sock->ssl->ossl = SSL_new(sock->ssl->ssl_ctx);
+    /* set app data to be used in h2o_socket_ssl_new_session_cb */
+    SSL_set_app_data(sock->ssl->ossl, sock);
     setup_bio(sock);
 }
 
@@ -942,6 +944,26 @@
     }
 }
 
+int h2o_socket_ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
+{
+    h2o_socket_t *sock = (h2o_socket_t *)SSL_get_app_data(s);
+    assert(sock != NULL);
+    assert(sock->ssl != NULL);
+
+    if (!SSL_is_server(s) && sock->ssl->handshake.client.session_cache != NULL
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010100fL
+        && SSL_SESSION_is_resumable(sess)
+#endif
+    ) {
+        h2o_cache_set(sock->ssl->handshake.client.session_cache, h2o_now(h2o_socket_get_loop(sock)),
+                      sock->ssl->handshake.client.session_cache_key, sock->ssl->handshake.client.session_cache_key_hash,
+                      h2o_iovec_init(sess, 1));
+        return 1; /* retain ref count */
+    }
+
+    return 0; /* drop ref count */
+}
+
 static int on_async_resumption_new(SSL *ssl, SSL_SESSION *session)
 {
     h2o_iovec_t data;
@@ -992,16 +1014,6 @@
                 sock->ssl->record_overhead = 32; /* sufficiently large number that can hold most payloads */
                 break;
             }
-        }
-    }
-
-    /* set ssl session into the cache */
-    if (sock->ssl->ossl != NULL && !SSL_is_server(sock->ssl->ossl) && sock->ssl->handshake.client.session_cache != NULL) {
-        if (err == NULL || err == h2o_socket_error_ssl_cert_name_mismatch) {
-            SSL_SESSION *session = SSL_get1_session(sock->ssl->ossl);
-            h2o_cache_set(sock->ssl->handshake.client.session_cache, h2o_now(h2o_socket_get_loop(sock)),
-                          sock->ssl->handshake.client.session_cache_key, sock->ssl->handshake.client.session_cache_key_hash,
-                          h2o_iovec_init(session, 1));
         }
     }
 
--- a/lib/handler/configurator/proxy.c
+++ b/lib/handler/configurator/proxy.c
@@ -27,6 +27,7 @@
 #include <openssl/ssl.h>
 #include "h2o.h"
 #include "h2o/configurator.h"
+#include "h2o/socket.h"
 
 struct proxy_configurator_t {
     h2o_configurator_t super;
@@ -86,6 +87,9 @@
 {
     SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
     SSL_CTX_set_options(ctx, SSL_CTX_get_options(ctx) | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
+    SSL_CTX_set_session_id_context(ctx, H2O_SESSID_CTX, H2O_SESSID_CTX_LEN);
+    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
+    SSL_CTX_sess_set_new_cb(ctx, h2o_socket_ssl_new_session_cb);
     return ctx;
 }
 
@@ -119,6 +123,7 @@
 
     /* create new ctx */
     *ctx = create_ssl_ctx();
+    SSL_CTX_set_session_id_context(*ctx, H2O_SESSID_CTX, H2O_SESSID_CTX_LEN);
     SSL_CTX_set_cert_store(*ctx, cert_store);
     SSL_CTX_set_verify(*ctx, verify_mode, NULL);
     if (new_session_cache != NULL)
--- a/src/main.c
+++ b/src/main.c
@@ -674,9 +674,15 @@
     ssl_options |= SSL_OP_NO_COMPRESSION;
 #endif
 
+#ifdef SSL_OP_NO_RENEGOTIATION
+    ssl_options |= SSL_OP_NO_RENEGOTIATION;
+#endif
+
     /* setup */
     ssl_ctx = SSL_CTX_new(SSLv23_server_method());
     SSL_CTX_set_options(ssl_ctx, ssl_options);
+
+    SSL_CTX_set_session_id_context(ssl_ctx, H2O_SESSID_CTX, H2O_SESSID_CTX_LEN);
 
     setup_ecc_key(ssl_ctx);
     if (SSL_CTX_use_certificate_chain_file(ssl_ctx, certificate_file->data.scalar) != 1) {
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -116,6 +116,7 @@
     size_t i;
     for (i = 0; i != num_contexts; ++i) {
         SSL_CTX_set_session_cache_mode(contexts[i], SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR);
+        SSL_CTX_set_session_id_context(contexts[i], H2O_SESSID_CTX, H2O_SESSID_CTX_LEN);
         SSL_CTX_set_timeout(contexts[i], conf.lifetime);
     }
     spawn_cache_cleanup_thread(contexts, num_contexts);
