JDK-8072384 : Setting IP_TOS on java.net sockets not working on unix
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-02-03
  • Updated: 2019-03-28
  • Resolved: 2015-06-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9
7u85Fixed 8u45Fixed 9Fixed
Related Reports
Relates :  
Description
Submitter reporting some problems around setting of TOS on the classic networking sockets. No issues seen on NIO sockets.

A typical use case might be : 
        ServerSocket ss = new ServerSocket();
        jdk.net.Sockets.setOption(ss, java.net.StandardSocketOptions.IP_TOS, 128);
        // bind
        // accept

 The remaining Java related problems are: 
 1. Blocking TCP IPv6 Server sockets (java.net). This is not working neither on Oracle Solaris 10 1/13 or a recent Linux (CentOS 7). 
 2. Blocking TCP IPv4 Server sockets (java.net) on Linux. Here the initial SYN packet is missing the TOS flag. 

 Solaris system: 
 java version "1.7.0_80-ea" 
 Java(TM) SE Runtime Environment (build 1.7.0_80-ea-b04) 
 Java HotSpot(TM) Server VM (build 24.80-b07, mixed mode) 

 cat /etc/release 
                    Oracle Solaris 10 1/13 s10x_u11wos_24a X86 
  Copyright (c) 1983, 2013, Oracle and/or its affiliates. All rights 
reserved. 
                            Assembled 17 January 2013 

 Results: 
 
 IPv6  
 TCP: 
 Client Socket: OK 
 Server Socket: Not OK 
 
 TCPNIO: 
 Client Socket: OK 
 Server Socket: OK 
 
 UDP: 
 Client Socket: OK 
 Server Socket: OK 
 
 IPv4(all with -Djava.net.preferIPv4Stack=true) 
 
 TCP: 
 Client Socket: OK 
 Server Socket: OK 
 
 TCPNIO: 
 Client Socket: OK 
 Server Socket: OK 
 
 UDP: 
 Client Socket: OK 
 Server Socket: OK 
Comments
some more updates. I found that the solaris kernel doesn't like anyone touching the TOS value once the socket is in connected state. EINVAL is returned and that causes the exception seen below. t4 $./jdk_tos/bin/java TestServer Exception in thread "main" java.net.SocketException: Invalid option or socket reset by remote peer at java.net.PlainSocketImpl.socketSetOption(Native Method) at java.net.AbstractPlainSocketImpl.setOption(AbstractPlainSocketImpl.java:269) at java.net.Socket.setTrafficClass(Socket.java:1337) at TestServer.main(TestServer.java:14) A new approach would be to only throw the exception if we get a problem code back from the setsockopt call && we're not connected. The spec states that changing of value after connection is not guaranteed : http://download.java.net/jdk7/archive/b123/docs/api/java/net/Socket.html#setTrafficClass(int) > Applications should not assume that they can change the TOS field after the connection. Given that setting TOS is now a real op, I'm conscious that not capturing/handling the above issue would result in a regression for apps that were running ok. I did try another approach of detecting and clearing the socket option if an error was detected and substituting a TCLASS set request with an IP_TOS set request, but solaris still wasn't happy. macosx and linux seemed to be fine with such an attempt. (set after connecting)
23-02-2015

NET_SetSockOpt seems to make TOS a no-op for IPv6 enabled environments on solaris. I'm proposing we map an IP_TOS request to a traffic class request in such scenarios. NIO code appears to do similar.
10-02-2015