Skip to content

Commit 70ab0e6

Browse files
jukkarhenrikbrixandersen
authored andcommitted
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>
1 parent 4d9d0ee commit 70ab0e6

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

include/zephyr/net/websocket.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ int websocket_disconnect(int ws_sock);
201201
*/
202202
int websocket_register(int http_sock, uint8_t *recv_buf, size_t recv_buf_len);
203203

204+
/**
205+
* @brief Unregister a websocket. This is called when we no longer need
206+
* the underlaying "real" socket. This will close first the websocket
207+
* and then the original socket.
208+
*
209+
* @param ws_sock Websocket connection socket.
210+
*
211+
* @return <0 if error, 0 the websocket connection is now fully closed
212+
*/
213+
int websocket_unregister(int ws_sock);
214+
204215
#if defined(CONFIG_WEBSOCKET_CLIENT)
205216
void websocket_init(void);
206217
#else

subsys/net/lib/websocket/websocket.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,58 @@ int websocket_register(int sock, uint8_t *recv_buf, size_t recv_buf_len)
11931193
return ret;
11941194
}
11951195

1196+
static struct websocket_context *websocket_search(int sock)
1197+
{
1198+
struct websocket_context *ctx = NULL;
1199+
int i;
1200+
1201+
k_sem_take(&contexts_lock, K_FOREVER);
1202+
1203+
for (i = 0; i < ARRAY_SIZE(contexts); i++) {
1204+
if (!websocket_context_is_used(&contexts[i])) {
1205+
continue;
1206+
}
1207+
1208+
if (contexts[i].sock != sock) {
1209+
continue;
1210+
}
1211+
1212+
ctx = &contexts[i];
1213+
break;
1214+
}
1215+
1216+
k_sem_give(&contexts_lock);
1217+
1218+
return ctx;
1219+
}
1220+
1221+
int websocket_unregister(int sock)
1222+
{
1223+
struct websocket_context *ctx;
1224+
1225+
if (sock < 0) {
1226+
return -EINVAL;
1227+
}
1228+
1229+
ctx = websocket_search(sock);
1230+
if (ctx == NULL) {
1231+
NET_DBG("[%p] Real socket for websocket sock %d not found!", ctx, sock);
1232+
return -ENOENT;
1233+
}
1234+
1235+
if (ctx->real_sock < 0) {
1236+
return -EALREADY;
1237+
}
1238+
1239+
(void)zsock_close(sock);
1240+
(void)zsock_close(ctx->real_sock);
1241+
1242+
ctx->real_sock = -1;
1243+
ctx->sock = -1;
1244+
1245+
return 0;
1246+
}
1247+
11961248
static const struct socket_op_vtable websocket_fd_op_vtable = {
11971249
.fd_vtable = {
11981250
.read = websocket_read_vmeth,

0 commit comments

Comments
 (0)