From ad1023b376af79c4b75fe5c638860d095e44b5ab Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Sun, 10 Sep 2023 08:47:48 +0100 Subject: [PATCH] Fix potential blocking of the router thread when waiting for ready. --- src/ipxwrapper.c | 21 +++++++++++++++++++-- src/ipxwrapper.h | 3 ++- src/winsock.c | 14 ++++---------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index 0e6e630..4c10bfb 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -1,5 +1,5 @@ /* ipxwrapper - Library functions - * Copyright (C) 2008-2021 Daniel Collins + * Copyright (C) 2008-2023 Daniel Collins * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -142,7 +142,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } /* Lock the sockets table and search for one by file descriptor. - * + * * Returns an ipx_socket pointer on success, unlocks the sockets table and * returns NULL if no match is found. */ @@ -161,6 +161,23 @@ ipx_socket *get_socket(SOCKET sockfd) return sock; } +/* Like get_socket(), but also calls wait_for_ready() if an IPX socket was found. */ +ipx_socket *get_socket_wait_for_ready(SOCKET sockfd, int timeout_ms) +{ + ipx_socket *sock = get_socket(sockfd); + + if(sock) + { + unlock_sockets(); + wait_for_ready(timeout_ms); + + sock = get_socket(sockfd); + } + + return sock; + lock_sockets(); +} + /* Lock the mutex */ void lock_sockets(void) { diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index 3dde11b..ef02c4e 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -1,5 +1,5 @@ /* ipxwrapper - Library header - * Copyright (C) 2008-2014 Daniel Collins + * Copyright (C) 2008-2023 Daniel Collins * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -138,6 +138,7 @@ extern ipx_socket *sockets; extern main_config_t main_config; ipx_socket *get_socket(SOCKET sockfd); +ipx_socket *get_socket_wait_for_ready(SOCKET sockfd, int timeout_ms); void lock_sockets(void); void unlock_sockets(void); uint64_t get_ticks(void); diff --git a/src/winsock.c b/src/winsock.c index 2807cf0..2c920f1 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -1,5 +1,5 @@ /* ipxwrapper - Winsock functions - * Copyright (C) 2008-2021 Daniel Collins + * Copyright (C) 2008-2023 Daniel Collins * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -538,12 +538,10 @@ static bool _resolve_bind_address(ipx_socket *sock, const struct sockaddr_ipx *a int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) { - ipx_socket *sock = get_socket(fd); + ipx_socket *sock = get_socket_wait_for_ready(fd, IPX_READY_TIMEOUT); if(sock) { - wait_for_ready(IPX_READY_TIMEOUT); - struct sockaddr_ipx ipxaddr; if(addrlen < sizeof(ipxaddr) || addr->sa_family != AF_IPX) @@ -938,12 +936,10 @@ int PASCAL WSARecvEx(SOCKET fd, char *buf, int len, int *flags) int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int FAR *optlen) { - ipx_socket *sock = get_socket(fd); + ipx_socket *sock = get_socket_wait_for_ready(fd, IPX_READY_TIMEOUT); if(sock) { - wait_for_ready(IPX_READY_TIMEOUT); - if(level == NSPROTO_IPX) { if(optname == IPX_PTYPE) @@ -1477,12 +1473,10 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s { struct sockaddr_ipx_ext *ipxaddr = (struct sockaddr_ipx_ext*)addr; - ipx_socket *sock = get_socket(fd); + ipx_socket *sock = get_socket_wait_for_ready(fd, IPX_READY_TIMEOUT); if(sock) { - wait_for_ready(IPX_READY_TIMEOUT); - if(sock->flags & IPX_IS_SPX) { unlock_sockets();