8198358: Align organization of TwoStacksPlainSocketImp with DualStackPlainSocketImpl [win]
authorigerasim
Tue, 27 Mar 2018 13:22:40 -0700
changeset 49431 5812849b5027
parent 49430 e376090dc07e
child 49432 f76e1ac74f28
8198358: Align organization of TwoStacksPlainSocketImp with DualStackPlainSocketImpl [win] Reviewed-by: chegar, clanger
src/java.base/unix/native/libnet/PlainSocketImpl.c
src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java
src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java
src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c
src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c
test/jdk/java/net/Socket/AddressTest.java
test/jdk/java/net/Socket/B6210227.java
test/jdk/java/net/Socket/CloseAvailable.java
test/jdk/java/net/Socket/DeadlockTest.java
test/jdk/java/net/Socket/HttpProxy.java
test/jdk/java/net/Socket/InheritHandle.java
test/jdk/java/net/Socket/InheritTimeout.java
test/jdk/java/net/Socket/LingerTest.java
test/jdk/java/net/Socket/LinkLocal.java
test/jdk/java/net/Socket/ProxyCons.java
test/jdk/java/net/Socket/RST.java
test/jdk/java/net/Socket/ReadTimeout.java
test/jdk/java/net/Socket/SetSoLinger.java
test/jdk/java/net/Socket/ShutdownInput.java
test/jdk/java/net/Socket/SocksConnectTimeout.java
test/jdk/java/net/Socket/TestAfterClose.java
test/jdk/java/net/Socket/TestClose.java
test/jdk/java/net/Socket/TestTcpNoDelay.java
test/jdk/java/net/Socket/Timeout.java
test/jdk/java/net/Socket/TrafficClass.java
test/jdk/java/net/Socket/UrgentDataTest.java
test/jdk/java/net/Socket/asyncClose/AsyncClose.java
test/jdk/java/net/Socket/asyncClose/BrokenPipe.java
test/jdk/java/net/Socket/setReuseAddress/Basic.java
test/jdk/java/net/Socket/setReuseAddress/Restart.java
test/jdk/java/net/SocketInputStream/SocketClosedException.java
test/jdk/java/net/SocketInputStream/SocketTimeout.java
test/jdk/java/net/SocketOption/ImmutableOptions.java
test/jdk/java/net/SocketOption/MinimumRcvBufferSize.java
test/jdk/java/net/SocketOption/SupportedOptionsSet.java
test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java
--- a/src/java.base/unix/native/libnet/PlainSocketImpl.c	Tue Mar 27 19:29:46 2018 +0100
+++ b/src/java.base/unix/native/libnet/PlainSocketImpl.c	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -920,7 +920,7 @@
 /*
  * Class:     java_net_PlainSocketImpl
  * Method:    socketGetOption
- * Signature: (I)I
+ * Signature: (ILjava/lang/Object;)I
  */
 JNIEXPORT jint JNICALL
 Java_java_net_PlainSocketImpl_socketGetOption
--- a/src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,10 +38,10 @@
  * @author Chris Hegarty
  */
 
-class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
-{
-    static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
+class DualStackPlainSocketImpl extends AbstractPlainSocketImpl {
 
+    private static final JavaIOFileDescriptorAccess fdAccess =
+        SharedSecrets.getJavaIOFileDescriptorAccess();
 
     // true if this socket is exclusively bound
     private final boolean exclusiveBind;
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Tue Mar 27 13:22:40 2018 -0700
@@ -27,6 +27,8 @@
 import java.io.IOException;
 import java.io.FileDescriptor;
 import sun.net.ResourceManager;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
 
 /*
  * This class defines the plain SocketImpl that is used when
@@ -37,16 +39,15 @@
 
 class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl {
 
+    private static final JavaIOFileDescriptorAccess fdAccess =
+        SharedSecrets.getJavaIOFileDescriptorAccess();
+
     // true if this socket is exclusively bound
     private final boolean exclusiveBind;
 
     // emulates SO_REUSEADDR when exclusiveBind is true
     private boolean isReuseAddress;
 
-    static {
-        initProto();
-    }
-
     public TwoStacksPlainSocketImpl(boolean exclBind) {
         exclusiveBind = exclBind;
     }
@@ -56,105 +57,268 @@
         exclusiveBind = exclBind;
     }
 
-    public Object getOption(int opt) throws SocketException {
-        if (isClosedOrPending()) {
-            throw new SocketException("Socket Closed");
+    void socketCreate(boolean stream) throws IOException {
+        if (fd == null)
+            throw new SocketException("Socket closed");
+
+        int newfd = socket0(stream, false /*v6 Only*/);
+
+        fdAccess.set(fd, newfd);
+    }
+
+    @Override
+    void socketConnect(InetAddress address, int port, int timeout)
+        throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+
+        if (address == null)
+            throw new NullPointerException("inet address argument is null.");
+
+        int connectResult;
+        if (timeout <= 0) {
+            connectResult = connect0(nativefd, address, port);
+        } else {
+            configureBlocking(nativefd, false);
+            try {
+                connectResult = connect0(nativefd, address, port);
+                if (connectResult == WOULDBLOCK) {
+                    waitForConnect(nativefd, timeout);
+                }
+            } finally {
+                configureBlocking(nativefd, true);
+            }
         }
-        if (opt == SO_BINDADDR) {
-            InetAddressContainer in = new InetAddressContainer();
-            socketGetOption(opt, in);
-            return in.addr;
-        } else if (opt == SO_REUSEADDR && exclusiveBind) {
-            // SO_REUSEADDR emulated when using exclusive bind
-            return isReuseAddress;
-        } else if (opt == SO_REUSEPORT) {
-            // SO_REUSEPORT is not supported on Windows.
-            throw new UnsupportedOperationException("unsupported option");
-        } else
-            return super.getOption(opt);
+        /*
+         * We need to set the local port field. If bind was called
+         * previous to the connect (by the client) then localport field
+         * will already be set.
+         */
+        if (localport == 0)
+            localport = localPort0(nativefd);
     }
 
     @Override
     void socketBind(InetAddress address, int port) throws IOException {
-        socketBind(address, port, exclusiveBind);
+        int nativefd = checkAndReturnNativeFD();
+
+        if (address == null)
+            throw new NullPointerException("inet address argument is null.");
+
+        bind0(nativefd, address, port, exclusiveBind);
+        if (port == 0) {
+            localport = localPort0(nativefd);
+        } else {
+            localport = port;
+        }
+
+        this.address = address;
+    }
+
+    @Override
+    void socketListen(int backlog) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+
+        listen0(nativefd, backlog);
+    }
+
+    @Override
+    void socketAccept(SocketImpl s) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+
+        if (s == null)
+            throw new NullPointerException("socket is null");
+
+        int newfd = -1;
+        InetSocketAddress[] isaa = new InetSocketAddress[1];
+        if (timeout <= 0) {
+            newfd = accept0(nativefd, isaa);
+        } else {
+            configureBlocking(nativefd, false);
+            try {
+                waitForNewConnection(nativefd, timeout);
+                newfd = accept0(nativefd, isaa);
+                if (newfd != -1) {
+                    configureBlocking(newfd, true);
+                }
+            } finally {
+                configureBlocking(nativefd, true);
+            }
+        }
+        /* Update (SocketImpl)s' fd */
+        fdAccess.set(s.fd, newfd);
+        /* Update socketImpls remote port, address and localport */
+        InetSocketAddress isa = isaa[0];
+        s.port = isa.getPort();
+        s.address = isa.getAddress();
+        s.localport = localport;
+    }
+
+    @Override
+    int socketAvailable() throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+        return available0(nativefd);
+    }
+
+    @Override
+    void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
+        if (fd == null)
+            throw new SocketException("Socket closed");
+
+        if (!fd.valid())
+            return;
+
+        final int nativefd = fdAccess.get(fd);
+        fdAccess.set(fd, -1);
+        close0(nativefd);
     }
 
     @Override
