blob: ce0a1033156e5af764689cb2d3861ea7207c9773 [file] [log] [blame]
chegare55424a2013-06-20 18:53:57 +01001/*
2 * Copyright (c) 2013, 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/* @test
25 * @bug 8014499
26 * @summary Test for interference when two sockets are bound to the same
27 * port but joined to different multicast groups
28 * @run main Promiscuous
29 * @run main/othervm -Djava.net.preferIPv4Stack=true Promiscuous
30 */
31
32import java.io.IOException;
33import static java.lang.System.out;
34import java.net.*;
35
36public class Promiscuous {
37
38 static final int TIMEOUT = 5 * 1000; // 5 secs
39 static int id = 1000;
40
41 static void receive(MulticastSocket mc, boolean datagramExpected, int id)
42 throws IOException
43 {
44 byte[] ba = new byte[100];
45 DatagramPacket p = new DatagramPacket(ba, ba.length);
46 try {
47 mc.receive(p);
48 int recvId = Integer.parseInt(
49 new String(p.getData(), 0, p.getLength(), "UTF-8"));
50 if (datagramExpected) {
51 if (recvId != id)
52 throw new RuntimeException("Unexpected id, got " + recvId
53 + ", expected: " + id);
54 out.printf("Received message as expected, %s\n", p.getAddress());
55 } else {
56 throw new RuntimeException("Unexpected message received, "
57 + p.getAddress());
58 }
59 } catch (SocketTimeoutException e) {
60 if (datagramExpected)
61 throw new RuntimeException("Expected message not received, "
62 + e.getMessage());
63 else
64 out.printf("Message not received, as expected\n");
65 }
66 }
67
68 static void test(InetAddress group1, InetAddress group2)
69 throws IOException
70 {
71 try (MulticastSocket mc1 = new MulticastSocket();
72 MulticastSocket mc2 = new MulticastSocket(mc1.getLocalPort());
73 DatagramSocket ds = new DatagramSocket()) {
74 final int port = mc1.getLocalPort();
75 out.printf("Using port: %d\n", port);
76
77 mc1.setSoTimeout(TIMEOUT);
78 mc2.setSoTimeout(TIMEOUT);
79 int nextId = id;
80 byte[] msg = Integer.toString(nextId).getBytes("UTF-8");
81 DatagramPacket p = new DatagramPacket(msg, msg.length);
82 p.setAddress(group1);
83 p.setPort(port);
84
85 mc1.joinGroup(group1);
86 out.printf("mc1 joined the MC group: %s\n", group1);
87 mc2.joinGroup(group2);
88 out.printf("mc2 joined the MC group: %s\n", group2);
89
90 out.printf("Sending datagram to: %s/%d\n", group1, port);
91 ds.send(p);
92
93 // the packet should be received by mc1 only
94 receive(mc1, true, nextId);
95 receive(mc2, false, 0);
96
97 nextId = ++id;
98 msg = Integer.toString(nextId).getBytes("UTF-8");
99 p = new DatagramPacket(msg, msg.length);
100 p.setAddress(group2);
101 p.setPort(port);
102
103 out.printf("Sending datagram to: %s/%d\n", group2, port);
104 ds.send(p);
105
106 // the packet should be received by mc2 only
107 receive(mc2, true, nextId);
108 receive(mc1, false, 0);
109
110 mc1.leaveGroup(group1);
111 mc2.leaveGroup(group2);
112 }
113 }
114
115 public static void main(String args[]) throws IOException {
116 String os = System.getProperty("os.name");
117
118 // Requires IP_MULTICAST_ALL on Linux (new since 2.6.31) so skip
119 // on older kernels. Note that we skip on <= version 3 to keep the
120 // parsing simple
121 if (os.equals("Linux")) {
122 String osversion = System.getProperty("os.version");
123 String[] vers = osversion.split("\\.", 0);
124 int major = Integer.parseInt(vers[0]);
125 if (major < 3) {
126 System.out.format("Kernel version is %s, test skipped%n", osversion);
127 return;
128 }
129 }
130
131 // multicast groups used for the test
132 InetAddress ip4Group1 = InetAddress.getByName("224.7.8.9");
133 InetAddress ip4Group2 = InetAddress.getByName("225.4.5.6");
134
135 test(ip4Group1, ip4Group2);
136 }
137}