/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketCreate
 * Signature: (Z)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketCreate
  (JNIEnv *env, jclass clazz, jboolean v6Only /*unused*/) {
    int fd, rv, opt=0, t=TRUE;
    DWORD x1, x2; /* ignored result codes */

    fd = (int) socket(AF_INET6, SOCK_DGRAM, 0);
    if (fd == INVALID_SOCKET) {
        NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
        return -1;
    }

    rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
    if (rv == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
        closesocket(fd);
        return -1;
    }

    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
    NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));

    /* SIO_UDP_CONNRESET fixes a "bug" introduced in Windows 2000, which
     * returns connection reset errors on unconnected UDP sockets (as well
     * as connected sockets). The solution is to only enable this feature
     * when the socket is connected.
     */
    t = FALSE;
    WSAIoctl(fd ,SIO_UDP_CONNRESET ,&t ,sizeof(t) ,&x1 ,sizeof(x1) ,&x2 ,0 ,0);

    return fd;
}
예제 #2
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
                            jboolean stream, jboolean reuse)
{
    SOCKET s;
    int domain = (preferIPv6) ? AF_INET6 : AF_INET;

    s = socket(domain, (stream ? SOCK_STREAM : SOCK_DGRAM), 0);
    if (s != INVALID_SOCKET) {
        SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);

        /* IPV6_V6ONLY is true by default */
        if (domain == AF_INET6) {
            int opt = 0;
            setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
                       (const char *)&opt, sizeof(opt));
        }

        /* Disable WSAECONNRESET errors for initially unconnected UDP sockets */
        if (!stream) {
            setConnectionReset(s, FALSE);
        }

    } else {
        NET_ThrowNew(env, WSAGetLastError(), "socket");
    }

    return (jint)s;
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    connect0
 * Signature: (ILjava/net/InetAddress;I)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_connect0
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
    SOCKETADDRESS sa;
    int rv;
    int sa_len = sizeof(sa);

    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
                                 &sa_len, JNI_TRUE) != 0) {
      return -1;
    }

    rv = connect(fd, (struct sockaddr *)&sa, sa_len);
    if (rv == SOCKET_ERROR) {
        int err = WSAGetLastError();
        if (err == WSAEWOULDBLOCK) {
            return java_net_DualStackPlainSocketImpl_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, err, "connect");
        }
        return -1;  // return value not important.
    }
    return rv;
}
예제 #4
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_connect0(JNIEnv *env, jclass clazz, jboolean preferIPv6, jobject fdo,
                             jobject iao, jint port)
{
    SOCKETADDRESS sa;
    int rv;
    int sa_len;
    SOCKET s = (SOCKET)fdval(env, fdo);

    if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
        return IOS_THROWN;
    }

    rv = connect(s, (struct sockaddr *)&sa, sa_len);
    if (rv != 0) {
        int err = WSAGetLastError();
        if (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK) {
            return IOS_UNAVAILABLE;
        }
        NET_ThrowNew(env, err, "connect");
        return IOS_THROWN;
    } else {
        /* Enable WSAECONNRESET errors when a UDP socket is connected */
        int type = 0, optlen = sizeof(type);
        rv = getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&type, &optlen);
        if (rv == 0 && type == SOCK_DGRAM) {
            setConnectionReset(s, TRUE);
        }
    }
    return 1;
}
예제 #5
0
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_listen(JNIEnv *env, jclass cl, jobject fdo, jint backlog)
{
    if (listen(fdval(env,fdo), backlog) == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "listen");
    }
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    getIntOption
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption
  (JNIEnv *env, jclass clazz, jint fd, jint cmd) {

    int level, opt;
    int result=0;
    struct linger linger;
    char *arg;
    int arglen;

    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
        JNU_ThrowByNameWithLastError(env,
                                     JNU_JAVANETPKG "SocketException",
                                     "Unsupported socket option");
        return -1;
    }

    if (opt == java_net_SocketOptions_SO_LINGER) {
        arg = (char *)&linger;
        arglen = sizeof(linger);
    } else {
        arg = (char *)&result;
        arglen = sizeof(result);
    }

    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_DualStackPlainSocketImpl
 * Method:    setIntOption
 * Signature: (III)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_setIntOption
  (JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value) {

    int level, opt;
    struct linger linger;
    char *parg;
    int arglen;

    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
        JNU_ThrowByNameWithLastError(env,
                                     JNU_JAVANETPKG "SocketException",
                                     "Invalid option");
        return;
    }

    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 (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) {
        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
    }
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    socket0
 * Signature: (ZZ)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_socket0
  (JNIEnv *env, jclass clazz, jboolean stream, jboolean v6Only /*unused*/) {
    int fd, rv, opt=0;

    fd = NET_Socket(AF_INET6, (stream ? SOCK_STREAM : SOCK_DGRAM), 0);
    if (fd == INVALID_SOCKET) {
        NET_ThrowNew(env, WSAGetLastError(), "create");
        return -1;
    }

    rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
    if (rv == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "create");
    }

    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);

    return fd;
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    available0
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_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_DualStackPlainDatagramSocketImpl
 * Method:    socketLocalPort
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalPort
  (JNIEnv *env, jclass clazz, jint fd) {
    SOCKETADDRESS sa;
    int len = sizeof(sa);

    if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "JVM_GetSockName");
        return -1;
    }
    return (int) ntohs((u_short)GET_PORT(&sa));
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    sendOOB
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_sendOOB
  (JNIEnv *env, jclass clazz, jint fd, jint data) {
    jint n;
    unsigned char d = (unsigned char) data & 0xff;

    n = send(fd, (char *)&data, 1, MSG_OOB);
    if (n == JVM_IO_ERR) {
        NET_ThrowNew(env, WSAGetLastError(), "send");
    } else if (n == JVM_IO_INTR) {
        JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
    }
}
/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketSend
 * Signature: (I[BIILjava/net/InetAddress;IZ)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSend
  (JNIEnv *env, jclass clazz, jint fd, jbyteArray data, jint offset, jint length,
     jobject iaObj, jint port, jboolean connected) {
    SOCKETADDRESS sa;
    int sa_len = sizeof(sa);
    SOCKETADDRESS *sap = &sa;
    char BUF[MAX_BUFFER_LEN];
    char *fullPacket;
    int rv;

    if (connected) {
        sap = 0; /* arg to JVM_Sendto () null in this case */
        sa_len = 0;
    } else {
        if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
                                       &sa_len, JNI_TRUE) != 0) {
            return;
        }
    }

    if (length > MAX_BUFFER_LEN) {
        /* Note: the buffer needn't be greater than 65,536 (0xFFFF)
         * the max size of an IP packet. Anything bigger is truncated anyway.
         */
        if (length > MAX_PACKET_LEN) {
            length = MAX_PACKET_LEN;
        }
        fullPacket = (char *)malloc(length);
        if (!fullPacket) {
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
            return;
        }
    } else {
        fullPacket = &(BUF[0]);
    }

    (*env)->GetByteArrayRegion(env, data, offset, length,
                               (jbyte *)fullPacket);
    rv = sendto(fd, fullPacket, length, 0, (struct sockaddr *)sap, sa_len);
    if (rv == SOCKET_ERROR) {
        if (rv == JVM_IO_ERR) {
            NET_ThrowNew(env, WSAGetLastError(), "Datagram send failed");
        } else if (rv == JVM_IO_INTR) {
            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
                            "operation interrupted");
        }
    }

    if (length > MAX_BUFFER_LEN) {
        free(fullPacket);
    }
}
예제 #13
0
JNIEXPORT jobject JNICALL
Java_sun_nio_ch_Net_remoteInetAddress(JNIEnv *env, jclass clazz, jobject fdo)
{
    SOCKETADDRESS sa;
    int sa_len = sizeof(sa);
    int port;

    if (getpeername(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
        NET_ThrowNew(env, WSAGetLastError(), "getsockname");
        return NULL;
    }
    return NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
}
/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketSetIntOption
 * Signature: (III)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSetIntOption
  (JNIEnv *env, jclass clazz, jint fd , jint cmd, jint value) {
    int level = 0, opt = 0;

    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                                     "Invalid option");
        return;
    }

    if (NET_SetSockOpt(fd, level, opt, (char *)&value, sizeof(value)) < 0) {
        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
    }
}
/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketLocalAddress
 * Signature: (I)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalAddress
  (JNIEnv *env , jclass clazz, jint fd) {
    SOCKETADDRESS sa;
    int len = sizeof(sa);
    jobject iaObj;
    int port;

    if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
        return NULL;
    }

    iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
    return iaObj;
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    bind0
 * Signature: (ILjava/net/InetAddress;I)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_bind0
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
    SOCKETADDRESS sa;
    int rv;
    int sa_len = sizeof(sa);

    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
                                 &sa_len, JNI_TRUE) != 0) {
      return;
    }

    rv = NET_Bind(fd, (struct sockaddr *)&sa, sa_len);

    if (rv == SOCKET_ERROR)
        NET_ThrowNew(env, WSAGetLastError(), "JVM_Bind");
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    localPort0
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_localPort0
  (JNIEnv *env, jclass clazz, jint fd) {
    SOCKETADDRESS sa;
    int len = sizeof(sa);

    if (getsockname(fd, (struct sockaddr *)&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));
}
예제 #18
0
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
                          jboolean isExclBind, jobject iao, jint port)
{
    SOCKETADDRESS sa;
    int rv;
    int sa_len;

    if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
      return;
    }

    rv = NET_WinBind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len, isExclBind);
    if (rv == SOCKET_ERROR)
        NET_ThrowNew(env, WSAGetLastError(), "bind");
}
예제 #19
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_remotePort(JNIEnv *env, jclass clazz, jobject fdo)
{
    SOCKETADDRESS sa;
    int sa_len = sizeof(sa);

    if (getpeername(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
        int error = WSAGetLastError();
        if (error == WSAEINVAL) {
            return 0;
        }
        NET_ThrowNew(env, error, "getsockname");
        return IOS_THROWN;
    }
    return NET_GetPortFromSockaddr((struct sockaddr *)&sa);
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    configureBlocking
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_configureBlocking
  (JNIEnv *env, jclass clazz, jint fd, jboolean blocking) {
    u_long arg;
    int result;

    if (blocking == JNI_TRUE) {
        arg = SET_BLOCKING;    // 0
    } else {
        arg = SET_NONBLOCKING;   // 1
    }

    result = ioctlsocket(fd, FIONBIO, &arg);
    if (result == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
    }
}
/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketGetIntOption
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketGetIntOption
  (JNIEnv *env, jclass clazz, jint fd, jint cmd) {
    int level = 0, opt = 0, result=0;
    int result_len = sizeof(result);

    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                                     "Invalid option");
        return -1;
    }

    if (NET_GetSockOpt(fd, level, opt, (void *)&result, &result_len) < 0) {
        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
        return -1;
    }

    return result;
}
/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketBind
 * Signature: (ILjava/net/InetAddress;I)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketBind
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port, jboolean exclBind) {
    SOCKETADDRESS sa;
    int rv;
    int sa_len = sizeof(sa);

    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
                                 &sa_len, JNI_TRUE) != 0) {
        return;
    }
    rv = NET_WinBind(fd, (struct sockaddr *)&sa, sa_len, exclBind);

    if (rv == SOCKET_ERROR) {
        if (WSAGetLastError() == WSAEACCES) {
            WSASetLastError(WSAEADDRINUSE);
        }
        NET_ThrowNew(env, WSAGetLastError(), "Cannot bind");
    }
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    localAddress
 * Signature: (ILjava/net/InetAddressContainer;)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_localAddress
  (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
    int port;
    SOCKETADDRESS sa;
    int len = sizeof(sa);
    jobject iaObj;
    jclass iaContainerClass;
    jfieldID iaFieldID;

    if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
        return;
    }
    iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
    CHECK_NULL(iaObj);

    iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
    iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
    CHECK_NULL(iaFieldID);
    (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
}
/*
 * Class:     java_net_DualStackPlainDatagramSocketImpl
 * Method:    socketConnect
 * Signature: (ILjava/net/InetAddress;I)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketConnect
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
    SOCKETADDRESS sa;
    int rv;
    int sa_len = sizeof(sa);
    DWORD x1, x2; /* ignored result codes */
    int t = TRUE;

    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
                                   &sa_len, JNI_TRUE) != 0) {
        return;
    }

    rv = connect(fd, (struct sockaddr *)&sa, sa_len);
    if (rv == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "connect");
        return;
    }

    /* see comment in socketCreate */
    WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
}
jint
handleSocketError(JNIEnv *env, int errorValue)
{
    NET_ThrowNew(env, errorValue, NULL);
    return IOS_THROWN;
}
예제 #26
0
void 
NET_ThrowCurrent(JNIEnv *env, char *msg) 
{
    NET_ThrowNew(env, WSAGetLastError(), msg);
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    waitForConnect
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect
  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
    int rv, retry;
    int optlen = sizeof(rv);
    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 timeout, connection established or
     * connection failed.
     */
    rv = 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 (rv == 0) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
                        "connect timed out");
        shutdown( fd, SD_BOTH );
        return;
    }

    /*
     * Socket is writable or error occured. On some Windows editions
     * the socket will appear writable when the connect fails so we
     * check for error rather than writable.
     */
    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;
        }
        Sleep(0);
    }

    if (rv == 0) {
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                        "Unable to establish connection");
    } else {
        NET_ThrowNew(env, rv, "connect");
    }
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    listen0
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_listen0
  (JNIEnv *env, jclass clazz, jint fd, jint backlog) {
    if (listen(fd, backlog) == SOCKET_ERROR) {
        NET_ThrowNew(env, WSAGetLastError(), "listen failed");
    }
}