7026376: (dc) DatagramChannel created without specifying protocol family fails to join IPv4 group
Reviewed-by: chegar
This commit is contained in:
parent
b96d0e610a
commit
4b0829340e
@ -95,6 +95,8 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_ch_NativeThread_current;
|
||||
Java_sun_nio_ch_NativeThread_init;
|
||||
Java_sun_nio_ch_NativeThread_signal;
|
||||
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0;
|
||||
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0;
|
||||
Java_sun_nio_ch_Net_socket0;
|
||||
Java_sun_nio_ch_Net_bind0;
|
||||
Java_sun_nio_ch_Net_connect0;
|
||||
|
@ -82,6 +82,8 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_ch_NativeThread_current;
|
||||
Java_sun_nio_ch_NativeThread_init;
|
||||
Java_sun_nio_ch_NativeThread_signal;
|
||||
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0;
|
||||
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0;
|
||||
Java_sun_nio_ch_Net_socket0;
|
||||
Java_sun_nio_ch_Net_bind0;
|
||||
Java_sun_nio_ch_Net_connect0;
|
||||
|
@ -755,11 +755,14 @@ class DatagramChannelImpl
|
||||
throw new IllegalArgumentException("Group not a multicast address");
|
||||
|
||||
// check multicast address is compatible with this socket
|
||||
if (!(group instanceof Inet4Address)) {
|
||||
if (family == StandardProtocolFamily.INET)
|
||||
throw new IllegalArgumentException("Group is not IPv4 address");
|
||||
if (!(group instanceof Inet6Address))
|
||||
throw new IllegalArgumentException("Address type not supported");
|
||||
if (group instanceof Inet4Address) {
|
||||
if (family == StandardProtocolFamily.INET6 && !Net.canIPv6SocketJoinIPv4Group())
|
||||
throw new IllegalArgumentException("Group is not IPv4 multicast address");
|
||||
} else if (group instanceof Inet6Address) {
|
||||
if (family != StandardProtocolFamily.INET6)
|
||||
throw new IllegalArgumentException("Group is not IPv6 multicast address");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Address type not supported");
|
||||
}
|
||||
|
||||
// check source address
|
||||
@ -791,7 +794,9 @@ class DatagramChannelImpl
|
||||
}
|
||||
|
||||
MembershipKeyImpl key;
|
||||
if (family == StandardProtocolFamily.INET6) {
|
||||
if ((family == StandardProtocolFamily.INET6) &&
|
||||
((group instanceof Inet6Address) || Net.canJoin6WithIPv4Group()))
|
||||
{
|
||||
int index = interf.getIndex();
|
||||
if (index == -1)
|
||||
throw new IOException("Network interface cannot be identified");
|
||||
@ -861,7 +866,7 @@ class DatagramChannelImpl
|
||||
return;
|
||||
|
||||
try {
|
||||
if (family == StandardProtocolFamily.INET6) {
|
||||
if (key instanceof MembershipKeyImpl.Type6) {
|
||||
MembershipKeyImpl.Type6 key6 =
|
||||
(MembershipKeyImpl.Type6)key;
|
||||
Net.drop6(fd, key6.groupAddress(), key6.index(), key6.source());
|
||||
@ -901,7 +906,7 @@ class DatagramChannelImpl
|
||||
throw new IllegalArgumentException("Source address is different type to group");
|
||||
|
||||
int n;
|
||||
if (family == StandardProtocolFamily.INET6) {
|
||||
if (key instanceof MembershipKeyImpl.Type6) {
|
||||
MembershipKeyImpl.Type6 key6 =
|
||||
(MembershipKeyImpl.Type6)key;
|
||||
n = Net.block6(fd, key6.groupAddress(), key6.index(),
|
||||
@ -931,7 +936,7 @@ class DatagramChannelImpl
|
||||
throw new IllegalStateException("key is no longer valid");
|
||||
|
||||
try {
|
||||
if (family == StandardProtocolFamily.INET6) {
|
||||
if (key instanceof MembershipKeyImpl.Type6) {
|
||||
MembershipKeyImpl.Type6 key6 =
|
||||
(MembershipKeyImpl.Type6)key;
|
||||
Net.unblock6(fd, key6.groupAddress(), key6.index(),
|
||||
|
@ -60,6 +60,21 @@ class Net { // package-private
|
||||
return isIPv6Available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether IPv6 sockets can join IPv4 multicast groups
|
||||
*/
|
||||
static boolean canIPv6SocketJoinIPv4Group() {
|
||||
return canIPv6SocketJoinIPv4Group0();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether {@link #join6} can be used to join an IPv4
|
||||
* multicast group (IPv4 group as IPv4-mapped IPv6 address)
|
||||
*/
|
||||
static boolean canJoin6WithIPv4Group() {
|
||||
return canJoin6WithIPv4Group0();
|
||||
}
|
||||
|
||||
static InetSocketAddress checkAddress(SocketAddress sa) {
|
||||
if (sa == null)
|
||||
throw new NullPointerException();
|
||||
@ -291,7 +306,11 @@ class Net { // package-private
|
||||
|
||||
// -- Socket operations --
|
||||
|
||||
static native boolean isIPv6Available0();
|
||||
private static native boolean isIPv6Available0();
|
||||
|
||||
private static native boolean canIPv6SocketJoinIPv4Group0();
|
||||
|
||||
private static native boolean canJoin6WithIPv4Group0();
|
||||
|
||||
static FileDescriptor socket(boolean stream) {
|
||||
return socket(UNSPEC, stream);
|
||||
|
@ -154,6 +154,22 @@ Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
|
||||
return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
#ifdef __solaris__
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL
|
||||
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
|
||||
jboolean stream, jboolean reuse)
|
||||
|
@ -100,6 +100,18 @@ Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
|
||||
{
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
|
||||
jboolean stream, jboolean reuse)
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4527345
|
||||
* @bug 4527345 7026376
|
||||
* @summary Unit test for DatagramChannel's multicast support
|
||||
* @build MulticastSendReceiveTests NetworkConfiguration
|
||||
* @run main MulticastSendReceiveTests
|
||||
@ -31,12 +31,19 @@
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.*;
|
||||
import java.net.*;
|
||||
import static java.net.StandardProtocolFamily.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MulticastSendReceiveTests {
|
||||
|
||||
static Random rand = new Random();
|
||||
static final Random rand = new Random();
|
||||
|
||||
static final ProtocolFamily UNSPEC = new ProtocolFamily() {
|
||||
public String name() {
|
||||
return "UNSPEC";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Send datagram from given local address to given multicast
|
||||
@ -130,75 +137,84 @@ public class MulticastSendReceiveTests {
|
||||
/**
|
||||
* Exercise multicast send/receive on given group/interface
|
||||
*/
|
||||
static void test(NetworkInterface nif, InetAddress group, InetAddress source)
|
||||
static void test(ProtocolFamily family,
|
||||
NetworkInterface nif,
|
||||
InetAddress group,
|
||||
InetAddress source)
|
||||
throws IOException
|
||||
{
|
||||
ProtocolFamily family = (group instanceof Inet6Address) ?
|
||||
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
|
||||
System.out.format("create channel to %s socket\n", family.name());
|
||||
DatagramChannel dc = DatagramChannel.open(family)
|
||||
.setOption(StandardSocketOption.SO_REUSEADDR, true)
|
||||
.bind(new InetSocketAddress(0));
|
||||
System.out.format("\nTest DatagramChannel to %s socket\n", family.name());
|
||||
try (DatagramChannel dc = (family == UNSPEC) ?
|
||||
DatagramChannel.open() : DatagramChannel.open(family)) {
|
||||
dc.setOption(StandardSocketOption.SO_REUSEADDR, true)
|
||||
.bind(new InetSocketAddress(0));
|
||||
|
||||
// join group
|
||||
System.out.format("join %s @ %s\n", group.getHostAddress(),
|
||||
nif.getName());
|
||||
MembershipKey key = dc.join(group, nif);
|
||||
// join group
|
||||
System.out.format("join %s @ %s\n", group.getHostAddress(),
|
||||
nif.getName());
|
||||
MembershipKey key;
|
||||
try {
|
||||
key = dc.join(group, nif);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (family == UNSPEC) {
|
||||
System.out.println("Not supported");
|
||||
return;
|
||||
}
|
||||
throw iae;
|
||||
}
|
||||
|
||||
// send message to group
|
||||
int port = ((InetSocketAddress)dc.getLocalAddress()).getPort();
|
||||
int id = sendDatagram(source, nif, group, port);
|
||||
// send message to group
|
||||
int port = ((InetSocketAddress)dc.getLocalAddress()).getPort();
|
||||
int id = sendDatagram(source, nif, group, port);
|
||||
|
||||
// receive message and check id matches
|
||||
receiveDatagram(dc, source, id);
|
||||
|
||||
// exclude-mode filtering
|
||||
|
||||
try {
|
||||
System.out.format("block %s\n", source.getHostAddress());
|
||||
|
||||
// may throw UOE
|
||||
key.block(source);
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, null, id);
|
||||
|
||||
// unblock source, send message, message should be received
|
||||
System.out.format("unblock %s\n", source.getHostAddress());
|
||||
key.unblock(source);
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
// receive message and check id matches
|
||||
receiveDatagram(dc, source, id);
|
||||
} catch (UnsupportedOperationException x) {
|
||||
System.out.println("Exclude-mode filtering not supported!");
|
||||
}
|
||||
|
||||
key.drop();
|
||||
// exclude-mode filtering
|
||||
|
||||
// include-mode filtering
|
||||
try {
|
||||
System.out.format("block %s\n", source.getHostAddress());
|
||||
|
||||
InetAddress bogus = (group instanceof Inet6Address) ?
|
||||
InetAddress.getByName("fe80::1234") :
|
||||
InetAddress.getByName("1.2.3.4");
|
||||
System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(),
|
||||
nif.getName(), bogus.getHostAddress());
|
||||
try {
|
||||
// may throw UOE
|
||||
key = dc.join(group, nif, bogus);
|
||||
// may throw UOE
|
||||
key.block(source);
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, null, id);
|
||||
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, null, id);
|
||||
// unblock source, send message, message should be received
|
||||
System.out.format("unblock %s\n", source.getHostAddress());
|
||||
key.unblock(source);
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, source, id);
|
||||
} catch (UnsupportedOperationException x) {
|
||||
System.out.println("Exclude-mode filtering not supported!");
|
||||
}
|
||||
|
||||
key.drop();
|
||||
|
||||
// include-mode filtering
|
||||
|
||||
InetAddress bogus = (group instanceof Inet6Address) ?
|
||||
InetAddress.getByName("fe80::1234") :
|
||||
InetAddress.getByName("1.2.3.4");
|
||||
System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(),
|
||||
nif.getName(), source.getHostAddress());
|
||||
key = dc.join(group, nif, source);
|
||||
nif.getName(), bogus.getHostAddress());
|
||||
try {
|
||||
// may throw UOE
|
||||
key = dc.join(group, nif, bogus);
|
||||
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, source, id);
|
||||
} catch (UnsupportedOperationException x) {
|
||||
System.out.println("Include-mode filtering not supported!");
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, null, id);
|
||||
|
||||
System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(),
|
||||
nif.getName(), source.getHostAddress());
|
||||
key = dc.join(group, nif, source);
|
||||
|
||||
id = sendDatagram(source, nif, group, port);
|
||||
receiveDatagram(dc, source, id);
|
||||
} catch (UnsupportedOperationException x) {
|
||||
System.out.println("Include-mode filtering not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
dc.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
@ -210,12 +226,14 @@ public class MulticastSendReceiveTests {
|
||||
|
||||
for (NetworkInterface nif: config.ip4Interfaces()) {
|
||||
InetAddress source = config.ip4Addresses(nif).iterator().next();
|
||||
test(nif, ip4Group, source);
|
||||
test(INET, nif, ip4Group, source);
|
||||
test(UNSPEC, nif, ip4Group, source);
|
||||
}
|
||||
|
||||
for (NetworkInterface nif: config.ip6Interfaces()) {
|
||||
InetAddress source = config.ip6Addresses(nif).iterator().next();
|
||||
test(nif, ip6Group, source);
|
||||
test(INET6, nif, ip6Group, source);
|
||||
test(UNSPEC, nif, ip6Group, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user