0

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?

QOSSetFlow documentation

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

0 Answers0