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