/*
 * Copyright (c) 1997, 2013, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <windows.h>
#include <winsock2.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/types.h>

#include "java_net_SocketOptions.h"
#include "java_net_TwoStacksPlainSocketImpl.h"
#include "java_net_InetAddress.h"
#include "java_io_FileDescriptor.h"
#include "java_lang_Integer.h"

#include "jvm.h"
#include "net_util.h"
#include "jni_util.h"

/************************************************************************
 * TwoStacksPlainSocketImpl
 */

static jfieldID IO_fd_fdID;

jfieldID psi_fdID;
jfieldID psi_fd1ID;
jfieldID psi_addressID;
jfieldID psi_portID;
jfieldID psi_localportID;
jfieldID psi_timeoutID;
jfieldID psi_trafficClassID;
jfieldID psi_serverSocketID;
jfieldID psi_lastfdID;

/*
 * 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);
}

static int getFD1(JNIEnv *env, jobject this) {
    jobject fdObj = (*env)->GetObjectField(env, this, psi_fd1ID);

    if (fdObj == NULL) {
        return -1;
    }
    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}


/*
 * The initProto 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

 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) {

    struct protoent *proto = getprotobyname("TCP");
    tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);

    psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;");
    CHECK_NULL(psi_fdID);
    psi_fd1ID =(*env)->GetFieldID(env, cls , "fd1", "Ljava/io/FileDescriptor;");
    CHECK_NULL(psi_fd1ID);
    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_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "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:    socketCreate
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
                                           jboolean stream) {
    jobject fdObj, fd1Obj;
    int fd, fd1;

    fdObj = (*env)->GetObjectField(env, this, psi_fdID);

    if (IS_NULL(fdObj)) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "null fd object");
        return;
    }
    fd = socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
    if (fd == -1) {
        NET_ThrowCurrent(env, "create");
        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);
    }
    if (ipv6_available()) {
        fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);

        if (IS_NULL(fd1Obj)) {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                            "null fd1 object");
            (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
            NET_SocketClose(fd);
            return;
        }
        fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
        if (fd1 == -1) {
            NET_ThrowCurrent(env, "create");
            (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
            NET_SocketClose(fd);
            return;
        } else {
            /* Set socket attribute so it is not passed to any child process */
            SetHandleInformation((HANDLE)(UINT_PTR)fd1, HANDLE_FLAG_INHERIT, FALSE);
            (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
        }
    } else {
        (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
    }
}

/*
 * inetAddress is the address object passed to the socket connect
 * call.
 *
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketConnect
 * Signature: (Ljava/net/InetAddress;I)V
 */
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 */
    int family;
    jint fd, fd1=-1;
    jint len;
    int  ipv6_supported = ipv6_available();

    /* fd initially points to the IPv4 socket and fd1 to the IPv6 socket
     * If we want to connect to IPv6 then we swap the two sockets/objects
     * This way, fd is always the connected socket, and fd1 always gets closed.
     */
    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);

    SOCKETADDRESS him;

    /* The result of the connection */
    int connect_res;
    memset((char *)&him, 0, sizeof(him));

    if (!IS_NULL(fdObj)) {
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
    }

    if (ipv6_supported && !IS_NULL(fd1Obj)) {
        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
    }

    if (IS_NULL(iaObj)) {
        JNU_ThrowNullPointerException(env, "inet address argument is null.");
        return;
    }

    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&him, &len, JNI_FALSE) != 0) {
      return;
    }

    family = him.him.sa_family;
    if (family == AF_INET6) {
        if (!ipv6_supported) {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                            "Protocol family not supported");
            return;
        } else {
            if (fd1 == -1) {
                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                                "Destination unreachable");
                return;
            }
            /* close the v4 socket, and set fd to be the v6 socket */
            (*env)->SetObjectField(env, this, psi_fdID, fd1Obj);
            (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
            NET_SocketClose(fd);
            fd = fd1; fdObj = fd1Obj;
        }
    } else {
        if (fd1 != -1) {
            (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
            NET_SocketClose(fd1);
        }
        if (fd == -1) {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                            "Destination unreachable");
            return;
        }
    }
    (*env)->SetObjectField(env, this, psi_fd1ID, NULL);

    if (timeout <= 0) {
        connect_res = connect(fd, (struct sockaddr *) &him, SOCKETADDRESS_LEN(&him));
        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, (struct sockaddr *) &him, SOCKETADDRESS_LEN(&him));
        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) {
            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");
        }
        return;
    }

    (*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);

    /* set the remote peer address and port */
    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
    (*env)->SetIntField(env, this, psi_portID, port);

    /*
     * 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
     */
    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 = SOCKETADDRESS_LEN(&him);
        if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {

            if (WSAGetLastError() == WSAENOTSOCK) {
                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "Socket closed");
            } else {
                NET_ThrowCurrent(env, "getsockname failed");
            }
            return;
        }
        port = ntohs ((u_short)GET_PORT(&him));
        (*env)->SetIntField(env, this, psi_localportID, (int) port);
    }
}

