esnet / iperf

iperf3: A TCP, UDP, and SCTP network bandwidth measurement tool
Other
6.75k stars 1.27k forks source link

DSCP/QoS tagging on Windows #336

Closed BasvanH closed 4 years ago

BasvanH commented 8 years ago

Hello,

I'm trying to get DSCP QoS tagging (-S option) to work on Windows 7, 8.1, 10, this without succes. I've created an post on the Microsoft ItPro forums. In the reply they ask about how the software (iperf3) has been developed to include QoS tags.

My question, could you please look at this forum post: https://social.technet.microsoft.com/Forums/en-US/175752f1-ce2a-478a-82f9-d4f81ad699bf/qos-tos-dscp-marking-removed-on-apps?forum=win10itpronetworking

Is perf3 compatible with the requirements stated in that post?

(If not, can this be done, there's currently no good QoS performance tool available for Windows 7+, so iperf3 would fill in a gap.)

Kind Regards, Bastiaan

BasvanH commented 8 years ago

Any update on this matter please?

bmah888 commented 8 years ago

If I understand this correctly, the question is whether iperf3 uses certain Windows-specific APIs to set the TOS bits. The answer to that question is "no". iperf3 does this by using the IP_TOS socket option.

It might be possible to make iperf3 use the Windows APIs for the case that it's being compiled and run on Windows, although please note that Windows is not an officially supported platform. We'd probably take a pull request for inclusion in the main code if someone were to develop a patch and if it didn't have too much impact on the rest of the code.

BasvanH commented 8 years ago

Yes, that is the case. Would be great if someone would make an pull to make iPerf full Windows compatible. This would make troubleshooting QoS configs on switches much more convenient, as there's currently no Windows based QoS test tool.

helloguys88 commented 8 years ago

I don't believe specific API is needed. What Microsoft talking about was to use those API to build "QoS-aware applications", which is more on 'receiving and interpreting' other than 'sending'.

Many other packet generators are using setsockopt function to set DSCP values and works fine. Here are some examples:

For some reason, iPerf3 (and iPerf2) didn't work.

bmah888 commented 7 years ago

Note that #508 added a --dscp option to iperf3. As of this writing it's not in a release yet, but the next release should ship this. There was some implication that the older --qos option in iperf3 didn't work, although that was on more Linux-like systems.

giantjunkbox commented 5 years ago

I built from source 3.6 on cygwin and tried the new shiny --dscp option in my Windows 10 environment. It does not appear to work. It does work in Linux.

The only way I can get Windows to set a DSCP value for iperf is by creating a static QoS policy in Windows, which is probably good enough for my current needs, but it would be really nice if it setting it in iperf worked.

I thought that perhaps Windows was just ignoring the values, and perhaps there are some policy changes that are required. I tried setting the "DisableUserTOSSetting" and "Do not use NLA" keys; but that didn't seem to make a difference.

At this point I'm not sure if this is Windows overwriting what iperf sets or iperf not setting anything.

Anyone have any better luck or insight?

bmah888 commented 4 years ago

Closing, mostly due to the fact that we don't officially support Windows or even have an easy way to investigate this.

iamhyc commented 2 years ago

Hi, for anyone interested, I have built a workable Windows version by modifying the setsockopt part in cygwin.

The reference implementation could be found here, lasso-sustech/newlib-cygwin.

Considering we are not acutally setting IP_TOS but DSCP, I have no idea where to submit the patch.

The binary is attached, please use at your own risk (cause it requires permission to work). test-iperf3.zip


The following test shows the effect on a 2.4GHz Wi-Fi link. (sudo is a PS script installed via scoop)

screenshot

davidBar-On commented 2 years ago

Hi @iamhyc, seem to be an important and useful enhancement to Cygwin. If I understand correctly, you can submit the patch to Cigwin per the Cygwin contribution instructions.

iamhyc commented 1 year ago

@davidBar-On Thanks for your comments! I will try to communicate with the Cygwin team, but I am afraid they would not accept it. "Only DSCP set" and "Administrator permission required" do not conform with the behavior of setsockopt on IP_TOS.

For now, I would just leave a workable solution here, if someone search for it online :)

talengu commented 1 year ago

@davidBar-On Thanks for your comments!

I will try to communicate with the Cygwin team, but I am afraid they would not accept it.

"Only DSCP set" and "Administrator permission required" do not conform with the behavior of setsockopt on IP_TOS.

For now, I would just leave a workable solution here, if someone search for it online :)

nice,support ipv4 dscp. but do not support IPv6 in win 11,any help?

