Hi Daniel, looks like an interesting saga … will give that twirl on my dinky laptop
wrt why MulticastSocket sets SO_REUSEADDR I reckon Chris or Alan are the authority on that. Conjecture would be that typically multicast scenarios require multiple processes receiving on the same address and port, with the prescribed idiom being wildcard IP address+ defined port. Thus, requiring the SO_REUSEADDR for multi instances on the same host, and it was done as a de facto convenience. The wildcard IP address idiom is somewhat perverse for multicast, and seems to be rooted in restrictive multicast support available on Windows. Although, Michael McM did say Solaris exhibits restrictive behaviour also, inhibiting the binding to a multicast address. regards Mark ________________________________ From: Daniel Fuchs <daniel.fu...@oracle.com> Sent: Monday 30 September 2019 16:47 To: mark sheppard <macanao...@hotmail.com>; OpenJDK Network Dev list <net-dev@openjdk.java.net> Subject: Re: (teststabilization) RFR: 8231506: Fix some instabilities in a few networking tests Hi Mark, On 30/09/2019 13:37, Daniel Fuchs wrote: > On 30/09/2019 12:56, mark sheppard wrote: >> the first uses the InetSocketAddress allocated and then the second >> uses the same address, without bind exception because of >> the SO_REUSEADDR option being set, even if the close had not >> completed at that time. > > No. The second doesn't use the address. I agree that it might - if > e.g. the system has run out of ephemeral ports, but I believe it's > highly unlikely. I take it back. One of my test run exhibited this exact behavior: The client's MulticastSocket was bound to the exact same address than the server's MulticastSocket - and of course the test failed (see below). Then I played with that a bit by forcing the client to bind to the same address than the server. On my machine, I could observe that only the last bound socket received any traffic. There seemed no way to make the server receive anything from the client in that configuration. So I revised the test logic: I added a Phaser to make sure the client and server advanced in phase, and I also added a loop to force the client to bind to a different address (actually a different port) than the server if binding to the ephemeral port returns the same port than the server. (I could test that by forcing the first bind to use the server port instead of port 0). So here is now my new webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8231506/webrev.02/index.html Only changes compared to webrev.01 are in UnreferencedMulticastSockets. By any chance, do you remember why MulticastSocket sets SO_REUSEADDR ? best regards, -- daniel ===================================================================== DatagramServer addr: localhost/127.0.0.1: 48429 serverMulticastSocket:: fd: java.io.FileDescriptor@65dd3755, fd: 5, cleanup: java.net.SocketCleanable@4ba89eb socketImplClass: class java.net.PlainDatagramSocketImpl socketImpl class name not matched: java.net.PlainDatagramSocketImpl != java.net.TwoStacksPlainDatagramSocketImpl client bound port: 48429 clientMulticastSocket:: fd: java.io.FileDescriptor@179da90c, fd: 9, cleanup: java.net.SocketCleanable@725335c5 socketImplClass: class java.net.PlainDatagramSocketImpl socketImpl class name not matched: java.net.PlainDatagramSocketImpl != java.net.TwoStacksPlainDatagramSocketImpl ping sent to: localhost/127.0.0.1:48429 echo received from: /127.0.0.1:48429 ----------System.err:(13/908)---------- java.lang.AssertionError: incorrect data received: expected: 2, actual: 1 at UnreferencedMulticastSockets.main(UnreferencedMulticastSockets.java:151) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127) at java.base/java.lang.Thread.run(Thread.java:830)