1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.tests.java.net; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertTrue; 25 import static org.junit.Assert.fail; 26 27 import java.io.IOException; 28 import java.net.BindException; 29 import java.net.DatagramPacket; 30 import java.net.Inet4Address; 31 import java.net.Inet6Address; 32 import java.net.InetAddress; 33 import java.net.InetSocketAddress; 34 import java.net.MulticastSocket; 35 import java.net.NetworkInterface; 36 import java.net.SocketAddress; 37 import java.net.SocketException; 38 import java.net.SocketTimeoutException; 39 import java.util.ArrayList; 40 import java.util.Enumeration; 41 import java.util.List; 42 43 import libcore.junit.util.ResourceLeakageDetector; 44 45 import org.junit.Assume; 46 import org.junit.Before; 47 import org.junit.Rule; 48 import org.junit.rules.TestRule; 49 import org.junit.Test; 50 51 public class MulticastSocketTest { 52 @Rule 53 public TestRule guardRule = ResourceLeakageDetector.getRule(); 54 lookup(String s)55 private static InetAddress lookup(String s) { 56 try { 57 return InetAddress.getByName(s); 58 } catch (IOException ex) { 59 throw new RuntimeException(ex); 60 } 61 } 62 63 // These IP addresses aren't inherently "good" or "bad"; they're just used like that. 64 // We use the "good" addresses for our actual group, and the "bad" addresses are for 65 // a group that we won't actually set up. 66 67 private static InetAddress GOOD_IPv4 = lookup("224.0.0.3"); 68 private static InetAddress BAD_IPv4 = lookup("224.0.0.4"); 69 private static InetAddress GOOD_IPv6 = lookup("ff05::7:7"); 70 private static InetAddress BAD_IPv6 = lookup("ff05::7:8"); 71 72 private NetworkInterface loopbackInterface; 73 private NetworkInterface ipv4NetworkInterface; 74 private NetworkInterface ipv6NetworkInterface; 75 private boolean supportsMulticast; 76 77 @Before setUp()78 public void setUp() throws Exception { 79 // The loopback interface isn't actually useful for sending/receiving multicast messages 80 // but it can be used as a fake for tests where that does not matter. 81 loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress()); 82 assertNotNull(loopbackInterface); 83 assertTrue(loopbackInterface.isLoopback()); 84 assertFalse(loopbackInterface.supportsMulticast()); 85 86 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 87 assertNotNull(interfaces); 88 89 // Determine if the device is marked to support multicast or not. If this propery is not 90 // set we assume the device has an interface capable of supporting multicast. 91 supportsMulticast = Boolean.parseBoolean( 92 System.getProperty("android.cts.device.multicast", "true")); 93 Assume.assumeTrue(supportsMulticast); 94 95 while (interfaces.hasMoreElements() 96 && (ipv4NetworkInterface == null || ipv6NetworkInterface == null)) { 97 NetworkInterface nextInterface = interfaces.nextElement(); 98 if (willWorkForMulticast(nextInterface)) { 99 Enumeration<InetAddress> addresses = nextInterface.getInetAddresses(); 100 while (addresses.hasMoreElements()) { 101 final InetAddress nextAddress = addresses.nextElement(); 102 if (nextAddress instanceof Inet6Address && ipv6NetworkInterface == null) { 103 ipv6NetworkInterface = nextInterface; 104 } else if (nextAddress instanceof Inet4Address 105 && ipv4NetworkInterface == null) { 106 ipv4NetworkInterface = nextInterface; 107 } 108 } 109 } 110 } 111 assertTrue("Test environment must have at least one interface capable of multicast for IPv4" 112 + " and IPv6", 113 ipv4NetworkInterface != null && ipv6NetworkInterface != null); 114 } 115 116 @Test constructor()117 public void constructor() throws IOException { 118 Assume.assumeTrue(supportsMulticast); 119 // Regression test for 497. 120 MulticastSocket s = new MulticastSocket(); 121 // Regression test for Harmony-1162. 122 assertTrue(s.getReuseAddress()); 123 124 s.close(); 125 } 126 127 @Test constructorI()128 public void constructorI() throws IOException { 129 Assume.assumeTrue(supportsMulticast); 130 MulticastSocket orig = new MulticastSocket(); 131 int port = orig.getLocalPort(); 132 orig.close(); 133 134 MulticastSocket dup = new MulticastSocket(port); 135 // Regression test for Harmony-1162. 136 assertTrue(dup.getReuseAddress()); 137 dup.close(); 138 } 139 140 @Test getInterface()141 public void getInterface() throws Exception { 142 Assume.assumeTrue(supportsMulticast); 143 // Validate that we get the expected response when one was not set. 144 MulticastSocket mss = new MulticastSocket(0); 145 // We expect an ANY address in this case. 146 assertTrue(mss.getInterface().isAnyLocalAddress()); 147 148 // Validate that we get the expected response when we set via setInterface. 149 Enumeration addresses = ipv4NetworkInterface.getInetAddresses(); 150 if (addresses.hasMoreElements()) { 151 InetAddress firstAddress = (InetAddress) addresses.nextElement(); 152 mss.setInterface(firstAddress); 153 assertEquals("getNetworkInterface did not return interface set by setInterface", 154 firstAddress, mss.getInterface()); 155 156 mss.close(); 157 mss = new MulticastSocket(0); 158 mss.setNetworkInterface(ipv4NetworkInterface); 159 assertEquals("getInterface did not return interface set by setNetworkInterface", 160 ipv4NetworkInterface, NetworkInterface.getByInetAddress(mss.getInterface())); 161 } 162 163 mss.close(); 164 } 165 166 @Test getNetworkInterface()167 public void getNetworkInterface() throws IOException { 168 Assume.assumeTrue(supportsMulticast); 169 // Validate that we get the expected response when one was not set. 170 MulticastSocket mss = new MulticastSocket(0); 171 NetworkInterface theInterface = mss.getNetworkInterface(); 172 assertTrue( 173 "network interface returned wrong network interface when not set:" + theInterface, 174 theInterface.getInetAddresses().hasMoreElements()); 175 InetAddress firstAddress = theInterface.getInetAddresses().nextElement(); 176 // Validate we the first address in the network interface is the ANY address. 177 assertTrue(firstAddress.isAnyLocalAddress()); 178 179 mss.setNetworkInterface(ipv4NetworkInterface); 180 assertEquals("getNetworkInterface did not return interface set by setNeworkInterface", 181 ipv4NetworkInterface, mss.getNetworkInterface()); 182 183 mss.setNetworkInterface(loopbackInterface); 184 assertEquals( 185 "getNetworkInterface did not return network interface set by second" 186 + " setNetworkInterface call", 187 loopbackInterface, mss.getNetworkInterface()); 188 mss.close(); 189 190 if (ipv6NetworkInterface != null) { 191 mss = new MulticastSocket(0); 192 mss.setNetworkInterface(ipv6NetworkInterface); 193 assertEquals("getNetworkInterface did not return interface set by setNeworkInterface", 194 ipv6NetworkInterface, mss.getNetworkInterface()); 195 mss.close(); 196 } 197 198 // Validate that we get the expected response when we set via setInterface. 199 mss = new MulticastSocket(0); 200 Enumeration addresses = ipv4NetworkInterface.getInetAddresses(); 201 if (addresses.hasMoreElements()) { 202 firstAddress = (InetAddress) addresses.nextElement(); 203 mss.setInterface(firstAddress); 204 assertEquals("getNetworkInterface did not return interface set by setInterface", 205 ipv4NetworkInterface, mss.getNetworkInterface()); 206 } 207 mss.close(); 208 } 209 210 @Test getTimeToLive()211 public void getTimeToLive() throws Exception { 212 Assume.assumeTrue(supportsMulticast); 213 MulticastSocket mss = new MulticastSocket(); 214 mss.setTimeToLive(120); 215 assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive()); 216 mss.setTimeToLive(220); 217 assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive()); 218 mss.close(); 219 } 220 221 @Test getTTL()222 public void getTTL() throws Exception { 223 Assume.assumeTrue(supportsMulticast); 224 MulticastSocket mss = new MulticastSocket(); 225 mss.setTTL((byte) 120); 226 assertEquals("Returned incorrect TTL", 120, mss.getTTL()); 227 mss.close(); 228 } 229 230 @Test joinGroupLjava_net_InetAddress_IPv4()231 public void joinGroupLjava_net_InetAddress_IPv4() throws Exception { 232 Assume.assumeTrue(supportsMulticast); 233 test_joinGroupLjava_net_InetAddress(GOOD_IPv4); 234 } 235 236 @Test joinGroupLjava_net_InetAddress_IPv6()237 public void joinGroupLjava_net_InetAddress_IPv6() throws Exception { 238 Assume.assumeTrue(supportsMulticast); 239 test_joinGroupLjava_net_InetAddress(GOOD_IPv6); 240 } 241 test_joinGroupLjava_net_InetAddress(InetAddress group)242 private void test_joinGroupLjava_net_InetAddress(InetAddress group) throws Exception { 243 MulticastSocket receivingSocket = createReceivingSocket(0); 244 receivingSocket.joinGroup(group); 245 246 String msg = "Hello World"; 247 MulticastSocket sendingSocket = new MulticastSocket(receivingSocket.getLocalPort()); 248 InetSocketAddress groupAddress = 249 new InetSocketAddress(group, receivingSocket.getLocalPort()); 250 DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); 251 sendingSocket.send(sdp, (byte) 10 /* ttl */); 252 253 DatagramPacket rdp = createReceiveDatagramPacket(); 254 receivingSocket.receive(rdp); 255 String receivedMessage = extractMessage(rdp); 256 assertEquals("Group member did not recv data", msg, receivedMessage); 257 258 sendingSocket.close(); 259 receivingSocket.close(); 260 } 261 262 @Test joinGroup_null_null()263 public void joinGroup_null_null() throws Exception { 264 Assume.assumeTrue(supportsMulticast); 265 MulticastSocket mss = new MulticastSocket(0); 266 try { 267 mss.joinGroup(null, null); 268 fail(); 269 } catch (IllegalArgumentException expected) { 270 } 271 mss.close(); 272 } 273 274 @Test joinGroup_non_multicast_address_IPv4()275 public void joinGroup_non_multicast_address_IPv4() throws Exception { 276 Assume.assumeTrue(supportsMulticast); 277 MulticastSocket mss = new MulticastSocket(0); 278 try { 279 mss.joinGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null); 280 fail(); 281 } catch (IOException expected) { 282 } 283 mss.close(); 284 } 285 286 @Test joinGroup_non_multicast_address_IPv6()287 public void joinGroup_non_multicast_address_IPv6() throws Exception { 288 Assume.assumeTrue(supportsMulticast); 289 MulticastSocket mss = new MulticastSocket(0); 290 try { 291 mss.joinGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null); 292 fail(); 293 } catch (IOException expected) { 294 } 295 mss.close(); 296 } 297 298 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()299 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() 300 throws Exception { 301 Assume.assumeTrue(supportsMulticast); 302 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( 303 ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4); 304 } 305 306 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()307 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() 308 throws Exception { 309 Assume.assumeTrue(supportsMulticast); 310 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( 311 ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6); 312 } 313 314 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4_nullInterface()315 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4_nullInterface() 316 throws Exception { 317 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv4, BAD_IPv4); 318 } 319 320 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6_nullInterface()321 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6_nullInterface() 322 throws Exception { 323 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv6, BAD_IPv6); 324 } 325 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( NetworkInterface networkInterface, InetAddress group, InetAddress group2)326 private void check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( 327 NetworkInterface networkInterface, InetAddress group, InetAddress group2) 328 throws Exception { 329 // Create the sending socket and specify the interface to use as needed (otherwise use the 330 // default). 331 MulticastSocket sendingSocket = new MulticastSocket(0); 332 if (networkInterface != null) { 333 sendingSocket.setNetworkInterface(networkInterface); 334 } 335 sendingSocket.setTimeToLive(2); 336 337 MulticastSocket receivingSocket = createReceivingSocket(0); 338 InetSocketAddress groupAddress = 339 new InetSocketAddress(group, receivingSocket.getLocalPort()); 340 // Join the group. A null network interface is valid and means "use default". 341 receivingSocket.joinGroup(groupAddress, networkInterface); 342 343 String msg = "Hello World"; 344 DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); 345 sendingSocket.send(sdp); 346 347 DatagramPacket rdp = createReceiveDatagramPacket(); 348 receivingSocket.receive(rdp); 349 // Now validate that we received the data as expected. 350 assertEquals("Group member did not recv data", msg, extractMessage(rdp)); 351 receivingSocket.close(); 352 sendingSocket.close(); 353 354 // Create the sending socket and specify the interface to use as needed (otherwise use the 355 // default). 356 sendingSocket = new MulticastSocket(0); 357 if (networkInterface != null) { 358 sendingSocket.setNetworkInterface(networkInterface); 359 } 360 sendingSocket.setTimeToLive(10); 361 362 receivingSocket = createReceivingSocket(0); 363 groupAddress = new InetSocketAddress(group, receivingSocket.getLocalPort()); 364 // Join the group. A null network interface is valid and means "use default". 365 receivingSocket.joinGroup(groupAddress, networkInterface); 366 367 msg = "Hello World - Different Group"; 368 InetSocketAddress group2Address = 369 new InetSocketAddress(group2, receivingSocket.getLocalPort()); 370 sdp = createSendDatagramPacket(group2Address, msg); 371 sendingSocket.send(sdp); 372 373 rdp = createReceiveDatagramPacket(); 374 try { 375 receivingSocket.receive(rdp); 376 fail("Expected timeout"); 377 } catch (SocketTimeoutException expected) { 378 } 379 380 receivingSocket.close(); 381 sendingSocket.close(); 382 } 383 384 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface()385 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception { 386 Assume.assumeTrue(supportsMulticast); 387 // Check that we can join on specific interfaces and that we only receive if data is 388 // received on that interface. This test is only really useful on devices with multiple 389 // non-loopback interfaces. 390 391 List<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>(); 392 Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces(); 393 while (theInterfaces.hasMoreElements()) { 394 NetworkInterface thisInterface = theInterfaces.nextElement(); 395 // Skip interfaces that do not support multicast - there's no point in proving 396 // they cannot send / receive multicast messages. 397 if (willWorkForMulticast(thisInterface)) { 398 realInterfaces.add(thisInterface); 399 } 400 } 401 402 for (NetworkInterface thisInterface : realInterfaces) { 403 // Find a suitable group IP and interface to use to sent packets to thisInterface. 404 Enumeration<InetAddress> addresses = thisInterface.getInetAddresses(); 405 406 NetworkInterface sendingInterface = null; 407 InetAddress group = null; 408 if (addresses.hasMoreElements()) { 409 InetAddress firstAddress = addresses.nextElement(); 410 if (firstAddress instanceof Inet4Address) { 411 group = GOOD_IPv4; 412 sendingInterface = ipv4NetworkInterface; 413 } else { 414 // if this interface only seems to support IPV6 addresses 415 group = GOOD_IPv6; 416 sendingInterface = ipv6NetworkInterface; 417 } 418 } 419 420 // Create a receivingSocket which is joined to the group and has only asked for packets 421 // on thisInterface. 422 MulticastSocket receivingSocket = createReceivingSocket(0); 423 InetSocketAddress groupAddress = 424 new InetSocketAddress(group, receivingSocket.getLocalPort()); 425 receivingSocket.joinGroup(groupAddress, thisInterface); 426 427 // Now send out a packet on sendingInterface. We should only see the packet if we send 428 // it on thisInterface. 429 MulticastSocket sendingSocket = new MulticastSocket(0); 430 sendingSocket.setNetworkInterface(sendingInterface); 431 String msg = "Hello World - Again " + thisInterface.getName(); 432 DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); 433 sendingSocket.send(sdp); 434 435 DatagramPacket rdp = createReceiveDatagramPacket(); 436 try { 437 receivingSocket.receive(rdp); 438 439 // If the packet is received.... 440 assertEquals(thisInterface, sendingInterface); 441 assertEquals("Group member did not recv data when bound on specific interface", 442 msg, extractMessage(rdp)); 443 } catch (SocketTimeoutException e) { 444 // If the packet was not received... 445 assertTrue(!thisInterface.equals(sendingInterface)); 446 } 447 448 receivingSocket.close(); 449 sendingSocket.close(); 450 } 451 } 452 453 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4()454 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4() 455 throws Exception { 456 Assume.assumeTrue(supportsMulticast); 457 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( 458 ipv4NetworkInterface, GOOD_IPv4); 459 } 460 461 @Test joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6()462 public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6() 463 throws Exception { 464 Assume.assumeTrue(supportsMulticast); 465 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( 466 ipv6NetworkInterface, GOOD_IPv6); 467 } 468 check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( NetworkInterface networkInterface, InetAddress group)469 private void check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( 470 NetworkInterface networkInterface, InetAddress group) throws Exception { 471 // Validate that we can join the same address on two different interfaces but not on the 472 // same interface. 473 MulticastSocket mss = new MulticastSocket(0); 474 SocketAddress groupSockAddr = new InetSocketAddress(group, mss.getLocalPort()); 475 mss.joinGroup(groupSockAddr, networkInterface); 476 mss.joinGroup(groupSockAddr, loopbackInterface); 477 try { 478 mss.joinGroup(groupSockAddr, networkInterface); 479 fail("Did not get expected exception when joining for second time on same interface"); 480 } catch (IOException e) { 481 } 482 mss.close(); 483 } 484 485 @Test leaveGroupLjava_net_InetAddress_IPv4()486 public void leaveGroupLjava_net_InetAddress_IPv4() throws Exception { 487 Assume.assumeTrue(supportsMulticast); 488 check_leaveGroupLjava_net_InetAddress(GOOD_IPv4); 489 } 490 491 @Test leaveGroupLjava_net_InetAddress_IPv6()492 public void leaveGroupLjava_net_InetAddress_IPv6() throws Exception { 493 Assume.assumeTrue(supportsMulticast); 494 check_leaveGroupLjava_net_InetAddress(GOOD_IPv6); 495 } 496 check_leaveGroupLjava_net_InetAddress(InetAddress group)497 private void check_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception { 498 String msg = "Hello World"; 499 MulticastSocket mss = new MulticastSocket(0); 500 InetSocketAddress groupAddress = new InetSocketAddress(group, mss.getLocalPort()); 501 DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); 502 mss.send(sdp, (byte) 10 /* ttl */); 503 try { 504 // Try to leave a group we didn't join. 505 mss.leaveGroup(group); 506 fail(); 507 } catch (IOException expected) { 508 } 509 mss.close(); 510 } 511 512 @Test leaveGroup_null_null()513 public void leaveGroup_null_null() throws Exception { 514 Assume.assumeTrue(supportsMulticast); 515 MulticastSocket mss = new MulticastSocket(0); 516 try { 517 mss.leaveGroup(null, null); 518 fail(); 519 } catch (IllegalArgumentException expected) { 520 } 521 mss.close(); 522 } 523 524 @Test leaveGroup_non_multicast_address_IPv4()525 public void leaveGroup_non_multicast_address_IPv4() throws Exception { 526 Assume.assumeTrue(supportsMulticast); 527 MulticastSocket mss = new MulticastSocket(0); 528 try { 529 mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null); 530 fail(); 531 } catch (IOException expected) { 532 } 533 mss.close(); 534 } 535 536 @Test leaveGroup_non_multicast_address_IPv6()537 public void leaveGroup_non_multicast_address_IPv6() throws Exception { 538 Assume.assumeTrue(supportsMulticast); 539 MulticastSocket mss = new MulticastSocket(0); 540 try { 541 mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null); 542 fail(); 543 } catch (IOException expected) { 544 } 545 mss.close(); 546 } 547 548 @Test leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()549 public void leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() 550 throws Exception { 551 Assume.assumeTrue(supportsMulticast); 552 check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( 553 ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4); 554 } 555 556 @Test leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()557 public void leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() 558 throws Exception { 559 Assume.assumeTrue(supportsMulticast); 560 check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( 561 ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6); 562 } 563 check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( NetworkInterface networkInterface, InetAddress group, InetAddress group2)564 private void check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( 565 NetworkInterface networkInterface, InetAddress group, InetAddress group2) 566 throws Exception { 567 SocketAddress groupSockAddr = null; 568 SocketAddress groupSockAddr2 = null; 569 570 try (MulticastSocket mss = new MulticastSocket(0)) { 571 groupSockAddr = new InetSocketAddress(group, mss.getLocalPort()); 572 mss.joinGroup(groupSockAddr, null); 573 mss.leaveGroup(groupSockAddr, null); 574 try { 575 mss.leaveGroup(groupSockAddr, null); 576 fail("Did not get exception when trying to leave group that was already left"); 577 } catch (IOException expected) { 578 } 579 580 groupSockAddr2 = new InetSocketAddress(group2, mss.getLocalPort()); 581 mss.joinGroup(groupSockAddr, networkInterface); 582 try { 583 mss.leaveGroup(groupSockAddr2, networkInterface); 584 fail("Did not get exception when trying to leave group that was never joined"); 585 } catch (IOException expected) { 586 } 587 588 mss.leaveGroup(groupSockAddr, networkInterface); 589 590 mss.joinGroup(groupSockAddr, networkInterface); 591 try { 592 mss.leaveGroup(groupSockAddr, loopbackInterface); 593 fail("Did not get exception when trying to leave group on wrong interface " + 594 "joined on [" + networkInterface + "] left on [" + loopbackInterface + "]"); 595 } catch (IOException expected) { 596 } 597 } 598 } 599 600 @Test sendLjava_net_DatagramPacketB_IPv4()601 public void sendLjava_net_DatagramPacketB_IPv4() throws Exception { 602 Assume.assumeTrue(supportsMulticast); 603 check_sendLjava_net_DatagramPacketB(GOOD_IPv4); 604 } 605 606 @Test sendLjava_net_DatagramPacketB_IPv6()607 public void sendLjava_net_DatagramPacketB_IPv6() throws Exception { 608 Assume.assumeTrue(supportsMulticast); 609 check_sendLjava_net_DatagramPacketB(GOOD_IPv6); 610 } 611 check_sendLjava_net_DatagramPacketB(InetAddress group)612 private void check_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception { 613 String msg = "Hello World"; 614 MulticastSocket sendingSocket = new MulticastSocket(0); 615 MulticastSocket receivingSocket = createReceivingSocket(sendingSocket.getLocalPort()); 616 receivingSocket.joinGroup(group); 617 618 InetSocketAddress groupAddress = new InetSocketAddress(group, sendingSocket.getLocalPort()); 619 DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); 620 sendingSocket.send(sdp, (byte) 10 /* ttl */); 621 sendingSocket.close(); 622 623 DatagramPacket rdp = createReceiveDatagramPacket(); 624 receivingSocket.receive(rdp); 625 String receivedMessage = extractMessage(rdp); 626 assertEquals("Failed to send data. Received " + rdp.getLength(), msg, receivedMessage); 627 receivingSocket.close(); 628 } 629 630 @Test setInterfaceLjava_net_InetAddress()631 public void setInterfaceLjava_net_InetAddress() throws Exception { 632 Assume.assumeTrue(supportsMulticast); 633 MulticastSocket mss = new MulticastSocket(); 634 mss.setInterface(InetAddress.getLocalHost()); 635 InetAddress theInterface = mss.getInterface(); 636 // Under IPV6 we are not guaranteed to get the same address back as the address that was 637 // set, all we should be guaranteed is that we get an address on the same interface. 638 if (theInterface instanceof Inet6Address) { 639 assertEquals("Failed to return correct interface IPV6", 640 NetworkInterface.getByInetAddress(mss.getInterface()), 641 NetworkInterface.getByInetAddress(theInterface)); 642 } else { 643 assertTrue("Failed to return correct interface IPV4 got:" + mss.getInterface() + 644 " expected: " + InetAddress.getLocalHost(), 645 mss.getInterface().equals(InetAddress.getLocalHost())); 646 } 647 mss.close(); 648 } 649 650 @Test setInterface_unbound_address_IPv4()651 public void setInterface_unbound_address_IPv4() throws Exception { 652 Assume.assumeTrue(supportsMulticast); 653 test_setInterface_unbound_address(GOOD_IPv4); 654 } 655 656 @Test setInterface_unbound_address_IPv6()657 public void setInterface_unbound_address_IPv6() throws Exception { 658 Assume.assumeTrue(supportsMulticast); 659 test_setInterface_unbound_address(GOOD_IPv6); 660 } 661 662 // Regression test for Harmony-2410. test_setInterface_unbound_address(InetAddress address)663 private void test_setInterface_unbound_address(InetAddress address) throws Exception { 664 MulticastSocket mss = new MulticastSocket(); 665 try { 666 mss.setInterface(address); 667 fail(); 668 } catch (SocketException expected) { 669 } 670 mss.close(); 671 } 672 673 @Test setNetworkInterfaceLjava_net_NetworkInterface_null()674 public void setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception { 675 Assume.assumeTrue(supportsMulticast); 676 // Validate that null interface is handled ok. 677 MulticastSocket mss = new MulticastSocket(); 678 try { 679 mss.setNetworkInterface(null); 680 fail("No socket exception when we set then network interface with NULL"); 681 } catch (SocketException ex) { 682 } 683 mss.close(); 684 } 685 686 @Test setNetworkInterfaceLjava_net_NetworkInterface_round_trip()687 public void setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception { 688 Assume.assumeTrue(supportsMulticast); 689 // Validate that we can get and set the interface. 690 MulticastSocket mss = new MulticastSocket(); 691 mss.setNetworkInterface(ipv4NetworkInterface); 692 assertEquals("Interface did not seem to be set by setNeworkInterface", 693 ipv4NetworkInterface, mss.getNetworkInterface()); 694 mss.close(); 695 } 696 697 @Test setNetworkInterfaceLjava_net_NetworkInterface_IPv4()698 public void setNetworkInterfaceLjava_net_NetworkInterface_IPv4() throws Exception { 699 Assume.assumeTrue(supportsMulticast); 700 check_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv4); 701 } 702 703 @Test setNetworkInterfaceLjava_net_NetworkInterface_IPv6()704 public void setNetworkInterfaceLjava_net_NetworkInterface_IPv6() throws Exception { 705 Assume.assumeTrue(supportsMulticast); 706 check_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6); 707 } 708 check_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group)709 private void check_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group) 710 throws IOException, InterruptedException { 711 // Set up the receiving socket and join the group. 712 Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces(); 713 while (theInterfaces.hasMoreElements()) { 714 NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement(); 715 if (willWorkForMulticast(thisInterface)) { 716 if ((!(thisInterface.getInetAddresses().nextElement()).isLoopbackAddress())) { 717 MulticastSocket receivingSocket = createReceivingSocket(0); 718 InetSocketAddress groupAddress = 719 new InetSocketAddress(group, receivingSocket.getLocalPort()); 720 receivingSocket.joinGroup(groupAddress, thisInterface); 721 722 // Send the packets on a particular interface. The source address in the 723 // received packet should be one of the addresses for the interface set. 724 MulticastSocket sendingSocket = new MulticastSocket(0); 725 sendingSocket.setNetworkInterface(thisInterface); 726 String msg = thisInterface.getName(); 727 DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); 728 sendingSocket.send(sdp); 729 730 DatagramPacket rdp = createReceiveDatagramPacket(); 731 receivingSocket.receive(rdp); 732 String receivedMessage = extractMessage(rdp); 733 assertEquals("Group member did not recv data sent on a specific interface", 734 msg, receivedMessage); 735 // Stop the server. 736 receivingSocket.close(); 737 sendingSocket.close(); 738 } 739 } 740 } 741 } 742 743 @Test setTimeToLiveI()744 public void setTimeToLiveI() throws Exception { 745 Assume.assumeTrue(supportsMulticast); 746 MulticastSocket mss = new MulticastSocket(); 747 mss.setTimeToLive(120); 748 assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive()); 749 mss.setTimeToLive(220); 750 assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive()); 751 mss.close(); 752 } 753 754 @Test setTTLB()755 public void setTTLB() throws Exception { 756 Assume.assumeTrue(supportsMulticast); 757 MulticastSocket mss = new MulticastSocket(); 758 mss.setTTL((byte) 120); 759 assertEquals("Failed to set TTL", 120, mss.getTTL()); 760 mss.close(); 761 } 762 763 @Test constructorLjava_net_SocketAddress()764 public void constructorLjava_net_SocketAddress() throws Exception { 765 Assume.assumeTrue(supportsMulticast); 766 MulticastSocket ms = new MulticastSocket((SocketAddress) null); 767 assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected()); 768 ms.bind(null); 769 assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected()); 770 ms.close(); 771 assertTrue("should be closed", ms.isClosed()); 772 773 ms = new MulticastSocket(0); 774 assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected()); 775 ms.close(); 776 assertTrue("should be closed", ms.isClosed()); 777 778 ms = new MulticastSocket(0); 779 assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected()); 780 ms.close(); 781 assertTrue("should be closed", ms.isClosed()); 782 783 try { 784 new MulticastSocket(new InetSocketAddress("unresolvedname", 31415)); 785 fail(); 786 } catch (IOException expected) { 787 } 788 789 // Regression test for Harmony-1162. 790 InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0); 791 MulticastSocket s = new MulticastSocket(addr); 792 assertTrue(s.getReuseAddress()); 793 s.close(); 794 } 795 796 @Test getLoopbackMode()797 public void getLoopbackMode() throws Exception { 798 Assume.assumeTrue(supportsMulticast); 799 MulticastSocket ms = new MulticastSocket(null); 800 assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected()); 801 ms.getLoopbackMode(); 802 assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected()); 803 ms.close(); 804 assertTrue("should be closed", ms.isClosed()); 805 } 806 807 @Test setLoopbackModeZ()808 public void setLoopbackModeZ() throws Exception { 809 Assume.assumeTrue(supportsMulticast); 810 MulticastSocket ms = new MulticastSocket(); 811 ms.setLoopbackMode(true); 812 assertTrue("loopback should be true", ms.getLoopbackMode()); 813 ms.setLoopbackMode(false); 814 assertTrue("loopback should be false", !ms.getLoopbackMode()); 815 ms.close(); 816 assertTrue("should be closed", ms.isClosed()); 817 } 818 819 @Test setLoopbackModeSendReceive_IPv4()820 public void setLoopbackModeSendReceive_IPv4() throws Exception { 821 Assume.assumeTrue(supportsMulticast); 822 check_setLoopbackModeSendReceive(GOOD_IPv4); 823 } 824 825 @Test setLoopbackModeSendReceive_IPv6()826 public void setLoopbackModeSendReceive_IPv6() throws Exception { 827 Assume.assumeTrue(supportsMulticast); 828 check_setLoopbackModeSendReceive(GOOD_IPv6); 829 } 830 check_setLoopbackModeSendReceive(InetAddress group)831 private void check_setLoopbackModeSendReceive(InetAddress group) throws IOException { 832 // Test send receive. 833 final String message = "Hello, world!"; 834 835 MulticastSocket socket = new MulticastSocket(0); 836 socket.setLoopbackMode(false); // false indicates doing loop back 837 socket.joinGroup(group); 838 839 // Send the datagram. 840 InetSocketAddress groupAddress = new InetSocketAddress(group, socket.getLocalPort()); 841 DatagramPacket sendDatagram = createSendDatagramPacket(groupAddress, message); 842 socket.send(sendDatagram); 843 844 // Receive the datagram. 845 DatagramPacket recvDatagram = createReceiveDatagramPacket(); 846 socket.setSoTimeout(5000); // Prevent eternal block in. 847 socket.receive(recvDatagram); 848 String recvMessage = extractMessage(recvDatagram); 849 assertEquals(message, recvMessage); 850 socket.close(); 851 } 852 853 @Test setReuseAddressZ()854 public void setReuseAddressZ() throws Exception { 855 Assume.assumeTrue(supportsMulticast); 856 // Test case were we to set ReuseAddress to false. 857 MulticastSocket theSocket1 = new MulticastSocket(null); 858 theSocket1.setReuseAddress(false); 859 860 MulticastSocket theSocket2 = new MulticastSocket(null); 861 theSocket2.setReuseAddress(false); 862 863 InetSocketAddress addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0); 864 theSocket1.bind(addr); 865 addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort()); 866 try { 867 theSocket2.bind(addr); 868 fail("No exception when trying to connect to do duplicate socket bind with re-useaddr" 869 + " set to false"); 870 } catch (BindException expected) { 871 } 872 theSocket1.close(); 873 theSocket2.close(); 874 875 // Test case were we set it to true. 876 theSocket1 = new MulticastSocket(null); 877 theSocket2 = new MulticastSocket(null); 878 theSocket1.setReuseAddress(true); 879 theSocket2.setReuseAddress(true); 880 addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0); 881 theSocket1.bind(addr); 882 addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort()); 883 theSocket2.bind(addr); 884 885 theSocket1.close(); 886 theSocket2.close(); 887 888 // Test the default case which we expect to be the same on all platforms. 889 theSocket1 = new MulticastSocket(null); 890 theSocket2 = new MulticastSocket(null); 891 addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0); 892 theSocket1.bind(addr); 893 addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort()); 894 theSocket2.bind(addr); 895 theSocket1.close(); 896 theSocket2.close(); 897 } 898 willWorkForMulticast(NetworkInterface iface)899 private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException { 900 return iface.isUp() 901 // Typically loopback interfaces do not support multicast, but we rule them out 902 // explicitly anyway. 903 && !iface.isLoopback() 904 // Point-to-point interfaces are known to cause problems. http://b/23279677 905 && !iface.isPointToPoint() 906 && iface.supportsMulticast() 907 && iface.getInetAddresses().hasMoreElements(); 908 } 909 createReceivingSocket(int aPort)910 private static MulticastSocket createReceivingSocket(int aPort) throws IOException { 911 MulticastSocket ms = new MulticastSocket(aPort); 912 ms.setSoTimeout(2000); 913 return ms; 914 } 915 createReceiveDatagramPacket()916 private static DatagramPacket createReceiveDatagramPacket() { 917 byte[] rbuf = new byte[512]; 918 return new DatagramPacket(rbuf, rbuf.length); 919 } 920 createSendDatagramPacket( InetSocketAddress groupAndPort, String msg)921 private static DatagramPacket createSendDatagramPacket( 922 InetSocketAddress groupAndPort, String msg) { 923 return new DatagramPacket( 924 msg.getBytes(), msg.length(), groupAndPort.getAddress(), groupAndPort.getPort()); 925 } 926 extractMessage(DatagramPacket rdp)927 private static String extractMessage(DatagramPacket rdp) { 928 return new String(rdp.getData(), 0, rdp.getLength()); 929 } 930 } 931