/*
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketBind
 * Signature: (Ljava/net/InetAddress;I)V
 */
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, fd1Obj;
    /* fd is an int field on fdObj */
    int fd, fd1, len = 0;
    int ipv6_supported = ipv6_available();

    /* family is an int field of iaObj */
    int family;
    int rv;

    SOCKETADDRESS him;

    fdObj = (*env)->GetObjectField(env, this, psi_fdID);
    fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);

    family = getInetAddress_family(env, iaObj);

    if (family == IPv6 && !ipv6_supported) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "Protocol family not supported");
        return;
    }

    if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "Socket closed");
        return;
    } else {
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
        if (ipv6_supported) {
            fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
        }
    }
    if (IS_NULL(iaObj)) {
        JNU_ThrowNullPointerException(env, "inet address argument");
        return;
    }

    if (NET_InetAddressToSockaddr(env, iaObj, localport,
                          (struct sockaddr *)&him, &len, JNI_FALSE) != 0) {
      return;
    }
    if (ipv6_supported) {
        struct ipv6bind v6bind;
        v6bind.addr = &him;
        v6bind.ipv4_fd = fd;
        v6bind.ipv6_fd = fd1;
        rv = NET_BindV6(&v6bind, exclBind);
        if (rv != -1) {
            /* check if the fds have changed */
            if (v6bind.ipv4_fd != fd) {
                fd = v6bind.ipv4_fd;
                if (fd == -1) {
                    /* socket is closed. */
                    (*env)->SetObjectField(env, this, psi_fdID, NULL);
                } else {
                    /* socket was re-created */
                    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
                }
            }
            if (v6bind.ipv6_fd != fd1) {
                fd1 = v6bind.ipv6_fd;
                if (fd1 == -1) {
                    /* socket is closed. */
                    (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
                } else {
                    /* socket was re-created */
                    (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
                }
            }
        } else {
            /* NET_BindV6() closes both sockets upon a failure */
            (*env)->SetObjectField(env, this, psi_fdID, NULL);
            (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
        }
    } else {
        rv = NET_WinBind(fd, (struct sockaddr *)&him, len, exclBind);
    }

    if (rv == -1) {
        NET_ThrowCurrent(env, "JVM_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 = SOCKETADDRESS_LEN(&him);
        u_short port;
        fd = him.him.sa_family == AF_INET? fd: fd1;

        if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
            NET_ThrowCurrent(env, "getsockname in plain socketBind");
            return;
        }
        port = ntohs ((u_short) GET_PORT (&him));

        (*env)->SetIntField(env, this, psi_localportID, (int) port);
    } else {
        (*env)->SetIntField(env, this, psi_localportID, localport);
    }
}

/*
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketListen
 * Signature: (I)V
 */
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);
    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
    jobject address;
    /* fdObj's int fd field */
    int fd, fd1;
    SOCKETADDRESS addr; int addrlen;

    if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "socket closed");
        return;
    }

    if (!IS_NULL(fdObj)) {
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
    }
    /* Listen on V4 if address type is v4 or if v6 and address is ::0.
     * Listen on V6 if address type is v6 or if v4 and address is 0.0.0.0.
     * In cases, where we listen on one space only, we close the other socket.
     */
    address = (*env)->GetObjectField(env, this, psi_addressID);
    if (IS_NULL(address)) {
        JNU_ThrowNullPointerException(env, "socket address");
        return;
    }
    if (NET_InetAddressToSockaddr(env, address, 0, (struct sockaddr *)&addr,
                                  &addrlen, JNI_FALSE) != 0) {
      return;
    }

    if (addr.him.sa_family == AF_INET || IN6ADDR_ISANY(&addr.him6)) {
        /* listen on v4 */
        if (listen(fd, count) == -1) {
            NET_ThrowCurrent(env, "listen failed");
        }
    } else {
        NET_SocketClose (fd);
        (*env)->SetObjectField(env, this, psi_fdID, NULL);
    }
    if (ipv6_available() && !IS_NULL(fd1Obj)) {
        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
        if (addr.him.sa_family == AF_INET6 || addr.him4.sin_addr.s_addr == INADDR_ANY) {
            /* listen on v6 */
            if (listen(fd1, count) == -1) {
                NET_ThrowCurrent(env, "listen failed");
            }
        } else {
            NET_SocketClose (fd1);
            (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
        }
    }
}

