`getpeername()` is currently handled in ntdll. This merge request changes ntdll to forward `getpeername()` to wineserver. The implementation utilises new `peer_addr` and `peer_addr_len` fields in wineserver's `struct sock`.
This fixes multiple `todo_wine`s in `ws2_32/tests` and allows for more accurate peer names to be provided in case the address the socket is bound to on the Unix side does not match what `bind()` was called with on the Windows side.
*This merge request was originally intended to be included in !2786 (Add support for AF_UNIX sockets) but was split into its own merge request because this is not an insignificant change.*
-- v23: server: Move getpeername() implementation from ntdll/unix.
From: Ally Sommers dropbear.sh@gmail.com
This brings getpeername() in line with getsockname(), which is also implemented in wineserver. It also allows getpeername() to return a possibly-more-accurate peer name, as in the case of AF_UNIX sockets.
This commit also removes todo_wine from multiple now-successful tests. --- dlls/ntdll/unix/socket.c | 24 ++--------------- dlls/ws2_32/tests/sock.c | 18 ++++++------- server/sock.c | 58 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 32 deletions(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 6969f411955..cb24457ebdb 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1937,30 +1937,10 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc }
case IOCTL_AFD_WINE_GETPEERNAME: - { - union unix_sockaddr unix_addr; - socklen_t unix_len = sizeof(unix_addr); - int len; - - if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) - return status; - - if (getpeername( fd, &unix_addr.addr, &unix_len ) < 0) - { - status = sock_errno_to_status( errno ); - break; - } + if (in_size) FIXME( "unexpected input size %u\n", in_size );
- len = sockaddr_from_unix( &unix_addr, out_buffer, out_size ); - if (out_size < len) - { - status = STATUS_BUFFER_TOO_SMALL; - break; - } - io->Information = len; - status = STATUS_SUCCESS; + status = STATUS_BAD_DEVICE_TYPE; break; - }
case IOCTL_AFD_WINE_GET_SO_BROADCAST: return do_getsockopt( handle, io, SOL_SOCKET, SO_BROADCAST, out_buffer, out_size ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index e53d9991e56..cc79a77efb1 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -9160,16 +9160,16 @@ static void test_shutdown(void)
addrlen = sizeof(addr); ret = getpeername(client, (struct sockaddr *)&addr, &addrlen); - todo_wine ok(!ret, "got error %u\n", WSAGetLastError()); - todo_wine ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n"); + ok(!ret, "got error %u\n", WSAGetLastError()); + ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
addrlen = sizeof(client_addr); ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen); ok(!ret, "got error %u\n", WSAGetLastError()); addrlen = sizeof(addr); ret = getpeername(server, (struct sockaddr *)&addr, &addrlen); - todo_wine ok(!ret, "got error %u\n", WSAGetLastError()); - todo_wine ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n"); + ok(!ret, "got error %u\n", WSAGetLastError()); + ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
WSASetLastError(0xdeadbeef); ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr)); @@ -9228,16 +9228,16 @@ static void test_shutdown(void)
addrlen = sizeof(addr); ret = getpeername(client, (struct sockaddr *)&addr, &addrlen); - todo_wine ok(!ret, "got error %u\n", WSAGetLastError()); - todo_wine ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n"); + ok(!ret, "got error %u\n", WSAGetLastError()); + ok(!memcmp(&addr, &server_addr, sizeof(server_addr)), "address didn't match\n");
addrlen = sizeof(client_addr); ret = getsockname(client, (struct sockaddr *)&client_addr, &addrlen); ok(!ret, "got error %u\n", WSAGetLastError()); addrlen = sizeof(addr); ret = getpeername(server, (struct sockaddr *)&addr, &addrlen); - todo_wine ok(!ret, "got error %u\n", WSAGetLastError()); - todo_wine ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n"); + ok(!ret, "got error %u\n", WSAGetLastError()); + ok(!memcmp(&addr, &client_addr, sizeof(addr)), "address didn't match\n");
closesocket(client); closesocket(server); @@ -12446,7 +12446,7 @@ static void test_connecting_socket(void)
len = sizeof(addr); ret = getpeername(client, (struct sockaddr *)&addr, &len); - todo_wine ok(!ret, "got error %u\n", WSAGetLastError()); + ok(!ret, "got error %u\n", WSAGetLastError()); if (!ret) { ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family); diff --git a/server/sock.c b/server/sock.c index 550fe61e477..162a62e43bc 100644 --- a/server/sock.c +++ b/server/sock.c @@ -238,6 +238,8 @@ struct sock struct poll_req *main_poll; /* main poll */ union win_sockaddr addr; /* socket name */ int addr_len; /* socket name length */ + union win_sockaddr peer_addr; /* peer name */ + int peer_addr_len; /* peer name length */ unsigned int rcvbuf; /* advisory recv buffer size */ unsigned int sndbuf; /* advisory send buffer size */ unsigned int rcvtimeo; /* receive timeout in ms */ @@ -1716,6 +1718,8 @@ static struct sock *create_socket(void) sock->main_poll = NULL; memset( &sock->addr, 0, sizeof(sock->addr) ); sock->addr_len = 0; + memset( &sock->peer_addr, 0, sizeof(sock->peer_addr) ); + sock->peer_addr_len = 0; sock->rd_shutdown = 0; sock->wr_shutdown = 0; sock->wr_shutdown_pending = 0; @@ -2018,8 +2022,15 @@ static struct sock *accept_socket( struct sock *sock ) } unix_len = sizeof(unix_addr); if (!getsockname( acceptfd, &unix_addr.addr, &unix_len )) + { acceptsock->addr_len = sockaddr_from_unix( &unix_addr, &acceptsock->addr.addr, sizeof(acceptsock->addr) ); + if (!getpeername( acceptfd, &unix_addr.addr, &unix_len )) + acceptsock->peer_addr_len = sockaddr_from_unix( &unix_addr, + &acceptsock->peer_addr.addr, + sizeof(acceptsock->peer_addr) ); + } } + clear_error(); sock->pending_events &= ~AFD_POLL_ACCEPT; sock->reported_events &= ~AFD_POLL_ACCEPT; @@ -2074,7 +2085,13 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock )
unix_len = sizeof(unix_addr); if (!getsockname( get_unix_fd( newfd ), &unix_addr.addr, &unix_len )) + { acceptsock->addr_len = sockaddr_from_unix( &unix_addr, &acceptsock->addr.addr, sizeof(acceptsock->addr) ); + if (!getpeername( get_unix_fd( newfd ), &unix_addr.addr, &unix_len )) + acceptsock->peer_addr_len = sockaddr_from_unix( &unix_addr, + &acceptsock->peer_addr.addr, + sizeof(acceptsock->peer_addr) ); + }
clear_error(); sock->pending_events &= ~AFD_POLL_ACCEPT; @@ -2543,7 +2560,7 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) { const struct afd_connect_params *params = get_req_data(); const struct WS_sockaddr *addr; - union unix_sockaddr unix_addr; + union unix_sockaddr unix_addr, peer_addr; struct connect_req *req; socklen_t unix_len; int send_len, ret; @@ -2605,6 +2622,7 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) if (unix_addr.addr.sa_family == AF_INET && !memcmp( &unix_addr.in.sin_addr, magic_loopback_addr, 4 )) unix_addr.in.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
+ memcpy( &peer_addr, &unix_addr, sizeof(unix_addr) ); ret = connect( unix_fd, &unix_addr.addr, unix_len ); if (ret < 0 && errno == ECONNABORTED) { @@ -2628,7 +2646,10 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
unix_len = sizeof(unix_addr); if (!getsockname( unix_fd, &unix_addr.addr, &unix_len )) + { sock->addr_len = sockaddr_from_unix( &unix_addr, &sock->addr.addr, sizeof(sock->addr) ); + sock->peer_addr_len = sockaddr_from_unix( &peer_addr, &sock->peer_addr.addr, sizeof(sock->peer_addr)); + } sock->bound = 1;
if (!ret) @@ -2963,6 +2984,41 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) set_reply_data( &sock->addr, sock->addr_len ); return;
+ case IOCTL_AFD_WINE_GETPEERNAME: + if (sock->state != SOCK_CONNECTED && + sock->state != SOCK_CONNECTING && + sock->state != SOCK_CONNECTIONLESS) + { + set_error( STATUS_INVALID_CONNECTION ); + return; + } + + /* If ConnectEx() hasn't finished connecting (or failing to connect) the provided + * socket, getpeername() can't be called on it. This seems to be undocumented + * and is *not* the case for connect(), but we do test for it in ws2_32. + * connect_req is non-NULL iff ConnectEx() was used and has not finished, + * so we can use it as a check for ConnectEx() usage here. */ + if (sock->connect_req) + { + set_error( STATUS_INVALID_CONNECTION ); + return; + } + + if (!sock->peer_addr_len && sock->type == WS_SOCK_DGRAM) + { + set_error( STATUS_INVALID_CONNECTION ); + return; + } + + if (get_reply_max_size() < sock->peer_addr_len) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return; + } + + set_reply_data( &sock->peer_addr, sock->peer_addr_len); + return; + case IOCTL_AFD_WINE_DEFER: { const obj_handle_t *handle = get_req_data();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=135313
Your paranoid android.
=== debian11b (64 bit WoW report) ===
d3d11: d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 0.500000, clamp 0.000000: Got depth 4.99374978e-003, expected 4.99999989e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 0.500000, clamp -0.000010: Got depth 4.99374978e-003, expected 4.99999989e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 0.500000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1.000000, clamp 0.000000: Got depth 7.48750009e-003, expected 7.49999983e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1.000000, clamp -0.000010: Got depth 7.48750009e-003, expected 7.49999983e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 2.000000, clamp 0.000000: Got depth 1.24749998e-002, expected 1.24999997e-002. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 2.000000, clamp -0.000010: Got depth 1.24749998e-002, expected 1.24999997e-002. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 2.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 128.000000, clamp 0.000000: Got depth 6.40899956e-001, expected 6.42499986e-001. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 128.000000, clamp -0.000010: Got depth 6.40899956e-001, expected 6.42499986e-001. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 128.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 1000.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28634: Test failed: Format 0x28: slope 1.000000: scale 10000.000000, clamp 0.000010: Got depth 2.50997487e-003, expected 2.50999994e-003. d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 0.500000, clamp 0.000000: Got value 0x14745 (4.99373721e-003), expected 0x147ae (4.99999570e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 0.500000, clamp -0.000010: Got value 0x14745 (4.99373721e-003), expected 0x147ae (4.99999570e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 0.500000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1.000000, clamp 0.000000: Got value 0x1eab3 (7.48747634e-003), expected 0x1eb85 (7.49999331e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1.000000, clamp -0.000010: Got value 0x1eab3 (7.48747634e-003), expected 0x1eb85 (7.49999331e-003). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 2.000000, clamp 0.000000: Got value 0x33190 (1.24750147e-002), expected 0x33333 (1.24999890e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 2.000000, clamp -0.000010: Got value 0x33190 (1.24750147e-002), expected 0x33333 (1.24999890e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 2.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 128.000000, clamp 0.000000: Got value 0xa41204 (6.40899956e-001), expected 0xa47ae0 (6.42499983e-001). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 128.000000, clamp -0.000010: Got value 0xa41204 (6.40899956e-001), expected 0xa47ae0 (6.42499983e-001). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 128.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 1000.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28643: Test failed: Format 0x2d: slope 1.000000: scale 10000.000000, clamp 0.000010: Got value 0x8528f (3.25097479e-002), expected 0x85293 (3.25099863e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 0.500000, clamp 0.000000: Got value 0x28e (9.97940078e-003), expected 0x290 (1.00099184e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 0.500000, clamp -0.000010: Got value 0x28e (9.97940078e-003), expected 0x290 (1.00099184e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 1.000000, clamp 0.000000: Got value 0x331 (1.24666207e-002), expected 0x334 (1.25123980e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 1.000000, clamp -0.000010: Got value 0x331 (1.24666207e-002), expected 0x334 (1.25123980e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 2.000000, clamp 0.000000: Got value 0x476 (1.74258035e-002), expected 0x47b (1.75020974e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 2.000000, clamp -0.000010: Got value 0x476 (1.74258035e-002), expected 0x47b (1.75020974e-002). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 128.000000, clamp 0.000000: Got value 0xa411 (6.40894175e-001), expected 0xa47a (6.42496347e-001). d3d11.c:28651: Test failed: Format 0x37: slope 1.000000: scale 128.000000, clamp -0.000010: Got value 0xa411 (6.40894175e-001), expected 0xa47a (6.42496347e-001).