MINOR: ssl: add a global tunable for the max SSL/TLS record size

Add new tunable "tune.ssl.maxrecord".

Over SSL/TLS, the client can decipher the data only once it has received
a full record. With large records, it means that clients might have to
download up to 16kB of data before starting to process them. Limiting the
record size can improve page load times on browsers located over high
latency or low bandwidth networks. It is suggested to find optimal values
which fit into 1 or 2 TCP segments (generally 1448 bytes over Ethernet
with TCP timestamps enabled, or 1460 when timestamps are disabled), keeping
in mind that SSL/TLS add some overhead. Typical values of 1419 and 2859
gave good results during tests. Use "strace -e trace=write" to find the
best value.

This trick was first suggested by Mike Belshe :

   http://www.belshe.com/2010/12/17/performance-and-the-tls-record-size/

Then requested again by Ilya Grigorik who provides some hints here :

   http://ofps.oreilly.com/titles/9781449344764/_transport_layer_security_tls.html#ch04_00000101
This commit is contained in:
Willy Tarreau 2013-02-21 07:46:09 +01:00
parent a6bd1a1c40
commit bfd5946aa1
4 changed files with 28 additions and 0 deletions

View File

@ -479,6 +479,8 @@ The following keywords are supported in the "global" section :
- tune.sndbuf.client - tune.sndbuf.client
- tune.sndbuf.server - tune.sndbuf.server
- tune.ssl.cachesize - tune.ssl.cachesize
- tune.ssl.lifetime
- tune.ssl.maxrecord
- tune.zlib.memlevel - tune.zlib.memlevel
- tune.zlib.windowsize - tune.zlib.windowsize
@ -900,6 +902,19 @@ tune.ssl.lifetime <timeout>
lifetime. The real usefulness of this setting is to prevent sessions from lifetime. The real usefulness of this setting is to prevent sessions from
being used for too long. being used for too long.
tune.ssl.maxrecord <number>
Sets the maximum amount of bytes passed to SSL_write() at a time. Default
value 0 means there is no limit. Over SSL/TLS, the client can decipher the
data only once it has received a full record. With large records, it means
that clients might have to download up to 16kB of data before starting to
process them. Limiting the value can improve page load times on browsers
located over high latency or low bandwidth networks. It is suggested to find
optimal values which fit into 1 or 2 TCP segments (generally 1448 bytes over
Ethernet with TCP timestamps enabled, or 1460 when timestamps are disabled),
keeping in mind that SSL/TLS add some overhead. Typical values of 1419 and
2859 gave good results during tests. Use "strace -e trace=write" to find the
best value.
tune.zlib.memlevel <number> tune.zlib.memlevel <number>
Sets the memLevel parameter in zlib initialization for each session. It Sets the memLevel parameter in zlib initialization for each session. It
defines how much memory should be allocated for the intenal compression defines how much memory should be allocated for the intenal compression

View File

@ -117,6 +117,7 @@ struct global {
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
int sslcachesize; /* SSL cache size in session, defaults to 20000 */ int sslcachesize; /* SSL cache size in session, defaults to 20000 */
unsigned int ssllifetime; /* SSL session lifetime in seconds */ unsigned int ssllifetime; /* SSL session lifetime in seconds */
unsigned int ssl_max_record; /* SSL max record size */
#endif #endif
#ifdef USE_ZLIB #ifdef USE_ZLIB
int zlibmemlevel; /* zlib memlevel */ int zlibmemlevel; /* zlib memlevel */

View File

@ -596,6 +596,14 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
global.tune.ssllifetime = ssllifetime; global.tune.ssllifetime = ssllifetime;
} }
else if (!strcmp(args[0], "tune.ssl.maxrecord")) {
if (*(args[1]) == 0) {
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
global.tune.ssl_max_record = atol(args[1]);
}
#endif #endif
else if (!strcmp(args[0], "tune.bufsize")) { else if (!strcmp(args[0], "tune.bufsize")) {
if (*(args[1]) == 0) { if (*(args[1]) == 0) {

View File

@ -1194,6 +1194,10 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
*/ */
while (buf->o) { while (buf->o) {
try = buf->o; try = buf->o;
if (global.tune.ssl_max_record && try > global.tune.ssl_max_record)
try = global.tune.ssl_max_record;
/* outgoing data may wrap at the end */ /* outgoing data may wrap at the end */
if (buf->data + try > buf->p) if (buf->data + try > buf->p)
try = buf->data + try - buf->p; try = buf->data + try - buf->p;