From d20b1aebf995a8c7e5ecbb4392303e8d9838e8b5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 23 Jun 2020 12:40:42 +0200 Subject: [PATCH] net: lwm2m: Fix poll fds handling Currently, functions for poll sock_fds array management are buggy, in case there is another socket open (for instance the socket for firmware update download), it could get overwritten, if the LwM2M socket was closed and re-opened in a meantime (e. g. on registration timeout). Fix this, by appending new entries to the sock_fds in continuous manner. In case of removal, the deleted entry is overwritten by the last one, and the last one is cleared. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_engine.c | 42 +++++++++++++++-------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 50cb3fcc20c..e34e9558a1a 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -4171,36 +4171,38 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx) int lwm2m_socket_add(struct lwm2m_ctx *ctx) { - int i; - - if (sock_nfds < MAX_POLL_FD) { - i = sock_nfds++; - } else { - for (i = 0; i < MAX_POLL_FD; i++) { - if (sock_ctx[i] == NULL) { - goto found; - } - } - + if (sock_nfds >= MAX_POLL_FD) { return -ENOMEM; } -found: - sock_ctx[i] = ctx; - sock_fds[i].fd = ctx->sock_fd; - sock_fds[i].events = POLLIN; + sock_ctx[sock_nfds] = ctx; + sock_fds[sock_nfds].fd = ctx->sock_fd; + sock_fds[sock_nfds].events = POLLIN; + sock_nfds++; + return 0; } void lwm2m_socket_del(struct lwm2m_ctx *ctx) { for (int i = 0; i < sock_nfds; i++) { - if (sock_ctx[i] == ctx) { - sock_ctx[i] = NULL; - sock_fds[i].fd = -1; - sock_nfds--; - break; + if (sock_ctx[i] != ctx) { + continue; } + + sock_nfds--; + + /* If not last, overwrite the entry with the last one. */ + if (i < sock_nfds) { + sock_ctx[i] = sock_ctx[sock_nfds]; + sock_fds[i].fd = sock_fds[sock_nfds].fd; + sock_fds[i].events = sock_fds[sock_nfds].events; + } + + /* Remove the last entry. */ + sock_ctx[sock_nfds] = NULL; + sock_fds[sock_nfds].fd = -1; + break; } }