Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java
32287 views
1
/*
2
* Copyright (c) 2007, 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. 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 sun.misc.SharedSecrets;
30
import sun.misc.JavaIOFileDescriptorAccess;
31
32
/**
33
* This class defines the plain SocketImpl that is used on Windows platforms
34
* greater or equal to Windows Vista. These platforms have a dual
35
* layer TCP/IP stack and can handle both IPv4 and IPV6 through a
36
* single file descriptor.
37
*
38
* @author Chris Hegarty
39
*/
40
41
class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
42
{
43
static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
44
45
46
// true if this socket is exclusively bound
47
private final boolean exclusiveBind;
48
49
// emulates SO_REUSEADDR when exclusiveBind is true
50
private boolean isReuseAddress;
51
52
public DualStackPlainSocketImpl(boolean exclBind) {
53
exclusiveBind = exclBind;
54
}
55
56
public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
57
this.fd = fd;
58
exclusiveBind = exclBind;
59
}
60
61
void socketCreate(boolean stream) throws IOException {
62
if (fd == null)
63
throw new SocketException("Socket closed");
64
65
int newfd = socket0(stream, false /*v6 Only*/);
66
67
fdAccess.set(fd, newfd);
68
}
69
70
void socketConnect(InetAddress address, int port, int timeout)
71
throws IOException {
72
int nativefd = checkAndReturnNativeFD();
73
74
if (address == null)
75
throw new NullPointerException("inet address argument is null.");
76
77
int connectResult;
78
if (timeout <= 0) {
79
connectResult = connect0(nativefd, address, port);
80
} else {
81
configureBlocking(nativefd, false);
82
try {
83
connectResult = connect0(nativefd, address, port);
84
if (connectResult == WOULDBLOCK) {
85
waitForConnect(nativefd, timeout);
86
}
87
} finally {
88
configureBlocking(nativefd, true);
89
}
90
}
91
/*
92
* We need to set the local port field. If bind was called
93
* previous to the connect (by the client) then localport field
94
* will already be set.
95
*/
96
if (localport == 0)
97
localport = localPort0(nativefd);
98
}
99
100
void socketBind(InetAddress address, int port) throws IOException {
101
int nativefd = checkAndReturnNativeFD();
102
103
if (address == null)
104
throw new NullPointerException("inet address argument is null.");
105
106
bind0(nativefd, address, port, exclusiveBind);
107
if (port == 0) {
108
localport = localPort0(nativefd);
109
} else {
110
localport = port;
111
}
112
113
this.address = address;
114
}
115
116
void socketListen(int backlog) throws IOException {
117
int nativefd = checkAndReturnNativeFD();
118
119
listen0(nativefd, backlog);
120
}
121
122
void socketAccept(SocketImpl s) throws IOException {
123
int nativefd = checkAndReturnNativeFD();
124
125
if (s == null)
126
throw new NullPointerException("socket is null");
127
128
int newfd = -1;
129
InetSocketAddress[] isaa = new InetSocketAddress[1];
130
if (timeout <= 0) {
131
newfd = accept0(nativefd, isaa);
132
} else {
133
configureBlocking(nativefd, false);
134
try {
135
waitForNewConnection(nativefd, timeout);
136
newfd = accept0(nativefd, isaa);
137
if (newfd != -1) {
138
configureBlocking(newfd, true);
139
}
140
} finally {
141
configureBlocking(nativefd, true);
142
}
143
}
144
/* Update (SocketImpl)s' fd */
145
fdAccess.set(s.fd, newfd);
146
/* Update socketImpls remote port, address and localport */
147
InetSocketAddress isa = isaa[0];
148
s.port = isa.getPort();
149
s.address = isa.getAddress();
150
s.localport = localport;
151
}
152
153
int socketAvailable() throws IOException {
154
int nativefd = checkAndReturnNativeFD();
155
return available0(nativefd);
156
}
157
158
void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
159
if (fd == null)
160
throw new SocketException("Socket closed");
161
162
if (!fd.valid())
163
return;
164
165
final int nativefd = fdAccess.get(fd);
166
fdAccess.set(fd, -1);
167
close0(nativefd);
168
}
169
170
void socketShutdown(int howto) throws IOException {
171
int nativefd = checkAndReturnNativeFD();
172
shutdown0(nativefd, howto);
173
}
174
175
// Intentional fallthrough after SO_REUSEADDR
176
@SuppressWarnings("fallthrough")
177
void socketSetOption(int opt, boolean on, Object value)
178
throws SocketException {
179
int nativefd = checkAndReturnNativeFD();
180
181
if (opt == SO_TIMEOUT) { // timeout implemented through select.
182
return;
183
}
184
185
int optionValue = 0;
186
187
switch(opt) {
188
case SO_REUSEADDR :
189
if (exclusiveBind) {
190
// SO_REUSEADDR emulated when using exclusive bind
191
isReuseAddress = on;
192
return;
193
}
194
// intentional fallthrough
195
case TCP_NODELAY :
196
case SO_OOBINLINE :
197
case SO_KEEPALIVE :
198
optionValue = on ? 1 : 0;
199
break;
200
case SO_SNDBUF :
201
case SO_RCVBUF :
202
case IP_TOS :
203
optionValue = ((Integer)value).intValue();
204
break;
205
case SO_LINGER :
206
if (on) {
207
optionValue = ((Integer)value).intValue();
208
} else {
209
optionValue = -1;
210
}
211
break;
212
default :/* shouldn't get here */
213
throw new SocketException("Option not supported");
214
}
215
216
setIntOption(nativefd, opt, optionValue);
217
}
218
219
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
220
int nativefd = checkAndReturnNativeFD();
221
222
// SO_BINDADDR is not a socket option.
223
if (opt == SO_BINDADDR) {
224
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
225
return 0; // return value doesn't matter.
226
}
227
228
// SO_REUSEADDR emulated when using exclusive bind
229
if (opt == SO_REUSEADDR && exclusiveBind)
230
return isReuseAddress? 1 : -1;
231
232
int value = getIntOption(nativefd, opt);
233
234
switch (opt) {
235
case TCP_NODELAY :
236
case SO_OOBINLINE :
237
case SO_KEEPALIVE :
238
case SO_REUSEADDR :
239
return (value == 0) ? -1 : 1;
240
}
241
return value;
242
}
243
244
void socketSendUrgentData(int data) throws IOException {
245
int nativefd = checkAndReturnNativeFD();
246
sendOOB(nativefd, data);
247
}
248
249
private int checkAndReturnNativeFD() throws SocketException {
250
if (fd == null || !fd.valid())
251
throw new SocketException("Socket closed");
252
253
return fdAccess.get(fd);
254
}
255
256
static final int WOULDBLOCK = -2; // Nothing available (non-blocking)
257
258
static {
259
initIDs();
260
}
261
262
/* Native methods */
263
264
static native void initIDs();
265
266
static native int socket0(boolean stream, boolean v6Only) throws IOException;
267
268
static native void bind0(int fd, InetAddress localAddress, int localport,
269
boolean exclBind)
270
throws IOException;
271
272
static native int connect0(int fd, InetAddress remote, int remotePort)
273
throws IOException;
274
275
static native void waitForConnect(int fd, int timeout) throws IOException;
276
277
static native int localPort0(int fd) throws IOException;
278
279
static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
280
281
static native void listen0(int fd, int backlog) throws IOException;
282
283
static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
284
285
static native void waitForNewConnection(int fd, int timeout) throws IOException;
286
287
static native int available0(int fd) throws IOException;
288
289
static native void close0(int fd) throws IOException;
290
291
static native void shutdown0(int fd, int howto) throws IOException;
292
293
static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
294
295
static native int getIntOption(int fd, int cmd) throws SocketException;
296
297
static native void sendOOB(int fd, int data) throws IOException;
298
299
static native void configureBlocking(int fd, boolean blocking) throws IOException;
300
}
301
302