iamhyc commented 1 year ago

@davidBar-On Thanks for your comments! I will try to communicate with the Cygwin team, but I am afraid they would not accept it. "Only DSCP set" and "Administrator permission required" do not conform with the behavior of setsockopt on IP_TOS. For now, I would just leave a workable solution here, if someone search for it online :)

nice,support ipv4 dscp. but do not support IPv6 in win 11,any help?

Hi @talengu , in my implementation, I only complete the code for IPPROTO_IP --> IP_TOS part which is for IPv4, and you need to complete the corresponding part for IPPROTO_IPV6 in cygwin.

I am not working on it any more but I think they use the same API, and you simply copy the code snippet to the IPv6 part.

talengu commented 1 year ago

@iamhyc thanks. IPv4 works well now.

$ cygcheck -c cygwin
Cygwin Package Information
Package              Version        Status
cygwin               3.4.8-1        OK

$ iperf3.exe -version
iperf 3.1.3

But when I add ipv6 func , I get a bug

D:\git\test\newlib-cygwin\build>iperf3.exe -c fe80::42ed:3ce9:4cf5:bc31 -p 5001 -B fe80::1969:f944:1c26:acd --tos 100 -b 1M -t 1000
Connecting to host fe80::42ed:3ce9:4cf5:bc31, port 5001
iperf3: error - unable to set IPv6 traffic class: Protocol not available

I found that winsock maybe do not support setsockopt IPPROTO_IPV6 -> IPV6_TCLASS 😞

const int trafficClass = 232;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &trafficClass, sizeof(int)) < 0) 
{
  //some code
}

Unable to set traffic class(IPV6_TCLASS) using setsockopt in windows Any Help ? or someone continue fixing it.

iamhyc commented 1 year ago

Hi @talengu , could you show us the patch to cygwin? If the patch works, I think it should let windows qos2 subsystem handle the DSCP setting and no "IPv6 traffic class" thing should happen. We even don't know where the error is raised.

I have done a quick search and it seems that Windows does support setting IPv6 ToS section:

talengu commented 1 year ago

just like the IPv4

case IPPROTO_IPV6:
      switch (optname)
    {
    case IPV6_TCLASS:
      /* Unsupported */
           {
      HANDLE qosHandle;
      QOS_FLOWID flowID;
      DWORD dscpValue;
      QOS_VERSION QosVersion = { 1 , 0 };

      // Initialize the QoS subsystem
      if (FALSE == QOSCreateHandle(&QosVersion, &qosHandle))
      {
        debug_printf("QOSCreateHandle failed (%d)\n", GetLastError());
      }

      // Create a flow for our socket
      flowID = 0;
      if (FALSE == QOSAddSocketToFlow(qosHandle, get_socket(), NULL, QOSTrafficTypeBestEffort, QOS_NON_ADAPTIVE_FLOW, &flowID))
      {
          debug_printf("QOSAddSocketToFlow failed (%d)\n", GetLastError());
      }

      // Set DSCP value for the flow
      dscpValue = (*(int *) optval) >> 2;
      if (FALSE == QOSSetFlow(qosHandle, flowID, (QOS_SET_FLOW) QOSSetOutgoingDSCPValue, sizeof(dscpValue), &dscpValue, 0, NULL))
      {
          debug_printf(" QOSSetFlow failed (%d)\n", GetLastError());
      }
    }
     }
     //ignore = true;
      break;

    default:
      break;
    }
talengu commented 1 year ago

@iamhyc thanks 👍 winsock setsockopt may not support IPV6_TCLASS as show in IPPROTO_IPV6 socket options

/* Call Winsock setsockopt (or not) */
  if (ignore)
    ret = 0;
  else
    {
      ret = ::setsockopt (get_socket (), level, optname, (const char *) optval,
              optlen);
      if (ret == SOCKET_ERROR)

what is the equivalent of IP_TOS (PPROTO_IP option in setsockopt function for IPv4 socket) in IPv6 addressing?

As per MSDN Article ID: 248611 ToS is ignored and the GQOS API is limited to IPv4-only. For IPv6 and IPv4 you must use qWAVE QOS which requires Vista or later platforms.

can not figure out the solution in qWAVE QOS ? any idea?

iamhyc commented 1 year ago

@talengu I am confused. We are not actually calling setsockopt at all and why ::setsockopt is called? maybe you could have ignore = true; enabled to bypass it.

If no dbug_printf is triggered in your snippet, then the DSCP setting is already applied to the corresponding winsock.