Bug #76921 Resume SSL / TLS sessions (use TLS tickets)
Submitted: 3 May 2015 15:29 Modified: 8 Feb 14:39
Reporter: Daniël van Eeden (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S5 (Performance)
Version:5.7.7-rc, 8.0.4 OS:Any
Assigned to: CPU Architecture:Any
Tags: SSL, tls

[3 May 2015 15:29] Daniël van Eeden
Description:
As far as I can tell MySQL doesn't use TLS session tickets to resume sessions. Support for resuming TLS sessions can result in a performance gain.

How to repeat:
1. Look in the source code

$ git grep SSL_set_session
extra/yassl/examples/client/client.cpp:    SSL_set_session(sslResume, session);
extra/yassl/include/openssl/prefix_ssl.h:#define SSL_set_session yaSSL_set_session
extra/yassl/include/openssl/ssl.h:int          SSL_set_session(SSL *ssl, SSL_SESSION *session);
extra/yassl/src/ssl.cpp:int SSL_set_session(SSL* ssl, SSL_SESSION* session)

It looks like SSL_set_session is only used in the YaSSL examples, but not in libmysql, client or server code.

2. Look at the wire protocol

When MySQL 5.7.7 is compiled against OpenSSL 1.0.1f it seems to:
* use "SessionTicket TLS" in the clientHelo packet. (empty ticket)
* send a session ticket in "New Session Ticket"
* use an empty session ticket on reconnect (e.g. after "ROLLBACK RELEASE")

Suggested fix:
Use SSL_set_session() to send a session ticket to the server on reconnect.

This could benefit situations where the connections are not persistent (common for PHP)
[3 May 2015 15:31] Daniël van Eeden
Added tags
Changed Severity
[5 May 2015 9:38] Daniël van Eeden
The server already supports this (if compiled against OpenSSL?)

A patch to let the client use this (expiremental!):
https://github.com/dveeden/mysql-server/commit/c55c561d4ed9843796d12c504850374d1a811030
[5 May 2015 9:39] Daniël van Eeden
Experimental patch for client

Attachment: c55c561d4ed9843796d12c504850374d1a811030.patch (text/x-diff), 2.10 KiB.

[5 May 2015 9:44] Daniël van Eeden
Example with the patch applied and no /tmp/mysql_sess.pem file present at the start.

===============================================================
mysql> show session status like 'Ssl_sessions_reused';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| Ssl_sessions_reused | 0     |
+---------------------+-------+
1 row in set (0.00 sec)

mysql> rollback release;
Query OK, 0 rows affected (0.00 sec)

mysql> show session status like 'Ssl_sessions_reused';
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> show session status like 'Ssl_sessions_reused';
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    53
Current database: *** NONE ***

+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| Ssl_sessions_reused | 1     |
+---------------------+-------+
1 row in set (0.02 sec)

===============================================================
[5 May 2015 9:58] Daniël van Eeden
A not-so-sientific benchmark:

With the patch applied:
$ time for i in {1..1000}; do ./my sql -h 127.0.0.1 -e "QUIT"; done

real	0m26.114s
user	0m18.880s
sys	0m5.777s

Without the patch:
$ time for i in {1..1000}; do ./my sql -h 127.0.0.1 -e "QUIT"; done

real	0m37.278s
user	0m24.160s
sys	0m6.287s
[7 Feb 13:20] Georgi Kodinov
As noted in bug #89549 the way to set and extract session tickets can be through mysql_options().
[7 Feb 16:38] Daniël van Eeden
Updated versions and category.
Anything else needed to get this verified?
[8 Feb 14:39] Umesh Shastry
Hello Daniël,

Thank you for the report and supplying patch along with it.
Please ensure to re-send the patch via "Contributions" tab. Otherwise we would not be able to accept it.

If you have no objections then as Joro mentioned I'll mark Bug #89549 as duplicate of this one.

Thanks,
Umesh