mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8290349: IP_DONTFRAGMENT doesn't set DF bit in IPv4 header
Reviewed-by: michaelm, alanb
This commit is contained in:
parent
26e5c112da
commit
ce61eb6ff9
9 changed files with 74 additions and 134 deletions
|
@ -133,11 +133,11 @@ public abstract class ExtendedSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a socket option, for the given socket. */
|
/** Sets the value of a socket option, for the given socket. */
|
||||||
public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
|
public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value, boolean isIPv6)
|
||||||
throws SocketException;
|
throws SocketException;
|
||||||
|
|
||||||
/** Returns the value of a socket option, for the given socket. */
|
/** Returns the value of a socket option, for the given socket. */
|
||||||
public abstract Object getOption(FileDescriptor fd, SocketOption<?> option)
|
public abstract Object getOption(FileDescriptor fd, SocketOption<?> option, boolean isIPv6)
|
||||||
throws SocketException;
|
throws SocketException;
|
||||||
|
|
||||||
protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
|
protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
|
||||||
|
@ -206,7 +206,7 @@ public abstract class ExtendedSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
|
public void setOption(FileDescriptor fd, SocketOption<?> option, Object value, boolean isIPv6)
|
||||||
throws SocketException
|
throws SocketException
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
|
@ -214,7 +214,7 @@ public abstract class ExtendedSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getOption(FileDescriptor fd, SocketOption<?> option)
|
public Object getOption(FileDescriptor fd, SocketOption<?> option, boolean isIPv6)
|
||||||
throws SocketException
|
throws SocketException
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
|
|
|
@ -402,9 +402,10 @@ public class Net {
|
||||||
|
|
||||||
// only simple values supported by this method
|
// only simple values supported by this method
|
||||||
Class<?> type = name.type();
|
Class<?> type = name.type();
|
||||||
|
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
|
||||||
|
|
||||||
if (extendedOptions.isOptionSupported(name)) {
|
if (extendedOptions.isOptionSupported(name)) {
|
||||||
extendedOptions.setOption(fd, name, value);
|
extendedOptions.setOption(fd, name, value, isIPv6);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +452,6 @@ public class Net {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean mayNeedConversion = (family == UNSPEC);
|
boolean mayNeedConversion = (family == UNSPEC);
|
||||||
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
|
|
||||||
setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6);
|
setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +467,8 @@ public class Net {
|
||||||
Class<?> type = name.type();
|
Class<?> type = name.type();
|
||||||
|
|
||||||
if (extendedOptions.isOptionSupported(name)) {
|
if (extendedOptions.isOptionSupported(name)) {
|
||||||
return extendedOptions.getOption(fd, name);
|
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
|
||||||
|
return extendedOptions.getOption(fd, name, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only simple values supported by this method
|
// only simple values supported by this method
|
||||||
|
|
|
@ -108,13 +108,13 @@ class LinuxSocketOptions extends PlatformSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setIpDontFragment(int fd, final boolean value) throws SocketException {
|
void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException {
|
||||||
setIpDontFragment0(fd, value);
|
setIpDontFragment0(fd, value, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean getIpDontFragment(int fd) throws SocketException {
|
boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException {
|
||||||
return getIpDontFragment0(fd);
|
return getIpDontFragment0(fd, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,11 +130,11 @@ class LinuxSocketOptions extends PlatformSocketOptions {
|
||||||
private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException;
|
private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException;
|
||||||
private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException;
|
private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException;
|
||||||
private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException;
|
private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException;
|
||||||
private static native void setIpDontFragment0(int fd, boolean value) throws SocketException;
|
private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException;
|
||||||
private static native int getTcpkeepAliveProbes0(int fd) throws SocketException;
|
private static native int getTcpkeepAliveProbes0(int fd) throws SocketException;
|
||||||
private static native int getTcpKeepAliveTime0(int fd) throws SocketException;
|
private static native int getTcpKeepAliveTime0(int fd) throws SocketException;
|
||||||
private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException;
|
private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException;
|
||||||
private static native boolean getIpDontFragment0(int fd) throws SocketException;
|
private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException;
|
||||||
private static native void setQuickAck0(int fd, boolean on) throws SocketException;
|
private static native void setQuickAck0(int fd, boolean on) throws SocketException;
|
||||||
private static native boolean getQuickAck0(int fd) throws SocketException;
|
private static native boolean getQuickAck0(int fd) throws SocketException;
|
||||||
private static native long getSoPeerCred0(int fd) throws SocketException;
|
private static native long getSoPeerCred0(int fd) throws SocketException;
|
||||||
|
|
|
@ -244,34 +244,18 @@ JNIEXPORT jint JNICALL Java_jdk_net_LinuxSocketOptions_getIncomingNapiId0
|
||||||
return optval;
|
return optval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socketFamily(jint fd) {
|
|
||||||
struct sockaddr_storage st;
|
|
||||||
struct sockaddr *sa = (struct sockaddr *)&st;
|
|
||||||
socklen_t sa_len = sizeof(st);
|
|
||||||
|
|
||||||
if (getsockname(fd, sa, &sa_len) == 0) {
|
|
||||||
return sa->sa_family;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_LinuxSocketOptions
|
* Class: jdk_net_LinuxSocketOptions
|
||||||
* Method: setIpDontFragment0
|
* Method: setIpDontFragment0
|
||||||
* Signature: (IZ)V
|
* Signature: (IZZ)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setIpDontFragment0
|
JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setIpDontFragment0
|
||||||
(JNIEnv *env, jobject unused, jint fd, jboolean optval) {
|
(JNIEnv *env, jobject unused, jint fd, jboolean optval, jboolean isIPv6) {
|
||||||
jint rv, optsetting;
|
jint rv, optsetting;
|
||||||
jint family = socketFamily(fd);
|
|
||||||
if (family == -1) {
|
|
||||||
handleError(env, family, "get socket family failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
optsetting = optval ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
|
optsetting = optval ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (!isIPv6) {
|
||||||
rv = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &optsetting, sizeof (optsetting));
|
rv = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &optsetting, sizeof (optsetting));
|
||||||
} else {
|
} else {
|
||||||
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &optsetting, sizeof (optsetting));
|
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &optsetting, sizeof (optsetting));
|
||||||
|
@ -282,18 +266,13 @@ JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setIpDontFragment0
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_LinuxSocketOptions
|
* Class: jdk_net_LinuxSocketOptions
|
||||||
* Method: getIpDontFragment0
|
* Method: getIpDontFragment0
|
||||||
* Signature: (I)Z;
|
* Signature: (IZ)Z;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jboolean JNICALL Java_jdk_net_LinuxSocketOptions_getIpDontFragment0
|
JNIEXPORT jboolean JNICALL Java_jdk_net_LinuxSocketOptions_getIpDontFragment0
|
||||||
(JNIEnv *env, jobject unused, jint fd) {
|
(JNIEnv *env, jobject unused, jint fd, jboolean isIPv6) {
|
||||||
jint optlevel, optname, optval, rv;
|
jint optlevel, optname, optval, rv;
|
||||||
jint family = socketFamily(fd);
|
|
||||||
if (family == -1) {
|
|
||||||
handleError(env, family, "get socket family failed");
|
|
||||||
return JNI_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (!isIPv6) {
|
||||||
optlevel = IPPROTO_IP;
|
optlevel = IPPROTO_IP;
|
||||||
optname = IP_MTU_DISCOVER;
|
optname = IP_MTU_DISCOVER;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -84,13 +84,13 @@ class MacOSXSocketOptions extends PlatformSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setIpDontFragment(int fd, final boolean value) throws SocketException {
|
void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException {
|
||||||
setIpDontFragment0(fd, value);
|
setIpDontFragment0(fd, value, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean getIpDontFragment(int fd) throws SocketException {
|
boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException {
|
||||||
return getIpDontFragment0(fd);
|
return getIpDontFragment0(fd, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,11 +106,11 @@ class MacOSXSocketOptions extends PlatformSocketOptions {
|
||||||
private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException;
|
private static native void setTcpkeepAliveProbes0(int fd, int value) throws SocketException;
|
||||||
private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException;
|
private static native void setTcpKeepAliveTime0(int fd, int value) throws SocketException;
|
||||||
private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException;
|
private static native void setTcpKeepAliveIntvl0(int fd, int value) throws SocketException;
|
||||||
private static native void setIpDontFragment0(int fd, boolean value) throws SocketException;
|
private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException;
|
||||||
private static native int getTcpkeepAliveProbes0(int fd) throws SocketException;
|
private static native int getTcpkeepAliveProbes0(int fd) throws SocketException;
|
||||||
private static native int getTcpKeepAliveTime0(int fd) throws SocketException;
|
private static native int getTcpKeepAliveTime0(int fd) throws SocketException;
|
||||||
private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException;
|
private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException;
|
||||||
private static native boolean getIpDontFragment0(int fd) throws SocketException;
|
private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException;
|
||||||
private static native long getSoPeerCred0(int fd) throws SocketException;
|
private static native long getSoPeerCred0(int fd) throws SocketException;
|
||||||
private static native boolean keepAliveOptionsSupported0();
|
private static native boolean keepAliveOptionsSupported0();
|
||||||
private static native boolean ipDontFragmentSupported0();
|
private static native boolean ipDontFragmentSupported0();
|
||||||
|
|
|
@ -178,17 +178,6 @@ JNIEXPORT jint JNICALL Java_jdk_net_MacOSXSocketOptions_getTcpKeepAliveIntvl0
|
||||||
return optval;
|
return optval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socketFamily(jint fd) {
|
|
||||||
struct sockaddr_storage st;
|
|
||||||
struct sockaddr* sa = (struct sockaddr *)&st;
|
|
||||||
socklen_t sa_len = sizeof(st);
|
|
||||||
|
|
||||||
if (getsockname(fd, sa, &sa_len) == 0) {
|
|
||||||
return sa->sa_family;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_MacOSXSocketOptions
|
* Class: jdk_net_MacOSXSocketOptions
|
||||||
* Method: ipDontFragmentSupported0
|
* Method: ipDontFragmentSupported0
|
||||||
|
@ -198,22 +187,22 @@ JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_ipDontFragmentSuppor
|
||||||
(JNIEnv *env, jobject unused) {
|
(JNIEnv *env, jobject unused) {
|
||||||
jint rv, fd, value;
|
jint rv, fd, value;
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (fd == -1)
|
if (fd != -1) {
|
||||||
return JNI_FALSE;
|
value = 1;
|
||||||
value = 1;
|
rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value));
|
||||||
rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value));
|
close(fd);
|
||||||
close(fd);
|
if (rv == -1) {
|
||||||
if (rv == -1) {
|
return JNI_FALSE;
|
||||||
return JNI_FALSE;
|
}
|
||||||
}
|
}
|
||||||
fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if (fd == -1)
|
if (fd != -1) {
|
||||||
return JNI_FALSE;
|
value = 1;
|
||||||
value = 1;
|
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value));
|
||||||
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value));
|
close(fd);
|
||||||
close(fd);
|
if (rv == -1) {
|
||||||
if (rv == -1) {
|
return JNI_FALSE;
|
||||||
return JNI_FALSE;
|
}
|
||||||
}
|
}
|
||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -221,19 +210,14 @@ JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_ipDontFragmentSuppor
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_MacOSXSocketOptions
|
* Class: jdk_net_MacOSXSocketOptions
|
||||||
* Method: setIpDontFragment0
|
* Method: setIpDontFragment0
|
||||||
* Signature: (IZ)V
|
* Signature: (IZZ)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setIpDontFragment0
|
JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setIpDontFragment0
|
||||||
(JNIEnv *env, jobject unused, jint fd, jboolean optval) {
|
(JNIEnv *env, jobject unused, jint fd, jboolean optval, jboolean isIPv6) {
|
||||||
jint rv;
|
jint rv;
|
||||||
jint family = socketFamily(fd);
|
|
||||||
jint value = optval ? 1 : 0;
|
jint value = optval ? 1 : 0;
|
||||||
|
|
||||||
if (family == -1) {
|
if (!isIPv6) {
|
||||||
handleError(env, family, "get socket family failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (family == AF_INET) {
|
|
||||||
rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value));
|
rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &value, sizeof(value));
|
||||||
} else {
|
} else {
|
||||||
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value));
|
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &value, sizeof(value));
|
||||||
|
@ -244,18 +228,13 @@ JNIEXPORT void JNICALL Java_jdk_net_MacOSXSocketOptions_setIpDontFragment0
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_MacOSXSocketOptions
|
* Class: jdk_net_MacOSXSocketOptions
|
||||||
* Method: getIpDontFragment0
|
* Method: getIpDontFragment0
|
||||||
* Signature: (I)Z;
|
* Signature: (IZ)Z;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_getIpDontFragment0
|
JNIEXPORT jboolean JNICALL Java_jdk_net_MacOSXSocketOptions_getIpDontFragment0
|
||||||
(JNIEnv *env, jobject unused, jint fd) {
|
(JNIEnv *env, jobject unused, jint fd, jboolean isIPv6) {
|
||||||
jint optval, rv;
|
jint optval, rv;
|
||||||
socklen_t sz = sizeof (optval);
|
socklen_t sz = sizeof (optval);
|
||||||
jint family = socketFamily(fd);
|
if (!isIPv6) {
|
||||||
if (family == -1) {
|
|
||||||
handleError(env, family, "get socket family failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (family == AF_INET) {
|
|
||||||
rv = getsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &optval, &sz);
|
rv = getsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &optval, &sz);
|
||||||
} else {
|
} else {
|
||||||
rv = getsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &optval, &sz);
|
rv = getsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &optval, &sz);
|
||||||
|
|
|
@ -28,6 +28,7 @@ package jdk.net;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketOption;
|
import java.net.SocketOption;
|
||||||
|
import java.net.StandardProtocolFamily;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -209,6 +210,9 @@ public final class ExtendedSocketOptions {
|
||||||
* sizes to the {@link java.net.NetworkInterface#getMTU() local MTU}. Depending
|
* sizes to the {@link java.net.NetworkInterface#getMTU() local MTU}. Depending
|
||||||
* on the implementation and the network interface, packets larger than the MTU
|
* on the implementation and the network interface, packets larger than the MTU
|
||||||
* may be sent or dropped silently or dropped with an exception thrown.
|
* may be sent or dropped silently or dropped with an exception thrown.
|
||||||
|
* For {@link StandardProtocolFamily#INET6 IPv6} sockets it is
|
||||||
|
* system dependent whether the option also applies to datagrams
|
||||||
|
* sent to IPv4 addresses.
|
||||||
*
|
*
|
||||||
* @apiNote
|
* @apiNote
|
||||||
* For IPv4 this option sets the DF (Do not Fragment) flag in the IP packet
|
* For IPv4 this option sets the DF (Do not Fragment) flag in the IP packet
|
||||||
|
@ -263,10 +267,9 @@ public final class ExtendedSocketOptions {
|
||||||
new sun.net.ext.ExtendedSocketOptions(extendedOptions) {
|
new sun.net.ext.ExtendedSocketOptions(extendedOptions) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("removal")
|
|
||||||
public void setOption(FileDescriptor fd,
|
public void setOption(FileDescriptor fd,
|
||||||
SocketOption<?> option,
|
SocketOption<?> option,
|
||||||
Object value)
|
Object value, boolean isIPv6)
|
||||||
throws SocketException
|
throws SocketException
|
||||||
{
|
{
|
||||||
if (fd == null || !fd.valid())
|
if (fd == null || !fd.valid())
|
||||||
|
@ -277,7 +280,7 @@ public final class ExtendedSocketOptions {
|
||||||
} else if (option == TCP_KEEPCOUNT) {
|
} else if (option == TCP_KEEPCOUNT) {
|
||||||
setTcpkeepAliveProbes(fd, (Integer) value);
|
setTcpkeepAliveProbes(fd, (Integer) value);
|
||||||
} else if (option == IP_DONTFRAGMENT) {
|
} else if (option == IP_DONTFRAGMENT) {
|
||||||
setIpDontFragment(fd, (Boolean) value);
|
setIpDontFragment(fd, (Boolean) value, isIPv6);
|
||||||
} else if (option == TCP_KEEPIDLE) {
|
} else if (option == TCP_KEEPIDLE) {
|
||||||
setTcpKeepAliveTime(fd, (Integer) value);
|
setTcpKeepAliveTime(fd, (Integer) value);
|
||||||
} else if (option == TCP_KEEPINTERVAL) {
|
} else if (option == TCP_KEEPINTERVAL) {
|
||||||
|
@ -295,9 +298,8 @@ public final class ExtendedSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("removal")
|
|
||||||
public Object getOption(FileDescriptor fd,
|
public Object getOption(FileDescriptor fd,
|
||||||
SocketOption<?> option)
|
SocketOption<?> option, boolean isIPv6)
|
||||||
throws SocketException
|
throws SocketException
|
||||||
{
|
{
|
||||||
if (fd == null || !fd.valid())
|
if (fd == null || !fd.valid())
|
||||||
|
@ -308,7 +310,7 @@ public final class ExtendedSocketOptions {
|
||||||
} else if (option == TCP_KEEPCOUNT) {
|
} else if (option == TCP_KEEPCOUNT) {
|
||||||
return getTcpkeepAliveProbes(fd);
|
return getTcpkeepAliveProbes(fd);
|
||||||
} else if (option == IP_DONTFRAGMENT) {
|
} else if (option == IP_DONTFRAGMENT) {
|
||||||
return getIpDontFragment(fd);
|
return getIpDontFragment(fd, isIPv6);
|
||||||
} else if (option == TCP_KEEPIDLE) {
|
} else if (option == TCP_KEEPIDLE) {
|
||||||
return getTcpKeepAliveTime(fd);
|
return getTcpKeepAliveTime(fd);
|
||||||
} else if (option == TCP_KEEPINTERVAL) {
|
} else if (option == TCP_KEEPINTERVAL) {
|
||||||
|
@ -352,9 +354,9 @@ public final class ExtendedSocketOptions {
|
||||||
platformSocketOptions.setTcpKeepAliveTime(fdAccess.get(fd), value);
|
platformSocketOptions.setTcpKeepAliveTime(fdAccess.get(fd), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setIpDontFragment(FileDescriptor fd, boolean value)
|
private static void setIpDontFragment(FileDescriptor fd, boolean value, boolean isIPv6)
|
||||||
throws SocketException {
|
throws SocketException {
|
||||||
platformSocketOptions.setIpDontFragment(fdAccess.get(fd), value);
|
platformSocketOptions.setIpDontFragment(fdAccess.get(fd), value, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setTcpKeepAliveIntvl(FileDescriptor fd, int value)
|
private static void setTcpKeepAliveIntvl(FileDescriptor fd, int value)
|
||||||
|
@ -366,8 +368,8 @@ public final class ExtendedSocketOptions {
|
||||||
return platformSocketOptions.getTcpkeepAliveProbes(fdAccess.get(fd));
|
return platformSocketOptions.getTcpkeepAliveProbes(fdAccess.get(fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getIpDontFragment(FileDescriptor fd) throws SocketException {
|
private static boolean getIpDontFragment(FileDescriptor fd, boolean isIPv6) throws SocketException {
|
||||||
return platformSocketOptions.getIpDontFragment(fdAccess.get(fd));
|
return platformSocketOptions.getIpDontFragment(fdAccess.get(fd), isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getTcpKeepAliveTime(FileDescriptor fd) throws SocketException {
|
private static int getTcpKeepAliveTime(FileDescriptor fd) throws SocketException {
|
||||||
|
@ -462,11 +464,11 @@ public final class ExtendedSocketOptions {
|
||||||
throw new UnsupportedOperationException("unsupported TCP_KEEPINTVL option");
|
throw new UnsupportedOperationException("unsupported TCP_KEEPINTVL option");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIpDontFragment(int fd, final boolean value) throws SocketException {
|
void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException {
|
||||||
throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option");
|
throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getIpDontFragment(int fd) throws SocketException {
|
boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException {
|
||||||
throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option");
|
throw new UnsupportedOperationException("unsupported IP_DONTFRAGMENT option");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,17 +42,17 @@ class WindowsSocketOptions extends PlatformSocketOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setIpDontFragment(int fd, final boolean value) throws SocketException {
|
void setIpDontFragment(int fd, final boolean value, boolean isIPv6) throws SocketException {
|
||||||
setIpDontFragment0(fd, value);
|
setIpDontFragment0(fd, value, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean getIpDontFragment(int fd) throws SocketException {
|
boolean getIpDontFragment(int fd, boolean isIPv6) throws SocketException {
|
||||||
return getIpDontFragment0(fd);
|
return getIpDontFragment0(fd, isIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void setIpDontFragment0(int fd, boolean value) throws SocketException;
|
private static native void setIpDontFragment0(int fd, boolean value, boolean isIPv6) throws SocketException;
|
||||||
private static native boolean getIpDontFragment0(int fd) throws SocketException;
|
private static native boolean getIpDontFragment0(int fd, boolean isIPv6) throws SocketException;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (System.getSecurityManager() == null) {
|
if (System.getSecurityManager() == null) {
|
||||||
|
|
|
@ -43,32 +43,16 @@ static void handleError(JNIEnv *env, jint rv, const char *errmsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socketFamily(jint fd) {
|
|
||||||
WSAPROTOCOL_INFO info;
|
|
||||||
socklen_t sa_len = sizeof(info);
|
|
||||||
|
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL_INFO, (char *)&info, &sa_len) == 0) {
|
|
||||||
return info.iAddressFamily;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_WindowsSocketOptions
|
* Class: jdk_net_WindowsSocketOptions
|
||||||
* Method: setIpDontFragment0
|
* Method: setIpDontFragment0
|
||||||
* Signature: (IZ)V
|
* Signature: (IZZ)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0
|
JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0
|
||||||
(JNIEnv *env, jobject unused, jint fd, jboolean optval) {
|
(JNIEnv *env, jobject unused, jint fd, jboolean optval, jboolean isIPv6) {
|
||||||
int rv, opt;
|
int rv, opt;
|
||||||
jint family = socketFamily(fd);
|
|
||||||
if (family == -1) {
|
|
||||||
handleError(env, family, "get socket family failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!isIPv6) {
|
||||||
if (family == AF_INET) {
|
|
||||||
opt = optval ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
|
opt = optval ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
|
||||||
rv = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&opt, sizeof(int));
|
rv = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&opt, sizeof(int));
|
||||||
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
||||||
|
@ -81,7 +65,7 @@ JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0
|
||||||
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
||||||
/* IPV6_MTU_DISCOVER not supported on W 2016 and older, can use old option */
|
/* IPV6_MTU_DISCOVER not supported on W 2016 and older, can use old option */
|
||||||
opt = optval;
|
opt = optval;
|
||||||
rv = setsockopt(fd, IPPROTO_IP, IP_DONTFRAGMENT, (char *)&opt, sizeof(int));
|
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, (char *)&opt, sizeof(int));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleError(env, rv, "set option IP_DONTFRAGMENT failed");
|
handleError(env, rv, "set option IP_DONTFRAGMENT failed");
|
||||||
|
@ -90,18 +74,13 @@ JNIEXPORT void JNICALL Java_jdk_net_WindowsSocketOptions_setIpDontFragment0
|
||||||
/*
|
/*
|
||||||
* Class: jdk_net_WindowsSocketOptions
|
* Class: jdk_net_WindowsSocketOptions
|
||||||
* Method: getIpDontFragment0
|
* Method: getIpDontFragment0
|
||||||
* Signature: (I)Z;
|
* Signature: (IZ)Z;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jboolean JNICALL Java_jdk_net_WindowsSocketOptions_getIpDontFragment0
|
JNIEXPORT jboolean JNICALL Java_jdk_net_WindowsSocketOptions_getIpDontFragment0
|
||||||
(JNIEnv *env, jobject unused, jint fd) {
|
(JNIEnv *env, jobject unused, jint fd, jboolean isIPv6) {
|
||||||
int optval, rv, sz = sizeof(optval);
|
int optval, rv, sz = sizeof(optval);
|
||||||
jint family = socketFamily(fd);
|
|
||||||
if (family == -1) {
|
|
||||||
handleError(env, family, "get socket family failed");
|
|
||||||
return JNI_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (!isIPv6) {
|
||||||
rv = getsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&optval, &sz);
|
rv = getsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&optval, &sz);
|
||||||
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
||||||
sz = sizeof(optval);
|
sz = sizeof(optval);
|
||||||
|
@ -115,7 +94,7 @@ JNIEXPORT jboolean JNICALL Java_jdk_net_WindowsSocketOptions_getIpDontFragment0
|
||||||
rv = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (char *)&optval, &sz);
|
rv = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (char *)&optval, &sz);
|
||||||
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
if (rv == SOCKET_ERROR && WSAGetLastError() == WSAENOPROTOOPT) {
|
||||||
sz = sizeof(optval);
|
sz = sizeof(optval);
|
||||||
rv = getsockopt(fd, IPPROTO_IP, IP_DONTFRAGMENT, (char *)&optval, &sz);
|
rv = getsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, (char *)&optval, &sz);
|
||||||
handleError(env, rv, "get option IP_DONTFRAGMENT failed");
|
handleError(env, rv, "get option IP_DONTFRAGMENT failed");
|
||||||
return optval;
|
return optval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue