/*
 * 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;
}
Esempio n. 2
0
/*
 * Class:     sun_nio_ch_sctp_SctpNet
 * Method:    getIntOption0
 * Signature: (II)I
 */
JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_getIntOption0
  (JNIEnv *env, jclass klass, jint fd, jint opt) {
    int klevel, kopt;
    int result;
    struct linger linger;
    void *arg;
    int arglen;

    memset((char *) &linger, 0, sizeof(linger));
    if (mapSocketOption(opt, &klevel, &kopt) < 0) {
        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                                     "Unsupported socket option");
        return -1;
    }

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

    if (NET_GetSockOpt(fd, klevel, kopt, arg, &arglen) < 0) {
        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                                     "sun.nio.ch.Net.getIntOption");
        return -1;
    }

    if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER)
        return linger.l_onoff ? linger.l_linger : -1;
    else
        return result;
}
Esempio n. 3
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz, jobject fdo,
                                  jboolean mayNeedConversion, jint level, jint opt)
{
    int result;
    struct linger linger;
    u_char carg;
    void *arg;
    socklen_t arglen;
    int n;

    /* Option value is an int except for a few specific cases */

    arg = (void *)&result;
    arglen = sizeof(result);

    if (level == IPPROTO_IP &&
        (opt == IP_MULTICAST_TTL || opt == IP_MULTICAST_LOOP)) {
        arg = (void*)&carg;
        arglen = sizeof(carg);
    }

    if (level == SOL_SOCKET && opt == SO_LINGER) {
        arg = (void *)&linger;
        arglen = sizeof(linger);
    }

    if (mayNeedConversion) {
        n = NET_GetSockOpt(fdval(env, fdo), level, opt, arg, (int*)&arglen);
    } else {
        n = getsockopt(fdval(env, fdo), level, opt, arg, &arglen);
    }
    if (n < 0) {
        JNU_ThrowByNameWithLastError(env,
                                     JNU_JAVANETPKG "SocketException",
                                     "sun.nio.ch.Net.getIntOption");
        return -1;
    }

    if (level == IPPROTO_IP &&
        (opt == IP_MULTICAST_TTL || opt == IP_MULTICAST_LOOP))
    {
        return (jint)carg;
    }

    if (level == SOL_SOCKET && opt == SO_LINGER)
        return linger.l_onoff ? (jint)linger.l_linger : (jint)-1;

    return (jint)result;
}
/*
 * 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;
}
Esempio n. 5
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz, jobject fdo,
                                  jboolean mayNeedConversion, jint level, jint opt)
{
    int result = 0;
    struct linger linger;
    char *arg;
    int arglen, n;

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

    /**
     * HACK: IP_TOS is deprecated on Windows and querying the option
     * returns a protocol error. NET_GetSockOpt handles this and uses
     * a fallback mechanism.
     */
    if (level == IPPROTO_IP && opt == IP_TOS) {
        mayNeedConversion = JNI_TRUE;
    }

    if (mayNeedConversion) {
        n = NET_GetSockOpt(fdval(env, fdo), level, opt, arg, &arglen);
    } else {
        n = getsockopt(fdval(env, fdo), level, opt, arg, &arglen);
    }
    if (n < 0) {
        handleSocketError(env, WSAGetLastError());
        return IOS_THROWN;
    }

    if (level == SOL_SOCKET && opt == SO_LINGER)
        return linger.l_onoff ? linger.l_linger : -1;
    else
        return result;
}
Esempio n. 6
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz,
				  jobject fdo, jint opt)
{
    int klevel, kopt;
    int result;
    struct linger linger;
    void *arg;
    int arglen;

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

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

    if (NET_GetSockOpt(fdval(env, fdo), klevel, kopt, arg, &arglen) < 0) {
	JNU_ThrowByNameWithLastError(env,
				     JNU_JAVANETPKG "SocketException",
				     "sun.nio.ch.Net.getIntOption");
	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:    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");
    }
}