summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/tls.txt6
-rw-r--r--memcached.c8
-rw-r--r--memcached.h1
-rw-r--r--t/ssl_settings.t1
-rw-r--r--tls.c10
5 files changed, 26 insertions, 0 deletions
diff --git a/doc/tls.txt b/doc/tls.txt
index e7fe2ca..974be58 100644
--- a/doc/tls.txt
+++ b/doc/tls.txt
@@ -18,6 +18,12 @@ will use new certificates without a need of re-starting the server process.
# Multiple ports with and without TLS : by default all TCP ports are secured. Optionally we can setup
the server to secure a specific TCP port.
+# Kernel TLS offload (kTLS): when compiled with OpenSSL 3.0.0+ with the `enable-ktls` build-time
+option set, and running on Linux with kernel version 4.17+ with `CONFIG_TLS` enabled, memcached can
+transparently offload cryptography operations to the kernel. Depending on a variety of factors
+(including the workload, NIC support for HW-accelerated cryptography, ciphers in use, etc.),
+kTLS may offer improved throughput and/or reduced memcached resource consumption.
+
Note that initial implementation does not support session renegotiation.
Design
diff --git a/memcached.c b/memcached.c
index 6623dec..41518d2 100644
--- a/memcached.c
+++ b/memcached.c
@@ -233,6 +233,7 @@ static void settings_init(void) {
settings.ssl_last_cert_refresh_time = current_time;
settings.ssl_wbuf_size = 16 * 1024; // default is 16KB (SSL max frame size is 17KB)
settings.ssl_session_cache = false;
+ settings.ssl_kernel_tls = false;
settings.ssl_min_version = TLS1_2_VERSION;
#endif
/* By default this string should be NULL for getaddrinfo() */
@@ -1976,6 +1977,7 @@ void process_stat_settings(ADD_STAT add_stats, void *c) {
APPEND_STAT("ssl_ca_cert", "%s", settings.ssl_ca_cert ? settings.ssl_ca_cert : "NULL");
APPEND_STAT("ssl_wbuf_size", "%u", settings.ssl_wbuf_size);
APPEND_STAT("ssl_session_cache", "%s", settings.ssl_session_cache ? "yes" : "no");
+ APPEND_STAT("ssl_kernel_tls", "%s", settings.ssl_kernel_tls ? "yes" : "no");
APPEND_STAT("ssl_min_version", "%s", ssl_proto_text(settings.ssl_min_version));
#endif
#ifdef PROXY
@@ -4069,6 +4071,7 @@ static void usage(void) {
" (default: %u)\n", settings.ssl_wbuf_size / (1 << 10));
printf(" - ssl_session_cache: enable server-side SSL session cache, to support session\n"
" resumption\n"
+ " - ssl_kernel_tls: enable kernel TLS offload\n"
" - ssl_min_version: minimum protocol version to accept (default: %s)\n"
#if defined(TLS1_3_VERSION)
" valid values are 0(%s), 1(%s), 2(%s), or 3(%s).\n",
@@ -4743,6 +4746,7 @@ int main (int argc, char **argv) {
SSL_CA_CERT,
SSL_WBUF_SIZE,
SSL_SESSION_CACHE,
+ SSL_KERNEL_TLS,
SSL_MIN_VERSION,
#endif
#ifdef PROXY
@@ -4802,6 +4806,7 @@ int main (int argc, char **argv) {
[SSL_CA_CERT] = "ssl_ca_cert",
[SSL_WBUF_SIZE] = "ssl_wbuf_size",
[SSL_SESSION_CACHE] = "ssl_session_cache",
+ [SSL_KERNEL_TLS] = "ssl_kernel_tls",
[SSL_MIN_VERSION] = "ssl_min_version",
#endif
#ifdef PROXY
@@ -5483,6 +5488,9 @@ int main (int argc, char **argv) {
case SSL_SESSION_CACHE:
settings.ssl_session_cache = true;
break;
+ case SSL_KERNEL_TLS:
+ settings.ssl_kernel_tls = true;
+ break;
case SSL_MIN_VERSION: {
int min_version;
if (subopts_value == NULL) {
diff --git a/memcached.h b/memcached.h
index 5a21aee..2320086 100644
--- a/memcached.h
+++ b/memcached.h
@@ -514,6 +514,7 @@ struct settings {
rel_time_t ssl_last_cert_refresh_time; /* time of the last server certificate refresh */
unsigned int ssl_wbuf_size; /* size of the write buffer used by ssl_sendmsg method */
bool ssl_session_cache; /* enable SSL server session caching */
+ bool ssl_kernel_tls; /* enable server kTLS */
int ssl_min_version; /* minimum SSL protocol version to accept */
#endif
int num_napi_ids; /* maximum number of NAPI IDs */
diff --git a/t/ssl_settings.t b/t/ssl_settings.t
index 0a3bf94..2fe9a0f 100644
--- a/t/ssl_settings.t
+++ b/t/ssl_settings.t
@@ -21,6 +21,7 @@ my $key = getcwd ."/t/". MemcachedTest::SRV_KEY;
is($settings->{'ssl_enabled'}, 'yes');
is($settings->{'ssl_session_cache'}, 'no');
+is($settings->{'ssl_kernel_tls'}, 'no');
is($settings->{'ssl_chain_cert'}, $cert);
is($settings->{'ssl_key'}, $key);
is($settings->{'ssl_verify_mode'}, 0);
diff --git a/tls.c b/tls.c
index db3aaa7..47ebc2f 100644
--- a/tls.c
+++ b/tls.c
@@ -212,6 +212,16 @@ int ssl_init(void) {
SSL_CTX_set_session_cache_mode(settings.ssl_ctx, SSL_SESS_CACHE_OFF);
}
+ // Optional kernel TLS offload; default disabled.
+ if (settings.ssl_kernel_tls) {
+#if defined(SSL_OP_ENABLE_KTLS)
+ SSL_CTX_set_options(settings.ssl_ctx, SSL_OP_ENABLE_KTLS);
+#else
+ fprintf(stderr, "Kernel TLS offload is not available\n");
+ exit(EX_USAGE);
+#endif
+ }
+
return 0;
}