Fixes SpellForce 3: Versus Edition connection to multiplayer.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/unix/socket.c | 8 ++++++++ dlls/ws2_32/tests/sock.c | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 53292246648..05cbaf9aaaa 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -983,6 +983,14 @@ static NTSTATUS try_send( int fd, struct async_send_ioctl *async ) ERR( "failed to convert address\n" ); return STATUS_ACCESS_VIOLATION; } + if (sock_type == SOCK_DGRAM && ((unix_addr.addr.sa_family == AF_INET && !unix_addr.in.sin_port) + || (unix_addr.addr.sa_family == AF_INET6 && !unix_addr.in6.sin6_port))) + { + /* Sending to port 0 succeeds on Windows. Use 'discard' service instead so sendmsg() works on Unix + * while still goes through other parameters validation. */ + WARN( "Trying to use destination port 0, substituing 9.\n" ); + unix_addr.in.sin_port = htons( 9 ); + }
#if defined(HAS_IPX) && defined(SOL_IPX) if (async->addr->sa_family == WS_AF_IPX) diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 0015aae67a5..437ee813611 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -3187,6 +3187,7 @@ static void test_UDP(void) struct sock_info peer[NUM_UDP_PEERS]; char buf[16], sockaddr_buf[1024]; int ss, i, n_recv, n_sent, ret; + struct sockaddr_in6 addr6; struct sockaddr_in addr; int sock; struct send_udp_thread_param udp_thread_param; @@ -3298,6 +3299,26 @@ static void test_UDP(void) CloseHandle( udp_thread_param.start_event );
closesocket(sock); + + /* Test sending to port 0. */ + sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + ok( sock != INVALID_SOCKET, "got error %u.\n", WSAGetLastError() ); + memset( &addr, 0, sizeof(addr) ); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr( "127.0.0.1" ); + ret = sendto( sock, buf, sizeof(buf), 0, (struct sockaddr *)&addr, sizeof(addr) ); + ok( ret == sizeof(buf), "got ret %d, error %u.\n", ret, WSAGetLastError() ); + closesocket(sock); + + sock = socket( AF_INET6, SOCK_DGRAM, 0 ); + ok( sock != INVALID_SOCKET, "got error %u.\n", WSAGetLastError() ); + memset( &addr6, 0, sizeof(addr6) ); + addr6.sin6_family = AF_INET6; + ret = inet_pton( AF_INET6, "::1", &addr6.sin6_addr ); + ok( ret, "got error %u.\n", WSAGetLastError() ); + ret = sendto( sock, buf, sizeof(buf), 0, (struct sockaddr *)&addr6, sizeof(addr6) ); + ok( ret == sizeof(buf), "got ret %d, error %u.\n", ret, WSAGetLastError() ); + closesocket(sock); }
static void test_WSASocket(void)
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=148246
Your paranoid android.
=== w8 (32 bit report) ===
ws2_32: sock.c:770: Test failed: oob_client (458): connect error: 10060 sock.c:314: Test failed: do_synchronous_send (458): error 10057 sock.c:777: Test failed: oob_client (458): sent less data than expected: 0 of 2048 sock.c:327: Test failed: do_synchronous_recv (458): error 10057: sock.c:782: Test failed: simple_client (458): received less data than expected: 0 of 2048 sock.c:785: Test failed: simple_client (458): test pattern error: 0 sock.c:314: Test failed: do_synchronous_send (458): error 10057 sock.c:789: Test failed: oob_client (458): sent less data than expected: 0 of 2048 sock.c:793: Test failed: simple_client (458): shutdown failed: 10057 sock.c:1162: Test failed: wait failed, error 258 sock.c:374: Test failed: failed to bind: 10048 sock.c:475: Test failed: simple_server (f24): listen failed: 10022 sock.c:484: Test failed: simple_server (f24): accept failed: 10022 sock.c:486: Test failed: simple_server (f24): strange peer address sock.c:327: Test failed: do_synchronous_recv (f24): error 10038: sock.c:491: Test failed: simple_server (f24): received less data than expected: 0 of 32768 sock.c:494: Test failed: simple_server (f24): test pattern error: 0 sock.c:314: Test failed: do_synchronous_send (f24): error 10038 sock.c:498: Test failed: simple_server (f24): sent less data than expected: 0 of 32768 sock.c:503: Test failed: simple_server (f24): closesocket error: 10038 sock.c:484: Test failed: simple_server (f24): accept failed: 10022 sock.c:486: Test failed: simple_server (f24): strange peer address sock.c:327: Test failed: do_synchronous_recv (f24): error 10038: sock.c:491: Test failed: simple_server (f24): received less data than expected: 0 of 32768 sock.c:494: Test failed: simple_server (f24): test pattern error: 0 sock.c:314: Test failed: do_synchronous_send (f24): error 10038 sock.c:498: Test failed: simple_server (f24): sent less data than expected: 0 of 32768 sock.c:503: Test failed: simple_server (f24): closesocket error: 10038 sock.c:547: Test failed: oob_server (f1c): test pattern error: 0 sock.c:570: Test failed: oob_server (f1c): not at the OOB mark: 1 sock.c:314: Test failed: do_synchronous_send (ee0): error 10053 sock.c:828: Test failed: simple_client (ee0): sent less data than expected: 4224 of 32768 sock.c:340: Test failed: do_synchronous_recv (ee0): error 10053: sock.c:842: Test failed: simple_client (ee0): received less data than expected: 0 of 32768 sock.c:853: Test failed: simple_client (ee0): test pattern error: 0 sock.c:821: Test failed: simple_client (d64): connect error: 10061 sock.c:314: Test failed: do_synchronous_send (d64): error 10057 sock.c:828: Test failed: simple_client (d64): sent less data than expected: 0 of 32768 sock.c:832: Test failed: simple_client (d64): shutdown failed: 10057 sock.c:340: Test failed: do_synchronous_recv (d64): error 10057: sock.c:842: Test failed: simple_client (d64): received less data than expected: 0 of 32768 sock.c:853: Test failed: simple_client (d64): test pattern error: 0 sock: Timeout
=== w1064_2qxl (64 bit report) ===
ws2_32: sock.c:13198: Test failed: wait timed out sock.c:13062: Test failed: got size 5 sock.c:13063: Test failed: got "datad" sock.c:13062: Test failed: got size 3 sock.c:13063: Test failed: got "ata"
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000033400F4, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
FWIW, !2100 does something similar without the actual network traffic.
Well, yes, this is unfortunate that the patch from there fell through the cracks. While I personally don't feel strong against that approach, I think avoid any further handling and just faking success is not ideal, the fact the port is 0 doesn't mean that there are no other potential errors if trying to send that, especially if that is sendmsg() and not sendto(). Also this variant is probably a tiny bit simpler.
Just to note, Windows doesn't fake success, it does indeed sends packets to port 0, either to loopback or real network. While we probably can't sanely implement that.
This merge request was approved by Elizabeth Figura.
FWIW, !2100 does something similar without the actual network traffic.
Yes, that's probably on me for dropping that patch on the floor, sorry. I do think this is slightly better, though.