Respect -Djava.net.preferIPv4Stack when using epoll transport
Motivation: On a system where ipv4 and ipv6 are supported a user may want to use -Djava.net.preferIPv4Stack=true to restrict it to use ipv4 only. This is currently ignored with the epoll transport. Modifications: Respect java.net.preferIPv4Stack system property. Result: -Djava.net.preferIPv4Stack=true will have the effect the user is looking for.
This commit is contained in:
parent
88beae6838
commit
3df7b4dac7
@ -115,6 +115,11 @@ public final class NetUtil {
|
|||||||
*/
|
*/
|
||||||
private static final int IPV4_SEPARATORS = 3;
|
private static final int IPV4_SEPARATORS = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code true} if ipv4 should be used on a system that supports ipv4 and ipv6.
|
||||||
|
*/
|
||||||
|
private static final boolean IPV4_PREFERRED = Boolean.getBoolean("java.net.preferIPv4Stack");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger being used by this class
|
* The logger being used by this class
|
||||||
*/
|
*/
|
||||||
@ -260,6 +265,13 @@ public final class NetUtil {
|
|||||||
SOMAXCONN = somaxconn;
|
SOMAXCONN = somaxconn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if ipv4 should be prefered on a system that supports ipv4 and ipv6.
|
||||||
|
*/
|
||||||
|
public static boolean isIpV4StackPreferred() {
|
||||||
|
return IPV4_PREFERRED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an byte[] based on an ipAddressString. No error handling is
|
* Creates an byte[] based on an ipAddressString. No error handling is
|
||||||
* performed here.
|
* performed here.
|
||||||
|
@ -84,6 +84,8 @@ jmethodID closedChannelExceptionMethodId = NULL;
|
|||||||
jclass inetSocketAddressClass = NULL;
|
jclass inetSocketAddressClass = NULL;
|
||||||
jclass datagramSocketAddressClass = NULL;
|
jclass datagramSocketAddressClass = NULL;
|
||||||
jclass nativeDatagramPacketClass = NULL;
|
jclass nativeDatagramPacketClass = NULL;
|
||||||
|
jclass netUtilClass = NULL;
|
||||||
|
jmethodID netUtilClassIpv4PreferredMethodId = NULL;
|
||||||
|
|
||||||
static int socketType;
|
static int socketType;
|
||||||
static const char* ip4prefix = "::ffff:";
|
static const char* ip4prefix = "::ffff:";
|
||||||
@ -305,7 +307,13 @@ static int init_sockaddr(JNIEnv* env, jbyteArray address, jint scopeId, jint jpo
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socket_type() {
|
static int socket_type(JNIEnv* env) {
|
||||||
|
jboolean ipv4Preferred = (*env)->CallStaticBooleanMethod(env, netUtilClass, netUtilClassIpv4PreferredMethodId);
|
||||||
|
|
||||||
|
if (ipv4Preferred) {
|
||||||
|
// User asked to use ipv4 explicitly.
|
||||||
|
return AF_INET;
|
||||||
|
}
|
||||||
int fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
int fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == EAFNOSUPPORT) {
|
if (errno == EAFNOSUPPORT) {
|
||||||
@ -343,6 +351,24 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||||||
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
} else {
|
} else {
|
||||||
|
jclass localNetUtilClass = (*env)->FindClass(env, "io/netty/util/NetUtil" );
|
||||||
|
if (localNetUtilClass == NULL) {
|
||||||
|
// pending exception...
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
netUtilClass = (jclass) (*env)->NewGlobalRef(env, localNetUtilClass);
|
||||||
|
if (netUtilClass == NULL) {
|
||||||
|
// out-of-memory!
|
||||||
|
throwOutOfMemoryError(env);
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
netUtilClassIpv4PreferredMethodId = (*env)->GetStaticMethodID(env, netUtilClass, "isIpV4StackPreferred", "()Z" );
|
||||||
|
if (netUtilClassIpv4PreferredMethodId == NULL) {
|
||||||
|
// position method was not found.. something is wrong so bail out
|
||||||
|
throwRuntimeException(env, "failed to get method ID: NetUild.isIpV4StackPreferred()");
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
// cache classes that are used within other jni methods for performance reasons
|
// cache classes that are used within other jni methods for performance reasons
|
||||||
jclass localClosedChannelExceptionClass = (*env)->FindClass(env, "java/nio/channels/ClosedChannelException");
|
jclass localClosedChannelExceptionClass = (*env)->FindClass(env, "java/nio/channels/ClosedChannelException");
|
||||||
if (localClosedChannelExceptionClass == NULL) {
|
if (localClosedChannelExceptionClass == NULL) {
|
||||||
@ -509,7 +535,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||||||
throwRuntimeException(env, "failed to get method ID: InetSocketAddress.<init>(String, int)");
|
throwRuntimeException(env, "failed to get method ID: InetSocketAddress.<init>(String, int)");
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
}
|
}
|
||||||
socketType = socket_type();
|
socketType = socket_type(env);
|
||||||
|
|
||||||
datagramSocketAddrMethodId = (*env)->GetMethodID(env, datagramSocketAddressClass, "<init>", "(Ljava/lang/String;II)V");
|
datagramSocketAddrMethodId = (*env)->GetMethodID(env, datagramSocketAddressClass, "<init>", "(Ljava/lang/String;II)V");
|
||||||
if (datagramSocketAddrMethodId == NULL) {
|
if (datagramSocketAddrMethodId == NULL) {
|
||||||
@ -575,6 +601,9 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
|||||||
if (datagramSocketAddressClass != NULL) {
|
if (datagramSocketAddressClass != NULL) {
|
||||||
(*env)->DeleteGlobalRef(env, datagramSocketAddressClass);
|
(*env)->DeleteGlobalRef(env, datagramSocketAddressClass);
|
||||||
}
|
}
|
||||||
|
if (netUtilClass != NULL) {
|
||||||
|
(*env)->DeleteGlobalRef(env, netUtilClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,7 +981,6 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_shutdown0(JNIEnv* env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline jint socket0(JNIEnv* env, jclass clazz, int type) {
|
static inline jint socket0(JNIEnv* env, jclass clazz, int type) {
|
||||||
// TODO: Maybe also respect -Djava.net.preferIPv4Stack=true
|
|
||||||
int fd = socket(socketType, type | SOCK_NONBLOCK, 0);
|
int fd = socket(socketType, type | SOCK_NONBLOCK, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return -errno;
|
return -errno;
|
||||||
|
Loading…
Reference in New Issue
Block a user