mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-26 15:03:53 +01:00
pkg/openwsn/sock: add mutex around linked list access
Fix possible race conditions when sock is closed while iterating through the linked list.
This commit is contained in:
parent
75d53b0c46
commit
ca2e59d6a2
@ -25,6 +25,7 @@
|
||||
#ifdef MODULE_ZTIMER_USEC
|
||||
#include "ztimer.h"
|
||||
#endif
|
||||
#include "mutex.h"
|
||||
#include "utlist.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -43,7 +44,10 @@
|
||||
#define _TIMEOUT_MSG_TYPE (0x8474)
|
||||
#endif /* MODULE_ZTIMER_USEC */
|
||||
|
||||
/* sock linked list */
|
||||
static sock_udp_t *_udp_socket_list;
|
||||
/* linked list lock */
|
||||
static mutex_t _sock_list_lock;
|
||||
|
||||
#ifdef MODULE_ZTIMER_USEC
|
||||
static void _timeout_cb(void *arg)
|
||||
@ -127,6 +131,7 @@ static uint16_t _get_dyn_port(void)
|
||||
void sock_udp_init(void)
|
||||
{
|
||||
_udp_socket_list = NULL;
|
||||
mutex_init(&_sock_list_lock);
|
||||
}
|
||||
|
||||
int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local,
|
||||
@ -199,7 +204,9 @@ int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local,
|
||||
sock->async_cb = NULL;
|
||||
#endif
|
||||
/* update socket list */
|
||||
mutex_lock(&_sock_list_lock);
|
||||
LL_PREPEND(_udp_socket_list, sock);
|
||||
mutex_unlock(&_sock_list_lock);
|
||||
}
|
||||
|
||||
/* set flags */
|
||||
@ -316,7 +323,10 @@ void sock_udp_close(sock_udp_t *sock)
|
||||
return;
|
||||
}
|
||||
if (sock) {
|
||||
/* remove sock from list */
|
||||
mutex_lock(&_sock_list_lock);
|
||||
LL_DELETE(_udp_socket_list, sock);
|
||||
mutex_unlock(&_sock_list_lock);
|
||||
sock->next = NULL;
|
||||
}
|
||||
}
|
||||
@ -495,7 +505,10 @@ void sock_receive_internal(void)
|
||||
LOG_ERROR("%s: not pkt in queue\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&_sock_list_lock);
|
||||
current = _udp_socket_list;
|
||||
|
||||
while (current != NULL) {
|
||||
if (current->gen_sock.local.port == pkt->l4_destination_port &&
|
||||
idmanager_isMyAddress(&pkt->l3_destinationAdd)) {
|
||||
@ -508,6 +521,8 @@ void sock_receive_internal(void)
|
||||
"openwsn_sock: dropped message to %p (was full)\n",
|
||||
(void *)¤t->mbox);
|
||||
}
|
||||
/* unlock mutex before callback execution */
|
||||
mutex_unlock(&_sock_list_lock);
|
||||
#ifdef SOCK_HAS_ASYNC
|
||||
if (current->async_cb != NULL) {
|
||||
current->async_cb(current, SOCK_ASYNC_MSG_RECV, NULL);
|
||||
@ -520,6 +535,8 @@ void sock_receive_internal(void)
|
||||
}
|
||||
|
||||
if (current == NULL) {
|
||||
/* unlock mutex if no associated sock was found */
|
||||
mutex_unlock(&_sock_list_lock);
|
||||
openqueue_freePacketBuffer(pkt);
|
||||
LOG_ERROR("%s: no associated socket found\n", __FUNCTION__);
|
||||
}
|
||||
@ -540,17 +557,24 @@ void sock_senddone_internal(OpenQueueEntry_t *msg, owerror_t error)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&_sock_list_lock);
|
||||
current = _udp_socket_list;
|
||||
|
||||
while (current != NULL) {
|
||||
if (current->gen_sock.local.port == pkt->l4_sourcePortORicmpv6Type &&
|
||||
current->async_cb != NULL) {
|
||||
/* unlock mutex before callback execution */
|
||||
mutex_unlock(&_sock_list_lock);
|
||||
current->async_cb(current, SOCK_ASYNC_MSG_SENT, &error);
|
||||
break;
|
||||
}
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if (current == NULL) {
|
||||
/* unlock mutex if no associated sock was found */
|
||||
mutex_unlock(&_sock_list_lock);
|
||||
}
|
||||
#else /* SOCK_HAS_ASYNC */
|
||||
(void)error;
|
||||
#endif /*SOCK_HAS_ASYNC */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user