-    void socketSetOption(int opt, boolean on, Object value)
-        throws SocketException
-    {
-        // SO_REUSEADDR emulated when using exclusive bind
-        if (opt == SO_REUSEADDR && exclusiveBind)
-            isReuseAddress = on;
-        else if (opt == SO_REUSEPORT) {
-            // SO_REUSEPORT is not supported on Windows.
-            throw new UnsupportedOperationException("unsupported option");
-        }
-        else
-            socketNativeSetOption(opt, on, value);
+    void socketShutdown(int howto) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+        shutdown0(nativefd, howto);
     }
 
-    /**
-     * Closes the socket.
-     */
+    // Intentional fallthrough after SO_REUSEADDR
+    @SuppressWarnings("fallthrough")
     @Override
-    protected void close() throws IOException {
-        synchronized(fdLock) {
-            if (fd != null) {
-                if (!stream) {
-                    ResourceManager.afterUdpClose();
+    void socketSetOption(int opt, boolean on, Object value)
+        throws SocketException {
+        int nativefd = checkAndReturnNativeFD();
+
+        if (opt == SO_TIMEOUT) {
+            // Don't enable the socket option on ServerSocket as it's
+            // meaningless (we don't receive on a ServerSocket).
+            if (serverSocket == null) {
+                setSoTimeout0(nativefd, ((Integer)value).intValue());
+            }
+            return;
+        }
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+
+        int optionValue = 0;
+
+        switch(opt) {
+            case SO_REUSEADDR :
+                if (exclusiveBind) {
+                    // SO_REUSEADDR emulated when using exclusive bind
+                    isReuseAddress = on;
+                    return;
+                }
+                // intentional fallthrough
+            case TCP_NODELAY :
+            case SO_OOBINLINE :
+            case SO_KEEPALIVE :
+                optionValue = on ? 1 : 0;
+                break;
+            case SO_SNDBUF :
+            case SO_RCVBUF :
+            case IP_TOS :
+                optionValue = ((Integer)value).intValue();
+                break;
+            case SO_LINGER :
+                if (on) {
+                    optionValue =  ((Integer)value).intValue();
+                } else {
+                    optionValue = -1;
                 }
-                if (fdUseCount == 0) {
-                    if (closePending) {
-                        return;
-                    }
-                    closePending = true;
-                    socketClose();
-                    fd = null;
-                    return;
-                } else {
-                    /*
-                     * If a thread has acquired the fd and a close
-                     * isn't pending then use a deferred close.
-                     * Also decrement fdUseCount to signal the last
-                     * thread that releases the fd to close it.
-                     */
-                    if (!closePending) {
-                        closePending = true;
-                        fdUseCount--;
-                        socketClose();
-                    }
-                }
-            }
+                break;
+            default :/* shouldn't get here */
+                throw new SocketException("Option not supported");
+        }
+
+        setIntOption(nativefd, opt, optionValue);
+    }
+
+    @Override
+    int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
+        int nativefd = checkAndReturnNativeFD();
+
+        // SO_BINDADDR is not a socket option.
+        if (opt == SO_BINDADDR) {
+            localAddress(nativefd, (InetAddressContainer)iaContainerObj);
+            return 0;  // return value doesn't matter.
+        }
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
         }
+
+        // SO_REUSEADDR emulated when using exclusive bind
+        if (opt == SO_REUSEADDR && exclusiveBind)
+            return isReuseAddress? 1 : -1;
+
+        int value = getIntOption(nativefd, opt);
+
+        switch (opt) {
+            case TCP_NODELAY :
+            case SO_OOBINLINE :
+            case SO_KEEPALIVE :
+            case SO_REUSEADDR :
+                return (value == 0) ? -1 : 1;
+        }
+        return value;
+    }
+
+    @Override
+    void socketSendUrgentData(int data) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+        sendOOB(nativefd, data);
+    }
+
+    private int checkAndReturnNativeFD() throws SocketException {
+        if (fd == null || !fd.valid())
+            throw new SocketException("Socket closed");
+
+        return fdAccess.get(fd);
+    }
+
+    static final int WOULDBLOCK = -2;       // Nothing available (non-blocking)
+
+    static {
+        initIDs();
     }
 
     /* Native methods */
 
-    static native void initProto();
+    static native void initIDs();
 
-    native void socketCreate(boolean stream) throws IOException;
+    static native int socket0(boolean stream, boolean v6Only) throws IOException;
 
-    native void socketConnect(InetAddress address, int port, int timeout)
+    static native void bind0(int fd, InetAddress localAddress, int localport,
+                             boolean exclBind)
         throws IOException;
 
-    native void socketBind(InetAddress address, int port, boolean exclBind)
+    static native int connect0(int fd, InetAddress remote, int remotePort)
         throws IOException;
 
-    native void socketListen(int count) throws IOException;
+    static native void waitForConnect(int fd, int timeout) throws IOException;
 
-    native void socketAccept(SocketImpl s) throws IOException;
+    static native int localPort0(int fd) throws IOException;
+
+    static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
 
-    native int socketAvailable() throws IOException;
+    static native void listen0(int fd, int backlog) throws IOException;
+
+    static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
 
-    native void socketClose0(boolean useDeferredClose) throws IOException;
+    static native void waitForNewConnection(int fd, int timeout) throws IOException;
+
+    static native int available0(int fd) throws IOException;
 
-    native void socketShutdown(int howto) throws IOException;
+    static native void close0(int fd) throws IOException;
 
-    native void socketNativeSetOption(int cmd, boolean on, Object value)
-        throws SocketException;
+    static native void shutdown0(int fd, int howto) throws IOException;
+
+    static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
 
-    native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
+    static native void setSoTimeout0(int fd, int timeout) throws SocketException;
+
+    static native int getIntOption(int fd, int cmd) throws SocketException;
 
-    native void socketSendUrgentData(int data) throws IOException;
+    static native void sendOOB(int fd, int data) throws IOException;
+
+    static native void configureBlocking(int fd, boolean blocking) throws IOException;
 }
--- a/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c	Tue Mar 27 19:29:46 2018 +0100
+++ b/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c	Tue Mar 27 13:22:40 2018 -0700
@@ -51,7 +51,7 @@
     initInetAddressIDs(env);
 
     // implement read timeout with select.
-    isRcvTimeoutSupported = 0;
+    isRcvTimeoutSupported = JNI_FALSE;
 }
 
 /*
--- a/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Tue Mar 27 19:29:46 2018 +0100
+++ b/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Tue Mar 27 13:22:40 2018 -0700
@@ -22,604 +22,420 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#include <malloc.h>
-
 #include "net_util.h"
 
 #include "java_net_TwoStacksPlainSocketImpl.h"
 #include "java_net_SocketOptions.h"
 #include "java_net_InetAddress.h"
 
+#define SET_BLOCKING 0
+#define SET_NONBLOCKING 1
+
+static jclass isa_class;        /* java.net.InetSocketAddress */
+static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
+
 /************************************************************************
  * TwoStacksPlainSocketImpl
  */
 
-static jfieldID IO_fd_fdID;
-
-jfieldID psi_fdID;
-jfieldID psi_addressID;
-jfieldID psi_portID;
-jfieldID psi_localportID;
-jfieldID psi_timeoutID;
-jfieldID psi_trafficClassID;
-jfieldID psi_serverSocketID;
-
 /*
- * the level of the TCP protocol for setsockopt and getsockopt
- * we only want to look this up once, from the static initializer
- * of TwoStacksPlainSocketImpl
- */
-static int tcp_level = -1;
-
-static int getFD(JNIEnv *env, jobject this) {
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    if (fdObj == NULL) {
-        return -1;
-    }
-    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-}
-
-
-/*
- * The initProto function is called whenever TwoStacksPlainSocketImpl is
+ * The initIDs function is called whenever TwoStacksPlainSocketImpl is
  * loaded, to cache fieldIds for efficiency. This is called everytime
  * the Java class is loaded.
  *
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    initProto
-
+ * Method:    initIDs
  * Signature: ()V
  */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_initIDs
+  (JNIEnv *env, jclass clazz) {
 
-    struct protoent *proto = getprotobyname("TCP");
-    tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);
+    jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+    CHECK_NULL(cls);
+    isa_class = (*env)->NewGlobalRef(env, cls);
+    CHECK_NULL(isa_class);
+    isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
+                                     "(Ljava/net/InetAddress;I)V");
+    CHECK_NULL(isa_ctorID);
+}
 
-    psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;");
-    CHECK_NULL(psi_fdID);
-    psi_addressID = (*env)->GetFieldID(env, cls, "address",
-                                          "Ljava/net/InetAddress;");
-    CHECK_NULL(psi_addressID);
-    psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
-    CHECK_NULL(psi_portID);
-    psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
-    CHECK_NULL(psi_localportID);
-    psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
-    CHECK_NULL(psi_timeoutID);
-    psi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I");
-    CHECK_NULL(psi_trafficClassID);
-    psi_serverSocketID = (*env)->GetFieldID(env, cls, "serverSocket",
-                                            "Ljava/net/ServerSocket;");
-    CHECK_NULL(psi_serverSocketID);
-    IO_fd_fdID = NET_GetFileDescriptorID(env);
-    CHECK_NULL(IO_fd_fdID);
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    socket0
+ * Signature: (ZZ)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_socket0
+  (JNIEnv *env, jclass clazz, jboolean stream, jboolean v6Only /*unused*/) {
+    int fd;
+
+    fd = socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
+    if (fd == INVALID_SOCKET) {
+        NET_ThrowNew(env, WSAGetLastError(), "create");
+        return -1;
+    }
+
+    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
+
+    return fd;
 }
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketCreate
- * Signature: (Z)V
+ * Method:    bind0
+ * Signature: (ILjava/net/InetAddress;I)V
  */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
-                                           jboolean stream) {
-    jobject fdObj;
-    int fd;
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_bind0
+  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port,
+   jboolean exclBind)
+{
+    SOCKETADDRESS sa;
+    int rv, sa_len = 0;
+    /* family is an int field of iaObj */
+    int family;
 
-    fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    if (IS_NULL(fdObj)) {
+    family = getInetAddress_family(env, iaObj);
+    if (family != java_net_InetAddress_IPv4) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "null fd object");
+                        "Protocol family not supported");
         return;
     }
-    fd = socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-    if (fd == -1) {
-        NET_ThrowCurrent(env, "create");
+
+    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+                                  &sa_len, JNI_FALSE) != 0) {
         return;
-    } else {
-        /* Set socket attribute so it is not passed to any child process */
-        SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
-        (*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
     }
+
+    rv = NET_WinBind(fd, &sa, sa_len, exclBind);
+
+    if (rv == SOCKET_ERROR)
+        NET_ThrowNew(env, WSAGetLastError(), "NET_Bind");
 }
 
 /*
- * inetAddress is the address object passed to the socket connect
- * call.
- *
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketConnect
- * Signature: (Ljava/net/InetAddress;I)V
+ * Method:    connect0
+ * Signature: (ILjava/net/InetAddress;I)I
  */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
-                                                     jobject iaObj, jint port,
-                                                     jint timeout)
-{
-    jint localport = (*env)->GetIntField(env, this, psi_localportID);
-
-    /* family and localport are int fields of iaObj */
+JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_connect0
+  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
+    SOCKETADDRESS sa;
+    int rv, sa_len = 0;
     int family;
-    jint fd = -1;
-    jint len;
 
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    SOCKETADDRESS sa;
-
-    /* The result of the connection */
-    int connect_res;
-    memset((char *)&sa, 0, sizeof(sa));
-
-    if (!IS_NULL(fdObj)) {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-
-    if (IS_NULL(iaObj)) {
-        JNU_ThrowNullPointerException(env, "inet address argument is null.");
-        return;
-    }
-
-    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa, &len,
-                                  JNI_FALSE) != 0) {
-        return;
+    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+                                  &sa_len, JNI_FALSE) != 0) {
+        return -1;
     }
 
     family = sa.sa.sa_family;
     if (family != AF_INET) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
-    }
-    if (fd == -1) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Destination unreachable");
-        return;
+        return -1;
     }
 
-    if (timeout <= 0) {
-        connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
-        if (connect_res == SOCKET_ERROR) {
-            connect_res = WSAGetLastError();
-        }
-    } else {
-        int optval;
-        int optlen = sizeof(optval);
-
-        /* make socket non-blocking */
-        optval = 1;
-        ioctlsocket(fd, FIONBIO, &optval);
-
-        /* initiate the connect */
-        connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
-        if (connect_res == SOCKET_ERROR) {
-            if (WSAGetLastError() != WSAEWOULDBLOCK) {
-                connect_res = WSAGetLastError();
-            } else {
-                fd_set wr, ex;
-                struct timeval t;
-
-                FD_ZERO(&wr);
-                FD_ZERO(&ex);
-                FD_SET(fd, &wr);
-                FD_SET(fd, &ex);
-                t.tv_sec = timeout / 1000;
-                t.tv_usec = (timeout % 1000) * 1000;
-
-                /*
-                 * Wait for timout, connection established or
-                 * connection failed.
-                 */
-                connect_res = select(fd+1, 0, &wr, &ex, &t);
-
-                /*
-                 * Timeout before connection is established/failed so
-                 * we throw exception and shutdown input/output to prevent
-                 * socket from being used.
-                 * The socket should be closed immediately by the caller.
-                 */
-                if (connect_res == 0) {
-                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                                    "connect timed out");
-                    shutdown( fd, SD_BOTH );
-
-                     /* make socket blocking again - just in case */
-                    optval = 0;
-                    ioctlsocket( fd, FIONBIO, &optval );
-                    return;
-                }
-
-                /*
-                 * We must now determine if the connection has been established
-                 * or if it has failed. The logic here is designed to work around
-                 * bug on Windows NT whereby using getsockopt to obtain the
-                 * last error (SO_ERROR) indicates there is no error. The workaround
-                 * on NT is to allow winsock to be scheduled and this is done by
-                 * yielding and retrying. As yielding is problematic in heavy
-                 * load conditions we attempt up to 3 times to get the error reason.
-                 */
-                if (!FD_ISSET(fd, &ex)) {
-                    connect_res = 0;
-                } else {
-                    int retry;
-                    for (retry=0; retry<3; retry++) {
-                        NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
-                                       (char*)&connect_res, &optlen);
-                        if (connect_res) {
-                            break;
-                        }
-                        Sleep(0);
-                    }
-
-                    if (connect_res == 0) {
-                        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                                        "Unable to establish connection");
-                        return;
-                    }
-                }
-            }
-        }
-
-        /* make socket blocking again */
-        optval = 0;
-        ioctlsocket(fd, FIONBIO, &optval);
-    }
-
-    if (connect_res) {
-        if (connect_res == WSAEADDRNOTAVAIL) {
+    rv = connect(fd, &sa.sa, sa_len);
+    if (rv == SOCKET_ERROR) {
+        int err = WSAGetLastError();
+        if (err == WSAEWOULDBLOCK) {
+            return java_net_TwoStacksPlainSocketImpl_WOULDBLOCK;
+        } else if (err == WSAEADDRNOTAVAIL) {
             JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
                 "connect: Address is invalid on local machine, or port is not valid on remote machine");
         } else {
-            NET_ThrowNew(env, connect_res, "connect");
+            NET_ThrowNew(env, err, "connect");
         }
-        return;
+        return -1;  // return value not important.
     }
+    return rv;
+}
 
