/*++ Copyright (c) 2004 Microsoft Corporation Module Name: qos2.h Abstract: This module contains QOS structures and function headers --*/ #pragma once #include #include // // Support calls from C++ // #if defined(__cplusplus) #define ExternC extern "C" #else #define ExternC #endif // // Each admitted flow has a unique Flow ID. This ID is valid only // in the process which called QOSAddSocketToFlow() for that flow // with the handle returned from QOSCreateHandle // typedef ULONG QOS_FLOWID, *PQOS_FLOWID; // // Definitions of various traffic types. Application identifies // each flow as being of a certain type. This enables the QOS // subsystem to apply user-specified per-type policies to flows // // QOSTrafficTypeBestEffort: // // This service type requests the same network priority to the traffic // as regular traffic not associated to the qWave api. For home scenarios, // this is DLNA class DLNAQOS_1. // // QOSTrafficTypeBackground: // // This service type requests a network priority to the traffic lower than // traffic of type QOSTrafficTypeBestEffort. For example, this service // could be used for traffic of applications doing data backups. For home // scenarios, this is DLNA class DLNAQOS_0. // // QOSTrafficTypeExcellentEffort: // // This service type requests a network priority to the traffic higher than // QOSTrafficTypeBestEffort. This service type should be used for data // traffic that, although not A/V, is more important than normal end-user // scenarios. For example, email traffic. This service type is not part of // the DLNA specification. // // QOSTrafficTypeAudioVideo: // // This service type should be used for A/V streaming scenarios such as // MPEG2 streaming. For home scenarios, this is DLNA class DLNAQOS_2. // // QOSTrafficTypeVoice: // // This service type should be used for realtime voice streams such as // VoIP. This service type is not part of the DLNA specification. // // QOSTrafficTypeControl: // // This service type should only be used for the most critical data. For // example, you might use it for data carrying user inputs to an A/V // experience, e.g. play, pause, FF, RW, etc. The A/V traffic however // should use QOSTrafficTypeAudioVideo. For home scenarios, this is DLNA // class DLNAQOS_3. // typedef enum _QOS_TRAFFIC_TYPE { QOSTrafficTypeBestEffort = 0, QOSTrafficTypeBackground = 1, QOSTrafficTypeExcellentEffort = 2, QOSTrafficTypeAudioVideo = 3, QOSTrafficTypeVoice = 4, QOSTrafficTypeControl = 5 } QOS_TRAFFIC_TYPE, *PQOS_TRAFFIC_TYPE; // // This enum lists the operations that may be given to the QOSSetFlow API. // // QOSSetTrafficType: // // Allows an application to change the traffic type of its // flow. For example, this may be useful if you are alternating between // best effort and other types. // // This must be accompanied by a QOS_TRAFFIC_TYPE value. // // QOSSetOutgoingRate: // // This allows an application to define the characteristics of the // outgoing traffic on its flow. This may be used to shape the outgoing // traffic or to create a contract linking packet marking to packet // shaping. Such a contract is required for environments were policy uses // admission control. The traffic type will not be respected until a // shaping rate is in place. // // Must be accompagnied by a QOS_FLOWRATE_OUTGOING structure. // // QOSSetOutgoingDSCPValue: // // This allows an application to specify the precise DSCP value used in // outgoing traffic. This setting is overriden if an adaptive flow // requests prioritization on the same machine. This setting requires // the calling application be a member of the Administrators or the // Network Configuration Operators group. This setting can only be // applied to a non-adaptive flow. // // Must be accompanied by a DWORD value representing the DSCP value to // use. The value must be from 0 to 63 inclusive. // // To revert the effect of setting a DSCP value, the caller should call // the QOSSetFlow API again with the operation value QOSSetTrafficType. // typedef enum _QOS_SET_FLOW { QOSSetTrafficType = 0, QOSSetOutgoingRate = 1, QOSSetOutgoingDSCPValue = 2 } QOS_SET_FLOW, *PQOS_SET_FLOW; // // This structure is returned by QOSQueryFlow and allows the application to // verify what priority markings (or tags) are applied to its traffic. These // values may change as the flow changes or policies get updated. // typedef struct _QOS_PACKET_PRIORITY { ULONG ConformantDSCPValue; // the DSCP marking used for the flow's // traffic that respects the flow rate // specified ULONG NonConformantDSCPValue; // the DSCP marking used for the flow's // traffic that exceeds the flow rate // specified. Applicable only if shaping // behavior is set to // QOSUseNonConformantMarkings ULONG ConformantL2Value; // the L2 tag used for the flow's traffic // that respects the flow rate specified ULONG NonConformantL2Value; // the L2 tag used for the flow's traffic // that respects the flow rate specified. // Applicable only if shaping behavior is // set to QOSUseNonConformantMarkings } QOS_PACKET_PRIORITY, *PQOS_PACKET_PRIORITY; typedef struct _QOS_FLOW_FUNDAMENTALS { BOOL BottleneckBandwidthSet; // TRUE if the BottleneckBandwidth field // contains a value. UINT64 BottleneckBandwidth; // In units of bits/s ; does not include // layer 3 BOOL AvailableBandwidthSet; // TRUE if the AvailableBandwidth field // contains a value. UINT64 AvailableBandwidth; // In units of bits/s ; does not include // layer 3 BOOL RTTSet; // TRUE if the RTT field // contains a value. UINT32 RTT; // RTT is in microseconds. } QOS_FLOW_FUNDAMENTALS, *PQOS_FLOW_FUNDAMENTALS; typedef enum _QOS_FLOWRATE_REASON { QOSFlowRateNotApplicable = 0, QOSFlowRateContentChange = 1, QOSFlowRateCongestion = 2, QOSFlowRateHigherContentEncoding = 3, QOSFlowRateUserCaused = 4 } QOS_FLOWRATE_REASON, *PQOS_FLOWRATE_REASON; // // This enum is used to define the shaping behavior. Remember that, if policy // demands admission control, packet priority is only applied through a contract // with the application. This enum allows you to define how the contract is // enforced. // // QOSShapeOnly: if the flow is set to shape only, qWave will use Window's // scheduler to enforce the flow rate requested. Any data packet that would // exceed the rate will be delayed until appropriate. Packets will be marked // as best effort packets. // // QOSShapeAndMark: if the flow is set to shape, qWave will use Window's // scheduler to enforce the flow rate requested. Any data packet that would // exceed the rate will be delayed until appropriate. Packets will always // receive conformant priority values. // // QOSUseNonConformantMarkings: if the flow is set to use non conformant values, // qWave will not enforce the flow rate requested. If sending a data packet // would exceed the flow rate, this packet will receive a priority value // indicating it is non-conformant. Such packets will receive default treatment - // which is best effort - from network equipment. This may lead to lost packets // and/or re-ordered packets. // typedef enum _QOS_SHAPING{ QOSShapeOnly = 0, QOSShapeAndMark = 1, QOSUseNonConformantMarkings = 2 } QOS_SHAPING, *PQOS_SHAPING; #define QOS_OUTGOING_DEFAULT_MINIMUM_BANDWIDTH 0xFFFFFFFF // // This struct describes the information required by qWave to accept a flowrate // from the application. We recommend that you read the description for // QOS_ADD_OVERHEAD and QOS_SUBTRACT_OVERHEAD before using this structure. // // Bandwidth: the rate (in bits/s) you expect to send your traffic at. As a // warning, you should note that traffic on the network is measured at the IP // level and not at the application level. Thus, the rate you specify should // account for the IP and protocol headers. Although there are various ways // to estimate this final rate, you may wish to use the QOS_ADD_OVERHEAD and // QOS_SUBTRACT_OVERHEAD functions for these calculations. // // If you are unsure what bandwidth value you need but expect to use very little // use QOS_OUTGOING_DEFAULT_MINIMUM_BANDWIDTH. The system will allocate you // a small amount of bandwidth for your operations. // // ShapingBehavior: how the contract for admission control will be enforced // // Reason: if a rate change has occured, this reason should indicate why. typedef struct _QOS_FLOWRATE_OUTGOING { UINT64 Bandwidth; // In units of bits/s QOS_SHAPING ShapingBehavior;// Shaping behavior QOS_FLOWRATE_REASON Reason; // Optional field for the // application to indicate why it's // changing a flow's data rate } QOS_FLOWRATE_OUTGOING, *PQOS_FLOWRATE_OUTGOING; // // When using the enum QOSQueryOutgoingRate you should expect the returned rate // to measure bandwidth at layer 3. If you wish to adjust this rate, based on // your application's characteristics, for the IP header and protocol header // overhead, you should review the QOS_SUBTRACT_OVERHEAD inlined function. typedef enum _QOS_QUERY_FLOW { QOSQueryFlowFundamentals = 0, QOSQueryPacketPriority = 1, QOSQueryOutgoingRate = 2 } QOS_QUERY_FLOW, *PQOS_QUERY_FLOW; typedef enum _QOS_NOTIFY_FLOW { QOSNotifyCongested = 0, QOSNotifyUncongested = 1, QOSNotifyAvailable = 2 } QOS_NOTIFY_FLOW, *PQOS_NOTIFY_FLOW; // // The type for QOS protocol version numbers. // For Vista, the version should be // MajorVersion: 1 // MinorVersion: 0 typedef struct _QOS_VERSION { USHORT MajorVersion; USHORT MinorVersion; } QOS_VERSION, *PQOS_VERSION; #define QOS_QUERYFLOW_FRESH 0x00000001 #define QOS_NON_ADAPTIVE_FLOW 0x00000002 __inline INT QOS_HEADER_OVERHEAD( __in INT af, __in INT protocol ){ UINT32 overhead; if (af == AF_INET) overhead = 20; // IPv4 header overhead in bytes else overhead = 40; // IPv6 header overhead in bytes if (protocol == IPPROTO_TCP) overhead += 20; // TCP header overhead in bytes else overhead += 8; // UDP header overhead in bytes return overhead; } // // Description: // // API to calculate the impact of IP and protocol header overhead on a data // rate. // // Arguments: // // .af - Address family used to create the socket. Please // review the socket and WSASocket documentation. This // should be AF_INET or AF_INET6 // // .protocol - Protocol type used to create the socket. Please review // the socket and WSASocket documentation. This should // be IPPROTO_TCP or IPPROTO_UDP // // .targetDataPacketSize // - This is the expected packet size of your data stream. // ***See note below on targetDataPacketSize*** // // .dataRate - Your dataRate in bits/s. // // Note on targetDataPacketSize: // // If you're using a TCP socket on IPv4 and will be making large sends then you // would expect the data packet size to be 1460 bytes: Ethernet has an MTU of // 1500 bytes and the overhead of an IPv4 header is typically 20 bytes // while a TCP header is also 20 bytes. // // If you're using a UDP socket and your packet size varies, you may wish to // pass in a reasonnable minimal value. This would adjust your rate for the // worst case. // // The value 0 is an invalid parameter which will result in a division by 0. // // Return Values: // // This call will return the data rate, in bits/s, augmented by the overhead // on each packet given the address family and the protocol you've created your // socket with. // __inline UINT64 QOS_ADD_OVERHEAD( __in INT af, __in INT protocol, __in UINT32 targetDataPacketSize, __in UINT64 dataRate ){ UINT32 overhead; double d; UINT64 r; // // Calculate the header overhead overhead = QOS_HEADER_OVERHEAD(af, protocol); // // Convert overhead and dataRate to bits overhead *= 8; targetDataPacketSize *= 8; // // The adjustment is: // // ( dataRate ) // returnRate = dataRate + ( -------------------- * overhead ) // ( targetDataPacketSize ) // // For each packet we expect to see go out, we need to add the // overhead d = (double) overhead; d /= (double) targetDataPacketSize; d *= (double) dataRate; r = dataRate; r += (UINT64) d; return r; } // // Description: // // API to calculate the impact of IP and protocol header overhead on a data // rate. // // Arguments: // // .af - Address family used to create the socket. Please // review the socket and WSASocket documentation. This // should be AF_INET or AF_INET6 // // .protocol - Protocol type used to create the socket. Please review // the socket and WSASocket documentation. This should // be IPPROTO_TCP or IPPROTO_UDP // // .targetDataPacketSize // - This is the expected packet size of your data stream. // ***See note below on targetDataPacketSize*** // // .dataRate - Your dataRate in bits/s. // // Note on targetDataPacketSize: // // If you're using a TCP socket on IPv4 and will be making large sends then you // would expect the data packet size to be 1460 bytes: Ethernet has an MTU of // 1500 bytes and that the overhead of an IPv4 header is typically 20 bytes // while a TCP header is also 20 bytes. // // If you're using a UDP socket and your packet size varies, you may wish to // pass in a reasonnable minimal value. This would adjust your rate for the // worst case. // // Return Values: // // This call will return the data rate, in bits/s, reduced by the overhead // on each packet given the address family and the protocol you've created your // socket with. // __inline UINT64 QOS_SUBTRACT_OVERHEAD( __in INT af, __in INT protocol, __in UINT32 targetDataPacketSize, __in UINT64 dataRate ){ UINT32 overhead; double d; UINT64 r; // // Calculate the header overhead overhead = QOS_HEADER_OVERHEAD(af, protocol); // // Convert overhead and dataRate to bits overhead *= 8; targetDataPacketSize *= 8; // // The adjustment is: // // ( dataRate ) // returnRate = dataRate - ( ------------------------------- * overhead ) // ( targetDataPacketSize + overhead ) // // For each packet we expect to see go out, we need to add the // overhead d = (double) overhead; d /= (double) targetDataPacketSize + overhead; d *= (double) dataRate; r = dataRate; r -= (UINT64) d; return r; } // // Description: // // API to initialize QOS subsystem. Every process intending to use // QOS must first make the QOSCreateHandle call. // // The handle returned by this call is useful for performing // overlapped IO. For example, it can be associated with a // IOCP to receive overlapped completion notifications. // // Although a single QOSHandle would be sufficient for most applications, // applications have the option of calling QOSCreateHandle multiple times // to obtain multiple handles // // .Version - Specifies what version of this API you wish to use. // This parameter must be of type QOS_VERSION. For Vista // the only valid value is 1.0 // // .QOSHandle - On output, if the call is successful, this will return // a file handle to the QOS subsystem. This handle should // be closed with QOSCloseHandle. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_SERVICE_DEPENDENCY_FAIL // One of the dependencies of the service is unavailable. The qWave // service could not be started. // // ERROR_RESOURCE_DISABLED // One of the resources required by the service is unavailable. This // error may be returned if the user has not enabled the firewall // exception for the qWave service. Please see the developer guidelines // and MSFT firewall documentation for more details. // ExternC BOOL WINAPI QOSCreateHandle( __in PQOS_VERSION Version, __out PHANDLE QOSHandle ); // // Description: // // API to close a handle returned by QOSCreateHandle // // When closing a handle, all flows added on this handle are immediately // removed from the system. Any traffic going out a socket used to create these // flows will no longer be marked. Moreover, any pending operations for these // flows are completed with ERROR_ABORTED. // // If any clients were tracked through this handle, the subsystem will continue // tracking these for some limited amount of time. This can be stopped by // calling either QOSStopTrackingClient on this handle before closing it or // through another handle once this one has been closed. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. // ExternC BOOL WINAPI QOSCloseHandle( __in HANDLE QOSHandle ); // // Description: // // API to inform the QOS subsystem of the existence of a new client. // The QOS subsystem will start gathering statistics about this client device. // This call is NOT required to add a flow, but it is recommended for adaptive // flows. // // Ideally, an application would make this API call as soon as it is aware of a // possible client device with which it may need to create a QOS flow. By using // this call, you increase the likelihood that qWave will have gathered // sufficient information on the network path to assist you when you attempt to // set the flow rate. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .DestAddr - IP address of the client device. Note that a client // is identified strictly by it's IP address and address // family. A port number is not required and will be // ignored. // // .Flags - Used to modify the behavior of the // QOSStartTrackingClient call. Reserved for future use. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_BAD_NET_NAME // qWave was unable to reach the host specified. Specifically, address // resolution failed. // // ERROR_HOST_UNREACHABLE // The qWave service was unable to communicate with the peer host to // run qWave experiments. This could be a sign that there is no // qWave sink on the remote host or that a firewall is blocking // communication. // // ERROR_NOT_SUPPORTED // The qWave subsystem cannot track information about the destination // you've specified. It could be that the other host does does not // have the required components or that it is not on the same link. // ExternC BOOL WINAPI QOSStartTrackingClient( __in HANDLE QOSHandle, __in PSOCKADDR DestAddr, __reserved DWORD Flags ); // // Description: // // API to remove a client. The QOS subsystem will stop gathering statistics // about this client device. This call will only be accepted if // QOSStartTrackingClient was previously called on the host. If a flow is // currently in progress, this will not affect the flow. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .DestAddr - IP address of the client device // // .Flags - Used to modify the behavior of the // QOSStopTrackingClient call. Reserved for future use. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. // ExternC BOOL WINAPI QOSStopTrackingClient( __in HANDLE QOSHandle, __in PSOCKADDR DestAddr, __reserved DWORD Flags ); // // Description: // // API to enumerate all the existing flows. This call requires administrative // rights. Through it the caller can obtain the list of current flow IDs on the // system. Using QOSQueryFlow, one can then query the flows. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .Size - On input represents the size in bytes of the buffer. // On output, if successful, the amount of bytes copied // in the buffer. If the call fails with // ERROR_INSUFFICIENT_BUFFER, the parameter size will // indicate the minimum required buffer size. // // .Buffer - On output contains an array of QOS_FLOWID. // // Note: // // One cannot modify flows from another process. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_ACCESS_DENIED // The caller does not have the administrator rights required // to perform this call. // ExternC BOOL WINAPI QOSEnumerateFlows( __in HANDLE QOSHandle, __inout PULONG Size, __out_bcount(*Size) PVOID Buffer ); // // Description: // // API to add a new flow. Note that the flow's traffic is not affected through // this call. There are two categories of applications that will use this api: // adaptive and non-adaptive. An adaptive application will make use of // notifications and information in QOS_FLOW_FUNDAMENTALS to adapt to changing // network characteristics (such as congestion). qWAVE utilizes Link Layer // Topology Discovery (LLTD) QoS extensions for adaptive flows, which may be // present on the destination. A non-adaptive application either does not // desire to adapt to changing network characteristics (priority marking and/or // throttling only), or is sending traffic to an endpoint that does not support // this capability as indicated by ERROR_NOT_SUPPORTED. For adaptive // applications, the caller should immediately call QOSSetFlow with the // QOSSetOutgoingRate parameter. Non-adaptive applications or applications // creating non-adaptive flows should call this api with the // QOS_NON_ADAPTIVE_FLOW flag set. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .Socket - The socket the application will use to source traffic. // ***See note below on Socket*** // // .DestAddr - The destination address the application will send // traffic to. A destination port must be specified. // This parameter is optional for connected sockets. See // the note below. // // .TrafficType - Describes the type of traffic your flow will be used // for. This parameter will be ignored when adding a // socket to an existing flow. // // .Flags - Used to modify the behavior of the QOSAddSocketToFlow // call. // ***See note below on Flags*** // // .FlowId - On input *FlowId MUST be 0 to create a new flow. On // output, if the call is successful, a flow ID is // generated and placed in *FlowId. // // If you are adding a socket to an existing flow, // *FlowId will be the flow ID of the existing flow. // ***See note below on Flags*** // // Note on Socket: // // If the app wishes to use a different interface to source its data // than the one favored by the routing table, it should bind its socket // before calling QOSAddSocketToFlow. // // Note on the DestAddr parameter: // // The DestAddr parameter is optional. Since the Qwave api must always // know the destination host (and IP port) to which your traffic will be // sent here are the ramifications: // // 1) If your socket is not connected, you MUST specify this parameter. // 2) If your socket is connected, you do not need to specify this // parameter however, if you do, the destination host and port must // match that use in the socket's connect call. // 3) Since, for TCP, the connect call incurs a delay (dependent on // network conditions and the peer host) you may start qWave experiments // beforehand. You would call QOSAddSocketToFlow passing in the // application's peer IP address and port. // // Note on TrafficType: // // Its worth noting that traffic types, if policy allows, will map to a // protocol level tagging of your traffic. For example, the traffic types // equivalent to DLNA may result in the DSCP markings specified in DLNA // being applied. Whether marking is applied, and if so which value, is // controlled by the policy system. In effect this is a request which may, // or may not, as appropriate for the network infrastructure, be honored. // // Policy may also require that you run through some form of admission // control and bind yourself to a contract. This is useful to prevent // applications from swamping the network. Such admission control will // rely on both your traffic type and the flow rate of your traffic. When // possible, you should specify the flow rate of your application using the // QOSSetFlow call with the QOSSetOutgoingRate operation. // // Note on Flags: // // Only one flag is currently supported for QOSAddSocketToFlow. // // QOS_NON_ADAPTIVE_FLOW - If specified, the QOS subsystem will not gather // data about the network path for this flow. As a // result, APIs which rely on bandwidth estimation // techniques will not be available. For example, // this would block QOSQueryFlow with // QOSQueryFlowFundamentals and QOSNotifyFlow with // QOSNotifyCongested, QOSNotifyUncongested or // QOSNotifyAvailable. // // An application should use this flag if it does // not intent to adapt its flow to changes in the // state of the network be it because of its // scenario, type of network or capabilities of // the receiving host. // // You can only add multiple sockets to the same // flow if the flow is not adaptive. You must also // specify this flag when you call to add a socket // to an existing flow. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_BAD_NET_NAME // qWave was unable to reach the host specified. Specifically, address // resolution failed. // // ERROR_CONNECTION_REFUSED // QOS could not connect to destination device. The remote host // rejected the connection. // // ERROR_HOST_UNREACHABLE // The host is not reachable given the current network configuration. // If the host was previously reachable, you should confirm that there // hasn't been a PnP state change // // ERROR_NOT_SUPPORTED // The qWave subsystem cannot track information about the destination // you've specified. It could be that the other host does does not // have the required components or that it is not on the same link. // ExternC BOOL WINAPI QOSAddSocketToFlow( __in HANDLE QOSHandle, __in SOCKET Socket, __in_opt PSOCKADDR DestAddr, __in QOS_TRAFFIC_TYPE TrafficType, __in_opt DWORD Flags, __inout PQOS_FLOWID FlowId ); // // Description: // // API used by app to notify QOS subsystem that a previously admitted flow has // been terminated by the app. QOS subsystem uses this call to update its // internal information // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .Socket - Socket to be removed from the flow // ***See note below on Socket*** // // .FlowId - The flow which the app is interested in modifying. // This is obtained through QOSAddSocketToFlow. // // .Flags - Used to modify the behavior of the // QOSRemoveSocketFromFlow call. This is currently // reserved for future use. // // Note: // // Closing a QOSHandle will automatically abort all pending operations issued // on that QOSHandle. If the handle is closed while a QOSRemoveSocketFromFlow // call is still in progress, the call will complete with // ERROR_OPERATION_ABORTED. // // Note on Socket: // // Only flows created with the QOS_NON_ADAPTIVE_FLOW flag may have multiple // sockets added to the same flow. By passing a socket parameter in this // api call you can remove each of these individually. // // If you do not pass a socket, the flow will be destroyed. // // If only one socket was attached to the flow, passing this socket as a // parameter to this api and passing NULL as a socket are equivalent calls. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_NOT_FOUND // Invalid FlowId specified // ExternC BOOL WINAPI QOSRemoveSocketFromFlow( __in HANDLE QOSHandle, __in_opt SOCKET Socket, __in QOS_FLOWID FlowId, __reserved DWORD Flags ); // // Description: // // This API is used by the app to inform the QOS subsystem of change in a flow. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .FlowId - The flow which the app is interested in modifying // This is obtained through QOSAddSocketToFlow. // // .Operation - What modification on the flow you are trying to // apply. This must be of the type QOS_SET_FLOW. The // input parameter should match the requested flow // information. // ***See note below on Operation*** // // .Size - The length, in bytes, of Buffer. You should specify // the correct buffer length for the structure you // specify in Buffer. // ***See note below on Operation*** // // .Buffer - Pointer to the buffer to describe the modication. // ***See note below on Operation*** // // .Flags - Used to modify the behavior of the QOSSetFlow call. // This is currently reserved for future use. // // .Overlapped - Pointer to an OVERLAPPED structure. // // Note on Operation: // // Given the input parameter for operation, the content of the buffer passed in // will differ. Here is the mapping: // // QOSSetTrafficType - QOS_TRAFFIC_TYPE // QOSSetOutgoingRate - QOS_FLOWRATE_OUTGOING // QOSSetOutgoingDSCPValue - DWORD // // Specific to QOS_FLOWRATE_OUTGOING structure: // // Bandwidth is defined as number of bits per second. It should include // Layer 3 overhead (e.g. IPv4 header, UDP, etc.). You may want to use the // macro QOS_ADD_OVERHEAD to help you estimate the overhead. // // Using Bandwidth == 0 disables shaping and stops affecting the flow (e.g. // the traffic is not marked anymore). MinPacketSize will be ignored. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_ACCESS_DISABLED_BY_POLICY // The QOS subsystem is currently configured by policy to not allow // this operation on the network path between this host and // your destination host. // // ERROR_BUSY // Indicates that the QOS subsystem has not had enough CPU cycles to // estimate the network characteristics of the path. // // ERROR_IO_PENDING // Indicates that update flow request was successfully initiated // (results will be returned during overlapped completion) // // ERROR_NETWORK_BUSY // Indicates that the requested flow properties were not available // on this path. The network currently cannot support the // characteristics you requested // // ERROR_NOT_FOUND // Invalid FlowId specified // // ERROR_NOT_SUPPORTED // The operation you're trying to do requires information about the // network which the qWave subsystem does not have. Obtaining this // information on your network is currently not supported. // // ERROR_RETRY // There is currently insufficient data about networking conditions // to answer your query. This is typically a transient state where // qWave has erred on the side of caution as it waits for more data // before ascertaining the state of the network. // // ERROR_ACCESS_DENIED // The caller does not have the administrator rights required // to perform this call. // ExternC BOOL WINAPI QOSSetFlow( __in HANDLE QOSHandle, __in QOS_FLOWID FlowId, __in QOS_SET_FLOW Operation, __in ULONG Size, __in_bcount(Size) PVOID Buffer, __reserved DWORD Flags, __out_opt LPOVERLAPPED Overlapped ); // // Description: // // API to query information about a flow. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .FlowId - The flow which the app is interested in receiving // information about. This is obtained through // QOSAddSocketToFlow. // // .Operation - What information about the flow you are trying to // obtain. This must be of the type QOS_QUERY_FLOW. The // input parameter should match the requested flow // information. // ***See note below on Operation*** // // .Size - The length, in bytes, of Buffer. If the buffer // specified is too small, the call will fail with error // ERROR_INSUFFICIENT_BUFFER and this parameter will // be updated the appropriate buffer size. // ***See note below on Operation*** // // .Buffer - Pointer to the buffer to receive the queried data. // ***See note below on Operation*** // // .Flags - Used to modify the behavior of the QOSQueryFlow call. // ***See note below on Flags*** // // .Overlapped - Pointer to an OVERLAPPED structure. // // Note on Operation: // // Given the input parameter for operation, the buffer passed in will differ. // Here is the mapping. // // QOSQueryFlowFundamentals - QOS_FLOW_FUNDAMENTALS // // QOSQueryPacketPriority - QOS_PACKET_PRIORITY // // This structure will return the actual // priority markings applied to your traffic // by the QOS subsystem given your asks and // the policy subsystem. // // QOSQueryOutgoingRate - UINT64 // // Note on Flags: // // Only one flag is currently supported for QOSQueryFlow. // // QOS_QUERYFLOW_FRESH - If specified, the QOS subsystem will only return // once fresh data is available. If fresh data is // unavailable, it will try to obtain such data. // If this is not possible, the call will fail // with ERROR_RETRY. // // This flag is only valid for // QOSQueryFlowFundamentals. // Note, this parameter is ignored if the caller is // not the owner of the flow. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_ACCESS_DISABLED_BY_POLICY // The QOS subsystem is currently configured by policy to not allow // this operation on the network path between this host and // your destination host. // // ERROR_BUSY // Indicates that the QOS subsystem has not had enough CPU cycles to // estimate the network characteristics of the path. // // ERROR_HOST_UNREACHABLE // The host is not reachable given the current network configuration. // If the host was previously reachable, you should confirm that there // hasn't been a PnP state change // // ERROR_INSUFFICIENT_BUFFER // The buffer length, as specified through Size, is not sufficient // for the queried data. Size now contains the required size. // // ERROR_IO_PENDING // Indicates that update flow request was successfully initiated // (results will be returned during overlapped completion) // // ERROR_NOT_FOUND // Invalid FlowId specified // // ERROR_NOT_SUPPORTED // The operation you're trying to do requires information about the // network which the qWave subsystem does not have. Obtaining this // information on your network is currently not supported. // // ERROR_RETRY // There is currently insufficient data about networking conditions // to answer your query. This is typically a transient state where // qWave has erred on the side of caution as it waits for more data // before ascertaining the state of the network. // ExternC BOOL WINAPI QOSQueryFlow( __in HANDLE QOSHandle, __in QOS_FLOWID FlowId, __in QOS_QUERY_FLOW Operation, __inout PULONG Size, __out_bcount(*Size) PVOID Buffer, __in_opt DWORD Flags, __out_opt LPOVERLAPPED Overlapped ); // // Description: // // API to receive notification of change of network characteristics. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .FlowId - The flow which the app is interested in receiving // notifications on changes. This is obtained through // QOSAddSocketToFlow. // // .Operation - What notification about the flow you are trying to // obtain. This must be of the type QOS_NOTIFY_FLOW. The // input parameter should match the requested flow // information. // // .Size - The length, in bytes, of Buffer. You should specify // the correct buffer length for the structure you // specify in Buffer. // ***See note below on Operation*** // // .Buffer - Pointer to the buffer to receive the queried data. // ***See note below on Operation*** // // .Flags - Used to modify the behavior of the QOSNotifyFlow call. // This is currently reserved for future use. // // .Overlapped - Pointer to an OVERLAPPED structure. // // // Note on Operation: // // The following notification may be supported. // // 1) QOSNotifyCongested // // QOSNotifyCongested will complete the operation when the network path // is congested. If the path is presently congested, the operation may // complete immediately. // // NOTE: The optional parameters Size and Buffer must be NULL. // // 2) QOSNotifyUncongested // // QOSNotifyUncongested will complete the operation when the network path // is not congested. If the path is not presently congested, the operation // may complete immediately. // // NOTE: The optional parameters Size and Buffer must be NULL. // // 2) QOSNotifyAvailable // // QOSNotifyAvailable will complete when available capacity is sufficient // to allow an existing flow to be upgraded from its currently admitted // bandwidth to the specified bandwidth. This should be used to upgrade a // transrated flow back to full bandwidth. // Requested bandwidth should include Layer 3 overhead. Please use the // QOS_ADD_OVERHEAD function inlined in this header file as a starting // point for your calculations. // // The Buffer parameter should point to a UINT64 value with the requested // bandwidth. This value should be the target bandwidth of the flow. // For example, if your flow is using 3 Mb but you want to increase that // by 2 Mb, the parameter Buffer should point to a UINT64 with the value // 5 Mb. // // UINT64 Requested bandwidth // // The call will fail if the requested bandwidth is less than or equal // to the bandwidth the flow is already using. // // Return Values: // // If the function succeeds, the return value is nonzero. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. Here are some of the errors possible. // This list is not exhaustive. // // ERROR_ACCESS_DISABLED_BY_POLICY // The QOS subsystem is currently configured by policy to not allow // this operation on the network path between this host and // your destination host. // // ERROR_ALREADY_EXISTS // There is already a request for notification of the same type pending // on this flow. // // ERROR_HOST_UNREACHABLE // The host is not reachable given the current network configuration. // If the host was previously reachable, you should confirm that there // hasn't been a PnP state change // // ERROR_IO_PENDING // Indicates that update flow request was successfully initiated // (results will be returned during overlapped completion) // // ERROR_NOT_FOUND // Invalid FlowId specified // // ERROR_NOT_SUPPORTED // The operation you're trying to do requires information about the // network which the qWave subsystem does not have. Obtaining this // information on your network is currently not supported. // ExternC BOOL WINAPI QOSNotifyFlow( __in HANDLE QOSHandle, __in QOS_FLOWID FlowId, __in QOS_NOTIFY_FLOW Operation, __inout_opt PULONG Size, __inout_bcount_opt(*Size) PVOID Buffer, __reserved DWORD Flags, __out_opt LPOVERLAPPED Overlapped ); // // Description: // // API to cancel a pending operation like QOSSetFlow. // // Closing a QOSHandle will automatically abort all pending // operations issued on that QOSHandle. If the handle is closed while // a QOSCancel call is still in progress, the call will complete // with ERROR_OPERATION_ABORTED. // // Arguments: // // .QOSHandle - Handle to the QOS subsystem obtained through // QOSCreateHandle. // // .Overlapped - Pointer to an OVERLAPPED structure. This is the // OVERLAPPED structure used in the original operation. // // Note: // // The QOSCancel call must be made in the same process from // which the original to-be-cancelled call was made. // // Return Values: // // If the function can successfully initiate cancellation of the specified // operation, the return value is nonzero. The cancelled operation completes // via its completion mechanism and indicates ERROR_OPERATION_ABORTED as the // completion code. // // If the function fails, the return value is zero. To get extended error // information, call GetLastError. // ExternC BOOL WINAPI QOSCancel( __in HANDLE QOSHandle, __in LPOVERLAPPED Overlapped );