1aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller/* 2aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Copyright (C) 2016 The Android Open Source Project 3aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * 4aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Licensed under the Apache License, Version 2.0 (the "License"); 5aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * you may not use this file except in compliance with the License. 6aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * You may obtain a copy of the License at 7aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * 8aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * http://www.apache.org/licenses/LICENSE-2.0 9aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * 10aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Unless required by applicable law or agreed to in writing, software 11aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 12aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * See the License for the specific language governing permissions and 14aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * limitations under the License 15aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller */ 16aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 17aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerpackage libcore.java.nio.channels; 18aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 19aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport junit.framework.AssertionFailedError; 20aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport junit.framework.TestCase; 21aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.io.IOException; 22aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.Inet4Address; 23aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.Inet6Address; 24aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.InetAddress; 25aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.InetSocketAddress; 26aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.InterfaceAddress; 27aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.NetworkInterface; 28aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.SocketAddress; 29aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.SocketException; 30d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kongimport java.net.SocketTimeoutException; 31aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.net.StandardSocketOptions; 32aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.nio.ByteBuffer; 33aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.nio.channels.ClosedChannelException; 34aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.nio.channels.DatagramChannel; 35aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.nio.channels.MembershipKey; 36aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.util.ArrayList; 37aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerimport java.util.Enumeration; 38aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 39d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kongimport libcore.io.IoBridge; 40d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong 416a68248983b32c8fe6e6c330ac8e09853b4e61b1Yi Kongimport static android.system.OsConstants.POLLIN; 426a68248983b32c8fe6e6c330ac8e09853b4e61b1Yi Kong 43aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller/** 44aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Tests associated with multicast behavior of DatagramChannel. 45aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * These tests require IPv6 multicasting enabled network. 46aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller */ 47aea78555169709a2586b585e61414d9aee1d8e28Neil Fullerpublic class DatagramChannelMulticastTest extends TestCase { 48aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 49aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static InetAddress lookup(String s) { 50aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 51aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller return InetAddress.getByName(s); 52aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IOException ex) { 53aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throw new RuntimeException(ex); 54aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 55aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 56aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 57aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // These IP addresses aren't inherently "good" or "bad"; they're just used like that. 58aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // We use the "good" addresses for our actual group, and the "bad" addresses are for 59aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // a group that we won't actually set up. 60aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress GOOD_MULTICAST_IPv4 = lookup("239.255.0.1"); 61aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress BAD_MULTICAST_IPv4 = lookup("239.255.0.2"); 62aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress GOOD_MULTICAST_IPv6 = lookup("ff05::7:7"); 63aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress BAD_MULTICAST_IPv6 = lookup("ff05::7:8"); 64aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 65aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Special addresses. 66aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress WILDCARD_IPv4 = lookup("0.0.0.0"); 67aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress WILDCARD_IPv6 = lookup("::"); 68aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 69aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Arbitrary unicast addresses. Used when the value doesn't actually matter. e.g. for source 70aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // filters. 71aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress UNICAST_IPv4_1 = lookup("192.168.1.1"); 72aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress UNICAST_IPv4_2 = lookup("192.168.1.2"); 73aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress UNICAST_IPv6_1 = lookup("2001:db8::1"); 74aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static final InetAddress UNICAST_IPv6_2 = lookup("2001:db8::2"); 75aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 76d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera private NetworkInterface ipv4NetworkInterface; 77d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera private NetworkInterface ipv6NetworkInterface; 78aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private NetworkInterface loopbackInterface; 79aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 80d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera private boolean supportsMulticast; 81d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera 82aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller @Override 83aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller protected void setUp() throws Exception { 84aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // The loopback interface isn't actually useful for sending/receiving multicast messages 85aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // but it can be used as a dummy for tests where that does not matter. 86aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress()); 87aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNotNull(loopbackInterface); 88aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(loopbackInterface.isLoopback()); 89aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(loopbackInterface.supportsMulticast()); 90aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 91aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 92aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 93d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera // Determine if the device is marked to support multicast or not. If this propery is not 94d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera // set we assume the device has an interface capable of supporting multicast. 95d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera supportsMulticast = Boolean.parseBoolean( 96d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera System.getProperty("android.cts.device.multicast", "true")); 97d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 98d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 99d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 100aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 101d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera while (interfaces.hasMoreElements() 102d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera && (ipv4NetworkInterface == null || ipv6NetworkInterface == null)) { 103d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface nextInterface = interfaces.nextElement(); 104d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (willWorkForMulticast(nextInterface)) { 105d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera Enumeration<InetAddress> addresses = nextInterface.getInetAddresses(); 106d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera while (addresses.hasMoreElements()) { 107d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera final InetAddress nextAddress = addresses.nextElement(); 108d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (nextAddress instanceof Inet6Address && ipv6NetworkInterface == null) { 109d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface = nextInterface; 110d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } else if (nextAddress instanceof Inet4Address 111d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera && ipv4NetworkInterface == null) { 112d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface = nextInterface; 113aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 114aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 115aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 116aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 117d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera 118d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (ipv4NetworkInterface == null) { 119d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera fail("Test environment must have at least one network interface capable of IPv4" 120d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera + " multicast"); 121d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 122d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (ipv6NetworkInterface == null) { 123d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera fail("Test environment must have at least one network interface capable of IPv6" 124d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera + " multicast"); 125d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 126aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 127aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 128aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_open() throws IOException { 129aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = DatagramChannel.open(); 130aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 131aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Unlike MulticastSocket, DatagramChannel has SO_REUSEADDR set to false by default. 132aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(dc.getOption(StandardSocketOptions.SO_REUSEADDR)); 133aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 134aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(dc.getLocalAddress()); 135aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(dc.isOpen()); 136aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(dc.isConnected()); 137aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 138aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 139aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_bind_null() throws Exception { 140aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 141aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNotNull(dc.getLocalAddress()); 142aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(dc.isOpen()); 143aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(dc.isConnected()); 144aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 145aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 146aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 147aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.getLocalAddress(); 148aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 149aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (ClosedChannelException expected) { 150aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 151aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(dc.isOpen()); 152aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(dc.isConnected()); 153aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 154aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 155aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_afterClose() throws Exception { 156d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 157d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 158d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 159aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 160aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 161aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 162d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 163aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 164aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (ClosedChannelException expected) { 165aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 166aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 167aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 168aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_nullGroupAddress() throws Exception { 169d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 170d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 171d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 172aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 173aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 174d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(null, ipv4NetworkInterface); 175aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 176aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 177aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 178aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 179aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 180aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 181aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_nullNetworkInterface() throws Exception { 182d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 183d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 184d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 185aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 186aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 187aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.join(GOOD_MULTICAST_IPv4, null); 188aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 189aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 190aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 191aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 192aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 193aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 194aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_nonMulticastGroupAddress_IPv4() throws Exception { 195d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 196d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 197d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 198aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 199aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 200d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(UNICAST_IPv4_1, ipv4NetworkInterface); 201aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 202aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 203aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 204aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 205aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 206aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 207aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_nonMulticastGroupAddress_IPv6() throws Exception { 208d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 209d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 210d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 211aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 212aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 213d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(UNICAST_IPv6_1, ipv6NetworkInterface); 214aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 215aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 216aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 217aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 218aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 219aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 220aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_IPv4() throws Exception { 221f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinAnySource(GOOD_MULTICAST_IPv4, BAD_MULTICAST_IPv4, ipv4NetworkInterface); 222aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 223aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 224aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_IPv6() throws Exception { 225f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinAnySource(GOOD_MULTICAST_IPv6, BAD_MULTICAST_IPv6, ipv6NetworkInterface); 226aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 227aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 228f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_joinAnySource(InetAddress group, InetAddress group2, 229d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) throws Exception { 230d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 231d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 232d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 233d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera // Set up a receiver join the group on ipv4NetworkInterface 234aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel receiverChannel = createReceiverChannel(); 235aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress localAddress = (InetSocketAddress) receiverChannel.getLocalAddress(); 236d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera receiverChannel.join(group, networkInterface); 237aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 238aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg = "Hello World"; 2394f51e6cf5f53293434b1ddd69bc6bb449898ae68Lorenzo Colitti sendMulticastMessage(group, localAddress.getPort(), msg, networkInterface); 240aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 241aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // now verify that we received the data as expected 242aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer recvBuffer = ByteBuffer.allocate(100); 243aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller SocketAddress sourceAddress = receiverChannel.receive(recvBuffer); 244aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNotNull(sourceAddress); 245aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position())); 246aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 247aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // now verify that we didn't receive the second message 248aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg2 = "Hello World - Different Group"; 2494f51e6cf5f53293434b1ddd69bc6bb449898ae68Lorenzo Colitti sendMulticastMessage(group2, localAddress.getPort(), msg2, networkInterface); 250aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller recvBuffer.position(0); 251aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller SocketAddress sourceAddress2 = receiverChannel.receive(recvBuffer); 252aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(sourceAddress2); 253aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 254aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receiverChannel.close(); 255aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 256aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 257aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_processLimit() throws Exception { 258d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 259d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 260d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 261aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 262aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller for (byte i = 1; i <= 25; i++) { 263aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress groupAddress = Inet4Address.getByName("239.255.0." + i); 264aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 265d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(groupAddress, ipv4NetworkInterface); 266aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (SocketException e) { 267aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // There is a limit, that's ok according to the RI docs. For this test a lower bound of 20 268aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // is used, which appears to be the default linux limit. 269aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // See /proc/sys/net/ipv4/igmp_max_memberships 270aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(i > 20); 271aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller break; 272aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 273aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 274aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 275aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 276aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 277aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 278aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_blockLimit() throws Exception { 279d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 280d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 281d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 282aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 283d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey key = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 284aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller for (byte i = 1; i <= 15; i++) { 285aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress sourceAddress = Inet4Address.getByName("10.0.0." + i); 286aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 287aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller key.block(sourceAddress); 288aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (SocketException e) { 289aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // There is a limit, that's ok according to the RI docs. For this test a lower bound of 10 290aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // is used, which appears to be the default linux limit. 291aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // See /proc/sys/net/ipv4/igmp_max_msf 292aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(i > 10); 293aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller break; 294aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 295aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 296aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 297aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 298aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 299aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 300aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Confirms that calling join() does not cause an implicit bind() to take place. */ 301aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_doesNotCauseBind() throws Exception { 302d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 303d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 304d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 305aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = DatagramChannel.open(); 306d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 307aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(dc.getLocalAddress()); 308aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 309aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 310aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 311aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 312aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_networkInterfaces() throws Exception { 313d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 314d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 315d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 316aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Check that we can join on specific interfaces and that we only receive if data is 317aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // received on that interface. This test is only really useful on devices with multiple 318aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // non-loopback interfaces. 319aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 320aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>(); 321aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces(); 322aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller while (theInterfaces.hasMoreElements()) { 323aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller NetworkInterface thisInterface = theInterfaces.nextElement(); 324aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (thisInterface.getInetAddresses().hasMoreElements()) { 325aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller realInterfaces.add(thisInterface); 326aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 327aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 328aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 329aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller for (int i = 0; i < realInterfaces.size(); i++) { 330aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller NetworkInterface thisInterface = realInterfaces.get(i); 331aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (!thisInterface.supportsMulticast()) { 332aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Skip interfaces that do not support multicast - there's no point in proving 333aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // they cannot send / receive multicast messages. 334aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller continue; 335aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 336aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 337aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // get the first address on the interface 338aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 339aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // start server which is joined to the group and has 340aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // only asked for packets on this interface 341aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller Enumeration<InetAddress> addresses = thisInterface.getInetAddresses(); 342aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 343aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller NetworkInterface sendingInterface = null; 344aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress group = null; 345aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (addresses.hasMoreElements()) { 346aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress firstAddress = addresses.nextElement(); 347aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (firstAddress instanceof Inet4Address) { 348aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller group = GOOD_MULTICAST_IPv4; 349d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera sendingInterface = ipv4NetworkInterface; 350aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } else { 351aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // if this interface only seems to support IPV6 addresses 352aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller group = GOOD_MULTICAST_IPv6; 353d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera sendingInterface = ipv6NetworkInterface; 354aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 355aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 356aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 357aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 358aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress(); 359aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.join(group, thisInterface); 360aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 361aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Now send out a package on sendingInterface. We should only see the packet if we send 362aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // it on the same interface we are listening on (thisInterface). 363aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg = "Hello World - Again" + thisInterface.getName(); 364aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMulticastMessage(group, localAddress.getPort(), msg, sendingInterface); 365aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 366aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer recvBuffer = ByteBuffer.allocate(100); 367aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller SocketAddress sourceAddress = dc.receive(recvBuffer); 368aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (thisInterface.equals(sendingInterface)) { 369aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position())); 370aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } else { 371aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(sourceAddress); 372aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 373aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 374aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 375aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 376aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 377aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 378aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Confirms that the scope of each membership is network interface-level. */ 379aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_join_canMixTypesOnDifferentInterfaces() throws Exception { 380d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 381d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 382d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 383aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = DatagramChannel.open(); 384d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey1 = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 385aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller MembershipKey membershipKey2 = dc.join(GOOD_MULTICAST_IPv4, loopbackInterface, UNICAST_IPv4_1); 386aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNotSame(membershipKey1, membershipKey2); 387aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 388aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 389aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 390aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 391aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 392aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private DatagramChannel createReceiverChannel() throws Exception { 393aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = DatagramChannel.open(); 394aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.bind(null /* leave the OS to determine the port, and use the wildcard address */); 395aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller configureChannelForReceiving(dc); 396aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller return dc; 397aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 398aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 399aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_multiple_joins_IPv4() 400aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws Exception { 401f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinAnySource_multiple_joins(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 402aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 403aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 404aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_multiple_joins_IPv6() 405aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws Exception { 406f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinAnySource_multiple_joins(GOOD_MULTICAST_IPv6, ipv6NetworkInterface); 407aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 408aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 409f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_joinAnySource_multiple_joins(InetAddress group, 410d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) throws Exception { 411d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 412d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 413d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 414aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 415aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 416d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey1 = dc.join(group, networkInterface); 417aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 418aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller MembershipKey membershipKey2 = dc.join(group, loopbackInterface); 419aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey1.equals(membershipKey2)); 420aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 421d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey1_2 = dc.join(group, networkInterface); 422aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(membershipKey1, membershipKey1_2); 423aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 424aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 425aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 426aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 427aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinAnySource_multicastLoopOption_IPv4() throws Exception { 428f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 429aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 430aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 431aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_multicastLoopOption_IPv6() throws Exception { 432f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv6, ipv6NetworkInterface); 433aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 434aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 435f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_joinAnySource_multicastLoopOption(InetAddress group, 436d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) throws Exception { 437d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 438d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 439d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 440aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller final String message = "Hello, world!"; 441aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 442aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 443aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true /* enable loop */); 4442c9bf1099057a50df42d7257b2e16115051e1370Shigeki Yokomichi dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface); 445aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller configureChannelForReceiving(dc); 446d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(group, networkInterface); 447aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 448aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress(); 449aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 450aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // send the datagram 451aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller byte[] sendData = message.getBytes(); 452aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer sendBuffer = ByteBuffer.wrap(sendData); 453aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.send(sendBuffer, new InetSocketAddress(group, localAddress.getPort())); 454aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 455aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // receive the datagram 456aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer recvBuffer = ByteBuffer.allocate(100); 457aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller SocketAddress sourceAddress = dc.receive(recvBuffer); 458aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNotNull(sourceAddress); 459aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 460aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String recvMessage = new String(recvBuffer.array(), 0, recvBuffer.position()); 461aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(message, recvMessage); 462aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 463aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Turn off loop 464aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false /* enable loopback */); 465aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 466aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // send another datagram 467aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller recvBuffer.position(0); 468aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer sendBuffer2 = ByteBuffer.wrap(sendData); 469aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.send(sendBuffer2, new InetSocketAddress(group, localAddress.getPort())); 470aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 471aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller SocketAddress sourceAddress2 = dc.receive(recvBuffer); 472aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(sourceAddress2); 473aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 474aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 475aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 476aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 477aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void testMembershipKeyAccessors_IPv4() throws Exception { 478f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer checkMembershipKeyAccessors(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 479aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 480aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 481aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void testMembershipKeyAccessors_IPv6() throws Exception { 482f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer checkMembershipKeyAccessors(GOOD_MULTICAST_IPv6, ipv6NetworkInterface); 483aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 484aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 485f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void checkMembershipKeyAccessors(InetAddress group, 486d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) throws Exception { 487d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 488d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 489d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 490aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 491aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 492d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey key = dc.join(group, networkInterface); 493aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertSame(dc, key.channel()); 494aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertSame(group, key.group()); 495aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(key.isValid()); 496d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera assertSame(networkInterface, key.networkInterface()); 497aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(key.sourceAddress()); 4982e5060e06146d114175319477783488d2360da93Shubham Ajmera dc.close(); 499aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 500aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 501aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_dropAnySource_twice_IPv4() throws Exception { 502f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_dropAnySource_twice(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 503aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 504aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 505aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_dropAnySource_twice_IPv6() throws Exception { 506f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_dropAnySource_twice(GOOD_MULTICAST_IPv6, ipv6NetworkInterface); 507aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 508aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 509f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_dropAnySource_twice(InetAddress group, 510d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) throws Exception { 511d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 512d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 513d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 514aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 515d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(group, networkInterface); 516aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 517aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey.isValid()); 518aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.drop(); 519aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey.isValid()); 520aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 521aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Try to leave a group we are no longer a member of - should do nothing. 522aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.drop(); 523aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 524aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 525aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 526aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 527aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_close_invalidatesMembershipKey() throws Exception { 528d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 529d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 530d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 531aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 532d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 533aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 534aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey.isValid()); 535aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 536aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 537aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 538aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey.isValid()); 539aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 540aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 541aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_null() throws Exception { 542d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 543d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 544d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 545aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 546d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 547aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 548aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(null); 549aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 550aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 551aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 552aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 553aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 554aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 555aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 556aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_mixedAddressTypes_IPv4() throws Exception { 557d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 558d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 559d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 560aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 561d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 562aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 563aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv6_1); 564aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 565aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 566aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 567aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 568aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 569aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 570aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 571aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_mixedAddressTypes_IPv6() throws Exception { 572d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 573d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 574d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 575aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 576d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv6, ipv6NetworkInterface); 577aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 578aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv4_1); 579aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 580aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 581aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 582aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 583aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 584aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 585aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 586aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_cannotBlockWithSourceSpecificMembership() throws Exception { 587d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 588d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 589d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 590aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 591d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, UNICAST_IPv4_1); 592aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 593aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv4_2); 594aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 595aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 596aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 597aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 598aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 599aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 600aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 601aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_multipleBlocksIgnored() throws Exception { 602d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 603d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 604d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 605aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 606d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 607aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv4_1); 608aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 609aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller MembershipKey membershipKey2 = membershipKey.block(UNICAST_IPv4_1); 610aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertSame(membershipKey2, membershipKey); 611aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 612aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 613aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 614aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 615aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_wildcardAddress() throws Exception { 616d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 617d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 618d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 619aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 620d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 621aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 622aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(WILDCARD_IPv4); 623aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 624aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 625aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 626aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 627aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 628aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 629aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 630aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_unblock_multipleUnblocksFail() throws Exception { 631d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 632d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 633d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 634aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 635d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 636aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 637aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 638aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(UNICAST_IPv4_1); 639aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 640aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 641aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 642aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 643aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey.isValid()); 644aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 645aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv4_1); 646aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(UNICAST_IPv4_1); 647aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 648aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 649aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(UNICAST_IPv4_1); 650aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 651aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 652aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 653aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 654aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 655aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 656aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 657aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_unblock_null() throws Exception { 658d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 659d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 660d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 661aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 662d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 663aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv4_1); 664aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 665aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 666aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(null); 667aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 668aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 669aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Either of these exceptions are fine 670aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 671aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Either of these exception are fine 672aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 673aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 674aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 675aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 676aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 677aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_unblock_mixedAddressTypes_IPv4() throws Exception { 678d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 679d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 680d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 681aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 682d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface); 683aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 684aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(UNICAST_IPv6_1); 685aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 686aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 687aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Either of these exceptions are fine 688aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 689aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Either of these exceptions are fine 690aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 691aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 692aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 693aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 694aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 695aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_unblock_mixedAddressTypes_IPv6() throws Exception { 696d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 697d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 698d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 699aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 700d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv6, ipv6NetworkInterface); 701aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 702aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(UNICAST_IPv4_1); 703aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 704aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 705aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Either of these exceptions are fine 706aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 707aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Either of these exceptions are fine 708aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 709aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 710aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 711aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 712aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 713aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Checks that block() works when the receiver is bound to the multicast group address */ 714aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_filtersAsExpected_groupBind_ipv4() throws Exception { 715f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 716f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 717f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 718d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv4LocalAddress = getLocalIpv4Address(ipv4NetworkInterface); 719f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_block_filtersAsExpected( 720aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv4LocalAddress /* senderBindAddress */, 721aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* receiverBindAddress */, 722d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera GOOD_MULTICAST_IPv4 /* groupAddress */, 723d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface); 724aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 725aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 726aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Checks that block() works when the receiver is bound to the multicast group address */ 727aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_filtersAsExpected_groupBind_ipv6() throws Exception { 728f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 729f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 730f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 731d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv6LocalAddress = getLocalIpv6Address(ipv6NetworkInterface); 732f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_block_filtersAsExpected( 733aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv6LocalAddress /* senderBindAddress */, 734aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv6 /* receiverBindAddress */, 735d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera GOOD_MULTICAST_IPv6 /* groupAddress */, 736d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface); 737aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 738aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 739aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Checks that block() works when the receiver is bound to the "any" address */ 740aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_filtersAsExpected_anyBind_ipv4() throws Exception { 741f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 742f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 743f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 744d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv4LocalAddress = getLocalIpv4Address(ipv4NetworkInterface); 745f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_block_filtersAsExpected( 746aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv4LocalAddress /* senderBindAddress */, 747aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller WILDCARD_IPv4 /* receiverBindAddress */, 748d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera GOOD_MULTICAST_IPv4 /* groupAddress */, 749d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface); 750aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 751aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 752aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Checks that block() works when the receiver is bound to the "any" address */ 753aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_block_filtersAsExpected_anyBind_ipv6() throws Exception { 754f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 755f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 756f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 757d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv6LocalAddress = getLocalIpv6Address(ipv6NetworkInterface); 758f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_block_filtersAsExpected( 759aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv6LocalAddress /* senderBindAddress */, 760aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller WILDCARD_IPv6 /* receiverBindAddress */, 761d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera GOOD_MULTICAST_IPv6 /* groupAddress */, 762d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface); 763aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 764aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 765f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_block_filtersAsExpected( 766d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress senderBindAddress, InetAddress receiverBindAddress, 767d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress groupAddress, NetworkInterface networkInterface) 768aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws Exception { 769aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel sendingChannel = DatagramChannel.open(); 770aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // In order to block a sender the sender's address must be known. The sendingChannel is 771aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // explicitly bound to a known, non-loopback address. 772aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendingChannel.bind(new InetSocketAddress(senderBindAddress, 0)); 773aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sendingAddress = (InetSocketAddress) sendingChannel.getLocalAddress(); 774aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 775aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel receivingChannel = DatagramChannel.open(); 776aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller configureChannelForReceiving(receivingChannel); 777aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receivingChannel.bind( 778aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller new InetSocketAddress(receiverBindAddress, 0) /* local port left to the OS to determine */); 779aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress localReceivingAddress = 780aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller (InetSocketAddress) receivingChannel.getLocalAddress(); 781aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress groupSocketAddress = 782aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller new InetSocketAddress(groupAddress, localReceivingAddress.getPort()); 783aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller MembershipKey membershipKey = 784d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera receivingChannel.join(groupSocketAddress.getAddress(), networkInterface); 785aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 786aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer receiveBuffer = ByteBuffer.allocate(10); 787aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 788aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Send a message. It should be received. 789aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg1 = "Hello1"; 790aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMessage(sendingChannel, msg1, groupSocketAddress); 791d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong IoBridge.poll(receivingChannel.socket().getFileDescriptor$(), POLLIN, 1000); 792aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sourceAddress1 = (InetSocketAddress) receivingChannel.receive(receiveBuffer); 793aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(sourceAddress1, sendingAddress); 794aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(msg1, new String(receiveBuffer.array(), 0, receiveBuffer.position())); 795aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 796aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Now block the sender 797aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(sendingAddress.getAddress()); 798aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 799aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Send a message. It should be filtered. 800aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg2 = "Hello2"; 801aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMessage(sendingChannel, msg2, groupSocketAddress); 802d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong try { 803d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong IoBridge.poll(receivingChannel.socket().getFileDescriptor$(), POLLIN, 1000); 804d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong fail(); 805d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong } catch (SocketTimeoutException expected) { } 806aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receiveBuffer.position(0); 807aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sourceAddress2 = (InetSocketAddress) receivingChannel.receive(receiveBuffer); 808aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(sourceAddress2); 809aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 810aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Now unblock the sender 811aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(sendingAddress.getAddress()); 812aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 813aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Send a message. It should be received. 814aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg3 = "Hello3"; 815aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMessage(sendingChannel, msg3, groupSocketAddress); 816d880e69f88b68996b19385d55bcdfe7796f95e02Yi Kong IoBridge.poll(receivingChannel.socket().getFileDescriptor$(), POLLIN, 1000); 817aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receiveBuffer.position(0); 818aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sourceAddress3 = (InetSocketAddress) receivingChannel.receive(receiveBuffer); 819aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(sourceAddress3, sendingAddress); 820aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(msg3, new String(receiveBuffer.array(), 0, receiveBuffer.position())); 821aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 822aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendingChannel.close(); 823aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receivingChannel.close(); 824aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 825aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 826aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nullGroupAddress() throws Exception { 827d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 828d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 829d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 830aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 831aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 832d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(null, ipv4NetworkInterface, UNICAST_IPv4_1); 833aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 834aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 835aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 836aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 837aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 838aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 839aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_afterClose() throws Exception { 840d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 841d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 842d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 843aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 844aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 845aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 846d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, UNICAST_IPv4_1); 847aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 848aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (ClosedChannelException expected) { 849aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 850aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 851aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 852aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nullNetworkInterface() throws Exception { 853d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 854d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 855d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 856aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 857aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 858aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.join(GOOD_MULTICAST_IPv4, null, UNICAST_IPv4_1); 859aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 860aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 861aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 862aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 863aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 864aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 865aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nonMulticastGroupAddress_IPv4() throws Exception { 866d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 867d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 868d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 869aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 870aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 871d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(UNICAST_IPv4_1, ipv4NetworkInterface, UNICAST_IPv4_1); 872aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 873aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 874aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 875aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 876aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 877aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 878aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nonMulticastGroupAddress_IPv6() throws Exception { 879d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 880d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 881d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 882aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 883aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 884d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(UNICAST_IPv6_1, ipv6NetworkInterface, UNICAST_IPv6_1); 885aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 886aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 887aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 888aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 889aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 890aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 891aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nullSourceAddress_IPv4() throws Exception { 892d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 893d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 894d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 895aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 896aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 897d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, null); 898aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 899aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 900aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 901aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 902aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 903aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 904aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nullSourceAddress_IPv6() throws Exception { 905d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 906d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 907d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 908aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 909aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 910d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv6, ipv6NetworkInterface, null); 911aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 912aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (NullPointerException expected) { 913aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 914aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 915aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 916aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 917aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_mixedAddressTypes() throws Exception { 918d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 919d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 920d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 921aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 922aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 923d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, UNICAST_IPv6_1); 924aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 925aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 926aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 927aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 928d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv6, ipv6NetworkInterface, UNICAST_IPv4_1); 929aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 930aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 931aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 932aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 933aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 934aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 935aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nonUnicastSourceAddress_IPv4() throws Exception { 936d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 937d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 938d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 939aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 940aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 941d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, BAD_MULTICAST_IPv4); 942aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 943aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 944aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 945aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 946aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 947aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 948aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_nonUniicastSourceAddress_IPv6() throws Exception { 949d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 950d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 951d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 952aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 953aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 954d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv6, ipv6NetworkInterface, BAD_MULTICAST_IPv6); 955aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller fail(); 956aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalArgumentException expected) { 957aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 958aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 959aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 960aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 961aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_multipleSourceAddressLimit() throws Exception { 962d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 963d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 964d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 965aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 966aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller for (byte i = 1; i <= 20; i++) { 967aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress sourceAddress = Inet4Address.getByAddress(new byte[] { 10, 0, 0, i}); 968aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 969d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, sourceAddress); 970aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (SocketException e) { 971aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // There is a limit, that's ok according to the RI docs. For this test a lower bound of 10 972aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // is used, which appears to be the default linux limit. See /proc/sys/net/ipv4/igmp_max_msf 973aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(i > 10); 974aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller break; 975aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 976aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 977aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 978aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 979aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 980aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 981aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** 982aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Checks that a source-specific join() works when the receiver is bound to the multicast group 983aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * address 984aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller */ 985aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_null() throws Exception { 986f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 987f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 988f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 989d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv4LocalAddress = getLocalIpv4Address(ipv4NetworkInterface); 990f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinSourceSpecific( 991aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv4LocalAddress /* senderBindAddress */, 992aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* receiverBindAddress */, 993aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* groupAddress */, 994d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv4_1 /* badSenderAddress */, 995d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface); 996aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 997aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 998aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** 999aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Checks that a source-specific join() works when the receiver is bound to the multicast group 1000aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * address 1001aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller */ 1002aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_groupBind_ipv4() throws Exception { 1003f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 1004f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 1005f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 1006d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv4LocalAddress = getLocalIpv4Address(ipv4NetworkInterface); 1007f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinSourceSpecific( 1008aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv4LocalAddress /* senderBindAddress */, 1009aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* receiverBindAddress */, 1010aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* groupAddress */, 1011d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv4_1 /* badSenderAddress */, 10127cd7bf2e543625280ac22d7b2a18ffa3e3cbbe44Tobias Thierer ipv4NetworkInterface); 1013aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1014aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1015aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** 1016aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Checks that a source-specific join() works when the receiver is bound to the multicast group 1017aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * address 1018aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller */ 1019aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_groupBind_ipv6() throws Exception { 1020f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 1021f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 1022f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 1023d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv6LocalAddress = getLocalIpv6Address(ipv6NetworkInterface); 1024f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinSourceSpecific( 1025aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv6LocalAddress /* senderBindAddress */, 1026aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv6 /* receiverBindAddress */, 1027aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv6 /* groupAddress */, 1028d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv6_1 /* badSenderAddress */, 1029d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface); 1030aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1031aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1032aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Checks that a source-specific join() works when the receiver is bound to the "any" address */ 1033aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_anyBind_ipv4() throws Exception { 1034f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 1035f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 1036f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 1037d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv4LocalAddress = getLocalIpv4Address(ipv4NetworkInterface); 1038f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinSourceSpecific( 1039aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv4LocalAddress /* senderBindAddress */, 1040aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller WILDCARD_IPv4 /* receiverBindAddress */, 1041aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* groupAddress */, 1042d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv4_1 /* badSenderAddress */, 1043d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface); 1044aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1045aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1046aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** Checks that a source-specific join() works when the receiver is bound to the "any" address */ 1047aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_joinSourceSpecific_anyBind_ipv6() throws Exception { 1048f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu if (!supportsMulticast) { 1049f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu return; 1050f515ad8fb5dac39b9e32f4cd06097ecaabb10fbdbohu } 1051d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress ipv6LocalAddress = getLocalIpv6Address(ipv6NetworkInterface); 1052f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_joinSourceSpecific( 1053aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ipv6LocalAddress /* senderBindAddress */, 1054aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller WILDCARD_IPv6 /* receiverBindAddress */, 1055aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv6 /* groupAddress */, 1056d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv6_1 /* badSenderAddress */, 1057d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface); 1058aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1059aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1060aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller /** 1061aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * Checks that the source-specific membership is correctly source-filtering. 1062aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * 1063aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * @param senderBindAddress the address to bind the sender socket to 1064aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * @param receiverBindAddress the address to bind the receiver socket to 1065aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * @param groupAddress the group address to join 1066aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller * @param badSenderAddress a unicast address to join to perform a negative test 10677cd7bf2e543625280ac22d7b2a18ffa3e3cbbe44Tobias Thierer * @param networkInterface The network interface on which to join the multicast group 1068aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller */ 1069f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_joinSourceSpecific( 1070aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress senderBindAddress, InetAddress receiverBindAddress, InetAddress groupAddress, 1071d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress badSenderAddress, NetworkInterface networkInterface) 1072aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws Exception { 1073aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel sendingChannel = DatagramChannel.open(); 1074aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // In order to be source-specific the sender's address must be known. The sendingChannel is 1075aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // explicitly bound to a known, non-loopback address. 1076aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendingChannel.bind(new InetSocketAddress(senderBindAddress, 0)); 1077aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sendingAddress = (InetSocketAddress) sendingChannel.getLocalAddress(); 1078aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1079aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel receivingChannel = DatagramChannel.open(); 1080aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receivingChannel.bind( 1081aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller new InetSocketAddress(receiverBindAddress, 0) /* local port left to the OS to determine */); 1082aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller configureChannelForReceiving(receivingChannel); 1083aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1084aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress localReceivingAddress = 1085aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller (InetSocketAddress) receivingChannel.getLocalAddress(); 1086aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress groupSocketAddress = 1087aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller new InetSocketAddress(groupAddress, localReceivingAddress.getPort()); 1088aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller MembershipKey membershipKey1 = receivingChannel 1089d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera .join(groupSocketAddress.getAddress(), networkInterface, senderBindAddress); 1090aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1091aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer receiveBuffer = ByteBuffer.allocate(10); 1092aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1093aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Send a message. It should be received. 1094aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg1 = "Hello1"; 1095aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMessage(sendingChannel, msg1, groupSocketAddress); 1096aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sourceAddress1 = (InetSocketAddress) receivingChannel.receive(receiveBuffer); 1097aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(sourceAddress1, sendingAddress); 1098aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertEquals(msg1, new String(receiveBuffer.array(), 0, receiveBuffer.position())); 1099aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1100aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey1.drop(); 1101aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1102d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera receivingChannel.join(groupSocketAddress.getAddress(), networkInterface, badSenderAddress); 1103aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1104aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Send a message. It should not be received. 1105aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller String msg2 = "Hello2"; 1106aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMessage(sendingChannel, msg2, groupSocketAddress); 1107aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetSocketAddress sourceAddress2 = (InetSocketAddress) receivingChannel.receive(receiveBuffer); 1108aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertNull(sourceAddress2); 1109aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1110aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receivingChannel.close(); 1111aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendingChannel.close(); 1112aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1113aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1114aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_dropSourceSpecific_twice_IPv4() throws Exception { 1115f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_dropSourceSpecific_twice( 1116d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera GOOD_MULTICAST_IPv4 /* groupAddress */, UNICAST_IPv4_1 /* sourceAddress */, 1117d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface); 1118aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1119aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1120aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_dropSourceSpecific_twice_IPv6() throws Exception { 1121f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_dropSourceSpecific_twice( 1122d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera GOOD_MULTICAST_IPv6 /* groupAddress */, UNICAST_IPv6_1 /* sourceAddress */, 1123d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface); 1124aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1125aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1126f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_dropSourceSpecific_twice(InetAddress groupAddress, InetAddress sourceAddress, 1127d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) 1128aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws Exception { 1129d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 1130d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 1131d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 1132aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 1133d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(groupAddress, networkInterface, sourceAddress); 1134aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1135aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey.isValid()); 1136aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.drop(); 1137aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey.isValid()); 1138aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1139aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Try to leave a group we are no longer a member of - should do nothing. 1140aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.drop(); 1141aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1142aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 1143aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1144aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1145aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_dropSourceSpecific_sourceKeysAreIndependent_IPv4() throws Exception { 1146f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_dropSourceSpecific_sourceKeysAreIndependent( 1147aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv4 /* groupAddress */, 1148aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller UNICAST_IPv4_1 /* sourceAddress1 */, 1149d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv4_2 /* sourceAddress2 */, 1150d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv4NetworkInterface); 1151aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1152aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1153aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_dropSourceSpecific_sourceKeysAreIndependent_IPv6() throws Exception { 1154f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer check_dropSourceSpecific_sourceKeysAreIndependent( 1155aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller GOOD_MULTICAST_IPv6 /* groupAddress */, 1156aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller UNICAST_IPv6_1 /* sourceAddress1 */, 1157d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera UNICAST_IPv6_2 /* sourceAddress2 */, 1158d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera ipv6NetworkInterface); 1159aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1160aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1161f393ec80c97a5baa736abe6ecfb074138988165dTobias Thierer private void check_dropSourceSpecific_sourceKeysAreIndependent( 1162d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera InetAddress groupAddress, InetAddress sourceAddress1, InetAddress sourceAddress2, 1163d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera NetworkInterface networkInterface) throws Exception { 1164d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 1165d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 1166d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 1167aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 1168d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey1 = dc.join(groupAddress, networkInterface, sourceAddress1); 1169d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey2 = dc.join(groupAddress, networkInterface, sourceAddress2); 1170aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey1.equals(membershipKey2)); 1171aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey1.isValid()); 1172aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey2.isValid()); 1173aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1174aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey1.drop(); 1175aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1176aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey1.isValid()); 1177aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertTrue(membershipKey2.isValid()); 1178aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1179aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 1180aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1181aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1182aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller public void test_drop_keyBehaviorAfterDrop() throws Exception { 1183d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera if (!supportsMulticast) { 1184d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera return; 1185d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera } 1186aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = createReceiverChannel(); 1187d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, UNICAST_IPv4_1); 1188aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.drop(); 1189aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertFalse(membershipKey.isValid()); 1190aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1191aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 1192aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.block(UNICAST_IPv4_1); 1193d4b7449574ca69c713a3f2230cb77c68ee642700Tobias Thierer fail(); 1194aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 1195aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1196aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1197aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller try { 1198aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller membershipKey.unblock(UNICAST_IPv4_1); 1199d4b7449574ca69c713a3f2230cb77c68ee642700Tobias Thierer fail(); 1200aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } catch (IllegalStateException expected) { 1201aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1202aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1203aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertSame(dc, membershipKey.channel()); 1204aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertSame(GOOD_MULTICAST_IPv4, membershipKey.group()); 1205aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller assertSame(UNICAST_IPv4_1, membershipKey.sourceAddress()); 1206d27d16405ee9c9753d253bc311bf00f5de2e25b5Shubham Ajmera assertSame(ipv4NetworkInterface, membershipKey.networkInterface()); 1207aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1208aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1209aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static void configureChannelForReceiving(DatagramChannel receivingChannel) 1210aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws Exception { 1211aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1212aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // NOTE: At the time of writing setSoTimeout() has no effect in the RI, making these tests hang 1213aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // if the channel is in blocking mode. configureBlocking(false) is used instead and rely on the 1214aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // network to the local host being instantaneous. 1215aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // receivingChannel.socket().setSoTimeout(200); 1216aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // receivingChannel.configureBlocking(true); 1217aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller receivingChannel.configureBlocking(false); 1218aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1219aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1220aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException { 1221aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller return iface.isUp() 1222aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Typically loopback interfaces do not support multicast, but they are ruled out 1223aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // explicitly here anyway. 1224aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller && !iface.isLoopback() && iface.supportsMulticast() 1225aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller && iface.getInetAddresses().hasMoreElements(); 1226aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1227aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1228aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static void sendMulticastMessage( 1229aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller InetAddress group, int port, String msg, NetworkInterface sendingInterface) 1230aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws IOException { 1231aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // Any datagram socket can send to a group. It does not need to have joined the group. 1232aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel dc = DatagramChannel.open(); 1233aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (sendingInterface != null) { 1234aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // For some reason, if set, this must be set to a real (non-loopback) device for an IPv6 1235aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller // group, but can be loopback for an IPv4 group. 1236aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, sendingInterface); 1237aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1238aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendMessage(dc, msg, new InetSocketAddress(group, port)); 1239aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller dc.close(); 1240aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1241aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1242aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static void sendMessage( 1243aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller DatagramChannel sendingChannel, String msg, InetSocketAddress targetAddress) 1244aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throws IOException { 1245aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1246aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller ByteBuffer sendBuffer = ByteBuffer.wrap(msg.getBytes()); 1247aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller sendingChannel.send(sendBuffer, targetAddress); 1248aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1249aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1250aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static InetAddress getLocalIpv4Address(NetworkInterface networkInterface) { 1251aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { 1252aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (interfaceAddress.getAddress() instanceof Inet4Address) { 1253aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller return interfaceAddress.getAddress(); 1254aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1255aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1256aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throw new AssertionFailedError("Unable to find local IPv4 address for " + networkInterface); 1257aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1258aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1259aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller private static InetAddress getLocalIpv6Address(NetworkInterface networkInterface) { 1260aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { 1261aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller if (interfaceAddress.getAddress() instanceof Inet6Address) { 1262aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller return interfaceAddress.getAddress(); 1263aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1264aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1265aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller throw new AssertionFailedError("Unable to find local IPv6 address for " + networkInterface); 1266aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller } 1267aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller} 1268aea78555169709a2586b585e61414d9aee1d8e28Neil Fuller 1269