]> sjero.net Git - iperf/commitdiff
Bring DiffServ codepoint support up-to-date
authorGerrit Renker <gerrit@erg.abdn.ac.uk>
Tue, 24 Feb 2009 19:50:23 +0000 (20:50 +0100)
committerGerrit Renker <gerrit@erg.abdn.ac.uk>
Tue, 24 Feb 2009 19:50:23 +0000 (20:50 +0100)
The -S/--tos argument currently only supports IPv4 TOS, for IPv6 a different
socket option is used. Both uses are unified through the definition of the
DiffServ codepoint in RFC 2474 (the two unused bits are used for ECN marking
and can not normally be influenced via socket options).

This patch
 * adds (conditional) support for IPv4/v6 socket options to set the DSCP;
 * adds an extra type argument mSockAF to remember the address family
   of mSock (to allow address-family-dependent TOS);
 * fixes a ToDo to support base-2 numbers for the DSCP string;
 * validates the numeric argument;
 * replaces the older IPv4-based `--tos' option with `--dscp'
   and the environment variable `IPERF_TOS' with `IPERF_DSCP'.

The argument types that are now supported are
 # iperf -c server -S 0x1f # hex string
 # iperf -c server -S 017 # octal string (=0xf)
 # iperf -c server -S 42 # decimal string
 # iperf -c server -S 011011 # binary string (must be 6 digits)

src/Locale.c
src/PerfSocket.cpp
src/Settings.cpp

index ade47f07c605c18ea01f3ce78f2851f039f0c08d..cc025220629dd40a48e1a50ca7f352c9c784532a 100644 (file)
@@ -106,6 +106,7 @@ Client specific:\n\
   -I, --stdin              input the data to be transmitted from stdin\n\
   -L, --listenport #       port to receive bidirectional tests back on\n\
   -P, --parallel  #        number of parallel client threads to run\n\
+  -S  --dscp      #        set the 6-bit IPv4/v6 DiffServ codepoint\n\
   -T, --ttl       #        time-to-live, for multicast (default 1)\n\
 \n\
 Miscellaneous:\n\
index 04a68b9583ced9bb44de5a7f070fdebbcd76c660..63e97ff9480b4405fe98f770498a3a2c0e67dcce 100644 (file)
@@ -99,14 +99,22 @@ void SetSocketOptions( thread_Settings *inSettings )
     }
 
 
-    // set IP TOS (type-of-service) field
-#ifdef IP_TOS
+    // Set the DiffServ codepoint for IPv4 TOS or IPv6 traffic class
     if ( inSettings->mTOS > 0 ) {
         val = inSettings->mTOS;
-        rc = setsockopt( inSettings->mSock, IPPROTO_IP, IP_TOS, &val, len );
-        WARN_errno( rc == SOCKET_ERROR, "setsockopt IP_TOS" );
-    }
+#if defined(IP_TOS)
+       if ( inSettings->mSockAF == AF_INET ) {
+          rc = setsockopt( inSettings->mSock, IPPROTO_IP, IP_TOS, &val, len );
+          WARN_errno( rc == SOCKET_ERROR, "setsockopt IP_TOS" );
+       }
 #endif
+#if defined(IPV6_TCLASS)
+       if ( inSettings->mSockAF == AF_INET6 ) {
+         rc = setsockopt( inSettings->mSock, IPPROTO_IPV6, IPV6_TCLASS, &val, len );
+          WARN_errno( rc == SOCKET_ERROR, "setsockopt IPV6_TCLASS" );
+       }
+#endif
+    }
 
 
     // TCP-specific options
index 4034158cf261d326965afb4d5496de18700871a4..15b5ccd532b5a88605f40a8d96798f722f4500bf 100644 (file)
@@ -118,7 +118,7 @@ const struct option long_options[] =
 {"listenport", required_argument, NULL, 'L'},
 {"parallel",   required_argument, NULL, 'P'},
 {"remove",           no_argument, NULL, 'R'},
-{"tos",        required_argument, NULL, 'S'},
+{"dscp",       required_argument, NULL, 'S'},
 {"ttl",        required_argument, NULL, 'T'},
 {"single_udp",       no_argument, NULL, 'U'},
 {"ipv6_domian",      no_argument, NULL, 'V'},
@@ -163,7 +163,7 @@ const struct option env_options[] =
 {"IPERF_NODELAY",          no_argument, NULL, 'N'},
 {"IPERF_LISTENPORT", required_argument, NULL, 'L'},
 {"IPERF_PARALLEL",   required_argument, NULL, 'P'},
-{"IPERF_TOS",        required_argument, NULL, 'S'},
+{"IPERF_DSCP",       required_argument, NULL, 'S'},
 {"IPERF_TTL",        required_argument, NULL, 'T'},
 {"IPERF_SINGLE_UDP",       no_argument, NULL, 'U'},
 {"IPERF_IPV6_DOMAIN",      no_argument, NULL, 'V'},
@@ -626,11 +626,20 @@ void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtS
             setRemoveService( mExtSettings );
             break;
 
-        case 'S': // IP type-of-service
-            // TODO use a function that understands base-2
-            // the zero base here allows the user to specify
-            // "0x#" hex, "0#" octal, and "#" decimal numbers
-            mExtSettings->mTOS = strtol( optarg, NULL, 0 );
+        case 'S':
+            // Convert into IPv4/v6 6-bit DiffServ codepoint. If string
+            //  - consists of six 0/1 digits, it is seen as binary number;
+            //  - is preceded by `0x', it is interpreted as hex number;
+            //  - is preceded by `0', it is interpreted as octal number;
+            //  - otherwise it is interpreted as decimal number.
+            // The maximum possible 6-bit value is 252 (0xfc).
+            if ( strspn(optarg, "01") == 6 )
+               mExtSettings->mTOS = strtol(optarg, NULL, 2);
+            else
+               mExtSettings->mTOS = strtol(optarg, NULL, 0);
+            if ( mExtSettings->mTOS < 0 || mExtSettings->mTOS  > 0xfc )
+               die("Invalid DiffServ codepoint %s", optarg);
+            mExtSettings->mTOS <<= 2;
             break;
 
         case 'T': // time-to-live for multicast