Skip to content

Commit 8a4e489

Browse files
rluboscfriedt
authored andcommitted
net: sockets: dtls: Fix handshake with socket offloading
Fix `poll()` handling for DTLS clients when the underlying socket is an offloaded socket. As in this case no `k_poll()` is used underneath, it's not possible to monitor the handhshake status with `tls_established` semaphore. Instead, do the following: 1. If no handhshake is in progress yet, just drop the incoming data - it's the client who should initiate the handshake, any data incoming before that should not be processed. 2. If handshake is currently in progress, lift the `POLLIN` flag and add small delay to allow the other thread to proceed with the handshake. 3. Otherwise, just proceed as usual. Signed-off-by: Robert Lubos <[email protected]>
1 parent b4366a8 commit 8a4e489

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

subsys/net/lib/sockets/sockets_tls.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ __net_socket struct tls_context {
9393
/** Information whether underlying socket is listening. */
9494
bool is_listening;
9595

96+
/** Information whether TLS handshake is currently in progress. */
97+
bool handshake_in_progress;
98+
9699
/** Information whether TLS handshake is complete or not. */
97100
struct k_sem tls_established;
98101

@@ -835,6 +838,8 @@ static int tls_mbedtls_handshake(struct tls_context *context, bool block)
835838
sock_flags & ~O_NONBLOCK);
836839
}
837840

841+
context->handshake_in_progress = true;
842+
838843
while ((ret = mbedtls_ssl_handshake(&context->ssl)) != 0) {
839844
if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
840845
ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
@@ -869,6 +874,8 @@ static int tls_mbedtls_handshake(struct tls_context *context, bool block)
869874
k_sem_give(&context->tls_established);
870875
}
871876

877+
context->handshake_in_progress = false;
878+
872879
return ret;
873880
}
874881

@@ -2112,7 +2119,48 @@ static int ztls_poll_update_ctx(struct tls_context *ctx,
21122119
return ret;
21132120
}
21142121

2115-
static inline int ztls_poll_offload(struct zsock_pollfd *fds, int nfds, int timeout)
2122+
/* Return true if needed to retry rightoff or false otherwise. */
2123+
static bool poll_offload_dtls_client_retry(struct tls_context *ctx,
2124+
struct zsock_pollfd *pfd)
2125+
{
2126+
/* DTLS client should wait for the handshake to complete before it
2127+
* reports that data is ready.
2128+
*/
2129+
if ((ctx->type != SOCK_DGRAM) ||
2130+
(ctx->options.role != MBEDTLS_SSL_IS_CLIENT)) {
2131+
return false;
2132+
}
2133+
2134+
if (ctx->handshake_in_progress) {
2135+
/* Add some sleep to allow lower priority threads to proceed
2136+
* with handshake.
2137+
*/
2138+
k_msleep(10);
2139+
2140+
pfd->revents &= ~ZSOCK_POLLIN;
2141+
return true;
2142+
} else if (!is_handshake_complete(ctx)) {
2143+
uint8_t byte;
2144+
int ret;
2145+
2146+
/* Handshake didn't start yet - just drop the incoming data -
2147+
* it's the client who should initiate the handshake.
2148+
*/
2149+
ret = zsock_recv(ctx->sock, &byte, sizeof(byte),
2150+
ZSOCK_MSG_DONTWAIT);
2151+
if (ret < 0) {
2152+
pfd->revents |= ZSOCK_POLLERR;
2153+
}
2154+
2155+
pfd->revents &= ~ZSOCK_POLLIN;
2156+
return true;
2157+
}
2158+
2159+
/* Handshake complete, just proceed. */
2160+
return false;
2161+
}
2162+
2163+
static int ztls_poll_offload(struct zsock_pollfd *fds, int nfds, int timeout)
21162164
{
21172165
int fd_backup[CONFIG_NET_SOCKETS_POLL_MAX];
21182166
const struct fd_op_vtable *vtable;
@@ -2181,6 +2229,12 @@ static inline int ztls_poll_offload(struct zsock_pollfd *fds, int nfds, int time
21812229
0);
21822230
if (ctx != NULL) {
21832231
if (fds[i].events & ZSOCK_POLLIN) {
2232+
if (poll_offload_dtls_client_retry(
2233+
ctx, &fds[i])) {
2234+
retry = true;
2235+
continue;
2236+
}
2237+
21842238
result = ztls_poll_update_pollin(
21852239
fd_backup[i], ctx, &fds[i]);
21862240
if (result == -EAGAIN) {

0 commit comments

Comments
 (0)