I'm looking to programatically mark the Type of Service / DSCP byte in packets from a network socket. The current implementation in C# is below:
UdpClient udpClient = new UdpClient();
string ipAddress = "xxx.xxx.xxx.xxx";
int port = 3999;
udpClient.Connect(ipAddress, port);
udpClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.TypeOfService, 8);
Console.WriteLine(udpClient.Client.GetSocketOption(SocketOptionLevel.IP, SocketOptionName.TypeOfService)); // Gives value 8
udpClient.Send(Encoding.ASCII.GetBytes("Hello World!"));
udpClient.Close();
However, the output shows it has been set successfully but when inspecting the packets in Wireshark they still have a DSCP value of 0
.
The solutions I have tried so far have been the following registry edits:
Do not use NLA
DWORD value to 1
in Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\QoS
. (As per this Cisco guide.DisableUserTOSSetting
DWORD value to 0
in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpIp\Parameters
. (As per this old Microsoft page (archive.org)).In an ideal world the solution would be programmatic and not require the user to edit their group policy as I wish for it to be controlled from the programs UI.
Final solution to setting the TOS value per socket was to use a raw socket.
I found the winsockdotnetworkprogramming.com guides to be useful. It's worth noting that by using a RawSocket you loose a lot of the quality of life features that udpClient handles for you (e.g. setting the correct source ip and sending out via the correct interface). It also requires the program to be run as Administrator.