/*
 * 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 scope;
    jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);

    /* the FileDescriptor field on socket */
    jobject socketFdObj;

    /* cache the Inet4/6Address classes */
    static jclass inet4Cls;
    static jclass inet6Cls;

    /* the InetAddress field on socket */
    jobject socketAddressObj;

    /* the fd int field on fdObj */
    jint fd=-1, fd1=-1;

    SOCKETADDRESS him;
    jint len;

    if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "Socket closed");
        return;
    }
    if (!IS_NULL(fdObj)) {
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
    }
    if (!IS_NULL(fd1Obj)) {
        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
    }
    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;
    }
    if (fd != -1 && fd1 != -1) {
        fd_set rfds;
        struct timeval t, *tP=&t;
        int lastfd, res, fd2;
        FD_ZERO(&rfds);
        FD_SET(fd,&rfds);
        FD_SET(fd1,&rfds);
        if (timeout) {
            t.tv_sec = timeout/1000;
            t.tv_usec = (timeout%1000)*1000;
        } else {
            tP = NULL;
        }
        res = select (fd, &rfds, NULL, NULL, tP);
        if (res == 0) {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
                            "Accept timed out");
            return;
        } else if (res == 1) {
            fd2 = FD_ISSET(fd, &rfds)? fd: fd1;
        } else if (res == 2) {
            /* avoid starvation */
            lastfd = (*env)->GetIntField(env, this, psi_lastfdID);
            if (lastfd != -1) {
                fd2 = lastfd==fd? fd1: fd;
            } else {
                fd2 = fd;
            }
            (*env)->SetIntField(env, this, psi_lastfdID, fd2);
        } else {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                            "select failed");
            return;
        }
        if (fd2 == fd) { /* v4 */
            len = sizeof (struct sockaddr_in);
        } else {
            len = sizeof (struct SOCKADDR_IN6);
        }
        fd = fd2;
    } else {
        int ret;
        if (fd1 != -1) {
            fd = fd1;
            len = sizeof (struct SOCKADDR_IN6);
        } else {
            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, (struct sockaddr *)&him, &len);
    if (fd < 0) {
        /* REMIND: SOCKET CLOSED PROBLEM */
        if (fd == -2) {
            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
                            "operation interrupted");
        } else {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                            "socket closed");
        }
        return;
    }
    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
    (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);

    if (him.him.sa_family == AF_INET) {
        if (inet4Cls == NULL) {
            jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
            if (c != NULL) {
                inet4Cls = (*env)->NewGlobalRef(env, c);
                (*env)->DeleteLocalRef(env, c);
            }
        }

        /*
         * 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
             * exist (there will be a pending exception).
             */
            NET_SocketClose(fd);
            return;
        }

        setInetAddress_addr(env, socketAddressObj, ntohl(him.him4.sin_addr.s_addr));
        setInetAddress_family(env, socketAddressObj, IPv4);
        (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
    } else {
        /* AF_INET6 -> Inet6Address */
        if (inet6Cls == 0) {
            jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
            if (c != NULL) {
                inet6Cls = (*env)->NewGlobalRef(env, c);
                (*env)->DeleteLocalRef(env, c);
            }
        }

        if (inet6Cls != NULL) {
            socketAddressObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID);
        } else {
            socketAddressObj = NULL;
        }
        if (socketAddressObj == NULL) {
            /*
             * FindClass or NewObject failed so close connection and
             * exist (there will be a pending exception).
             */
            NET_SocketClose(fd);
            return;
        }
        setInet6Address_ipaddress(env, socketAddressObj, (const char *)&him.him6.sin6_addr);
        setInetAddress_family(env, socketAddressObj, IPv6);
        setInet6Address_scopeid(env, socketAddressObj, him.him6.sin6_scope_id);

    }
    /* fields common to AF_INET and AF_INET6 */

    port = ntohs ((u_short) GET_PORT (&him));
    (*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);
}