-    (*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    waitForConnect
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_waitForConnect
+  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
+    int rv, retry;
+    int optlen = sizeof(rv);
+    fd_set wr, ex;
+    struct timeval t;
 
-    /* set the remote peer address and port */
-    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
-    (*env)->SetIntField(env, this, psi_portID, port);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+    FD_SET(fd, &wr);
+    FD_SET(fd, &ex);
+    t.tv_sec = timeout / 1000;
+    t.tv_usec = (timeout % 1000) * 1000;
+
+    /*
+     * Wait for timeout, connection established or
+     * connection failed.
+     */
+    rv = select(fd+1, 0, &wr, &ex, &t);
 
     /*
-     * we need to initialize the local port field if bind was called
-     * previously to the connect (by the client) then localport field
-     * will already be initialized
+     * Timeout before connection is established/failed so
+     * we throw exception and shutdown input/output to prevent
+     * socket from being used.
+     * The socket should be closed immediately by the caller.
+     */
+    if (rv == 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                        "connect timed out");
+        shutdown( fd, SD_BOTH );
+        return;
+    }
+    /*
+     * Socket is writable or error occurred. On some Windows editions
+     * the socket will appear writable when the connect fails so we
+     * check for error rather than writable.
      */
-    if (localport == 0) {
-        /* Now that we're a connected socket, let's extract the port number
-         * that the system chose for us and store it in the Socket object.
-         */
-        u_short port;
-        int len = sizeof(SOCKETADDRESS);
-        if (getsockname(fd, &sa.sa, &len) == -1) {
-            if (WSAGetLastError() == WSAENOTSOCK) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                                "Socket closed");
-            } else {
-                NET_ThrowCurrent(env, "getsockname failed");
-            }
-            return;
+    if (!FD_ISSET(fd, &ex)) {
+        return;         /* connection established */
+    }
+
+    /*
+     * Connection failed. The logic here is designed to work around
+     * bug on Windows NT whereby using getsockopt to obtain the
+     * last error (SO_ERROR) indicates there is no error. The workaround
+     * on NT is to allow winsock to be scheduled and this is done by
+     * yielding and retrying. As yielding is problematic in heavy
+     * load conditions we attempt up to 3 times to get the error reason.
+     */
+    for (retry=0; retry<3; retry++) {
+        NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
+                       (char*)&rv, &optlen);
+        if (rv) {
+            break;
         }
-        port = ntohs((u_short)GET_PORT(&sa));
-        (*env)->SetIntField(env, this, psi_localportID, (int) port);
+        Sleep(0);
+    }
+
+    if (rv == 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Unable to establish connection");
+    } else if (rv == WSAEADDRNOTAVAIL) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
+                        "connect: Address is invalid on local machine,"
+                        " or port is not valid on remote machine");
+    } else {
+        NET_ThrowNew(env, rv, "connect");
     }
 }
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketBind
- * Signature: (Ljava/net/InetAddress;I)V
+ * Method:    localPort0
+ * Signature: (I)I
  */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
-                                         jobject iaObj, jint localport,
-                                         jboolean exclBind) {
-
-    /* fdObj is the FileDescriptor field on this */
-    jobject fdObj;
-    /* fd is an int field on fdObj */
-    int fd, len = 0;
+JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_localPort0
+  (JNIEnv *env, jclass clazz, jint fd) {
+    SOCKETADDRESS sa;
+    int len = sizeof(sa);
 
-    /* family is an int field of iaObj */
-    int family;
-    int rv;
-
-    SOCKETADDRESS sa;
+    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
+        if (WSAGetLastError() == WSAENOTSOCK) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                    "Socket closed");
+        } else {
+            NET_ThrowNew(env, WSAGetLastError(), "getsockname failed");
+        }
+        return -1;
+    }
+    return (int) ntohs((u_short)GET_PORT(&sa));
+}
 
-    fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    family = getInetAddress_family(env, iaObj);
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    localAddress
+ * Signature: (ILjava/net/InetAddressContainer;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_localAddress
+  (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
+    int port;
+    SOCKETADDRESS sa;
+    int len = sizeof(sa);
+    jobject iaObj;
+    jclass iaContainerClass;
+    jfieldID iaFieldID;
 
-    if (family != java_net_InetAddress_IPv4) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Protocol family not supported");
+    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
         return;
     }
+    iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
+    CHECK_NULL(iaObj);
 
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    if (IS_NULL(iaObj)) {
-        JNU_ThrowNullPointerException(env, "inet address argument");
-        return;
-    }
+    iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
+    iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
+    CHECK_NULL(iaFieldID);
+    (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
+}
 
-    if (NET_InetAddressToSockaddr(env, iaObj, localport, &sa, &len,
-                                  JNI_FALSE) != 0) {
-        return;
-    }
-    rv = NET_WinBind(fd, &sa, len, exclBind);
 
-    if (rv == -1) {
-        NET_ThrowCurrent(env, "NET_Bind");
-        return;
-    }
-
-    /* set the address */
-    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
-
-    /* intialize the local port */
-    if (localport == 0) {
-        /* Now that we're a bound socket, let's extract the port number
-         * that the system chose for us and store it in the Socket object.
-         */
-        int len = sizeof(SOCKETADDRESS);
-        u_short port;
-
-        if (getsockname(fd, &sa.sa, &len) == -1) {
-            NET_ThrowCurrent(env, "getsockname in plain socketBind");
-            return;
-        }
-        port = ntohs((u_short) GET_PORT (&sa));
-
-        (*env)->SetIntField(env, this, psi_localportID, (int)port);
-    } else {
-        (*env)->SetIntField(env, this, psi_localportID, localport);
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    listen0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_listen0
+  (JNIEnv *env, jclass clazz, jint fd, jint backlog) {
+    if (listen(fd, backlog) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "listen failed");
     }
 }
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketListen
- * Signature: (I)V
+ * Method:    accept0
+ * Signature: (I[Ljava/net/InetSocketAddress;)I
  */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketListen
-  (JNIEnv *env, jobject this, jint count)
-{
-    /* this FileDescriptor fd field */
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    /* fdObj's int fd field */
-    int fd;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-
-    if (listen(fd, count) == -1) {
-        NET_ThrowCurrent(env, "listen failed");
-    }
-
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketAccept
- * Signature: (Ljava/net/SocketImpl;)V
- */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
-                                           jobject socket)
-{
-    /* fields on this */
-    jint port;
-    jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    /* the FileDescriptor field on socket */
-    jobject socketFdObj;
-
-    /* cache the Inet4 class */
-    static jclass inet4Cls;
-
-    /* the InetAddress field on socket */
-    jobject socketAddressObj;
+JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_accept0
+  (JNIEnv *env, jclass clazz, jint fd, jobjectArray isaa) {
+    int newfd, port=0;
+    jobject isa;
+    jobject ia;
+    SOCKETADDRESS sa;
+    int len = sizeof(sa);
 
-    /* the fd int field on fdObj */
-    jint fd=-1;
-
-    SOCKETADDRESS sa;
-    jint len;
-    int ret;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    }
-
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    memset((char *)&sa, 0, len);
+    newfd = accept(fd, &sa.sa, &len);
 
-    if (IS_NULL(socket)) {
-        JNU_ThrowNullPointerException(env, "socket is null");
-        return;
-    } else {
-        socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
-        socketAddressObj = (*env)->GetObjectField(env, socket, psi_addressID);
-    }
-    if ((IS_NULL(socketAddressObj)) || (IS_NULL(socketFdObj))) {
-        JNU_ThrowNullPointerException(env, "socket address or fd obj");
-        return;
-    }
-
-    len = sizeof(struct sockaddr_in);
-    if (timeout) {
-        ret = NET_Timeout(fd, timeout);
-        if (ret == 0) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                            "Accept timed out");
-            return;
-        } else if (ret == -1) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
-        /* REMIND: SOCKET CLOSED PROBLEM */
-/*        NET_ThrowCurrent(env, "Accept failed"); */
-            return;
-        } else if (ret == -2) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-            return;
-        }
-    }
-
-    fd = accept(fd, &sa.sa, &len);
-    if (fd < 0) {
-        /* REMIND: SOCKET CLOSED PROBLEM */
-        if (fd == -2) {
+    if (newfd < 0) {
+        if (newfd == -2) {
             JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
                             "operation interrupted");
         } else {
             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                             "socket closed");
         }
-        return;
+        return -1;
     }
-    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
-    (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
+
+    SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
 
     if (sa.sa.sa_family != AF_INET) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
-        return;
-    }
-
-    if (inet4Cls == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
-        if (c != NULL) {
-            inet4Cls = (*env)->NewGlobalRef(env, c);
-            (*env)->DeleteLocalRef(env, c);
-        }
+        NET_SocketClose(newfd);
+        return -1;
     }
 
-    /*
-     * fill up the remote peer port and address in the new socket structure
-     */
-    if (inet4Cls != NULL) {
-        socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
-    } else {
-        socketAddressObj = NULL;
-    }
-    if (socketAddressObj == NULL) {
-        /*
-         * FindClass or NewObject failed so close connection and
-         * exit (there will be a pending exception).
-         */
-        NET_SocketClose(fd);
-        return;
-    }
+    ia = NET_SockaddrToInetAddress(env, &sa, &port);
+    isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
+    (*env)->SetObjectArrayElement(env, isaa, 0, isa);
 
-    setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
-    setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
-    (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
-    port = ntohs ((u_short)GET_PORT(&sa));
-    (*env)->SetIntField(env, socket, psi_portID, (int)port);
-    port = (*env)->GetIntField(env, this, psi_localportID);
-    (*env)->SetIntField(env, socket, psi_localportID, port);
-    (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
+    return newfd;
 }
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketAvailable
- * Signature: ()I
+ * Method:    waitForNewConnection
+ * Signature: (II)V
  */
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketAvailable(JNIEnv *env, jobject this) {
-
-    jint available = -1;
-    jint res;
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jint fd;
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_waitForNewConnection
+  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
+    int rv;
 
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-        return -1;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    rv = NET_Timeout(fd, timeout);
+    if (rv == 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                        "Accept timed out");
+    } else if (rv == -1) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+    } else if (rv == -2) {
+        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                        "operation interrupted");
     }
-    res = ioctlsocket(fd, FIONREAD, &available);
-    /* if result isn't 0, it means an error */
-    if (res != 0) {
-        NET_ThrowNew(env, res, "socket available");
+}
+
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    available0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_available0
+  (JNIEnv *env, jclass clazz, jint fd) {
+    jint available = -1;
+
+    if ((ioctlsocket(fd, FIONREAD, &available)) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "socket available");
     }
+
     return available;
 }
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketClose
- * Signature: ()V
+ * Method:    close0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_close0
+  (JNIEnv *env, jclass clazz, jint fd) {
+     NET_SocketClose(fd);
+}
+
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    shutdown0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_shutdown0
+  (JNIEnv *env, jclass clazz, jint fd, jint howto) {
+    shutdown(fd, howto);
+}
+
+
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    setIntOption
+ * Signature: (III)V
  */
 JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
