Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/net/MulticastSocket/SetLoopbackOption.java
41149 views
1
/*
2
* Copyright (c) 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 8233296
27
* @summary Check that MulticastSocket::setOption and MulticastSocket::getOption
28
* return the correct result for StandardSocketOptions.IP_MULTICAST_LOOP.
29
* The test sets a DatagramSocketImplFactory and needs to run in /othervm
30
* mode.
31
* @run testng/othervm SetLoopbackOption
32
* @run testng/othervm -Djava.net.preferIPv4Stack=true SetLoopbackOption
33
* @run testng/othervm -Djava.net.preferIPv6Addresses=true SetLoopbackOption
34
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackOption
35
*/
36
37
import java.io.FileDescriptor;
38
import java.io.IOException;
39
import java.net.DatagramPacket;
40
import java.net.DatagramSocket;
41
import java.net.DatagramSocketImpl;
42
import java.net.DatagramSocketImplFactory;
43
import java.net.InetAddress;
44
import java.net.InetSocketAddress;
45
import java.net.MulticastSocket;
46
import java.net.NetworkInterface;
47
import java.net.SocketAddress;
48
import java.net.SocketException;
49
import java.net.SocketOption;
50
import java.net.SocketOptions;
51
import java.net.StandardSocketOptions;
52
import java.util.HashMap;
53
import java.util.Map;
54
import java.util.Set;
55
56
import org.testng.annotations.Test;
57
import static org.testng.Assert.*;
58
59
import static java.lang.System.out;
60
61
public class SetLoopbackOption {
62
63
final InetAddress loopbackAddress = InetAddress.getLoopbackAddress();
64
65
@Test
66
public void run() throws Exception {
67
var bindAddress = new InetSocketAddress(loopbackAddress, 0);
68
try (MulticastSocket sock = new MulticastSocket(null)) {
69
out.println("Testing unbound socket");
70
test(sock, null);
71
out.printf("\nBinding socket to %s and testing again%n", bindAddress);
72
sock.bind(bindAddress);
73
test(sock, null);
74
}
75
TestDatagramSocketImplFactory factory = new TestDatagramSocketImplFactory();
76
DatagramSocket.setDatagramSocketImplFactory(factory);
77
try (MulticastSocket sock = new MulticastSocket(null)) {
78
out.println("\nTesting unbound socket with custom impl");
79
TestDatagramSocketImpl impl = factory.last;
80
test(sock, impl);
81
out.printf("\nBinding socket to %s and testing again%n", bindAddress);
82
sock.bind(new InetSocketAddress(loopbackAddress, 0));
83
test(sock, impl);
84
}
85
}
86
87
private void test(MulticastSocket sock, TestDatagramSocketImpl impl) throws Exception {
88
out.println("Testing with " + sock.getClass() + (impl == null ? "" : ", " + impl.getClass()));
89
var op = StandardSocketOptions.IP_MULTICAST_LOOP;
90
var opId = SocketOptions.IP_MULTICAST_LOOP;
91
boolean enable = sock.getOption(op);
92
assertTrue(enable, "Initial Value for " + op);
93
boolean disable = sock.getLoopbackMode();
94
assertFalse(disable, "Initial Value for getLoopbackMode()");
95
if (impl != null) {
96
assertFalse((Boolean)impl.getOption(opId));
97
assertTrue((Boolean)impl.getOption(op));
98
}
99
100
out.println("Setting " + op + " to " + false);
101
if (impl != null) {
102
// allows setOption(SocketOption, Object) to be called
103
impl.allowAllSetOptions(true);
104
}
105
sock.setOption(op, false);
106
enable = sock.getOption(op);
107
assertFalse(enable, "Value for " + op);
108
disable = sock.getLoopbackMode();
109
assertTrue(disable, "Value for getLoopbackMode()");
110
if (impl != null) {
111
assertTrue((Boolean)impl.getOption(opId));
112
assertFalse((Boolean)impl.getOption(op));
113
}
114
out.println("Setting " + op + " to " + true);
115
sock.setOption(op, true);
116
enable = sock.getOption(op);
117
assertTrue(enable, "Value for " + op);
118
disable = sock.getLoopbackMode();
119
assertFalse(disable, "Value for getLoopbackMode()");
120
if (impl != null) {
121
assertFalse((Boolean)impl.getOption(opId));
122
assertTrue((Boolean)impl.getOption(op));
123
}
124
125
out.println("Calling setLoopbackMode(true)");
126
if (impl != null) {
127
// for backward compatibility reason, setLoopbackMode
128
// should call setOption(int, Object), not setOption(SocketOption, Object)
129
// Make sure that an exception is thrown if the latter is ever called.
130
impl.allowAllSetOptions(false);
131
}
132
sock.setLoopbackMode(true);
133
enable = sock.getOption(op);
134
assertFalse(enable, "Value for " + op);
135
disable = sock.getLoopbackMode();
136
assertTrue(disable, "Value for getLoopbackMode()");
137
if (impl != null) {
138
assertTrue((Boolean)impl.getOption(opId));
139
assertFalse((Boolean)impl.getOption(op));
140
}
141
out.println("Calling setLoopbackMode(false)");
142
sock.setLoopbackMode(false);
143
enable = sock.getOption(op);
144
assertTrue(enable, "Value for " + op);
145
disable = sock.getLoopbackMode();
146
assertFalse(disable, "Value for getLoopbackMode()");
147
if (impl != null) {
148
assertFalse((Boolean)impl.getOption(opId));
149
assertTrue((Boolean)impl.getOption(op));
150
}
151
}
152
153
// Used to attempt to control what is called/passed to the impl.
154
static class TestDatagramSocketImplFactory implements DatagramSocketImplFactory {
155
TestDatagramSocketImpl last;
156
public synchronized DatagramSocketImpl createDatagramSocketImpl() {
157
TestDatagramSocketImpl last = this.last;
158
if (last == null) {
159
return (last = this.last = new TestDatagramSocketImpl());
160
} else {
161
throw new AssertionError("Only one instance should be created");
162
}
163
}
164
}
165
166
// Used to attempt to control what is called/passed to the impl.
167
static class TestDatagramSocketImpl extends DatagramSocketImpl {
168
InetAddress address;
169
private boolean allowAllSetOptions;
170
171
@Override
172
protected void create() throws SocketException {
173
legacyOptions.put(SocketOptions.IP_MULTICAST_LOOP, false);
174
options.put(StandardSocketOptions.IP_MULTICAST_LOOP, true);
175
}
176
177
final Map<Integer, Object> legacyOptions = new HashMap<>();
178
final Map<SocketOption<?>, Object> options = new HashMap<>();
179
180
static <T> T shouldNotComeHere() {
181
throw new AssertionError("should not come here");
182
}
183
184
@Override
185
protected void bind(int lport, InetAddress laddr) throws SocketException {
186
this.localPort = (lport == 0 ? 6789 : lport);
187
this.address = laddr;
188
}
189
190
@Override
191
protected void send(DatagramPacket p) throws IOException {
192
shouldNotComeHere();
193
}
194
195
@Override
196
protected int peek(InetAddress i) throws IOException {
197
return shouldNotComeHere();
198
}
199
200
@Override
201
protected int peekData(DatagramPacket p) throws IOException {
202
return shouldNotComeHere();
203
}
204
205
@Override
206
protected void receive(DatagramPacket p) throws IOException {
207
shouldNotComeHere();
208
}
209
210
@Override
211
protected void setTTL(byte ttl) throws IOException {
212
shouldNotComeHere();
213
}
214
215
@Override
216
protected byte getTTL() throws IOException {
217
return shouldNotComeHere();
218
}
219
220
@Override
221
protected void setTimeToLive(int ttl) throws IOException {
222
shouldNotComeHere();
223
}
224
225
@Override
226
protected int getTimeToLive() throws IOException {
227
return shouldNotComeHere();
228
}
229
230
@Override
231
protected void join(InetAddress inetaddr) throws IOException {
232
shouldNotComeHere();
233
}
234
235
@Override
236
protected void leave(InetAddress inetaddr) throws IOException {
237
shouldNotComeHere();
238
}
239
240
@Override
241
protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
242
throws IOException {
243
shouldNotComeHere();
244
}
245
246
@Override
247
protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
248
throws IOException {
249
shouldNotComeHere();
250
}
251
252
@Override
253
protected void close() {
254
255
}
256
257
@Override
258
public void setOption(int optID, Object value) throws SocketException {
259
legacyOptions.put(optID, value);
260
if (optID == SocketOptions.IP_MULTICAST_LOOP) {
261
boolean disable = (Boolean) value;
262
options.put(StandardSocketOptions.IP_MULTICAST_LOOP, !disable);
263
}
264
}
265
266
@Override
267
public Object getOption(int optID) throws SocketException {
268
return legacyOptions.get(optID);
269
}
270
271
@Override
272
protected Set<SocketOption<?>> supportedOptions() {
273
return Set.of(StandardSocketOptions.IP_MULTICAST_LOOP);
274
}
275
276
@Override
277
protected void connect(InetAddress address, int port) throws SocketException {
278
shouldNotComeHere();
279
}
280
281
@Override
282
protected void disconnect() {
283
shouldNotComeHere();
284
}
285
286
@Override
287
protected FileDescriptor getFileDescriptor() {
288
return super.getFileDescriptor();
289
}
290
291
@Override
292
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
293
if (!allowAllSetOptions) shouldNotComeHere();
294
options.put(name, value);
295
if (name.equals(StandardSocketOptions.IP_MULTICAST_LOOP)) {
296
boolean enable = (Boolean)value;
297
legacyOptions.put(SocketOptions.IP_MULTICAST_LOOP, !enable);
298
}
299
}
300
301
@Override
302
protected <T> T getOption(SocketOption<T> name) throws IOException {
303
return (T) options.get(name);
304
}
305
306
public void allowAllSetOptions(boolean allow) {
307
this.allowAllSetOptions = allow;
308
}
309
}
310
311
public static void main (String args[]) throws Exception {
312
new SetLoopbackOption().run();
313
}
314
}
315
316