< prev index next >

src/java.base/unix/native/libnet/ExtendedOptionsImpl.c

Print this page

        

*** 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 reuseportSupported0() ; /* * 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,487 ---- return JNI_FALSE; } #endif /* __solaris__ */ + + #ifdef __linux__ + /* + * Class: sun_net_ExtendedOptionsImpl + * Method: setReusePortOption + * Signature: (Ljava/io/FileDescriptor;Ljava/lang/Object;)V + */ + JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setReusePortOption + (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"); + return; + } else { + int rv; + optval = (on ? 1 : 0); + rv = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &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"); + } + return; + } + } + } + /* + * Class: sun_net_ExtendedOptionsImpl + * Method: getReusePortOption + * Signature: (Ljava/io/FileDescriptor;)Ljava/lang/Object; + */ + JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getReusePortOption + (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_REUSEPORT, &on, &sz); + 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"); + } + } + printf("getReusePortOption returns %d\n", on); + return createBoolean(env, on); + } + } + + static jboolean reuseportsupported; + static jboolean reuseportsupported_set = JNI_FALSE; + + static jboolean reuseportSupported0() + { + /* Do a simple dummy call, and try to figure out from that */ + int one = 1; + int rv, s; + if (reuseportsupported_set) { + return reuseportsupported; + } + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) { + reuseportsupported = JNI_FALSE; + reuseportsupported_set = JNI_TRUE; + return JNI_FALSE; + } + rv = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(one)); + if (rv != 0 && errno == ENOPROTOOPT) { + rv = JNI_FALSE; + } else { + rv = JNI_TRUE; + } + close(s); + reuseportsupported = rv; + reuseportsupported_set = JNI_TRUE; + return reuseportsupported; + } + + #else /* __linux__ */ + + /* Non Linux. Functionality is not supported. So, throw UnsupportedOpExc */ + + JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setReusePortOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jboolean on) + { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } + + JNIEXPORT jobject JNICALL Java_sun_net_ExtendedOptionsImpl_getReusePortOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc) + { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + return JNI_FALSE; + } + + static jboolean reuseportSupported0() { + 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_reuseportSupported + (JNIEnv *env, jclass UNUSED) + { + return reuseportSupported0(); + }
< prev index next >