diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractDatagramTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractDatagramTest.java index 003b786846..2076358120 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractDatagramTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractDatagramTest.java @@ -35,7 +35,7 @@ public abstract class AbstractDatagramTest extends AbstractComboTestsuiteTest> newFactories() { - return SocketTestPermutation.INSTANCE.datagram(internetProtocolFamily()); + return SocketTestPermutation.INSTANCE.datagram(socketInternetProtocalFamily()); } @Override @@ -45,7 +45,7 @@ public abstract class AbstractDatagramTest extends AbstractComboTestsuiteTest> newFactories() { - return SocketTestPermutation.INSTANCE.datagram(internetProtocolFamily()); + return SocketTestPermutation.INSTANCE.datagram(socketInternetProtocalFamily()); } private InetSocketAddress newAnySocketAddress() throws UnknownHostException { - switch (internetProtocolFamily()) { + switch (socketInternetProtocalFamily()) { case IPv4: return new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0); case IPv6: @@ -182,7 +182,7 @@ public class DatagramMulticastTest extends AbstractDatagramTest { Enumeration addresses = iface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = addresses.nextElement(); - if (internetProtocolFamily().addressType().isAssignableFrom(address.getClass())) { + if (socketInternetProtocalFamily().addressType().isAssignableFrom(address.getClass())) { return new InetSocketAddress(address, 0); } } @@ -197,13 +197,13 @@ public class DatagramMulticastTest extends AbstractDatagramTest { Enumeration addresses = iface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = addresses.nextElement(); - if (internetProtocolFamily().addressType().isAssignableFrom(address.getClass())) { + if (socketInternetProtocalFamily().addressType().isAssignableFrom(address.getClass())) { MulticastSocket socket = new MulticastSocket(newAnySocketAddress()); socket.setReuseAddress(true); socket.setNetworkInterface(iface); try { socket.send(new java.net.DatagramPacket(new byte[] { 1, 2, 3, 4 }, 4, - new InetSocketAddress(groupAddress(), 12345))); + new InetSocketAddress(groupAddress(), 12345))); return iface; } catch (IOException ignore) { // Try the next interface @@ -218,7 +218,7 @@ public class DatagramMulticastTest extends AbstractDatagramTest { } private String groupAddress() { - return internetProtocolFamily() == InternetProtocolFamily.IPv4 ? + return groupInternetProtocalFamily() == InternetProtocolFamily.IPv4? "230.0.0.1" : "FF01:0:0:0:0:0:0:101"; } } diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/LinuxSocket.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/LinuxSocket.java index 62283fb5dc..4296d79898 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/LinuxSocket.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/LinuxSocket.java @@ -117,11 +117,14 @@ final class LinuxSocket extends Socket { final boolean isIpv6 = group instanceof Inet6Address; final NativeInetAddress i = NativeInetAddress.newInstance(deriveInetAddress(netInterface, isIpv6)); if (source != null) { + if (source.getClass() != group.getClass()) { + throw new IllegalArgumentException("Source address is different type to group"); + } final NativeInetAddress s = NativeInetAddress.newInstance(source); - joinSsmGroup(intValue(), ipv6, g.address(), i.address(), + joinSsmGroup(intValue(), ipv6 && isIpv6, g.address(), i.address(), g.scopeId(), interfaceIndex(netInterface), s.address()); } else { - joinGroup(intValue(), ipv6, g.address(), i.address(), g.scopeId(), interfaceIndex(netInterface)); + joinGroup(intValue(), ipv6 && isIpv6, g.address(), i.address(), g.scopeId(), interfaceIndex(netInterface)); } } @@ -130,11 +133,14 @@ final class LinuxSocket extends Socket { final boolean isIpv6 = group instanceof Inet6Address; final NativeInetAddress i = NativeInetAddress.newInstance(deriveInetAddress(netInterface, isIpv6)); if (source != null) { + if (source.getClass() != group.getClass()) { + throw new IllegalArgumentException("Source address is different type to group"); + } final NativeInetAddress s = NativeInetAddress.newInstance(source); - leaveSsmGroup(intValue(), ipv6, g.address(), i.address(), + leaveSsmGroup(intValue(), ipv6 && isIpv6, g.address(), i.address(), g.scopeId(), interfaceIndex(netInterface), s.address()); } else { - leaveGroup(intValue(), ipv6, g.address(), i.address(), g.scopeId(), interfaceIndex(netInterface)); + leaveGroup(intValue(), ipv6 && isIpv6, g.address(), i.address(), g.scopeId(), interfaceIndex(netInterface)); } } diff --git a/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollDatagramMulticastIpv6WithIpv4AddrTest.java b/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollDatagramMulticastIpv6WithIpv4AddrTest.java new file mode 100644 index 0000000000..ef77fa3490 --- /dev/null +++ b/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollDatagramMulticastIpv6WithIpv4AddrTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2021 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.channel.epoll; + +import io.netty.channel.socket.InternetProtocolFamily; +import io.netty.testsuite.transport.socket.DatagramMulticastTest; + +public class EpollDatagramMulticastIpv6WithIpv4AddrTest extends DatagramMulticastTest { + + @Override + protected InternetProtocolFamily groupInternetProtocalFamily() { + return InternetProtocolFamily.IPv4; + } + + @Override + protected InternetProtocolFamily socketInternetProtocalFamily() { + return InternetProtocolFamily.IPv6; + } +}