#define SSL_SOCK_F_KTLS_RECV (1 << 3) /* kTLS receive is configure on that socket */
#define SSL_SOCK_F_CTRL_SEND (1 << 4) /* We want to send a kTLS control message for that socket */
#define SSL_SOCK_F_HAS_ALPN (1 << 5) /* An ALPN has been negotiated */
+#define SSL_SOCK_F_KTLS_ULP (1 << 6) /* TLS ULP is enabled on that socket */
struct ssl_sock_ctx {
struct connection *conn;
}
#ifdef HA_USE_KTLS
+static int ktls_enable_ulp(struct ssl_sock_ctx *ctx)
+{
+ int ret = 0;
+
+ if (!(ctx->flags & SSL_SOCK_F_KTLS_ULP)) {
+ ret = setsockopt(ctx->conn->handle.fd, SOL_TCP, TCP_ULP, "tls",
+ sizeof("tls"));
+ if (ret == 0)
+ ctx->flags |= SSL_SOCK_F_KTLS_ULP;
+ else
+ ctx->flags &= ~SSL_SOCK_F_KTLS_ENABLED;
+ }
+
+ return ret;
+}
+
/* Returns 0 on success, -1 on failure */
static int ktls_set_key(struct ssl_sock_ctx *ctx, void *info, size_t info_len, int is_tx)
{
if (!(ctx->flags & SSL_SOCK_F_KTLS_ENABLED))
return 0;
+
+ if (ktls_enable_ulp(ctx) == -1)
+ return 0;
/*
* As OpenSSL doesn't export struct tls_crypto_info_all,
* and it puts the size at the end of the struct,
if (ret < 0)
return ret;
}
-#ifdef HA_USE_KTLS
- /*
- * Make the socket usable for kTLS. That does not mean that we will
- * use kTLS, though, just that the socket will be able to do it.
- */
- if ((ctx->flags & SSL_SOCK_F_KTLS_ENABLED) && setsockopt(conn->handle.fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) != 0)
- ctx->flags &= ~SSL_SOCK_F_KTLS_ENABLED;
-#endif
tasklet_wakeup(ctx->wait_event.tasklet);
return 0;
if (!(ctx->flags & SSL_SOCK_F_KTLS_ENABLED))
return;
+ if (ktls_enable_ulp(ctx) == -1)
+ return;
+
switch (SSL_version(ctx->ssl)) {
case TLS_1_2_VERSION:
is_tls_12 = 1;