Mercurial > hg > release > icedtea7-forest-2.5 > jdk
changeset 8187:f4334685483a
8029607, PR2418: Type of Service (TOS) cannot be set in IPv6 header
Reviewed-by: alanb
author | michaelm |
---|---|
date | Fri, 15 Aug 2014 14:50:27 +0100 |
parents | ef3273e2be46 |
children | c9edd4f4aee1 |
files | src/share/classes/sun/nio/ch/DatagramChannelImpl.java src/share/classes/sun/nio/ch/Net.java src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java src/share/classes/sun/nio/ch/SocketChannelImpl.java src/share/native/sun/nio/ch/genSocketOptionRegistry.c src/solaris/native/java/net/net_util_md.c src/solaris/native/sun/nio/ch/Net.c src/windows/native/sun/nio/ch/Net.c |
diffstat | 8 files changed, 40 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Mon Mar 23 17:05:01 2015 +0000 +++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Aug 15 14:50:27 2014 +0100 @@ -194,15 +194,8 @@ synchronized (stateLock) { ensureOpen(); - if (name == StandardSocketOptions.IP_TOS) { - // IPv4 only; no-op for IPv6 - if (family == StandardProtocolFamily.INET) { - Net.setSocketOption(fd, family, name, value); - } - return this; - } - - if (name == StandardSocketOptions.IP_MULTICAST_TTL || + if (name == StandardSocketOptions.IP_TOS || + name == StandardSocketOptions.IP_MULTICAST_TTL || name == StandardSocketOptions.IP_MULTICAST_LOOP) { // options are protocol dependent @@ -255,16 +248,8 @@ synchronized (stateLock) { ensureOpen(); - if (name == StandardSocketOptions.IP_TOS) { - // IPv4 only; always return 0 on IPv6 - if (family == StandardProtocolFamily.INET) { - return (T) Net.getSocketOption(fd, family, name); - } else { - return (T) Integer.valueOf(0); - } - } - - if (name == StandardSocketOptions.IP_MULTICAST_TTL || + if (name == StandardSocketOptions.IP_TOS || + name == StandardSocketOptions.IP_MULTICAST_TTL || name == StandardSocketOptions.IP_MULTICAST_LOOP) { return (T) Net.getSocketOption(fd, family, name);
--- a/src/share/classes/sun/nio/ch/Net.java Mon Mar 23 17:05:01 2015 +0000 +++ b/src/share/classes/sun/nio/ch/Net.java Fri Aug 15 14:50:27 2014 +0100 @@ -370,7 +370,8 @@ } boolean mayNeedConversion = (family == UNSPEC); - setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg); + boolean isIPv6 = (family == StandardProtocolFamily.INET6); + setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6); } static Object getSocketOption(FileDescriptor fd, ProtocolFamily family, @@ -507,7 +508,7 @@ throws IOException; private static native void setIntOption0(FileDescriptor fd, boolean mayNeedConversion, - int level, int opt, int arg) + int level, int opt, int arg, boolean isIPv6) throws IOException; // -- Multicast support --
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Mon Mar 23 17:05:01 2015 +0000 +++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Aug 15 14:50:27 2014 +0100 @@ -133,6 +133,14 @@ synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); + + if (name == StandardSocketOptions.IP_TOS) { + ProtocolFamily family = Net.isIPv6Available() ? + StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; + Net.setSocketOption(fd, family, name, value); + return this; + } + if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) { @@ -177,6 +185,7 @@ HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_REUSEADDR); + set.add(StandardSocketOptions.IP_TOS); return Collections.unmodifiableSet(set); } }
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java Mon Mar 23 17:05:01 2015 +0000 +++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Aug 15 14:50:27 2014 +0100 @@ -172,14 +172,14 @@ if (!isOpen()) throw new ClosedChannelException(); - // special handling for IP_TOS: no-op when IPv6 if (name == StandardSocketOptions.IP_TOS) { - if (!Net.isIPv6Available()) - Net.setSocketOption(fd, StandardProtocolFamily.INET, name, value); + ProtocolFamily family = Net.isIPv6Available() ? + StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; + Net.setSocketOption(fd, family, name, value); return this; - } else if (name == StandardSocketOptions.SO_REUSEADDR && - Net.useExclusiveBind()) - { + } + + if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) { // SO_REUSEADDR emulated when using exclusive bind isReuseAddress = (Boolean)value; return this; @@ -214,8 +214,9 @@ // special handling for IP_TOS: always return 0 when IPv6 if (name == StandardSocketOptions.IP_TOS) { - return (Net.isIPv6Available()) ? (T) Integer.valueOf(0) : - (T) Net.getSocketOption(fd, StandardProtocolFamily.INET, name); + ProtocolFamily family = Net.isIPv6Available() ? + StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; + return (T) Net.getSocketOption(fd, family, name); } // no options that require special handling
--- a/src/share/native/sun/nio/ch/genSocketOptionRegistry.c Mon Mar 23 17:05:01 2015 +0000 +++ b/src/share/native/sun/nio/ch/genSocketOptionRegistry.c Fri Aug 15 14:50:27 2014 +0100 @@ -110,6 +110,7 @@ emit_inet("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IP, IP_MULTICAST_LOOP); #ifdef AF_INET6 + emit_inet6("StandardSocketOptions.IP_TOS", IPPROTO_IPV6, IPV6_TCLASS); emit_inet6("StandardSocketOptions.IP_MULTICAST_IF", IPPROTO_IPV6, IPV6_MULTICAST_IF); emit_inet6("StandardSocketOptions.IP_MULTICAST_TTL", IPPROTO_IPV6, IPV6_MULTICAST_HOPS); emit_inet6("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
--- a/src/solaris/native/java/net/net_util_md.c Mon Mar 23 17:05:01 2015 +0000 +++ b/src/solaris/native/java/net/net_util_md.c Fri Aug 15 14:50:27 2014 +0100 @@ -1355,7 +1355,7 @@ * or sending UDP packet. * 2. IPv6 on Linux: By default Linux ignores flowinfo * field so enable IPV6_FLOWINFO_SEND so that flowinfo - * will be examined. + * will be examined. We also set the IPv4 TOS option in this case. * 3. IPv4: set socket option based on ToS and Precedence * fields (otherwise get invalid argument) */ @@ -1371,8 +1371,10 @@ #if defined(AF_INET6) && defined(__linux__) if (ipv6_available()) { int optval = 1; - return setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, - (void *)&optval, sizeof(optval)); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, + (void *)&optval, sizeof(optval)) < 0) { + return -1; + } } #endif
--- a/src/solaris/native/sun/nio/ch/Net.c Mon Mar 23 17:05:01 2015 +0000 +++ b/src/solaris/native/sun/nio/ch/Net.c Fri Aug 15 14:50:27 2014 +0100 @@ -441,7 +441,8 @@ JNIEXPORT void JNICALL Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz, jobject fdo, - jboolean mayNeedConversion, jint level, jint opt, jint arg) + jboolean mayNeedConversion, jint level, + jint opt, jint arg, jboolean isIPv6) { int result; struct linger linger; @@ -484,6 +485,12 @@ JNU_JAVANETPKG "SocketException", "sun.nio.ch.Net.setIntOption"); } +#ifdef __linux__ + if (level == IPPROTO_IPV6 && opt == IPV6_TCLASS && isIPv6) { + // set the V4 option also + setsockopt(fdval(env, fdo), IPPROTO_IP, IP_TOS, parg, arglen); + } +#endif } JNIEXPORT jint JNICALL
--- a/src/windows/native/sun/nio/ch/Net.c Mon Mar 23 17:05:01 2015 +0000 +++ b/src/windows/native/sun/nio/ch/Net.c Fri Aug 15 14:50:27 2014 +0100 @@ -318,7 +318,7 @@ JNIEXPORT void JNICALL Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz, jobject fdo, - jboolean mayNeedConversion, jint level, jint opt, jint arg) + jboolean mayNeedConversion, jint level, jint opt, jint arg, jboolean ipv6) { struct linger linger; char *parg;