SYNOPSIS
--------
Socket.setTrafficClass() does not work for packets sent from an IPv6 Socket connected to a IPv4 mapped IPv6 address
OPERATING SYSTEM
----------------
Linux
FULL JDK VERSIONS
-----------------
All
PROBLEM DESCRIPTION
-------------------
The current implementation of Socket.setTrafficClass() does the following on an IPv6 enabled Linux system:
1. Call NET_SetSockOpt with IP_TOS.
2. If the system is IPv6 enabled, enable IPV6_FLOWINFO_SEND on the
socket.
3. Set sin6_flowinfo field of the connecting IPv6 address at the time of
connection with the trafficClass already set by the user.
However, this flow does not set the TOS value of packets sent from an IPv6 Socket connected to a IPv4 mapped IPv6 addresses.
According to the team in our Linux Technology Centre, a socket created with AF_INET6 family and bound to a IPv4 mapped IPv6 address continues to send IPv4 packets only. So, setsockopt() needs to be used to enable TOS on the packets dispatched even if the socket is a IPv6 socket.
TESTCASE
--------
import java.net.*;
import java.util.*;
public class tosTest {
public static void main(String[] args) throws Exception {
if (args.length != 2) { // Test for correct # of args
args = new String[]{"localhost","6000"};
}
InetAddress destAddr = InetAddress.getByName(args[0]); // Destination address
int destPort = Integer.parseInt(args[1]); //Destination port
System.out.println("Client try to connect to : " + destAddr + "@" + destPort);
Socket sock = new Socket();
sock.setTrafficClass(28);
sock.connect(new InetSocketAddress(destAddr, destPort));
System.out.println("after set and connect getTrafficClass: " + sock.getTrafficClass());
byte[] array = new byte[]{1,2,3,4,5,6,7,8,9};
while (true) {
System.out.println("in write loop getTrafficClass: " + sock.getTrafficClass());
sock.getOutputStream().write(array);
System.out.println("client write : " + Arrays.toString(array));
Thread.sleep(5000);
}
}
}
Output from tcpdump tool:
06:33:58.278111 IP (tos 0x0, ttl 64, id 5977, offset 0, flags [DF], proto: TCP (6), length: 61) linos.in.ibm.com.52754 > ibm-ai71o7pp6o5.in.ibm.com.6000: P, cksum 0xd27e (incorrect (-> 0x9b39), 18:27(9) ack 13 win 46 <nop,nop,timestamp 2680373519 7545518>
06:34:03.282344 IP (tos 0x0, ttl 64, id 5978, offset 0, flags [DF], proto: TCP (6), length: 61) linos.in.ibm.com.52754 > ibm-ai71o7pp6o5.in.ibm.com.6000: P, cksum 0xd27e (incorrect (-> 0x9461), 27:36(9) ack 13 win 46 <nop,nop,timestamp 2680374770 7546010>
WORKAROUND
----------
Enable IPv4 Stack.