< 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 >