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