MulticastSocketTest.java revision 561ee011997c6c2f1befbfaa9d5f0a99771c1d63
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.luni.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.UnknownHostException;
32import java.util.ArrayList;
33import java.util.Enumeration;
34
35import tests.support.Support_NetworkInterface;
36import tests.support.Support_PortManager;
37
38public class MulticastSocketTest extends SocketTestCase {
39
40	Thread t;
41
42	MulticastSocket mss;
43
44	MulticastServer server;
45
46	// private member variables used for tests
47	boolean atLeastOneInterface = false;
48
49	boolean atLeastTwoInterfaces = false;
50
51	private NetworkInterface networkInterface1 = null;
52
53	private NetworkInterface networkInterface2 = null;
54
55	private NetworkInterface IPV6networkInterface1 = null;
56
57	static class MulticastServer extends Thread {
58
59		public MulticastSocket ms;
60
61		boolean running = true;
62
63		volatile public byte[] rbuf = new byte[512];
64
65        volatile DatagramPacket rdp = null;
66
67        private InetAddress groupAddr = null;
68        private SocketAddress groupSockAddr = null;
69        private NetworkInterface groupNI = null;
70
71        public void run() {
72			try {
73                byte[] tmpbuf = new byte[512];
74                DatagramPacket tmpPack =
75                        new DatagramPacket(tmpbuf, tmpbuf.length);
76
77                while (running) {
78					try {
79                        ms.receive(tmpPack);
80
81                        System.arraycopy(tmpPack.getData(), 0, rdp.getData(),
82                                rdp.getOffset(), tmpPack.getLength());
83                        rdp.setLength(tmpPack.getLength());
84                        rdp.setAddress(tmpPack.getAddress());
85                        rdp.setPort(tmpPack.getPort());
86                    } catch (java.io.InterruptedIOException e) {
87                        Thread.yield();
88					}
89				}
90			} catch (java.io.IOException e) {
91				System.out.println("Multicast server failed: " + e);
92			} finally {
93				ms.close();
94			}
95		}
96
97		public void stopServer() {
98			running = false;
99            try {
100                if (groupAddr != null) {
101                    ms.leaveGroup(groupAddr);
102                } else if (groupSockAddr != null) {
103                    ms.leaveGroup(groupSockAddr, groupNI);
104                }
105            } catch (IOException e) {}
106        }
107
108        public MulticastServer(InetAddress anAddress, int aPort)
109                throws java.io.IOException {
110            rbuf = new byte[512];
111            rbuf[0] = -1;
112            rdp = new DatagramPacket(rbuf, rbuf.length);
113            ms = new MulticastSocket(aPort);
114            ms.setSoTimeout(2000);
115            groupAddr = anAddress;
116            ms.joinGroup(groupAddr);
117        }
118
119
120        public MulticastServer(SocketAddress anAddress, int aPort,
121				NetworkInterface netInterface) throws java.io.IOException {
122			rbuf = new byte[512];
123			rbuf[0] = -1;
124			rdp = new DatagramPacket(rbuf, rbuf.length);
125			ms = new MulticastSocket(aPort);
126			ms.setSoTimeout(2000);
127            groupSockAddr = anAddress;
128            groupNI = netInterface;
129            ms.joinGroup(groupSockAddr, groupNI);
130		}
131	}
132
133	/**
134	 * @tests java.net.MulticastSocket#MulticastSocket()
135	 */
136	public void test_Constructor() throws IOException {
137		// regression test for 497
138        MulticastSocket s = new MulticastSocket();
139        // regression test for Harmony-1162
140        assertTrue(s.getReuseAddress());
141	}
142
143	/**
144	 * @tests java.net.MulticastSocket#MulticastSocket(int)
145	 */
146	public void test_ConstructorI() throws IOException {
147	    MulticastSocket orig = new MulticastSocket();
148        int port = orig.getLocalPort();
149        orig.close();
150		MulticastSocket dup = null;
151		try {
152			dup = new MulticastSocket(port);
153            // regression test for Harmony-1162
154            assertTrue(dup.getReuseAddress());
155		} catch (IOException e) {
156			fail("duplicate binding not allowed: " + e);
157		}
158		if (dup != null)
159			dup.close();
160	}
161
162	/**
163	 * @tests java.net.MulticastSocket#getInterface()
164	 */
165	public void test_getInterface() throws Exception {
166		// Test for method java.net.InetAddress
167		// java.net.MulticastSocket.getInterface()
168		assertTrue("Used for testing.", true);
169
170		int groupPort = Support_PortManager.getNextPortForUDP();
171
172                if (atLeastOneInterface) {
173                        // validate that we get the expected response when one was not
174                        // set
175                        mss = new MulticastSocket(groupPort);
176                        String preferIPv4StackValue = System
177                                        .getProperty("java.net.preferIPv4Stack");
178                        String preferIPv6AddressesValue = System
179                                        .getProperty("java.net.preferIPv6Addresses");
180                        if (((preferIPv4StackValue == null) || preferIPv4StackValue
181                                        .equalsIgnoreCase("false"))
182                                        && (preferIPv6AddressesValue != null)
183                                        && (preferIPv6AddressesValue.equals("true"))) {
184                                // we expect an IPv6 ANY in this case
185                                assertEquals("inet Address returned when not set",
186                                             InetAddress.getByName("::0"),
187                                             mss.getInterface());
188                        } else {
189                                // we expect an IPv4 ANY in this case
190                                assertEquals("inet Address returned when not set",
191                                             InetAddress.getByName("0.0.0.0"),
192                                             mss.getInterface());
193                        }
194
195                        // validate that we get the expected response when we set via
196                        // setInterface
197                        Enumeration addresses = networkInterface1.getInetAddresses();
198                        if (addresses.hasMoreElements()) {
199                                InetAddress firstAddress = (InetAddress) addresses
200                                                .nextElement();
201                                mss.setInterface(firstAddress);
202                                assertEquals("getNetworkInterface did not return interface set by setInterface",
203                                             firstAddress, mss.getInterface());
204
205                                groupPort = Support_PortManager.getNextPortForUDP();
206                                mss = new MulticastSocket(groupPort);
207                                mss.setNetworkInterface(networkInterface1);
208                                assertEquals("getInterface did not return interface set by setNetworkInterface",
209                                             networkInterface1,
210                                             NetworkInterface.getByInetAddress(mss.getInterface()));
211                        }
212
213                }
214	}
215
216	/**
217	 * @throws IOException
218	 * @tests java.net.MulticastSocket#getNetworkInterface()
219	 */
220	public void test_getNetworkInterface() throws IOException {
221        int groupPort = Support_PortManager.getNextPortForUDP();
222        if (atLeastOneInterface) {
223            // validate that we get the expected response when one was not
224            // set
225            mss = new MulticastSocket(groupPort);
226            NetworkInterface theInterface = mss.getNetworkInterface();
227            assertTrue(
228                    "network interface returned wrong network interface when not set:"
229                            + theInterface, theInterface.getInetAddresses()
230                            .hasMoreElements());
231            InetAddress firstAddress = (InetAddress) theInterface
232                    .getInetAddresses().nextElement();
233            // validate we the first address in the network interface is the
234            // ANY address
235            String preferIPv4StackValue = System
236                    .getProperty("java.net.preferIPv4Stack");
237            String preferIPv6AddressesValue = System
238                    .getProperty("java.net.preferIPv6Addresses");
239            if (((preferIPv4StackValue == null) || preferIPv4StackValue
240                    .equalsIgnoreCase("false"))
241                    && (preferIPv6AddressesValue != null)
242                    && (preferIPv6AddressesValue.equals("true"))) {
243                assertEquals("network interface returned wrong network interface when not set:"
244                             + theInterface,
245                             firstAddress, InetAddress.getByName("::0"));
246
247            } else {
248                assertEquals("network interface returned wrong network interface when not set:"
249                             + theInterface,
250                             InetAddress.getByName("0.0.0.0"),
251                             firstAddress);
252            }
253
254            mss.setNetworkInterface(networkInterface1);
255            assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
256                         networkInterface1, mss.getNetworkInterface());
257
258            if (atLeastTwoInterfaces) {
259                mss.setNetworkInterface(networkInterface2);
260                assertEquals("getNetworkInterface did not return network interface set by second setNetworkInterface call",
261                             networkInterface2, mss.getNetworkInterface());
262            }
263
264            groupPort = Support_PortManager.getNextPortForUDP();
265            mss = new MulticastSocket(groupPort);
266            if (IPV6networkInterface1 != null) {
267                mss.setNetworkInterface(IPV6networkInterface1);
268                assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
269                             IPV6networkInterface1,
270                             mss.getNetworkInterface());
271            }
272
273            // validate that we get the expected response when we set via
274            // setInterface
275            groupPort = Support_PortManager.getNextPortForUDP();
276            mss = new MulticastSocket(groupPort);
277            Enumeration addresses = networkInterface1.getInetAddresses();
278            if (addresses.hasMoreElements()) {
279                firstAddress = (InetAddress) addresses.nextElement();
280                mss.setInterface(firstAddress);
281                assertEquals("getNetworkInterface did not return interface set by setInterface",
282                             networkInterface1,
283                             mss.getNetworkInterface());
284            }
285        }
286    }
287
288	/**
289	 * @tests java.net.MulticastSocket#getTimeToLive()
290	 */
291	public void test_getTimeToLive() {
292		try {
293			mss = new MulticastSocket();
294			mss.setTimeToLive(120);
295			assertEquals("Returned incorrect 1st TTL",
296                                     120, mss.getTimeToLive());
297			mss.setTimeToLive(220);
298			assertEquals("Returned incorrect 2nd TTL",
299                                     220, mss.getTimeToLive());
300			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
301		} catch (Exception e) {
302			handleException(e, SO_MULTICAST);
303		}
304	}
305
306	/**
307	 * @tests java.net.MulticastSocket#getTTL()
308	 */
309	public void test_getTTL() {
310		// Test for method byte java.net.MulticastSocket.getTTL()
311
312		try {
313			mss = new MulticastSocket();
314			mss.setTTL((byte) 120);
315			assertEquals("Returned incorrect TTL",
316                                     120, mss.getTTL());
317			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
318		} catch (Exception e) {
319			handleException(e, SO_MULTICAST);
320		}
321	}
322
323	/**
324	 * @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
325	 */
326	public void test_joinGroupLjava_net_InetAddress() throws Exception {
327		// Test for method void
328		// java.net.MulticastSocket.joinGroup(java.net.InetAddress)
329                String msg = null;
330		InetAddress group = null;
331		int[] ports = Support_PortManager.getNextPortsForUDP(2);
332		int groupPort = ports[0];
333                group = InetAddress.getByName("224.0.0.3");
334                server = new MulticastServer(group, groupPort);
335                server.start();
336                Thread.sleep(1000);
337                msg = "Hello World";
338                mss = new MulticastSocket(ports[1]);
339                DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
340                                .length(), group, groupPort);
341                mss.send(sdp, (byte) 10);
342                Thread.sleep(1000);
343
344                assertEquals("Group member did not recv data",
345                             msg,
346                             new String(server.rdp.getData(), 0, server.rdp.getLength()));
347	}
348
349	/**
350	 * @throws IOException
351	 * @throws InterruptedException
352	 * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,java.net.NetworkInterface)
353	 */
354	public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws IOException, InterruptedException {
355		// security manager that allows us to check that we only return the
356		// addresses that we should
357		class mySecurityManager extends SecurityManager {
358
359			public void checkMulticast(InetAddress address) {
360				throw new SecurityException("not allowed");
361			}
362		}
363
364		String msg = null;
365		InetAddress group = null;
366		SocketAddress groupSockAddr = null;
367		int[] ports = Support_PortManager.getNextPortsForUDP(2);
368		int groupPort = ports[0];
369		int serverPort = ports[1];
370
371        Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
372
373        // first validate that we handle a null group ok
374        mss = new MulticastSocket(groupPort);
375        try {
376            mss.joinGroup(null, null);
377            fail("Did not get exception when group was null");
378        } catch (IllegalArgumentException e) {
379        }
380
381        // now validate we get the expected error if the address specified
382        // is not a multicast group
383        try {
384            groupSockAddr = new InetSocketAddress(InetAddress
385                    .getByName("255.255.255.255"), groupPort);
386            mss.joinGroup(groupSockAddr, null);
387            fail("Did not get exception when group is not a multicast address");
388        } catch (IOException e) {
389        }
390
391        // now try to join a group if we are not authorized
392        // set the security manager that will make the first address not
393        // visible
394        System.setSecurityManager(new mySecurityManager());
395        try {
396            group = InetAddress.getByName("224.0.0.3");
397            groupSockAddr = new InetSocketAddress(group, groupPort);
398            mss.joinGroup(groupSockAddr, null);
399            fail("Did not get exception when joining group is not allowed");
400        } catch (SecurityException e) {
401        }
402        System.setSecurityManager(null);
403
404        if (atLeastOneInterface) {
405            // now validate that we can properly join a group with a null
406            // network interface
407            ports = Support_PortManager.getNextPortsForUDP(2);
408            groupPort = ports[0];
409            serverPort = ports[1];
410            mss = new MulticastSocket(groupPort);
411            mss.joinGroup(groupSockAddr, null);
412            mss.setTimeToLive(2);
413            Thread.sleep(1000);
414
415            // set up the server and join the group on networkInterface1
416            group = InetAddress.getByName("224.0.0.3");
417            groupSockAddr = new InetSocketAddress(group, groupPort);
418            server = new MulticastServer(groupSockAddr, serverPort,
419                    networkInterface1);
420            server.start();
421            Thread.sleep(1000);
422            msg = "Hello World";
423            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
424                    .length(), group, serverPort);
425            mss.setTimeToLive(2);
426            mss.send(sdp);
427            Thread.sleep(1000);
428            // now vaildate that we received the data as expected
429            assertEquals("Group member did not recv data",
430                         msg,
431                         new String(server.rdp.getData(), 0, server.rdp.getLength()));
432            server.stopServer();
433
434            // now validate that we handled the case were we join a
435            // different multicast address.
436            // verify we do not receive the data
437            ports = Support_PortManager.getNextPortsForUDP(2);
438            serverPort = ports[0];
439            server = new MulticastServer(groupSockAddr, serverPort,
440                    networkInterface1);
441            server.start();
442            Thread.sleep(1000);
443
444            groupPort = ports[1];
445            mss = new MulticastSocket(groupPort);
446            InetAddress group2 = InetAddress.getByName("224.0.0.4");
447            mss.setTimeToLive(10);
448            msg = "Hello World - Different Group";
449            sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2,
450                    serverPort);
451            mss.send(sdp);
452            Thread.sleep(1000);
453            assertFalse(
454                    "Group member received data when sent on different group: ",
455                    new String(server.rdp.getData(), 0, server.rdp.getLength())
456                            .equals(msg));
457            server.stopServer();
458
459            // if there is more than one network interface then check that
460            // we can join on specific interfaces and that we only receive
461            // if data is received on that interface
462            if (atLeastTwoInterfaces) {
463                // set up server on first interfaces
464                NetworkInterface loopbackInterface = NetworkInterface
465                        .getByInetAddress(InetAddress.getByName("127.0.0.1"));
466
467                boolean anyLoop = networkInterface1.equals(loopbackInterface) || networkInterface2.equals(loopbackInterface);
468
469                ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
470                theInterfaces = NetworkInterface.getNetworkInterfaces();
471                while (theInterfaces.hasMoreElements()) {
472                    NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
473                    if (thisInterface.getInetAddresses().hasMoreElements()
474                            && (Support_NetworkInterface
475                                    .useInterface(thisInterface) == true)){
476                        realInterfaces.add(thisInterface);
477                    }
478                }
479
480                for (int i = 0; i < realInterfaces.size(); i++) {
481                    final int SECOND = 1;
482                    NetworkInterface thisInterface = realInterfaces.get(i);
483
484                        // get the first address on the interface
485
486                        // start server which is joined to the group and has
487                        // only asked for packets on this interface
488                        Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
489
490                        NetworkInterface sendingInterface = null;
491                        if (addresses.hasMoreElements()) {
492                            InetAddress firstAddress = (InetAddress) addresses.nextElement();
493                            if (firstAddress instanceof Inet4Address) {
494                                group = InetAddress.getByName("224.0.0.4");
495                                if (anyLoop) {
496                                    if (networkInterface1.equals(loopbackInterface)) {
497                                        sendingInterface = networkInterface2;
498                                    } else {
499                                        sendingInterface = networkInterface1;
500                                    }
501                                } else {
502                                    if(i == SECOND){
503                                        sendingInterface = networkInterface2;
504                                    } else {
505                                        sendingInterface = networkInterface1;
506                                }
507                               }
508                            } else {
509                                // if this interface only seems to support
510                                // IPV6 addresses
511                                group = InetAddress
512                                        .getByName("FF01:0:0:0:0:0:2:8001");
513                                sendingInterface = IPV6networkInterface1;
514                            }
515                        }
516
517                        ports = Support_PortManager.getNextPortsForUDP(2);
518                        serverPort = ports[0];
519                        groupPort = ports[1];
520                        groupSockAddr = new InetSocketAddress(group, serverPort);
521                        server = new MulticastServer(groupSockAddr, serverPort,
522                                thisInterface);
523                        server.start();
524                        Thread.sleep(1000);
525
526                        // Now send out a package on interface
527                        // networkInterface 1. We should
528                        // only see the packet if we send it on interface 1
529                        mss = new MulticastSocket(groupPort);
530                        mss.setNetworkInterface(sendingInterface);
531                        msg = "Hello World - Again" + thisInterface.getName();
532                        sdp = new DatagramPacket(msg.getBytes(), msg.length(),
533                                group, serverPort);
534                        mss.send(sdp);
535                        Thread.sleep(1000);
536                        if (thisInterface.equals(sendingInterface)) {
537                            assertEquals("Group member did not recv data when bound on specific interface",
538                                         msg,
539                                         new String(server.rdp.getData(), 0, server.rdp.getLength()));
540                        } else {
541                            assertFalse(
542                                    "Group member received data on other interface when only asked for it on one interface: ",
543                                    new String(server.rdp.getData(), 0,
544                                            server.rdp.getLength()).equals(msg));
545                        }
546
547                        server.stopServer();
548                    }
549
550
551                // validate that we can join the same address on two
552                // different interfaces but not on the same interface
553                groupPort = Support_PortManager.getNextPortForUDP();
554                mss = new MulticastSocket(groupPort);
555                mss.joinGroup(groupSockAddr, networkInterface1);
556                mss.joinGroup(groupSockAddr, networkInterface2);
557                try {
558                    mss.joinGroup(groupSockAddr, networkInterface1);
559                    fail("Did not get expected exception when joining for second time on same interface");
560                } catch (IOException e) {
561                }
562            }
563        }
564		System.setSecurityManager(null);
565	}
566
567	/**
568	 * @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
569	 */
570	public void test_leaveGroupLjava_net_InetAddress() {
571		// Test for method void
572		// java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
573		String msg = null;
574		boolean except = false;
575		InetAddress group = null;
576		int[] ports = Support_PortManager.getNextPortsForUDP(2);
577		int groupPort = ports[0];
578
579		try {
580			group = InetAddress.getByName("224.0.0.3");
581			msg = "Hello World";
582			mss = new MulticastSocket(ports[1]);
583			DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
584					.length(), group, groupPort);
585			mss.send(sdp, (byte) 10);
586			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
587		} catch (Exception e) {
588			handleException(e, SO_MULTICAST);
589		}
590		try {
591			// Try to leave s group that mss is not a member of
592			mss.leaveGroup(group);
593		} catch (java.io.IOException e) {
594			// Correct
595			except = true;
596		}
597		assertTrue("Failed to throw exception leaving non-member group", except);
598	}
599
600	/**
601	 * @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,java.net.NetworkInterface)
602	 */
603	public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
604		// security manager that allows us to check that we only return the
605		// addresses that we should
606		class mySecurityManager extends SecurityManager {
607
608			public void checkMulticast(InetAddress address) {
609				throw new SecurityException("not allowed");
610			}
611		}
612
613		String msg = null;
614		InetAddress group = null;
615		int groupPort = Support_PortManager.getNextPortForUDP();
616		SocketAddress groupSockAddr = null;
617		SocketAddress groupSockAddr2 = null;
618
619                Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
620
621                // first validate that we handle a null group ok
622                mss = new MulticastSocket(groupPort);
623                try {
624                        mss.leaveGroup(null, null);
625                        fail("Did not get exception when group was null");
626                } catch (IllegalArgumentException e) {
627                }
628
629                // now validate we get the expected error if the address specified
630                // is not a multicast group
631                try {
632                        group = InetAddress.getByName("255.255.255.255");
633                        groupSockAddr = new InetSocketAddress(group, groupPort);
634                        mss.leaveGroup(groupSockAddr, null);
635                        fail("Did not get exception when group is not a multicast address");
636                } catch (IOException e) {
637                }
638
639                // now try to leave a group if we are not authorized
640                // set the security manager that will make the first address not
641                // visible
642                System.setSecurityManager(new mySecurityManager());
643                try {
644                        group = InetAddress.getByName("224.0.0.3");
645                        groupSockAddr = new InetSocketAddress(group, groupPort);
646                        mss.leaveGroup(groupSockAddr, null);
647                        fail("Did not get exception when joining group is not allowed");
648                } catch (SecurityException e) {
649                }
650                System.setSecurityManager(null);
651
652                if (atLeastOneInterface) {
653
654                        // now test that we can join and leave a group successfully
655                        groupPort = Support_PortManager.getNextPortForUDP();
656                        mss = new MulticastSocket(groupPort);
657                        groupSockAddr = new InetSocketAddress(group, groupPort);
658                        mss.joinGroup(groupSockAddr, null);
659                        mss.leaveGroup(groupSockAddr, null);
660                        try {
661                                mss.leaveGroup(groupSockAddr, null);
662                                fail(
663                                                "Did not get exception when trying to leave group that was allready left");
664                        } catch (IOException e) {
665                        }
666
667                        InetAddress group2 = InetAddress.getByName("224.0.0.4");
668                        groupSockAddr2 = new InetSocketAddress(group2, groupPort);
669                        mss.joinGroup(groupSockAddr, networkInterface1);
670                        try {
671                                mss.leaveGroup(groupSockAddr2, networkInterface1);
672                                fail(
673                                                "Did not get exception when trying to leave group that was never joined");
674                        } catch (IOException e) {
675                        }
676
677                        mss.leaveGroup(groupSockAddr, networkInterface1);
678                        if (atLeastTwoInterfaces) {
679                                mss.joinGroup(groupSockAddr, networkInterface1);
680                                try {
681                                        mss.leaveGroup(groupSockAddr, networkInterface2);
682                                        fail(
683                                                        "Did not get exception when trying to leave group on wrong interface joined on ["
684                                                                        + networkInterface1
685                                                                        + "] left on ["
686                                                                        + networkInterface2 + "]");
687                                } catch (IOException e) {
688                                }
689                        }
690                }
691
692                System.setSecurityManager(null);
693	}
694
695	/**
696	 * @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
697	 */
698	public void test_sendLjava_net_DatagramPacketB() {
699		// Test for method void
700		// java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
701
702		String msg = "Hello World";
703		InetAddress group = null;
704		int[] ports = Support_PortManager.getNextPortsForUDP(2);
705		int groupPort = ports[0];
706
707		try {
708			group = InetAddress.getByName("224.0.0.3");
709			mss = new MulticastSocket(ports[1]);
710			server = new MulticastServer(group, groupPort);
711			server.start();
712			Thread.sleep(200);
713			DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
714					.length(), group, groupPort);
715			mss.send(sdp, (byte) 10);
716			Thread.sleep(1000);
717			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
718		} catch (Exception e) {
719			handleException(e, SO_MULTICAST);
720			try {
721				mss.close();
722			} catch (Exception ex) {
723			}
724			;
725			return;
726		}
727		mss.close();
728		byte[] data = server.rdp.getData();
729		int length = server.rdp.getLength();
730		assertEquals("Failed to send data. Received " + length,
731                             msg, new String(data, 0, length));
732	}
733
734	/**
735	 * @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
736	 */
737	public void test_setInterfaceLjava_net_InetAddress() throws UnknownHostException {
738		// Test for method void
739		// java.net.MulticastSocket.setInterface(java.net.InetAddress)
740		// Note that the machine is not multi-homed
741
742		try {
743			mss = new MulticastSocket();
744			mss.setInterface(InetAddress.getLocalHost());
745			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
746		} catch (Exception e) {
747			handleException(e, SO_MULTICAST_INTERFACE);
748			return;
749		}
750		try {
751			InetAddress theInterface = mss.getInterface();
752			// under IPV6 we are not guarrenteed to get the same address back as
753			// the address, all we should be guaranteed is that we get an
754			// address on the same interface
755			if (theInterface instanceof Inet6Address) {
756				assertTrue(
757						"Failed to return correct interface IPV6",
758						NetworkInterface
759								.getByInetAddress(mss.getInterface())
760								.equals(
761										NetworkInterface
762												.getByInetAddress(theInterface)));
763			} else {
764				assertTrue("Failed to return correct interface IPV4 got:"
765						+ mss.getInterface() + " excpeted: "
766						+ InetAddress.getLocalHost(), mss.getInterface()
767						.equals(InetAddress.getLocalHost()));
768			}
769			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
770		} catch (SocketException e) {
771			handleException(e, SO_MULTICAST);
772		}
773
774		// Regression test for Harmony-2410
775		try {
776			mss = new MulticastSocket();
777			mss.setInterface(InetAddress.getByName("224.0.0.5"));
778		} catch (SocketException se) {
779			// expected
780		} catch (IOException ioe) {
781			handleException(ioe, SO_MULTICAST_INTERFACE);
782			return;
783		}
784	}
785
786	/**
787	 * @throws IOException
788	 * @throws InterruptedException
789	 * @tests java.net.MulticastSocket#setNetworkInterface(java.net.NetworkInterface)
790	 */
791	public void test_setNetworkInterfaceLjava_net_NetworkInterface() throws IOException, InterruptedException {
792		String msg = null;
793		InetAddress group = null;
794		int[] ports = Support_PortManager.getNextPortsForUDP(2);
795		int groupPort = ports[0];
796		int serverPort = ports[1];
797		if (atLeastOneInterface) {
798            // validate that null interface is handled ok
799            mss = new MulticastSocket(groupPort);
800
801            // this should through a socket exception to be compatible
802            try {
803                mss.setNetworkInterface(null);
804                fail("No socket exception when we set then network interface with NULL");
805            } catch (SocketException ex) {
806            }
807
808            // validate that we can get and set the interface
809            groupPort = Support_PortManager.getNextPortForUDP();
810            mss = new MulticastSocket(groupPort);
811            mss.setNetworkInterface(networkInterface1);
812            assertEquals("Interface did not seem to be set by setNeworkInterface",
813                         networkInterface1, mss.getNetworkInterface());
814
815            // set up the server and join the group
816            group = InetAddress.getByName("224.0.0.3");
817
818            Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
819            while (theInterfaces.hasMoreElements()) {
820                NetworkInterface thisInterface = (NetworkInterface) theInterfaces
821                        .nextElement();
822                if (thisInterface.getInetAddresses().hasMoreElements()) {
823                    if ((!((InetAddress) thisInterface.getInetAddresses()
824                            .nextElement()).isLoopbackAddress())
825                            &&
826                            // for windows we cannot use these pseudo
827                            // interfaces for the test as the packets still
828                            // come from the actual interface, not the
829                            // Pseudo interface that was set
830                            (Support_NetworkInterface
831                                    .useInterface(thisInterface) == true)) {
832                        ports = Support_PortManager.getNextPortsForUDP(2);
833                        serverPort = ports[0];
834                        server = new MulticastServer(group, serverPort);
835                        server.start();
836                        // give the server some time to start up
837                        Thread.sleep(1000);
838
839                        // Send the packets on a particular interface. The
840                        // source address in the received packet
841                        // should be one of the addresses for the interface
842                        // set
843                        groupPort = ports[1];
844                        mss = new MulticastSocket(groupPort);
845                        mss.setNetworkInterface(thisInterface);
846                        msg = thisInterface.getName();
847                        byte theBytes[] = msg.getBytes();
848                        DatagramPacket sdp = new DatagramPacket(theBytes,
849                                theBytes.length, group, serverPort);
850                        mss.send(sdp);
851                        Thread.sleep(1000);
852                        String receivedMessage = new String(server.rdp
853                                .getData(), 0, server.rdp.getLength());
854                        assertEquals("Group member did not recv data sent on a specific interface",
855                                     msg, receivedMessage);
856                        // stop the server
857                        server.stopServer();
858                    }
859                }
860            }
861        }
862	}
863
864	/**
865	 * @tests java.net.MulticastSocket#setTimeToLive(int)
866	 */
867	public void test_setTimeToLiveI() {
868		try {
869			mss = new MulticastSocket();
870			mss.setTimeToLive(120);
871			assertEquals("Returned incorrect 1st TTL",
872                                     120, mss.getTimeToLive());
873			mss.setTimeToLive(220);
874			assertEquals("Returned incorrect 2nd TTL",
875                                     220, mss.getTimeToLive());
876			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
877		} catch (Exception e) {
878			handleException(e, SO_MULTICAST);
879		}
880	}
881
882	/**
883	 * @tests java.net.MulticastSocket#setTTL(byte)
884	 */
885	public void test_setTTLB() {
886		// Test for method void java.net.MulticastSocket.setTTL(byte)
887		try {
888			mss = new MulticastSocket();
889			mss.setTTL((byte) 120);
890			assertEquals("Failed to set TTL", 120, mss.getTTL());
891			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
892		} catch (Exception e) {
893			handleException(e, SO_MULTICAST);
894		}
895	}
896
897	/**
898	 * @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
899	 */
900	public void test_ConstructorLjava_net_SocketAddress() throws Exception {
901		MulticastSocket ms = new MulticastSocket((SocketAddress) null);
902        assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
903                && !ms.isConnected());
904        ms.bind(new InetSocketAddress(InetAddress.getLocalHost(),
905                Support_PortManager.getNextPortForUDP()));
906        assertTrue("should be bound", ms.isBound() && !ms.isClosed()
907                && !ms.isConnected());
908        ms.close();
909        assertTrue("should be closed", ms.isClosed());
910        ms = new MulticastSocket(new InetSocketAddress(InetAddress
911                .getLocalHost(), Support_PortManager.getNextPortForUDP()));
912        assertTrue("should be bound", ms.isBound() && !ms.isClosed()
913                && !ms.isConnected());
914        ms.close();
915        assertTrue("should be closed", ms.isClosed());
916        ms = new MulticastSocket(new InetSocketAddress("localhost",
917                Support_PortManager.getNextPortForUDP()));
918        assertTrue("should be bound", ms.isBound() && !ms.isClosed()
919                && !ms.isConnected());
920        ms.close();
921        assertTrue("should be closed", ms.isClosed());
922        boolean exception = false;
923        try {
924            ms = new MulticastSocket(new InetSocketAddress("unresolvedname",
925                    Support_PortManager.getNextPortForUDP()));
926        } catch (IOException e) {
927            exception = true;
928        }
929        assertTrue("Expected IOException", exception);
930
931        // regression test for Harmony-1162
932        InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
933        MulticastSocket s = new MulticastSocket(addr);
934        assertTrue(s.getReuseAddress());
935	}
936
937	/**
938	 * @tests java.net.MulticastSocket#getLoopbackMode()
939	 */
940	public void test_getLoopbackMode() {
941		try {
942			MulticastSocket ms = new MulticastSocket((SocketAddress) null);
943			assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
944					&& !ms.isConnected());
945			ms.getLoopbackMode();
946			assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
947					&& !ms.isConnected());
948			ms.close();
949			assertTrue("should be closed", ms.isClosed());
950			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
951		} catch (IOException e) {
952			handleException(e, SO_USELOOPBACK);
953		}
954	}
955
956	/**
957	 * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
958	 */
959	public void test_setLoopbackModeZ() {
960		try {
961			MulticastSocket ms = new MulticastSocket();
962			ms.setLoopbackMode(true);
963			assertTrue("loopback should be true", ms.getLoopbackMode());
964			ms.setLoopbackMode(false);
965			assertTrue("loopback should be false", !ms.getLoopbackMode());
966			ms.close();
967			assertTrue("should be closed", ms.isClosed());
968			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
969		} catch (IOException e) {
970			handleException(e, SO_USELOOPBACK);
971		}
972	}
973
974    /**
975     * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
976     */
977    public void test_setLoopbackModeSendReceive() throws IOException{
978        final String ADDRESS = "224.1.2.3";
979        final int PORT = Support_PortManager.getNextPortForUDP();
980        final String message = "Hello, world!";
981
982        // test send receive
983        MulticastSocket socket = null;
984        try {
985            // open a multicast socket
986            socket = new MulticastSocket(PORT);
987            socket.setLoopbackMode(false); // false indecates doing loop back
988            socket.joinGroup(InetAddress.getByName(ADDRESS));
989
990            // send the datagram
991            byte[] sendData = message.getBytes();
992            DatagramPacket sendDatagram = new DatagramPacket(sendData, 0,
993                    sendData.length, new InetSocketAddress(InetAddress
994                            .getByName(ADDRESS), PORT));
995            socket.send(sendDatagram);
996
997            // receive the datagram
998            byte[] recvData = new byte[100];
999            DatagramPacket recvDatagram = new DatagramPacket(recvData,
1000                    recvData.length);
1001            socket.setSoTimeout(5000); // prevent eternal block in
1002            // socket.receive()
1003            socket.receive(recvDatagram);
1004            String recvMessage = new String(recvData, 0, recvDatagram
1005                    .getLength());
1006            assertEquals(message, recvMessage);
1007        }finally {
1008            if (socket != null)
1009                socket.close();
1010        }
1011    }
1012
1013
1014	/**
1015	 * @tests java.net.MulticastSocket#setReuseAddress(boolean)
1016	 */
1017	public void test_setReuseAddressZ() throws Exception {
1018		try {
1019			// test case were we set it to false
1020			MulticastSocket theSocket1 = null;
1021			MulticastSocket theSocket2 = null;
1022			try {
1023				InetSocketAddress theAddress = new InetSocketAddress(
1024						InetAddress.getLocalHost(), Support_PortManager
1025								.getNextPortForUDP());
1026				theSocket1 = new MulticastSocket(null);
1027				theSocket2 = new MulticastSocket(null);
1028				theSocket1.setReuseAddress(false);
1029				theSocket2.setReuseAddress(false);
1030				theSocket1.bind(theAddress);
1031				theSocket2.bind(theAddress);
1032				fail(
1033						"No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
1034			} catch (BindException e) {
1035
1036			}
1037			if (theSocket1 != null)
1038				theSocket1.close();
1039			if (theSocket2 != null)
1040				theSocket2.close();
1041
1042			// test case were we set it to true
1043                        InetSocketAddress theAddress = new InetSocketAddress(
1044                                        InetAddress.getLocalHost(), Support_PortManager
1045                                                        .getNextPortForUDP());
1046                        theSocket1 = new MulticastSocket(null);
1047                        theSocket2 = new MulticastSocket(null);
1048                        theSocket1.setReuseAddress(true);
1049                        theSocket2.setReuseAddress(true);
1050                        theSocket1.bind(theAddress);
1051                        theSocket2.bind(theAddress);
1052
1053                        if (theSocket1 != null)
1054				theSocket1.close();
1055			if (theSocket2 != null)
1056				theSocket2.close();
1057
1058			// test the default case which we expect to be
1059			// the same on all platforms
1060                        theAddress =
1061                            new InetSocketAddress(
1062                                    InetAddress.getLocalHost(),
1063                                    Support_PortManager.getNextPortForUDP());
1064                        theSocket1 = new MulticastSocket(null);
1065                        theSocket2 = new MulticastSocket(null);
1066                        theSocket1.bind(theAddress);
1067                        theSocket2.bind(theAddress);
1068			if (theSocket1 != null)
1069				theSocket1.close();
1070			if (theSocket2 != null)
1071				theSocket2.close();
1072			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
1073		} catch (Exception e) {
1074			handleException(e, SO_REUSEADDR);
1075		}
1076	}
1077
1078	/**
1079	 * Sets up the fixture, for example, open a network connection. This method
1080	 * is called before a test is executed.
1081	 */
1082	protected void setUp() {
1083
1084		Enumeration theInterfaces = null;
1085		try {
1086			theInterfaces = NetworkInterface.getNetworkInterfaces();
1087		} catch (Exception e) {
1088		}
1089
1090		// only consider interfaces that have addresses associated with them.
1091		// Otherwise tests don't work so well
1092		if (theInterfaces != null) {
1093
1094			atLeastOneInterface = false;
1095			while (theInterfaces.hasMoreElements()
1096                    && (atLeastOneInterface == false)) {
1097                networkInterface1 = (NetworkInterface) theInterfaces
1098                        .nextElement();
1099                if (networkInterface1.getInetAddresses().hasMoreElements() &&
1100                        // we only want real interfaces
1101                        (Support_NetworkInterface
1102                                .useInterface(networkInterface1) == true)) {
1103                    atLeastOneInterface = true;
1104                }
1105            }
1106
1107			atLeastTwoInterfaces = false;
1108			if (theInterfaces.hasMoreElements()) {
1109                while (theInterfaces.hasMoreElements()
1110                        && (atLeastTwoInterfaces == false)) {
1111                    networkInterface2 = (NetworkInterface) theInterfaces
1112                            .nextElement();
1113                    if (networkInterface2.getInetAddresses().hasMoreElements()
1114                            &&
1115                            // we only want real interfaces
1116                            (Support_NetworkInterface
1117                                    .useInterface(networkInterface2) == true)) {
1118                        atLeastTwoInterfaces = true;
1119                    }
1120                }
1121            }
1122
1123			Enumeration addresses;
1124
1125			// first the first interface that supports IPV6 if one exists
1126			try {
1127				theInterfaces = NetworkInterface.getNetworkInterfaces();
1128			} catch (Exception e) {
1129			}
1130			boolean found = false;
1131			while (theInterfaces.hasMoreElements() && !found) {
1132				NetworkInterface nextInterface = (NetworkInterface) theInterfaces
1133						.nextElement();
1134				addresses = nextInterface.getInetAddresses();
1135				if (addresses.hasMoreElements()) {
1136					while (addresses.hasMoreElements()) {
1137						InetAddress nextAddress = (InetAddress) addresses
1138								.nextElement();
1139						if (nextAddress instanceof Inet6Address) {
1140							IPV6networkInterface1 = nextInterface;
1141							found = true;
1142							break;
1143						}
1144					}
1145				}
1146			}
1147		}
1148	}
1149
1150	/**
1151	 * Tears down the fixture, for example, close a network connection. This
1152	 * method is called after a test is executed.
1153	 */
1154	protected void tearDown() {
1155
1156		if (t != null)
1157			t.interrupt();
1158		if (mss != null)
1159			mss.close();
1160		if (server != null)
1161			server.stopServer();
1162	}
1163}
1164