summaryrefslogtreecommitdiff
path: root/native/jni/java-net/javanet.c
diff options
context:
space:
mode:
Diffstat (limited to 'native/jni/java-net/javanet.c')
-rw-r--r--native/jni/java-net/javanet.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/native/jni/java-net/javanet.c b/native/jni/java-net/javanet.c
index bf9ca957b..2db6eecbc 100644
--- a/native/jni/java-net/javanet.c
+++ b/native/jni/java-net/javanet.c
@@ -577,6 +577,10 @@ _javanet_bind(JNIEnv *env, jobject this, jobject addr, jint port, int stream)
}
DBG("_javanet_bind(): Past native_fd lookup\n");
+ _javanet_set_option (env, this, SOCKOPT_SO_REUSEADDR,
+ _javanet_create_boolean (env, JNI_TRUE));
+
+
/* Bind the socket */
memset(&si, 0, sizeof(struct sockaddr_in));
@@ -942,6 +946,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val)
break;
/* SO_TIMEOUT case. Val will be an integer with the new value */
+ /* Not writable on Linux */
case SOCKOPT_SO_TIMEOUT:
#ifdef SO_TIMEOUT
mid = (*env)->GetMethodID(env, cls, "intValue", "()I");
@@ -954,11 +959,8 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val)
return;
rc = setsockopt(fd, SOL_SOCKET, SO_TIMEOUT, &optval, sizeof(int));
-#else
- JCL_ThrowException(env, SOCKET_EXCEPTION,
- "SO_TIMEOUT not supported by this platform");
- return;
#endif
+ return; // ignore errors and do not throw an exception
break;
case SOCKOPT_SO_SNDBUF:
@@ -1007,6 +1009,21 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val)
sizeof(struct sockaddr_in));
break;
+ case SOCKOPT_SO_REUSEADDR:
+ mid = (*env)->GetMethodID(env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ { JCL_ThrowException(env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()"); return; }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod(env, val, mid);
+ if ((*env)->ExceptionOccurred(env))
+ return;
+
+ rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval,
+ sizeof(int));
+ break;
+
default:
JCL_ThrowException(env, SOCKET_EXCEPTION, "Unrecognized option");
return;
@@ -1055,9 +1072,9 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id)
}
if (optval)
- return(_javanet_create_boolean(env, 1));
+ return(_javanet_create_boolean(env, JNI_TRUE));
else
- return(_javanet_create_boolean(env, 0));
+ return(_javanet_create_boolean(env, JNI_FALSE));
break;
@@ -1077,7 +1094,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id)
if (linger.l_onoff)
return(_javanet_create_integer(env, linger.l_linger));
else
- return(_javanet_create_boolean(env, 0));
+ return(_javanet_create_boolean(env, JNI_FALSE));
break;
@@ -1150,6 +1167,22 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id)
return(_javanet_create_inetaddress(env, ntohl(si.sin_addr.s_addr)));
break;
+ case SOCKOPT_SO_REUSEADDR:
+ optlen = sizeof(int);
+ rc = getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, &optlen);
+ if (rc == -1)
+ {
+ JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno));
+ return(0);
+ }
+
+ if (optval)
+ return(_javanet_create_boolean(env, JNI_TRUE));
+ else
+ return(_javanet_create_boolean(env, JNI_FALSE));
+
+ break;
+
default:
JCL_ThrowException(env, SOCKET_EXCEPTION, "No such option" );
return(0);