1 /* 2 * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4742177 27 * @library /test/lib 28 * @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code 29 */ 30 import java.util.*; 31 import java.net.*; 32 import jdk.test.lib.net.IPSupport; 33 34 public class NoLoopbackPackets { 35 private static String osname; 36 37 static boolean isWindows() { 38 if (osname == null) 39 osname = System.getProperty("os.name"); 40 return osname.contains("Windows"); 41 } 42 43 private static final String MESSAGE = "hello world (" + System.nanoTime() + ")"; 44 public static void main(String[] args) throws Exception { 45 if (isWindows()) { 46 System.out.println("The test only run on non-Windows OS. Bye."); 47 return; 48 } 49 50 MulticastSocket msock = null; 51 List<SocketAddress> failedGroups = new ArrayList<SocketAddress>(); 52 Sender sender = null; 53 Thread senderThread = null; 54 try { 55 msock = new MulticastSocket(); 56 int port = msock.getLocalPort(); 57 58 // we will send packets to three multicast groups :- 59 // 224.1.1.1, ::ffff:224.1.1.2, and ff02::1:1 60 // 61 List<SocketAddress> groups = new ArrayList<SocketAddress>(); 62 if (IPSupport.hasIPv4()) { 63 groups.add(new InetSocketAddress(InetAddress.getByName("224.1.1.1"), port)); 64 } 65 if (IPSupport.hasIPv6()) { 66 groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port)); 67 groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port)); 68 } 69 if (groups.isEmpty()) { 70 System.err.println("Nothing to test: there are no network interfaces"); 71 } 72 73 sender = new Sender(groups); 74 senderThread = new Thread(sender); 75 senderThread.start(); 76 77 // Now try to receive multicast packets. we should not see any of them 78 // since we disable loopback mode. 79 // 80 msock.setSoTimeout(5000); // 5 seconds 81 82 byte[] buf = new byte[1024]; 83 for (int i = 0; i < buf.length; i++) { 84 buf[i] = (byte) 'z'; 85 } 86 DatagramPacket packet = new DatagramPacket(buf, 0, buf.length); 87 byte[] expected = MESSAGE.getBytes(); 88 assert expected.length <= buf.length; 89 for (SocketAddress group : groups) { 90 System.out.println("joining group: " + group); 91 msock.joinGroup(group, null); 92 93 try { 94 do { 95 for (int i = 0; i < buf.length; i++) { 96 buf[i] = (byte) 'a'; 97 } 98 msock.receive(packet); 99 byte[] data = packet.getData(); 100 int len = packet.getLength(); 101 102 if (expected(data, len, expected)) { 103 failedGroups.add(group); 104 break; 105 } else { 106 System.err.println("WARNING: Unexpected packet received from " 107 + group + ": " 108 + len + " bytes"); 109 System.err.println("\t as text: " + new String(data, 0, len)); 110 } 111 } while (true); 112 } catch (SocketTimeoutException e) { 113 // we expect this 114 System.out.println("Received expected exception from " + group + ": " + e); 115 } finally { 116 msock.leaveGroup(group, null); 117 } 118 } 119 } finally { 120 if (msock != null) try { msock.close(); } catch (Exception e) {} 121 if (sender != null) { 122 sender.stop(); 123 } 124 } 125 try { 126 if (failedGroups.size() > 0) { 127 System.out.println("We should not receive anything from following groups, but we did:"); 128 for (SocketAddress group : failedGroups) 129 System.out.println(group); 130 throw new RuntimeException("test failed."); 131 } 132 } finally { 133 if (senderThread != null) { 134 senderThread.join(); 135 } 136 } 137 } 138 139 static boolean expected(byte[] data, int len, byte[] expected) { 140 if (len != expected.length) return false; 141 for (int i = 0; i < len; i++) { 142 if (data[i] != expected[i]) return false; 143 } 144 return true; 145 } 146 147 static class Sender implements Runnable { 148 private List<SocketAddress> sendToGroups; 149 private volatile boolean stop; 150 151 public Sender(List<SocketAddress> groups) { 152 sendToGroups = groups; 153 } 154 155 public void run() { 156 byte[] buf = MESSAGE.getBytes(); 157 List<DatagramPacket> packets = new ArrayList<DatagramPacket>(); 158 159 try (MulticastSocket msock = new MulticastSocket()) { 160 for (SocketAddress group : sendToGroups) { 161 DatagramPacket packet = new DatagramPacket(buf, buf.length, group); 162 packets.add(packet); 163 } 164 165 msock.setLoopbackMode(true); // disable loopback mode 166 while (!stop) { 167 for (DatagramPacket packet : packets) { 168 msock.send(packet); 169 } 170 171 Thread.sleep(1000); // 1 second 172 } 173 } catch (Exception e) { 174 throw new RuntimeException(e); 175 } 176 } 177 178 void stop() { 179 stop = true; 180 } 181 } 182 }