2
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
28
import java.security.PrivilegedAction;
31
* This class PlainSocketImpl simply delegates to the appropriate real
32
* SocketImpl. We do this because PlainSocketImpl is already extended
35
* There are two possibilities for the real SocketImpl,
36
* TwoStacksPlainSocketImpl or DualStackPlainSocketImpl. We use
37
* DualStackPlainSocketImpl on systems that have a dual stack
38
* TCP implementation. Otherwise we create an instance of
39
* TwoStacksPlainSocketImpl and delegate to it.
41
* @author Chris Hegarty
44
class PlainSocketImpl extends AbstractPlainSocketImpl
46
private AbstractPlainSocketImpl impl;
48
/* the windows version. */
49
private static float version;
51
/* java.net.preferIPv4Stack */
52
private static boolean preferIPv4Stack = false;
54
/* If the version supports a dual stack TCP implementation */
55
private static boolean useDualStackImpl = false;
58
java.security.AccessController.doPrivileged( new PrivilegedAction<Object>() {
62
version = Float.parseFloat(System.getProperties().getProperty("os.version"));
63
preferIPv4Stack = Boolean.parseBoolean(
64
System.getProperties().getProperty("java.net.preferIPv4Stack"));
65
} catch (NumberFormatException e ) {
68
return null; // nothing to return
71
String ipv6 = ikvm.internal.Util.SafeGetEnvironmentVariable("IKVM_IPV6");
74
if ((Integer.parseInt(ipv6) & 4) == 0) {
75
preferIPv4Stack = true;
77
useDualStackImpl = true;
79
} catch (NumberFormatException _) {
81
} else if (!InetAddressImplFactory.isIPv6Supported()) {
82
preferIPv4Stack = true;
85
// (version >= 6.0) implies Vista or greater.
86
if (version >= 6.0 && !preferIPv4Stack) {
87
useDualStackImpl = true;
92
* Constructs an empty instance.
95
if (useDualStackImpl) {
96
impl = new DualStackPlainSocketImpl();
98
impl = new TwoStacksPlainSocketImpl();
103
* Constructs an instance with the given file descriptor.
105
PlainSocketImpl(FileDescriptor fd) {
106
if (useDualStackImpl) {
107
impl = new DualStackPlainSocketImpl(fd);
109
impl = new TwoStacksPlainSocketImpl(fd);
113
// Override methods in SocketImpl that access impl's fields.
115
protected FileDescriptor getFileDescriptor() {
116
return impl.getFileDescriptor();
119
protected InetAddress getInetAddress() {
120
return impl.getInetAddress();
123
protected int getPort() {
124
return impl.getPort();
127
protected int getLocalPort() {
128
return impl.getLocalPort();
131
void setSocket(Socket soc) {
136
return impl.getSocket();
139
void setServerSocket(ServerSocket soc) {
140
impl.setServerSocket(soc);
143
ServerSocket getServerSocket() {
144
return impl.getServerSocket();
147
public String toString() {
148
return impl.toString();
151
// Override methods in AbstractPlainSocketImpl that access impl's fields.
153
protected synchronized void create(boolean stream) throws IOException {
156
// set fd to delegate's fd to be compatible with older releases
160
protected void connect(String host, int port)
161
throws UnknownHostException, IOException
163
impl.connect(host, port);
166
protected void connect(InetAddress address, int port) throws IOException {
167
impl.connect(address, port);
170
protected void connect(SocketAddress address, int timeout) throws IOException {
171
impl.connect(address, timeout);
174
public void setOption(int opt, Object val) throws SocketException {
175
impl.setOption(opt, val);
178
public Object getOption(int opt) throws SocketException {
179
return impl.getOption(opt);
182
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
183
impl.doConnect(address, port, timeout);
186
protected synchronized void bind(InetAddress address, int lport)
189
impl.bind(address, lport);
192
protected synchronized void accept(SocketImpl s) throws IOException {
193
// pass in the real impl not the wrapper.
194
SocketImpl delegate = ((PlainSocketImpl)s).impl;
195
delegate.address = new InetAddress();
196
delegate.fd = new FileDescriptor();
197
impl.accept(delegate);
199
// set fd to delegate's fd to be compatible with older releases
203
void setFileDescriptor(FileDescriptor fd) {
204
impl.setFileDescriptor(fd);
207
void setAddress(InetAddress address) {
208
impl.setAddress(address);
211
void setPort(int port) {
215
void setLocalPort(int localPort) {
216
impl.setLocalPort(localPort);
219
protected synchronized InputStream getInputStream() throws IOException {
220
return impl.getInputStream();
223
void setInputStream(SocketInputStream in) {
224
impl.setInputStream(in);
227
protected synchronized OutputStream getOutputStream() throws IOException {
228
return impl.getOutputStream();
231
protected void close() throws IOException {
235
// set fd to delegate's fd to be compatible with older releases
240
void reset() throws IOException {
244
// set fd to delegate's fd to be compatible with older releases
249
protected void shutdownInput() throws IOException {
250
impl.shutdownInput();
253
protected void shutdownOutput() throws IOException {
254
impl.shutdownOutput();
257
protected void sendUrgentData(int data) throws IOException {
258
impl.sendUrgentData(data);
261
FileDescriptor acquireFD() {
262
return impl.acquireFD();
269
public boolean isConnectionReset() {
270
return impl.isConnectionReset();
273
public boolean isConnectionResetPending() {
274
return impl.isConnectionResetPending();
277
public void setConnectionReset() {
278
impl.setConnectionReset();
281
public void setConnectionResetPending() {
282
impl.setConnectionResetPending();
285
public boolean isClosedOrPending() {
286
return impl.isClosedOrPending();
289
public int getTimeout() {
290
return impl.getTimeout();
293
// Override methods in AbstractPlainSocketImpl that need to be implemented.
295
void socketCreate(boolean isServer) throws IOException {
296
impl.socketCreate(isServer);
299
void socketConnect(InetAddress address, int port, int timeout)
301
impl.socketConnect(address, port, timeout);
304
void socketBind(InetAddress address, int port)
306
impl.socketBind(address, port);
309
void socketListen(int count) throws IOException {
310
impl.socketListen(count);
313
void socketAccept(SocketImpl s) throws IOException {
314
impl.socketAccept(s);
317
int socketAvailable() throws IOException {
318
return impl.socketAvailable();
321
void socketClose0(boolean useDeferredClose) throws IOException {
322
impl.socketClose0(useDeferredClose);
325
void socketShutdown(int howto) throws IOException {
326
impl.socketShutdown(howto);
329
void socketSetOption(int cmd, boolean on, Object value)
330
throws SocketException {
331
socketSetOption(cmd, on, value);
334
int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
335
return impl.socketGetOption(opt, iaContainerObj);
338
void socketSendUrgentData(int data) throws IOException {
339
impl.socketSendUrgentData(data);