Skip to content

Commit

Permalink
net: dns: Add per socket user data for the dispatcher
Browse files Browse the repository at this point in the history
The socket services API has a limitation where the user data is shared
between file descriptors described in the same service.

This can cause problem in DNS dispatcher where each listened socket
needs to have their own dispatcher struct set as user data so that we
can map between dispatcher context and socket. Solve this by always
have a dispatcher table as user data, and then have the actual mapping
done via the dispatcher table when receiving data to the dispatcher socket.

Fixes zephyrproject-rtos#78146

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
  • Loading branch information
jukkar authored and nagelkl committed Sep 16, 2024
1 parent aea1ce0 commit 595a377
Showing 1 changed file with 25 additions and 2 deletions.
27 changes: 25 additions & 2 deletions subsys/net/lib/dns/dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ static sys_slist_t sockets;
NET_BUF_POOL_DEFINE(dns_msg_pool, DNS_RESOLVER_BUF_CTR,
DNS_RESOLVER_MAX_BUF_SIZE, 0, NULL);

static struct socket_dispatch_table {
struct dns_socket_dispatcher *ctx;
} dispatch_table[CONFIG_NET_SOCKETS_POLL_MAX];

static int dns_dispatch(struct dns_socket_dispatcher *dispatcher,
int sock, struct sockaddr *addr, size_t addrlen,
struct net_buf *dns_data, size_t buf_len)
Expand Down Expand Up @@ -96,14 +100,17 @@ static int dns_dispatch(struct dns_socket_dispatcher *dispatcher,

static int recv_data(struct net_socket_service_event *pev)
{
struct dns_socket_dispatcher *dispatcher = pev->user_data;
struct socket_dispatch_table *table = pev->user_data;
struct dns_socket_dispatcher *dispatcher;
socklen_t optlen = sizeof(int);
struct net_buf *dns_data = NULL;
struct sockaddr addr;
size_t addrlen;
int family, sock_error;
int ret = 0, len;

dispatcher = table[pev->event.fd].ctx;

k_mutex_lock(&dispatcher->lock, K_FOREVER);

(void)zsock_getsockopt(pev->event.fd, SOL_SOCKET,
Expand Down Expand Up @@ -227,6 +234,12 @@ int dns_dispatcher_register(struct dns_socket_dispatcher *ctx)

entry->pair = ctx;

for (int i = 0; i < ctx->fds_len; i++) {
if (dispatch_table[ctx->fds[i].fd].ctx == NULL) {
dispatch_table[ctx->fds[i].fd].ctx = ctx;
}
}

/* Basically we are now done. If there is incoming data to
* the socket, the dispatcher will then pass it to the correct
* recipient.
Expand All @@ -253,7 +266,13 @@ int dns_dispatcher_register(struct dns_socket_dispatcher *ctx)

ctx->pair = NULL;

ret = net_socket_service_register(ctx->svc, ctx->fds, ctx->fds_len, ctx);
for (int i = 0; i < ctx->fds_len; i++) {
if (dispatch_table[ctx->fds[i].fd].ctx == NULL) {
dispatch_table[ctx->fds[i].fd].ctx = ctx;
}
}

ret = net_socket_service_register(ctx->svc, ctx->fds, ctx->fds_len, &dispatch_table);
if (ret < 0) {
NET_DBG("Cannot register socket service (%d)", ret);
goto out;
Expand All @@ -273,6 +292,10 @@ int dns_dispatcher_unregister(struct dns_socket_dispatcher *ctx)

(void)sys_slist_find_and_remove(&sockets, &ctx->node);

for (int i = 0; i < ctx->fds_len; i++) {
dispatch_table[ctx->fds[i].fd].ctx = NULL;
}

k_mutex_unlock(&lock);

return 0;
Expand Down

0 comments on commit 595a377

Please sign in to comment.