Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7169676

setTrafficClass() doesn't work on packets sent from IPv6 Socket connected to a v4 mapped v6 address

XMLWordPrintable

    • generic
    • linux

      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.

            Unassigned Unassigned
            dkorbel David Korbel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: