xpmgr/BuildTools/Include/qos2.h

1280 lines
48 KiB
C

/*++
Copyright (c) 2004 Microsoft Corporation
Module Name:
qos2.h
Abstract:
This module contains QOS structures and function headers
--*/
#pragma once
#include <ws2tcpip.h>
#include <mstcpip.h>
//
// 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
);