< prev index next >
src/java.base/unix/native/libnet/ExtendedOptionsImpl.c
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2014, 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
--- 1,7 ----
/*
! * Copyright (c) 2014, 2016, 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
*** 52,61 ****
--- 52,62 ----
static void setStatus(JNIEnv *env, jobject obj, int errval);
/* OS specific code is implemented in these three functions */
static jboolean flowSupported0() ;
+ static jboolean quickack_available();
/*
* Class: sun_net_ExtendedOptionsImpl
* Method: init
* Signature: ()V
*** 140,149 ****
--- 141,169 ----
CHECK_NULL_RETURN(f, NULL);
return f;
}
/*
+ * Returns a java.lang.Boolean based on 'b'
+ */
+ static jobject createBoolean(JNIEnv *env, int b) {
+ static jclass b_class;
+ static jmethodID b_ctrID;
+
+ if (b_class == NULL) {
+ jclass c = (*env)->FindClass(env, "java/lang/Boolean");
+ CHECK_NULL_RETURN(c, NULL);
+ b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
+ CHECK_NULL_RETURN(b_ctrID, NULL);
+ b_class = (*env)->NewGlobalRef(env, c);
+ CHECK_NULL_RETURN(b_class, NULL);
+ }
+
+ return ((*env)->NewObject(env, b_class, b_ctrID, (jboolean) (b != 0)));
+ }
+
+ /*
* Retrieve the int file-descriptor from a public socket type object.
* Gets impl, then the FileDescriptor from the impl, and then the fd
* from that.
*/
static int getFD(JNIEnv *env, jobject fileDesc) {
*** 335,344 ****
--- 355,476 ----
return JNI_FALSE;
}
#endif /* __solaris__ */
+ #ifdef __linux__
+
+ /*
+ * Class: sun_net_ExtendedOptionsImpl
+ * Method: setQuickAckOption
+ * Signature: (Ljava/io/FileDescriptor;Ljava/lang/Object;)V
+ */
+ JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption
+ (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) {
+ int fd = getFD(env, fileDesc);
+ int optval;
+ if (fd < 0) {
+ NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ } else {
+ int rv;
+ optval = (on ? 1 : 0);
+ rv = setsockopt(fd, SOL_SOCKET, SO_QUICKACK, &optval, sizeof (optval));
+ if (rv < 0) {
+ if (errno == ENOPROTOOPT) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ } else {
+ NET_ERROR(env, JNU_JAVANETPKG "SocketException",
+ "set option SO_REUSEPORT failed");
+ }
+ }
+ }
+ }
+
+ /*
+ * Class: sun_net_ExtendedOptionsImpl
+ * Method: getQuickAckOption
+ * Signature: (Ljava/io/FileDescriptor;)Ljava/lang/Object;
+ */
+ JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption
+ (JNIEnv *env, jclass UNUSED, jobject fileDesc)
+ {
+ int fd = getFD(env, fileDesc);
+ if (fd < 0) {
+ NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ return JNI_FALSE;
+ } else {
+ int on;
+ socklen_t sz = sizeof(on);
+ int rv = getsockopt(fd, SOL_SOCKET, SO_QUICKACK, &on, &sz);
+ if (rv < 0) {
+ if (errno == ENOPROTOOPT) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ } else {
+ NET_ERROR(env, JNU_JAVANETPKG "SocketException",
+ "setoption SO_QUICKACK failed");
+ }
+ }
+ return createBoolean(env, on);
+ }
+ }
+
+ static jboolean isQuickAckAvailable;
+ static jboolean isQuickAckAvailableChecked = JNI_FALSE;
+ static jboolean quickack_available() {
+ int one = 1;
+ int rv, s;
+ if (isQuickAckAvailableChecked) {
+ return isQuickAckAvailable;
+ }
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ isQuickAckAvailable = JNI_FALSE;
+ isQuickAckAvailableChecked = JNI_TRUE;
+ return JNI_FALSE;
+ }
+ rv = setsockopt(s, SOL_SOCKET, SO_QUICKACK, (void *) &one, sizeof (one));
+ isQuickAckAvailableChecked = JNI_TRUE;
+ if (rv != 0 && errno == ENOPROTOOPT) {
+ isQuickAckAvailable = JNI_FALSE;
+ } else {
+ isQuickAckAvailable = JNI_TRUE;
+ }
+ close(s);
+ return isQuickAckAvailable;
+ }
+
+ #else
+
+ JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setQuickAckOption
+ (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on)
+ {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ }
+
+ JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_getQuickAckOption
+ (JNIEnv *env, jclass UNUSED, jobject fileDesc)
+ {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ return JNI_FALSE;
+ }
+
+ static jboolean quickack_available() {
+ return JNI_FALSE;
+ }
+
+ #endif /* __linux__ */
+
JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
(JNIEnv *env, jclass UNUSED)
{
return flowSupported0();
}
+
+ JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_isQuickAckAvailable0
+ (JNIEnv *env, jclass UNUSED)
+ {
+ return quickack_available();
+ }
< prev index next >