Jinoh Kang : server: Ensure datagram sockets are bound in send_socket.
Alexandre Julliard
julliard at winehq.org
Fri Mar 25 15:28:09 CDT 2022
Module: wine
Branch: master
Commit: 0ac256eacc9cd67d689bdc0956315670cd60dfbc
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0ac256eacc9cd67d689bdc0956315670cd60dfbc
Author: Jinoh Kang <jinoh.kang.kr at gmail.com>
Date: Thu Mar 24 02:25:20 2022 +0900
server: Ensure datagram sockets are bound in send_socket.
If the type of the socket is SOCK_DGRAM, it shall always be bound to an
address if we ever attempt to send datagrams through the socket, whether
the attempt succeeds or not.
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/sock.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
diff --git a/server/sock.c b/server/sock.c
index 1beff85cbe0..e3779940174 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -471,6 +471,32 @@ static socklen_t sockaddr_to_unix( const struct WS_sockaddr *wsaddr, int wsaddrl
}
}
+static socklen_t get_unix_sockaddr_any( union unix_sockaddr *uaddr, int ws_family )
+{
+ memset( uaddr, 0, sizeof(*uaddr) );
+ switch (ws_family)
+ {
+ case WS_AF_INET:
+ uaddr->in.sin_family = AF_INET;
+ return sizeof(uaddr->in);
+ case WS_AF_INET6:
+ uaddr->in6.sin6_family = AF_INET6;
+ return sizeof(uaddr->in6);
+#ifdef HAS_IPX
+ case WS_AF_IPX:
+ uaddr->ipx.sipx_family = AF_IPX;
+ return sizeof(uaddr->ipx);
+#endif
+#ifdef HAS_IRDA
+ case WS_AF_IRDA:
+ uaddr->irda.sir_family = AF_IRDA;
+ return sizeof(uaddr->irda);
+#endif
+ default:
+ return 0;
+ }
+}
+
/* some events are generated at the same time but must be sent in a particular
* order (e.g. CONNECT must be sent before READ) */
static const enum afd_poll_bit event_bitorder[] =
@@ -3490,15 +3516,24 @@ DECL_HANDLER(send_socket)
if (!sock) return;
fd = sock->fd;
- if (sock->type == WS_SOCK_DGRAM)
+ if (sock->type == WS_SOCK_DGRAM && !sock->bound)
{
- /* sendto() and sendmsg() implicitly binds a socket */
union unix_sockaddr unix_addr;
- socklen_t unix_len = sizeof(unix_addr);
+ socklen_t unix_len;
+ int bind_errno = 0;
+ int unix_fd = get_unix_fd( fd );
- if (!sock->bound && !getsockname( get_unix_fd( fd ), &unix_addr.addr, &unix_len ))
+ unix_len = get_unix_sockaddr_any( &unix_addr, sock->family );
+ if (bind( unix_fd, &unix_addr.addr, unix_len ) < 0)
+ bind_errno = errno;
+
+ if (getsockname( unix_fd, &unix_addr.addr, &unix_len ) >= 0)
+ {
sock->addr_len = sockaddr_from_unix( &unix_addr, &sock->addr.addr, sizeof(sock->addr) );
- sock->bound = 1;
+ sock->bound = 1;
+ }
+ else if (status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY)
+ status = sock_get_ntstatus( bind_errno ? bind_errno : errno );
}
/* If we had a short write and the socket is nonblocking (and the client is
More information about the wine-cvs
mailing list