/*
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketAvailable
 * Signature: ()I
 */
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;

    if (IS_NULL(fdObj)) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
        return -1;
    } else {
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
    }
    res = ioctlsocket(fd, FIONREAD, &available);
    /* if result isn't 0, it means an error */
    if (res != 0) {
        NET_ThrowNew(env, res, "socket available");
    }
    return available;
}

/*
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketClose
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
                                           jboolean useDeferredClose) {

    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
    jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
    jint fd=-1, fd1=-1;

    if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "socket already closed");
        return;
    }
    if (!IS_NULL(fdObj)) {
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
    }
    if (!IS_NULL(fd1Obj)) {
        fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
    }
    if (fd != -1) {
        (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
        NET_SocketClose(fd);
    }
    if (fd1 != -1) {
        (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
        NET_SocketClose(fd1);
    }
}

/*
 * Socket options for plainsocketImpl
 *
 *
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketNativeSetOption
 * Signature: (IZLjava/lang/Object;)V
 */
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption(JNIEnv *env,
                                              jobject this,
                                              jint cmd, jboolean on,
                                              jobject value) {
    int fd, fd1;
    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);
    fd1 = getFD1(env, this);
    if (fd < 0 && fd1 < 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.
     * It does not typically map to a native level socket option.
     * For Windows we special-case this and use the SOL_SOCKET/SO_RCVTIMEO
     * socket option to specify a receive timeout on the socket. This
     * receive timeout is applicable to Socket only and the socket
     * option should not be set on ServerSocket.
     */
    if (cmd == java_net_SocketOptions_SO_TIMEOUT) {

        /*
         * Don't enable the socket option on ServerSocket as it's
         * meaningless (we don't receive on a ServerSocket).
         */
        jobject ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
        if (ssObj != NULL) {
            return;
        }

        /*
         * 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");
                }
            }
            if (fd1 != -1) {
                if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
                                        sizeof(timeout)) < 0) {
                    NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
                }
            }
        }
        return;
    }

    /*
     * Map the Java level socket option to the platform specific
     * level
     */
    if (NET_MapSocketOption(cmd, &level, &optname)) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "Invalid option");
        return;
    }

    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 (fd != -1) {
        if (NET_SetSockOpt(fd, level, optname, (void *)&optval, optlen) < 0) {
            NET_ThrowCurrent(env, "setsockopt");
        }
    }

    if (fd1 != -1) {
        if (NET_SetSockOpt(fd1, level, optname, (void *)&optval, optlen) < 0) {
            NET_ThrowCurrent(env, "setsockopt");
        }
    }
}


/*
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketGetOption
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL
Java_java_net_TwoStacksPlainSocketImpl_socketGetOption(JNIEnv *env, jobject this,
                                              jint opt, jobject iaContainerObj) {

    int fd, fd1;
    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);
    fd1 = getFD1(env, this);
    memset((char *)&optval, 0, sizeof(optval));

    if (fd < 0 && fd1 < 0) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
        return -1;
    }
    if (fd < 0) {
        fd = fd1;
    }

    /* For IPv6, we assume both sockets have the same setting always */

    /*
     * SO_BINDADDR isn't a socket option
     */
    if (opt == java_net_SocketOptions_SO_BINDADDR) {
        SOCKETADDRESS him;
        int len;
        int port;
        jobject iaObj;
        jclass iaCntrClass;
        jfieldID iaFieldID;

        len = sizeof(him);
        memset((char *)&him, 0, len);

        if (fd == -1) {
            /* must be an IPV6 only socket. Case where both sockets are != -1
             * is handled in java
             */
            fd = getFD1 (env, this);
        }

        if (getsockname(fd, (struct sockaddr *)&him, &len) < 0) {
            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                             "Error getting socket name");
            return -1;
        }
        iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
        CHECK_NULL_RETURN(iaObj, -1);

        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, JNU_JAVANETPKG "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;
    }
}

/*
 * Class:     java_net_TwoStacksPlainSocketImpl
 * Method:    socketShutdown
 * Signature: (I)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);
}

/*
 * 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 (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 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 == JVM_IO_ERR) {
        NET_ThrowCurrent(env, "send");
        return;
    }
    if (n == JVM_IO_INTR) {
        JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
        return;
    }
}
