battleblow / openjdk-jdk11u

BSD port of OpenJDK 11
GNU General Public License v2.0
9 stars 8 forks source link

Multicast source blocking doesn't work on FreeBSD #73

Closed battleblow closed 5 years ago

battleblow commented 5 years ago

The follow JDK test fails on FreeBSD:

jdk/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java

The test fails because it is able to receive a datagram sent from a blocked source. The test output reflects this:

join 225.4.5.6 @ wlan0
Send message from 172.16.0.1 -> group 225.4.5.6 (id=0x22c33d62)
Waiting to receive message
Received message from /172.16.0.1 (id=0x22c33d62)
Message expected
block 172.16.0.1
Send message from 172.16.0.1 -> group 225.4.5.6 (id=0x63c7dc9f)
Waiting to receive message
Received message from /172.16.0.1 (id=0x63c7dc9f)

At this point the test throws an exception since the last message shouldn't have been able to be received since the source was blocked.

The test passes on OpenBSD because it doesn't support this functionality. This is legitimate. The test itself notes that it only expects this functionality available on Solaris and Linux (IIRC) and is ok with other platforms throwing UnsupportedOperationException.

However, this functionality, according to ip(4), has been supported on FreeBSD since FreeBSD 8.x and should work.

battleblow commented 5 years ago

Note that based on this, we could modify the code to not support blocking for FreeBSD and pass the test. It would be preferable to get it working though.

battleblow commented 5 years ago

The test passes on Linux with the correct behaviour.

battleblow commented 5 years ago

I've got a slightly cut down version (I could cut it down further tbh) and from truss I see the following calls occuring:

setsockopt(4,IPPROTO_IP,IP_BLOCK_SOURCE,0x7fffdfffd4f0,12) = 0 (0x0)
socket(PF_INET,SOCK_DGRAM,0) = 5 (0x5)
getsockname(5,{ AF_INET 172.16.0.1:27161 },0x7fffdfffd4d4) = 0 (0x0)
getsockname(5,{ AF_INET 172.16.0.1:27161 },0x7fffdfffd4c4) = 0 (0x0)
setsockopt(5,IPPROTO_IP,IP_MULTICAST_IF,0x7fffdfffd5a0,4) = 0 (0x0)
sendto(5,"-2013921054",11,0,{ AF_INET 225.4.5.6:13534 },16) = 11 (0xb)
recvfrom(4,"-2013921054",100,0,{ AF_INET 172.16.0.1:27161 },0x7fffdfffd3d0) = 11 (0xb)

That first call should institute the block. The others are to send and receive the message. I have some other debugging that confirms the structure passed to the initial setsockopt call has the correct source address in it.

battleblow commented 5 years ago

Created a C program to demonstrate this and a PR against FreeBSD.

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=240137

I'm going to disable blocking on *BSD until we get some traction there.

battleblow commented 5 years ago

Closing this for now as it has been disabled (so will now throw an UnsupportedOperationException rather than silently not working). If the upstream PR gets some attention and the feature is fixed on FreeBSD then we can revisit this.