I'm trying to use Qos2.h to set the maximum bandwidth for a connected UDP socket. This works well for the UINT32 max (which gives us approx. 4 Gbps) but higher values result in error 8: ERROR_NOT_ENOUGH_MEMORY when calling QOSSetFlow even though the QOS_FLOWRATE_OUTGOING structure takes a UINT64 for the bandwidth field. Is it a Windows bug or am I doing something wrong?
OS: Windows Server 2022, updated.
Code:
#include <stdlib.h>
#include <limits>
#include <iostream>
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <Mswsock.h>
#include <qos2.h>
#include <ws2ipdef.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Mswsock.lib")
#pragma comment(lib, "QWave.lib")
using namespace std;
string ip = "10.10.194.47";
int port = 55000;
int main() {
WSADATA wsaData = {0};
int iResult = 0;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET s = WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET) {
cout << "error creating socket" << endl;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip.c_str());
int ret = ::connect(s, (sockaddr *)&addr, sizeof(addr));
if (ret) {
cout << "error connect" << endl;
}
QOS_VERSION qos_version;
qos_version.MajorVersion = 1;
qos_version.MinorVersion = 0;
HANDLE handle = NULL;
int ok = QOSCreateHandle(&qos_version, &handle);
if (!ok) {
cout << "Error in QOSCreateHandle: " << GetLastError() << endl;
}
QOS_FLOWID flowId = 0;
QOS_FLOWRATE_OUTGOING outFlowRate;
//outFlowRate.Bandwidth = (numeric_limits<uint32_t>::max)(); // works
outFlowRate.Bandwidth = 5000000000ui64; // does not work
outFlowRate.ShapingBehavior = QOSShapeOnly;
outFlowRate.Reason = QOSFlowRateNotApplicable;
ok = QOSAddSocketToFlow(handle, s, NULL, QOSTrafficTypeControl,
QOS_NON_ADAPTIVE_FLOW, &flowId);
if (!ok) {
cout << "Error in QOSAddSocketToFlow: " << GetLastError() << endl;
}
ok = QOSSetFlow(handle, flowId, QOSSetOutgoingRate, sizeof(outFlowRate),
(PVOID)&outFlowRate, 0, NULL);
if (!ok) {
cout << "Error in QOSSetFlow: " << GetLastError() << endl;
}
closesocket(s);
WSACleanup();
return 0;
}
Output:
Error in QOSSetFlow: 8