From df3ea61582fb0f7c44053ddbf12998f8b08b430f Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Tue, 7 Mar 2023 16:07:51 +0100 Subject: [PATCH] udp: add a lock for the helpers list --- src/udp/udp.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/udp/udp.c b/src/udp/udp.c index 5168b3ffd..590cccf08 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ struct udp_sock { QOS_FLOWID qos_id; /**< QOS IPv4 flow id */ QOS_FLOWID qos_id6; /**< QOS IPv6 flow id */ #endif + mtx_t *lock; /**< A lock for helpers */ }; /** Defines a UDP helper */ @@ -120,7 +122,10 @@ static void udp_destructor(void *data) { struct udp_sock *us = data; + mtx_lock(us->lock); list_flush(&us->helpers); + mtx_unlock(us->lock); + mem_deref(us->lock); #ifdef WIN32 if (us->qos && us->qos_id) @@ -185,6 +190,7 @@ static void udp_read(struct udp_sock *us, re_sock_t fd) (void)mbuf_resize(mb, mb->end); /* call helpers */ + mtx_lock(us->lock); le = us->helpers.head; while (le) { struct udp_helper *uh = le->data; @@ -200,6 +206,7 @@ static void udp_read(struct udp_sock *us, re_sock_t fd) us->rh(&src, mb, us->arg); out: + mtx_unlock(us->lock); mem_deref(mb); } @@ -250,6 +257,10 @@ int udp_listen(struct udp_sock **usp, const struct sa *local, if (!us) return ENOMEM; + err = mutex_alloc(&us->lock); + if (err) + goto out; + list_init(&us->helpers); us->fd = RE_BAD_SOCK; @@ -382,6 +393,10 @@ int udp_alloc_sockless(struct udp_sock **usp, if (!us) return ENOMEM; + int err = mutex_alloc(&us->lock); + if (err) + goto out; + list_init(&us->helpers); us->fd = RE_BAD_SOCK; @@ -391,9 +406,13 @@ int udp_alloc_sockless(struct udp_sock **usp, us->arg = arg; us->rxsz = UDP_RXSZ_DEFAULT; - *usp = us; +out: + if (err) + mem_deref(us); + else + *usp = us; - return 0; + return err; } @@ -407,6 +426,10 @@ int udp_alloc_fd(struct udp_sock **usp, re_sock_t fd, if (!us) return ENOMEM; + int err = mutex_alloc(&us->lock); + if (err) + goto out; + list_init(&us->helpers); us->fd = fd; @@ -415,7 +438,11 @@ int udp_alloc_fd(struct udp_sock **usp, re_sock_t fd, us->arg = arg; us->rxsz = UDP_RXSZ_DEFAULT; - *usp = us; +out: + if (err) + mem_deref(us); + else + *usp = us; return 0; } @@ -442,6 +469,10 @@ int udp_open(struct udp_sock **usp, int af) if (!us) return ENOMEM; + err = mutex_alloc(&us->lock); + if (err) + goto out; + us->fd = RE_BAD_SOCK; us->fd6 = RE_BAD_SOCK; @@ -879,6 +910,7 @@ int udp_register_helper(struct udp_helper **uhp, struct udp_sock *us, if (!uh) return ENOMEM; + mtx_lock(us->lock); list_append(&us->helpers, &uh->le, uh); uh->layer = layer; @@ -891,6 +923,7 @@ int udp_register_helper(struct udp_helper **uhp, struct udp_sock *us, if (uhp) *uhp = uh; + mtx_unlock(us->lock); return 0; } @@ -957,19 +990,24 @@ void udp_recv_helper(struct udp_sock *us, const struct sa *src, struct udp_helper *udp_helper_find(const struct udp_sock *us, int layer) { struct le *le; + struct udp_helper *uhf = NULL; if (!us) return NULL; + mtx_lock(us->lock); for (le = us->helpers.head; le; le = le->next) { struct udp_helper *uh = le->data; - if (layer == uh->layer) - return uh; + if (layer == uh->layer) { + uhf = uh; + break; + } } - return NULL; + mtx_unlock(us->lock); + return uhf; } @@ -1005,11 +1043,13 @@ void udp_recv_packet(struct udp_sock *us, const struct sa *src, struct mbuf *mb) { struct sa hsrc; + struct le *le; if (!us || !src || !mb) return; - struct le *le = us->helpers.head; + mtx_lock(us->lock); + le = us->helpers.head; while (le) { struct udp_helper *uh = le->data; bool hdld; @@ -1023,8 +1063,10 @@ void udp_recv_packet(struct udp_sock *us, const struct sa *src, hdld = uh->recvh(&hsrc, mb, uh->arg); if (hdld) - return; + goto out; } us->rh(src, mb, us->arg); +out: + mtx_unlock(us->lock); }