-                                           jboolean useDeferredClose) {
+Java_java_net_TwoStacksPlainSocketImpl_setIntOption
+  (JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value)
+{
+    int level = 0, opt = 0;
+    struct linger linger = {0, 0};
+    char *parg;
+    int arglen;
 
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jint fd=-1;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket already closed");
+    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
+        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
         return;
     }
-    if (!IS_NULL(fdObj)) {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+    if (opt == java_net_SocketOptions_SO_LINGER) {
+        parg = (char *)&linger;
+        arglen = sizeof(linger);
+        if (value >= 0) {
+            linger.l_onoff = 1;
+            linger.l_linger = (unsigned short)value;
+        } else {
+            linger.l_onoff = 0;
+            linger.l_linger = 0;
+        }
+    } else {
+        parg = (char *)&value;
+        arglen = sizeof(value);
     }
-    if (fd != -1) {
-        (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
-        NET_SocketClose(fd);
+
+    if (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) {
+        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
     }
 }
 
 /*
- * Socket options for plainsocketImpl
- *
- *
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketNativeSetOption
- * Signature: (IZLjava/lang/Object;)V
+ * Method:    setSoTimeout0
+ * Signature: (II)V
  */
 JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
-  (JNIEnv *env, jobject this, jint cmd, jboolean on, jobject value)
+Java_java_net_TwoStacksPlainSocketImpl_setSoTimeout0
+  (JNIEnv *env, jclass clazz, jint fd, jint timeout)
 {
-    int fd;
-    int level = 0, optname = 0, optlen = 0;
-    union {
-        int i;
-        struct linger ling;
-    } optval;
-
-    memset((char *)&optval, 0, sizeof(optval));
-    /*
-     * Get SOCKET and check that it hasn't been closed
-     */
-    fd = getFD(env, this);
-    if (fd < 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-        return;
-    }
-
     /*
      * SO_TIMEOUT is the socket option used to specify the timeout
      * for ServerSocket.accept and Socket.getInputStream().read.
@@ -629,283 +445,106 @@
      * receive timeout is applicable to Socket only and the socket
      * option should not be set on ServerSocket.
      */
-    if (cmd == java_net_SocketOptions_SO_TIMEOUT) {
 
+    /*
+     * SO_RCVTIMEO is only supported on Microsoft's implementation
+     * of Windows Sockets so if WSAENOPROTOOPT returned then
+     * reset flag and timeout will be implemented using
+     * select() -- see SocketInputStream.socketRead.
+     */
+    if (isRcvTimeoutSupported) {
         /*
-         * Don't enable the socket option on ServerSocket as it's
-         * meaningless (we don't receive on a ServerSocket).
+         * Disable SO_RCVTIMEO if timeout is <= 5 second.
          */
-        jobject ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
-        if (ssObj != NULL) {
-            return;
+        if (timeout <= 5000) {
+            timeout = 0;
         }
 
-        /*
-         * SO_RCVTIMEO is only supported on Microsoft's implementation
-         * of Windows Sockets so if WSAENOPROTOOPT returned then
-         * reset flag and timeout will be implemented using
-         * select() -- see SocketInputStream.socketRead.
-         */
-        if (isRcvTimeoutSupported) {
-            jclass iCls = (*env)->FindClass(env, "java/lang/Integer");
-            jfieldID i_valueID;
-            jint timeout;
-
-            CHECK_NULL(iCls);
-            i_valueID = (*env)->GetFieldID(env, iCls, "value", "I");
-            CHECK_NULL(i_valueID);
-            timeout = (*env)->GetIntField(env, value, i_valueID);
-
-            /*
-             * Disable SO_RCVTIMEO if timeout is <= 5 second.
-             */
-            if (timeout <= 5000) {
-                timeout = 0;
-            }
-
-            if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
-                sizeof(timeout)) < 0) {
-                if (WSAGetLastError() == WSAENOPROTOOPT) {
-                    isRcvTimeoutSupported = JNI_FALSE;
-                } else {
-                    NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
-                    return;
-                }
+        if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
+            sizeof(timeout)) < 0) {
+            int err = WSAGetLastError();
+            if (err == WSAENOPROTOOPT) {
+                isRcvTimeoutSupported = JNI_FALSE;
+            } else {
+                NET_ThrowNew(env, err, "setsockopt SO_RCVTIMEO");
             }
         }
-        return;
     }
+}
 
-    /*
-     * Map the Java level socket option to the platform specific
-     * level and option name.
-     */
-    if (NET_MapSocketOption(cmd, &level, &optname)) {
+/*
+ * Class:     java_net_TwoStacksPlainSocketImpl
+ * Method:    getIntOption
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_getIntOption
+  (JNIEnv *env, jclass clazz, jint fd, jint cmd)
+{
+    int level = 0, opt = 0;
+    int result=0;
+    struct linger linger = {0, 0};
+    char *arg;
+    int arglen;
+
+    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
         JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return;
+        return -1;
     }
 
-    switch (cmd) {
-
-        case java_net_SocketOptions_TCP_NODELAY :
-        case java_net_SocketOptions_SO_OOBINLINE :
-        case java_net_SocketOptions_SO_KEEPALIVE :
-        case java_net_SocketOptions_SO_REUSEADDR :
-            optval.i = (on ? 1 : 0);
-            optlen = sizeof(optval.i);
-            break;
-
-        case java_net_SocketOptions_SO_SNDBUF :
-        case java_net_SocketOptions_SO_RCVBUF :
-        case java_net_SocketOptions_IP_TOS :
-            {
-                jclass cls;
-                jfieldID fid;
-
-                cls = (*env)->FindClass(env, "java/lang/Integer");
-                CHECK_NULL(cls);
-                fid = (*env)->GetFieldID(env, cls, "value", "I");
-                CHECK_NULL(fid);
-
-                optval.i = (*env)->GetIntField(env, value, fid);
-                optlen = sizeof(optval.i);
-            }
-            break;
-
-        case java_net_SocketOptions_SO_LINGER :
-            {
-                jclass cls;
-                jfieldID fid;
-
-                cls = (*env)->FindClass(env, "java/lang/Integer");
-                CHECK_NULL(cls);
-                fid = (*env)->GetFieldID(env, cls, "value", "I");
-                CHECK_NULL(fid);
-
-                if (on) {
-                    optval.ling.l_onoff = 1;
-                    optval.ling.l_linger =
-                        (unsigned short)(*env)->GetIntField(env, value, fid);
-                } else {
-                    optval.ling.l_onoff = 0;
-                    optval.ling.l_linger = 0;
-                }
-                optlen = sizeof(optval.ling);
-            }
-            break;
-
-        default: /* shouldn't get here */
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                "Option not supported by TwoStacksPlainSocketImpl");
-            return;
+    if (opt == java_net_SocketOptions_SO_LINGER) {
+        arg = (char *)&linger;
+        arglen = sizeof(linger);
+    } else {
+        arg = (char *)&result;
+        arglen = sizeof(result);
     }
 
-    if (fd != -1) {
-        if (NET_SetSockOpt(fd, level, optname, (void *)&optval, optlen) < 0) {
-            NET_ThrowCurrent(env, "setsockopt");
-        }
+    if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) {
+        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
+        return -1;
     }
+
+    if (opt == java_net_SocketOptions_SO_LINGER)
+        return linger.l_onoff ? linger.l_linger : -1;
+    else
+        return result;
 }
 
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketGetOption
- * Signature: (I)I
+ * Method:    sendOOB
+ * Signature: (II)V
  */
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
-  (JNIEnv *env, jobject this, jint opt, jobject iaContainerObj)
-{
-    int fd;
-    int level = 0, optname = 0, optlen = 0;
-    union {
-        int i;
-        struct linger ling;
-    } optval;
-
-    /*
-     * Get SOCKET and check it hasn't been closed
-     */
-    fd = getFD(env, this);
-    memset((char *)&optval, 0, sizeof(optval));
-
-    if (fd < 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-        return -1;
-    }
-
-    /*
-     * SO_BINDADDR isn't a socket option
-     */
-    if (opt == java_net_SocketOptions_SO_BINDADDR) {
-        SOCKETADDRESS sa;
-        int len = sizeof(SOCKETADDRESS);
-        int port;
-        jobject iaObj;
-        jclass iaCntrClass;
-        jfieldID iaFieldID;
-
-        memset((char *)&sa, 0, len);
-
-        if (getsockname(fd, &sa.sa, &len) < 0) {
-            JNU_ThrowByNameWithMessageAndLastError
-                (env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
-            return -1;
-        }
-        iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
-        CHECK_NULL_RETURN(iaObj, -1);
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_sendOOB
+  (JNIEnv *env, jclass clazz, jint fd, jint data) {
+    jint n;
+    unsigned char d = (unsigned char) data & 0xff;
 
-        iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
-        iaFieldID = (*env)->GetFieldID(env, iaCntrClass, "addr", "Ljava/net/InetAddress;");
-        CHECK_NULL_RETURN(iaFieldID, -1);
-        (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
-        return 0; /* notice change from before */
-    }
-
-    /*
-     * Map the Java level socket option to the platform specific
-     * level and option name.
-     */
-    if (NET_MapSocketOption(opt, &level, &optname)) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return -1;
-    }
-
-    /*
-     * Args are int except for SO_LINGER
-     */
-    if (opt == java_net_SocketOptions_SO_LINGER) {
-        optlen = sizeof(optval.ling);
-    } else {
-        optlen = sizeof(optval.i);
-        optval.i = 0;
-    }
-
-    if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
-        NET_ThrowCurrent(env, "getsockopt");
-        return -1;
-    }
-
-    switch (opt) {
-        case java_net_SocketOptions_SO_LINGER:
-            return (optval.ling.l_onoff ? optval.ling.l_linger: -1);
-
-        case java_net_SocketOptions_SO_SNDBUF:
-        case java_net_SocketOptions_SO_RCVBUF:
-        case java_net_SocketOptions_IP_TOS:
-            return optval.i;
-
-        case java_net_SocketOptions_TCP_NODELAY :
-        case java_net_SocketOptions_SO_OOBINLINE :
-        case java_net_SocketOptions_SO_KEEPALIVE :
-        case java_net_SocketOptions_SO_REUSEADDR :
-            return (optval.i == 0) ? -1 : 1;
-
-        default: /* shouldn't get here */
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                "Option not supported by TwoStacksPlainSocketImpl");
-            return -1;
+    n = send(fd, (char *)&data, 1, MSG_OOB);
+    if (n == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "send");
     }
 }
 
 /*
  * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketShutdown
- * Signature: (I)V
+ * Method:    configureBlocking
+ * Signature: (IZ)V
  */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
-                                             jint howto)
-{
-
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jint fd;
-
-    /*
-     * WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being
-     * -1 already?
-     */
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket already closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    shutdown(fd, howto);
-}
+JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_configureBlocking
+  (JNIEnv *env, jclass clazz, jint fd, jboolean blocking) {
+    u_long arg;
+    int result;
 
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socketSendUrgentData
- * Signature: (B)V
- */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketSendUrgentData(JNIEnv *env, jobject this,
-                                             jint data) {
-    /* The fd field */
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    int n, fd;
-    unsigned char d = data & 0xff;
+    if (blocking == JNI_TRUE) {
+        arg = SET_BLOCKING;    // 0
+    } else {
+        arg = SET_NONBLOCKING;   // 1
+    }
 
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-        /* Bug 4086704 - If the Socket associated with this file descriptor
-         * was closed (sysCloseFD), the file descriptor is set to -1.
-         */
-        if (fd == -1) {
-            JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
-            return;
-        }
-
-    }
-    n = send(fd, (char *)&data, 1, MSG_OOB);
-    if (n == -1) {
-        NET_ThrowCurrent(env, "send");
-        return;
+    result = ioctlsocket(fd, FIONBIO, &arg);
+    if (result == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
     }
 }
--- a/test/jdk/java/net/Socket/AddressTest.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/AddressTest.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,10 @@
 /*
  * @test
  * @bug 4507501
- * @summary Test various methods that should throw IAE when passed improper SocketAddress
- *
+ * @summary Test various methods that should throw IAE when passed improper
+ *          SocketAddress
+ * @run main AddressTest
+ * @run main/othervm -Djava.net.preferIPv4Stack=true AddressTest
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/B6210227.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/B6210227.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
  * @test
  * @bug 6210227
  * @summary  REGRESSION: Socket.getLocalAddress() returns address of 0.0.0.0 on outbound TCP
+ * @run main B6210227
+ * @run main/othervm -Djava.net.preferIPv4Stack=true B6210227
  */
 
 import java.util.*;
--- a/test/jdk/java/net/Socket/CloseAvailable.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/CloseAvailable.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  * @test
  * @bug 4091859
  * @summary Test Socket.available()
- *
+ * @run main CloseAvailable
+ * @run main/othervm -Djava.net.preferIPv4Stack=true CloseAvailable
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/DeadlockTest.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/DeadlockTest.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 4176738
  * @summary Make sure a deadlock situation
  *     would not occur
+ * @run main DeadlockTest
+ * @run main/othervm -Djava.net.preferIPv4Stack=true DeadlockTest
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/HttpProxy.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/HttpProxy.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6370908
  * @summary Add support for HTTP_CONNECT proxy in Socket class
  * @modules java.base/sun.net.www
+ * @run main HttpProxy
+ * @run main/othervm -Djava.net.preferIPv4Stack=true HttpProxy
  */
 
 import java.io.IOException;
--- a/test/jdk/java/net/Socket/InheritHandle.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/InheritHandle.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,9 +22,11 @@
  */
 
 /* @test
-   @bug  6598160
-   @summary Windows IPv6 Socket implementation doesn't set the handle to not inherit
-   @author Chris Hegarty
+ * @bug  6598160
+ * @summary Windows IPv6 Socket implementation doesn't set the handle to not inherit
+ * @author Chris Hegarty
+ * @run main InheritHandle
+ * @run main/othervm -Djava.net.preferIPv4Stack=true InheritHandle
  */
 
 import java.net.BindException;
--- a/test/jdk/java/net/Socket/InheritTimeout.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/InheritTimeout.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 4508149
  * @summary Setting ServerSocket.setSoTimeout shouldn't cause
  *          the timeout to be inherited by accepted connections
+ * @run main InheritTimeout
+ * @run main/othervm -Djava.net.preferIPv4Stack=true InheritTimeout
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/LingerTest.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/LingerTest.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
  * @test
  * @bug 4796166
  * @summary Linger interval delays usage of released file descriptor
+ * @run main LingerTest
+ * @run main/othervm -Djava.net.preferIPv4Stack=true LingerTest
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/LinkLocal.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/LinkLocal.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
  * @build jdk.test.lib.NetworkConfiguration
  *        jdk.test.lib.Platform
  * @run main LinkLocal
+ * @run main/othervm -Djava.net.preferIPv4Stack=true LinkLocal
  */
 
 import jdk.test.lib.NetworkConfiguration;
--- a/test/jdk/java/net/Socket/ProxyCons.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/ProxyCons.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @bug 4097826
  * @summary SOCKS support inadequate
  * @run main/timeout=40/othervm -DsocksProxyHost=nonexistant ProxyCons
+ * @run main/timeout=40/othervm -DsocksProxyHost=nonexistant -Djava.net.preferIPv4Stack=true ProxyCons
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/RST.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/RST.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
 /*
  * @bug 4468997
  * @summary SO_LINGER is ignored on Windows with Winsock 2
+ * @run main RST
+ * @run main/othervm -Djava.net.preferIPv4Stack=true RST
  */
 import java.net.*;
 import java.io.*;
--- a/test/jdk/java/net/Socket/ReadTimeout.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/ReadTimeout.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @bug 4169831
  * @summary test timeout on a socket read
  * @run main/timeout=15 ReadTimeout
+ * @run main/othervm/timeout=15 -Djava.net.preferIPv4Stack=true ReadTimeout
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/SetSoLinger.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/SetSoLinger.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  * @test
  * @bug 4151834
  * @summary Test Socket.setSoLinger
- *
+ * @run main SetSoLinger
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SetSoLinger
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/ShutdownInput.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/ShutdownInput.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 7014860
  * @summary Socket.getInputStream().available() not clear for
  *          case that connection is shutdown for reading
+ * @run main ShutdownInput
+ * @run main/othervm -Djava.net.preferIPv4Stack=true ShutdownInput
  */
 
 import java.io.InputStream;
--- a/test/jdk/java/net/Socket/SocksConnectTimeout.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/SocksConnectTimeout.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
  * @test
  * @bug 6223635
  * @summary Code hangs at connect call even when Timeout is specified
+ * @run main SocksConnectTimeout
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SocksConnectTimeout
  */
 
 import java.net.InetAddress;
--- a/test/jdk/java/net/Socket/TestAfterClose.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/TestAfterClose.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,10 @@
 /*
  * @test
  * @bug 6505016
- * @summary Socket spec should clarify what getInetAddress/getPort/etc return after the Socket is closed
+ * @summary Socket spec should clarify what getInetAddress/getPort/etc return
+ *          after the Socket is closed
+ * @run main TestAfterClose
+ * @run main/othervm -Djava.net.preferIPv4Stack=true TestAfterClose
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/TestClose.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/TestClose.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,11 +22,12 @@
  */
 /*
  * @test
- *
  * @bug 4408755
- *
- * @summary This tests wether it's possible to get some informations
- * out of a closed socket. This is for backward compatibility purposes.
+ * @summary This tests whether it's possible to get some informations
+ *          out of a closed socket. This is for backward compatibility
+ *          purposes.
+ * @run main TestClose
+ * @run main/othervm -Djava.net.preferIPv4Stack=true TestClose
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/TestTcpNoDelay.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/TestTcpNoDelay.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
  * @test
  * @bug 6404388
  * @summary VISTA: Socket setTcpNoDelay & setKeepAlive working incorrectly
+ * @run main TestTcpNoDelay
+ * @run main/othervm -Djava.net.preferIPv4Stack=true TestTcpNoDelay
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/Timeout.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/Timeout.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @bug 4163126
  * @summary  test to see if timeout hangs
  * @run main/timeout=15 Timeout
+ * @run main/othervm/timeout=15 -Djava.net.preferIPv4Stack=true Timeout
  */
 import java.net.*;
 import java.io.*;
--- a/test/jdk/java/net/Socket/TrafficClass.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/TrafficClass.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 4511783
  * @summary Test that setTrafficClass/getTraffiClass don't
  *          throw an exception
+ * @run main TrafficClass
+ * @run main/othervm -Djava.net.preferIPv4Stack=true TrafficClass
  */
 import java.net.*;
 import java.nio.*;
--- a/test/jdk/java/net/Socket/UrgentDataTest.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/UrgentDataTest.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  * @test
  * @bug 4092038
  * @summary TCP Urgent data support
- *
+ * @run main UrgentDataTest
+ * @run main/othervm -Djava.net.preferIPv4Stack=true UrgentDataTest
  */
 
 import java.net.*;
--- a/test/jdk/java/net/Socket/asyncClose/AsyncClose.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/asyncClose/AsyncClose.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,8 @@
  * @bug 4344135
  * @summary Check that {Socket,ServerSocket,DatagramSocket}.close will
  *          cause any thread blocked on the socket to throw a SocketException.
+ * @run main AsyncClose
+ * @run main/othervm -Djava.net.preferIPv4Stack=true AsyncClose
  */
 
 public class AsyncClose {
--- a/test/jdk/java/net/Socket/asyncClose/BrokenPipe.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/asyncClose/BrokenPipe.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,10 +22,12 @@
  */
 
 /*
- * @test 1.1 01/09/19
+ * @test
  * @bug 4511404
  * @summary Check that a broken pipe error doesn't throw an exception
  *          indicating the socket is closed.
+ * @run main BrokenPipe
+ * @run main/othervm -Djava.net.preferIPv4Stack=true BrokenPipe
  */
 import java.io.*;
 import java.net.*;
--- a/test/jdk/java/net/Socket/setReuseAddress/Basic.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/setReuseAddress/Basic.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
  * method.
  * @run main Basic
  * @run main/othervm -Dsun.net.useExclusiveBind Basic
+ * @run main/othervm -Djava.net.preferIPv4Stack=true Basic
+ * @run main/othervm -Dsun.net.useExclusiveBind -Djava.net.preferIPv4Stack=true Basic
  */
 import java.net.*;
 
--- a/test/jdk/java/net/Socket/setReuseAddress/Restart.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/Socket/setReuseAddress/Restart.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
  *          after a crash.
  * @run main Restart
  * @run main/othervm -Dsun.net.useExclusiveBind Restart
+ * @run main/othervm -Djava.net.preferIPv4Stack=true Restart
+ * @run main/othervm -Dsun.net.useExclusiveBind -Djava.net.preferIPv4Stack=true Restart
  */
 import java.net.*;
 
--- a/test/jdk/java/net/SocketInputStream/SocketClosedException.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/SocketInputStream/SocketClosedException.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 4681556
  * @summary Wrong text if a read is performed on a socket after it
  *      has been closed
+ * @run main SocketClosedException
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SocketClosedException
  */
 
 import java.io.*;
--- a/test/jdk/java/net/SocketInputStream/SocketTimeout.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/SocketInputStream/SocketTimeout.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
  * @test
  * @bug 4158021
  * @summary cannot distinguish Thread.interrupt and Socket.setSoTimeout exceptions
+ * @run main SocketTimeout
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SocketTimeout
  */
 
 import java.net.*;
--- a/test/jdk/java/net/SocketOption/ImmutableOptions.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/SocketOption/ImmutableOptions.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,9 @@
  /*
  * @test
  * @bug 8148609
+ * @summary Assert that the set of socket options are immutable
  * @run testng/othervm ImmutableOptions
- * @summary Assert that the set of socket options are immutable
+ * @run testng/othervm -Djava.net.preferIPv4Stack=true ImmutableOptions
  */
 import java.io.IOException;
 import java.io.InputStream;
--- a/test/jdk/java/net/SocketOption/MinimumRcvBufferSize.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/SocketOption/MinimumRcvBufferSize.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
  * @test
  * @bug 8170920
  * @run main MinimumRcvBufferSize
+ * @run main/othervm -Djava.net.preferIPv4Stack=true MinimumRcvBufferSize
  */
 
 import java.nio.channels.*;
--- a/test/jdk/java/net/SocketOption/SupportedOptionsSet.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/SocketOption/SupportedOptionsSet.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@
  * @summary java.net socket supportedOptions set depends on call order
  * @run main/othervm SupportedOptionsSet first
  * @run main/othervm SupportedOptionsSet second
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SupportedOptionsSet first
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SupportedOptionsSet second
  */
 
 // Run with othervm as the implementation of the supported options sets, once
--- a/test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java	Tue Mar 27 19:29:46 2018 +0100
+++ b/test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java	Tue Mar 27 13:22:40 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,10 @@
  * @test
  * @bug 8143554 8044773
  * @summary Test checks that UnsupportedOperationException for unsupported
- * SOCKET_OPTIONS is thrown by both getOption() and setOption() methods.
+ *          SOCKET_OPTIONS is thrown by both getOption() and setOption() methods.
  * @requires !vm.graal.enabled
  * @run main UnsupportedOptionsTest
+ * @run main/othervm -Djava.net.preferIPv4Stack=true UnsupportedOptionsTest
  * @run main/othervm --limit-modules=java.base UnsupportedOptionsTest
  */