Path: blob/master/test/jdk/java/net/MulticastSocket/Promiscuous.java
41152 views
/*1* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*2223/* @test24* @bug 8014499 821980425* @library /test/lib26* @summary Test for interference when two sockets are bound to the same27* port but joined to different multicast groups28* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl Promiscuous29* @run main Promiscuous30* @run main/othervm -Djava.net.preferIPv4Stack=true Promiscuous31*/3233import java.io.IOException;34import static java.lang.System.out;3536import java.io.UncheckedIOException;37import java.net.*;3839import jdk.test.lib.NetworkConfiguration;40import jdk.test.lib.net.IPSupport;4142public class Promiscuous {4344static final int TIMEOUT = 5 * 1000; // 5 secs45static int id = 1000;4647static void receive(MulticastSocket mc, boolean datagramExpected, int id)48throws IOException49{50byte[] ba = new byte[100];51DatagramPacket p;52try {53String data = null;54while (true) {55p = new DatagramPacket(ba, ba.length);56mc.receive(p);57data = new String(p.getData(), 0, p.getLength(), "UTF-8");58if (data.length() > UUID.length() && data.startsWith(UUID)) {59data = data.substring(UUID.length());60break;61}62logUnexpected(p);63}64int recvId = Integer.parseInt(data);65if (datagramExpected) {66if (recvId != id)67throw new RuntimeException("Unexpected id, got " + recvId68+ ", expected: " + id);69out.printf("Received message as expected, %s\n", p.getAddress());70} else {71throw new RuntimeException("Unexpected message received, "72+ p.getAddress());73}74} catch (SocketTimeoutException e) {75if (datagramExpected)76throw new RuntimeException(mc.getLocalSocketAddress()77+ ": Expected message not received, "78+ e.getMessage());79else80out.printf("Message not received, as expected\n");81}82}8384static void logUnexpected(DatagramPacket p) {85byte[] ba = p.getData();86System.out.printf("Unexpected packet: length: %d. First three bytes: %d, %d, %d\n",87p.getLength(), ba[0], ba[1], ba[2]);88}8990static final String UUID; // process-id : currentTimeMillis9192static {93String s1 = Long.toString(ProcessHandle.current().pid());94String s2 = Long.toString(System.currentTimeMillis());95UUID = "<" + s1 + s2 + ">";96}9798static SocketAddress toSocketAddress(InetAddress group) {99return new InetSocketAddress(group, 0);100}101102static void test(InetAddress group1, InetAddress group2)103throws IOException104{105try (MulticastSocket mc1 = new MulticastSocket();106MulticastSocket mc2 = new MulticastSocket(mc1.getLocalPort());107DatagramSocket ds = new DatagramSocket()) {108final int port = mc1.getLocalPort();109out.printf("Using port: %d\n", port);110111mc1.setSoTimeout(TIMEOUT);112mc2.setSoTimeout(TIMEOUT);113int nextId = id;114byte[] msg = (UUID + Integer.toString(nextId)).getBytes("UTF-8");115DatagramPacket p = new DatagramPacket(msg, msg.length);116p.setAddress(group1);117p.setPort(port);118119// join groups on all network interfaces120NetworkConfiguration.probe()121.ip4MulticastInterfaces(false)122.forEach((nic) -> {123try {124mc1.joinGroup(toSocketAddress(group1), nic);125out.printf("mc1 joined the MC group on %s: %s\n",126nic.getDisplayName(), group1);127mc2.joinGroup(toSocketAddress(group2), nic);128out.printf("mc2 joined the MC group on %s: %s\n",129nic.getDisplayName(), group2);130} catch (IOException io) {131throw new UncheckedIOException(io);132}133});134135out.printf("Sending datagram to: %s/%d\n", group1, port);136ds.send(p);137138// the packet should be received by mc1 only139receive(mc1, true, nextId);140receive(mc2, false, 0);141142nextId = ++id;143msg = (UUID + Integer.toString(nextId)).getBytes("UTF-8");144p = new DatagramPacket(msg, msg.length);145p.setAddress(group2);146p.setPort(port);147148out.printf("Sending datagram to: %s/%d\n", group2, port);149ds.send(p);150151// the packet should be received by mc2 only152receive(mc2, true, nextId);153receive(mc1, false, 0);154155// leave groups on all network interfaces156NetworkConfiguration.probe()157.ip4MulticastInterfaces(false)158.forEach((nic) -> {159try {160mc1.leaveGroup(toSocketAddress(group1), nic);161out.printf("mc1 left the MC group on %s: %s\n",162nic.getDisplayName(), group1);163mc2.leaveGroup(toSocketAddress(group2), nic);164out.printf("mc2 left the MC group on %s: %s\n",165nic.getDisplayName(), group2);166} catch (IOException io) {167throw new UncheckedIOException(io);168}169});170}171}172173public static void main(String args[]) throws IOException {174IPSupport.throwSkippedExceptionIfNonOperational();175String os = System.getProperty("os.name");176177// Requires IP_MULTICAST_ALL on Linux (new since 2.6.31) so skip178// on older kernels. Note that we skip on <= version 3 to keep the179// parsing simple180if (os.equals("Linux")) {181String osversion = System.getProperty("os.version");182String[] vers = osversion.split("\\.", 0);183int major = Integer.parseInt(vers[0]);184if (major < 3) {185System.out.format("Kernel version is %s, test skipped%n", osversion);186return;187}188}189190// multicast groups used for the test191InetAddress ip4Group1 = InetAddress.getByName("224.1.1.120");192InetAddress ip4Group2 = InetAddress.getByName("224.1.1.121");193194test(ip4Group1, ip4Group2);195}196}197198199