[TLS] ssl.read-ahead = "disable" for low mem (fixes #2778)

new directive ssl.read-ahead = "enable"/"disable" to control
SSL_CTX_set_read_ahead().  Default "enable".  The "disable" setting
is intended for use on low memory systems with a slow CPU which is
unable to keep up with decryption of large request bodies.

x-ref:
  "larger memory usage for file uploads via SSL on embedded system"
  https://redmine.lighttpd.net/issues/2778
This commit is contained in:
Glenn Strauss 2017-01-10 15:59:50 -05:00
parent be520a8058
commit b03c496298
4 changed files with 12 additions and 3 deletions

View File

@ -295,6 +295,7 @@ typedef struct {
buffer *ssl_verifyclient_username;
unsigned short ssl_verifyclient_export_cert;
unsigned short ssl_disable_client_renegotiation;
unsigned short ssl_read_ahead;
unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */
unsigned short defer_accept;

View File

@ -144,6 +144,7 @@ static int config_insert(server *srv) {
{ "server.stream-request-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 76 */
{ "server.stream-response-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 77 */
{ "server.max-request-field-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 78 */
{ "ssl.read-ahead", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 79 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@ -247,6 +248,7 @@ static int config_insert(server *srv) {
s->ssl_verifyclient_depth = 9;
s->ssl_verifyclient_export_cert = 0;
s->ssl_disable_client_renegotiation = 1;
s->ssl_read_ahead = (0 == i ? 1 : srv->config_storage[0]->ssl_read_ahead);
s->listen_backlog = (0 == i ? 1024 : srv->config_storage[0]->listen_backlog);
s->stream_request_body = 0;
s->stream_response_body = 0;
@ -315,6 +317,7 @@ static int config_insert(server *srv) {
#endif
cv[76].destination = &(s->stream_request_body);
cv[77].destination = &(s->stream_response_body);
cv[79].destination = &(s->ssl_read_ahead);
srv->config_storage[i] = s;
@ -543,6 +546,7 @@ int config_setup_connection(server *srv, connection *con) {
PATCH(ssl_verifyclient_username);
PATCH(ssl_verifyclient_export_cert);
PATCH(ssl_disable_client_renegotiation);
PATCH(ssl_read_ahead);
return 0;
}
@ -671,6 +675,8 @@ int config_patch_connection(server *srv, connection *con) {
PATCH(ssl_verifyclient_export_cert);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.disable-client-renegotiation"))) {
PATCH(ssl_disable_client_renegotiation);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.read-ahead"))) {
PATCH(ssl_read_ahead);
}
}
}

View File

@ -127,7 +127,7 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_ERROR);
return -1;
}
} while (len > 0);
} while (len > 0 && (con->conf.ssl_read_ahead || SSL_pending(con->ssl) > 0));
if (len < 0) {
int oerrno = errno;
@ -206,11 +206,13 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_ERROR);
return -1;
} else { /*(len == 0)*/
} else if (len == 0) {
con->is_readable = 0;
/* the other end close the connection -> KEEP-ALIVE */
return -2;
} else {
return 0;
}
#else
UNUSED(srv);

View File

@ -994,7 +994,7 @@ int network_init(server *srv) {
s->ssl_pemfile);
return -1;
}
SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1);
SSL_CTX_set_default_read_ahead(s->ssl_ctx, s->ssl_read_ahead);
SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx)
| SSL_MODE_ENABLE_PARTIAL_WRITE
| SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER