Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/classes/java/net/PlainSocketImpl.java
41133 views
1
/*
2
* Copyright (c) 2007, 2021, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package java.net;
26
27
import java.io.IOException;
28
import java.io.FileDescriptor;
29
import java.security.AccessController;
30
31
import sun.security.action.GetPropertyAction;
32
import jdk.internal.access.SharedSecrets;
33
import jdk.internal.access.JavaIOFileDescriptorAccess;
34
35
/**
36
* On Windows system we simply delegate to native methods.
37
*
38
* @author Chris Hegarty
39
*/
40
41
class PlainSocketImpl extends AbstractPlainSocketImpl {
42
43
private static final JavaIOFileDescriptorAccess fdAccess =
44
SharedSecrets.getJavaIOFileDescriptorAccess();
45
46
@SuppressWarnings("removal")
47
private static final boolean preferIPv4Stack =
48
Boolean.parseBoolean(AccessController.doPrivileged(
49
new GetPropertyAction("java.net.preferIPv4Stack", "false")));
50
51
/**
52
* Empty value of sun.net.useExclusiveBind is treated as 'true'.
53
*/
54
private static final boolean useExclusiveBind;
55
56
static {
57
@SuppressWarnings("removal")
58
String exclBindProp = AccessController.doPrivileged(
59
new GetPropertyAction("sun.net.useExclusiveBind", ""));
60
useExclusiveBind = exclBindProp.isEmpty()
61
|| Boolean.parseBoolean(exclBindProp);
62
}
63
64
// emulates SO_REUSEADDR when useExclusiveBind is true
65
private boolean isReuseAddress;
66
67
/**
68
* Constructs an empty instance.
69
*/
70
PlainSocketImpl(boolean isServer) {
71
super(isServer);
72
}
73
74
@Override
75
void socketCreate(boolean stream) throws IOException {
76
if (fd == null)
77
throw new SocketException("Socket closed");
78
79
int newfd = socket0(stream);
80
81
fdAccess.set(fd, newfd);
82
}
83
84
@Override
85
void socketConnect(InetAddress address, int port, int timeout)
86
throws IOException {
87
int nativefd = checkAndReturnNativeFD();
88
89
if (address == null)
90
throw new NullPointerException("inet address argument is null.");
91
92
if (preferIPv4Stack && !(address instanceof Inet4Address))
93
throw new SocketException("Protocol family not supported");
94
95
int connectResult;
96
if (timeout <= 0) {
97
connectResult = connect0(nativefd, address, port);
98
} else {
99
configureBlocking(nativefd, false);
100
try {
101
connectResult = connect0(nativefd, address, port);
102
if (connectResult == WOULDBLOCK) {
103
waitForConnect(nativefd, timeout);
104
}
105
} finally {
106
configureBlocking(nativefd, true);
107
}
108
}
109
/*
110
* We need to set the local port field. If bind was called
111
* previous to the connect (by the client) then localport field
112
* will already be set.
113
*/
114
if (localport == 0)
115
localport = localPort0(nativefd);
116
}
117
118
@Override
119
void socketBind(InetAddress address, int port) throws IOException {
120
int nativefd = checkAndReturnNativeFD();
121
122
if (address == null)
123
throw new NullPointerException("inet address argument is null.");
124
125
if (preferIPv4Stack && !(address instanceof Inet4Address))
126
throw new SocketException("Protocol family not supported");
127
128
bind0(nativefd, address, port, useExclusiveBind);
129
if (port == 0) {
130
localport = localPort0(nativefd);
131
} else {
132
localport = port;
133
}
134
135
this.address = address;
136
}
137
138
@Override
139
void socketListen(int backlog) throws IOException {
140
int nativefd = checkAndReturnNativeFD();
141
142
listen0(nativefd, backlog);
143
}
144
145
@Override
146
void socketAccept(SocketImpl s) throws IOException {
147
int nativefd = checkAndReturnNativeFD();
148
149
if (s == null)
150
throw new NullPointerException("socket is null");
151
152
int newfd = -1;
153
InetSocketAddress[] isaa = new InetSocketAddress[1];
154
if (timeout <= 0) {
155
newfd = accept0(nativefd, isaa);
156
} else {
157
configureBlocking(nativefd, false);
158
try {
159
waitForNewConnection(nativefd, timeout);
160
newfd = accept0(nativefd, isaa);
161
if (newfd != -1) {
162
configureBlocking(newfd, true);
163
}
164
} finally {
165
configureBlocking(nativefd, true);
166
}
167
}
168
/* Update (SocketImpl)s' fd */
169
fdAccess.set(s.fd, newfd);
170
/* Update socketImpls remote port, address and localport */
171
InetSocketAddress isa = isaa[0];
172
s.port = isa.getPort();
173
s.address = isa.getAddress();
174
s.localport = localport;
175
if (preferIPv4Stack && !(s.address instanceof Inet4Address))
176
throw new SocketException("Protocol family not supported");
177
}
178
179
@Override
180
int socketAvailable() throws IOException {
181
int nativefd = checkAndReturnNativeFD();
182
return available0(nativefd);
183
}
184
185
@Override
186
void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
187
if (fd == null)
188
throw new SocketException("Socket closed");
189
190
if (!fd.valid())
191
return;
192
193
final int nativefd = fdAccess.get(fd);
194
fdAccess.set(fd, -1);
195
close0(nativefd);
196
}
197
198
@Override
199
void socketShutdown(int howto) throws IOException {
200
int nativefd = checkAndReturnNativeFD();
201
shutdown0(nativefd, howto);
202
}
203
204
// Intentional fallthrough after SO_REUSEADDR
205
@SuppressWarnings("fallthrough")
206
@Override
207
void socketSetOption(int opt, boolean on, Object value)
208
throws SocketException {
209
210
// SO_REUSEPORT is not supported on Windows.
211
if (opt == SO_REUSEPORT) {
212
throw new UnsupportedOperationException("unsupported option");
213
}
214
215
int nativefd = checkAndReturnNativeFD();
216
217
if (opt == SO_TIMEOUT) {
218
if (preferIPv4Stack) {
219
// Don't enable the socket option on ServerSocket as it's
220
// meaningless (we don't receive on a ServerSocket).
221
if (!isServer) {
222
setSoTimeout0(nativefd, ((Integer)value).intValue());
223
}
224
} // else timeout is implemented through select.
225
return;
226
}
227
228
int optionValue = 0;
229
230
switch(opt) {
231
case SO_REUSEADDR:
232
if (useExclusiveBind) {
233
// SO_REUSEADDR emulated when using exclusive bind
234
isReuseAddress = on;
235
return;
236
}
237
// intentional fallthrough
238
case TCP_NODELAY:
239
case SO_OOBINLINE:
240
case SO_KEEPALIVE:
241
optionValue = on ? 1 : 0;
242
break;
243
case SO_SNDBUF:
244
case SO_RCVBUF:
245
case IP_TOS:
246
optionValue = ((Integer)value).intValue();
247
break;
248
case SO_LINGER:
249
if (on) {
250
optionValue = ((Integer)value).intValue();
251
} else {
252
optionValue = -1;
253
}
254
break;
255
default :/* shouldn't get here */
256
throw new SocketException("Option not supported");
257
}
258
259
setIntOption(nativefd, opt, optionValue);
260
}
261
262
@Override
263
int socketGetOption(int opt, Object iaContainerObj)
264
throws SocketException {
265
266
// SO_REUSEPORT is not supported on Windows.
267
if (opt == SO_REUSEPORT) {
268
throw new UnsupportedOperationException("unsupported option");
269
}
270
271
int nativefd = checkAndReturnNativeFD();
272
273
// SO_BINDADDR is not a socket option.
274
if (opt == SO_BINDADDR) {
275
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
276
return 0; // return value doesn't matter.
277
}
278
279
// SO_REUSEADDR emulated when using exclusive bind
280
if (opt == SO_REUSEADDR && useExclusiveBind)
281
return isReuseAddress ? 1 : -1;
282
283
int value = getIntOption(nativefd, opt);
284
285
switch (opt) {
286
case TCP_NODELAY:
287
case SO_OOBINLINE:
288
case SO_KEEPALIVE:
289
case SO_REUSEADDR:
290
return (value == 0) ? -1 : 1;
291
}
292
return value;
293
}
294
295
@Override
296
void socketSendUrgentData(int data) throws IOException {
297
int nativefd = checkAndReturnNativeFD();
298
sendOOB(nativefd, data);
299
}
300
301
private int checkAndReturnNativeFD() throws SocketException {
302
if (fd == null || !fd.valid())
303
throw new SocketException("Socket closed");
304
305
return fdAccess.get(fd);
306
}
307
308
static final int WOULDBLOCK = -2; // Nothing available (non-blocking)
309
310
static {
311
initIDs();
312
}
313
314
/* Native methods */
315
316
static native void initIDs();
317
318
static native int socket0(boolean stream) throws IOException;
319
320
static native void bind0(int fd, InetAddress localAddress, int localport,
321
boolean exclBind)
322
throws IOException;
323
324
static native int connect0(int fd, InetAddress remote, int remotePort)
325
throws IOException;
326
327
static native void waitForConnect(int fd, int timeout) throws IOException;
328
329
static native int localPort0(int fd) throws IOException;
330
331
static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
332
333
static native void listen0(int fd, int backlog) throws IOException;
334
335
static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
336
337
static native void waitForNewConnection(int fd, int timeout) throws IOException;
338
339
static native int available0(int fd) throws IOException;
340
341
static native void close0(int fd) throws IOException;
342
343
static native void shutdown0(int fd, int howto) throws IOException;
344
345
static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
346
347
static native void setSoTimeout0(int fd, int timeout) throws SocketException;
348
349
static native int getIntOption(int fd, int cmd) throws SocketException;
350
351
static native void sendOOB(int fd, int data) throws IOException;
352
353
static native void configureBlocking(int fd, boolean blocking) throws IOException;
354
}
355
356