net: websocket: Add a way to unregister a websocket connection

Doing a normal close for a websocket does not close the underlying
real socket. If we do not have fd for the real socket, then it is
not possible to fully close a websocket connection. As we are allocating
a websocket using websocket_register() in HTTP server use case,
create a websocket_unregister() that will close both the real
socket and the websocket socket.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2024-05-09 14:33:04 +03:00 committed by Henrik Brix Andersen
parent 4d9d0ee64c
commit 70ab0e65a5
2 changed files with 63 additions and 0 deletions

View File

@ -201,6 +201,17 @@ int websocket_disconnect(int ws_sock);
*/
int websocket_register(int http_sock, uint8_t *recv_buf, size_t recv_buf_len);
/**
* @brief Unregister a websocket. This is called when we no longer need
* the underlaying "real" socket. This will close first the websocket
* and then the original socket.
*
* @param ws_sock Websocket connection socket.
*
* @return <0 if error, 0 the websocket connection is now fully closed
*/
int websocket_unregister(int ws_sock);
#if defined(CONFIG_WEBSOCKET_CLIENT)
void websocket_init(void);
#else

View File

@ -1193,6 +1193,58 @@ out:
return ret;
}
static struct websocket_context *websocket_search(int sock)
{
struct websocket_context *ctx = NULL;
int i;
k_sem_take(&contexts_lock, K_FOREVER);
for (i = 0; i < ARRAY_SIZE(contexts); i++) {
if (!websocket_context_is_used(&contexts[i])) {
continue;
}
if (contexts[i].sock != sock) {
continue;
}
ctx = &contexts[i];
break;
}
k_sem_give(&contexts_lock);
return ctx;
}
int websocket_unregister(int sock)
{
struct websocket_context *ctx;
if (sock < 0) {
return -EINVAL;
}
ctx = websocket_search(sock);
if (ctx == NULL) {
NET_DBG("[%p] Real socket for websocket sock %d not found!", ctx, sock);
return -ENOENT;
}
if (ctx->real_sock < 0) {
return -EALREADY;
}
(void)zsock_close(sock);
(void)zsock_close(ctx->real_sock);
ctx->real_sock = -1;
ctx->sock = -1;
return 0;
}
static const struct socket_op_vtable websocket_fd_op_vtable = {
.fd_vtable = {
.read = websocket_read_vmeth,