https://bugs.winehq.org/show_bug.cgi?id=50499
Bug ID: 50499 Summary: SO_REUSEADDR compatibility problems Product: Wine Version: 6.0-rc6 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: James@superbug.co.uk Distribution: ---
The use case I am struggling with is the use of a Windows program running in wine that is sending and receiving UDP packets. This particular windows program uses SO_REUSEADDR socket option and opens two sockets. Lets call the first one socket A, and the second one Socket B.
The SO_REUSEADDR from the Windows application is translated by "wine" into a SO_REUSEADDR in Linux. Unfortunately the behaviour of these is different between Windows and Linux so the Windows application fails to run on Linux under wine. 1 ) On windows: All received unicast UDP packets will arrive on the first opened socket. Thus on socket A. 2) On Linux: All received unicast UDP packets will arrive on the last opened socket. Thus on socket B.
The problem is that this windows program only expects to receive unicast UDP packets on socket A, and thus it sees no packets.
There are no currently existing socket options in Linux that would permit wine to simulate the Windows behaviour. And thus, the reason I am asking the question here. Please can we add an extra socket option to the Linux socket options such that we can get wine to simulate Windows correctly. I.e. behave like (1) above. Now wine is pretty good at simulating most things Windows throws at it, but socket options is not one of them yet. Also note, that (1) is actually more secure than (2) because it prevents other applications with the same UserID from hijacking the socket. Although (2) is more helpful in more gracefully handling some error edge cases.
Suggested new option name: SO_REUSEADDR_WS
https://bugs.winehq.org/show_bug.cgi?id=50499
--- Comment #1 from James James@superbug.co.uk --- Test case for this: https://github.com/jcdutton/wine-testing
Run ./compile.sh to compile them. There is udpclient and udpserver program. The udpclient sends packets, but one can use "nc -u ip-address port" just instead of the client. The "udpserver" linux executable shows the behavior on Linux. The "udpserver.exe" windows executable shows the behavior on Wine and native Windows.
The aim is to get the output the same on both Windows and Wine, but currently it does not.
https://bugs.winehq.org/show_bug.cgi?id=50499
--- Comment #2 from James James@superbug.co.uk --- Fixing this bug, might also fix https://bugs.winehq.org/show_bug.cgi?id=33008
https://bugs.winehq.org/show_bug.cgi?id=50499
James James@superbug.co.uk changed:
What |Removed |Added ---------------------------------------------------------------------------- Blocks| |33008
https://bugs.winehq.org/show_bug.cgi?id=50499
James James@superbug.co.uk changed:
What |Removed |Added ---------------------------------------------------------------------------- Blocks| |26031
https://bugs.winehq.org/show_bug.cgi?id=50499
Erich E. Hoover erich.e.hoover@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |erich.e.hoover@gmail.com
--- Comment #3 from Erich E. Hoover erich.e.hoover@gmail.com --- Didn't the kernel add a couple options to allow you to manage this behavior (SO_ATTACH_REUSEPORT_CBPF and SO_ATTACH_REUSEPORT_EBPF)?
https://bugs.winehq.org/show_bug.cgi?id=50499
--- Comment #4 from James James@superbug.co.uk --- So, if wine transposed the SO_REUSEADDR to a SO_REUSEPORT together with a SO_ATTACH_REUSEPORT_CBPF that had a bpf that returns zero. It might actually work.
https://bugs.winehq.org/show_bug.cgi?id=50499
--- Comment #5 from Erich E. Hoover erich.e.hoover@gmail.com --- (In reply to James from comment #4)
So, if wine transposed the SO_REUSEADDR to a SO_REUSEPORT together with a SO_ATTACH_REUSEPORT_CBPF that had a bpf that returns zero. It might actually work.
That is my understanding of how that option works, though I have not tested it myself. Because the filter is so easy it shouldn't be too hard to test it. The code related to that other bug has been moved into the server now, but it gives a good example of how to make a much more complicated filter: https://source.winehq.org/source/server/sock.c#1726
https://bugs.winehq.org/show_bug.cgi?id=50499
--- Comment #6 from James James@superbug.co.uk --- I have tested it, and SO_ATTACH_REUSEPORT_CBPF works. One can get Linux to behave like Windows on receipt of UDP packets.
See "udpbftserver.c" from here: https://github.com/jcdutton/wine-testing
https://bugs.winehq.org/show_bug.cgi?id=50499
--- Comment #7 from Erich E. Hoover erich.e.hoover@gmail.com --- (In reply to James from comment #6)
I have tested it, and SO_ATTACH_REUSEPORT_CBPF works. One can get Linux to behave like Windows on receipt of UDP packets.
See "udpbftserver.c" from here: https://github.com/jcdutton/wine-testing
Wonderful, that's excellent news! Have you ever put together a test case for wine before? (This should probably be two patches: one with a test case and another that fixes the problem)