Last week I added QOS2 calls to a sample Winsock application to obtain DSCP marking. The second request we get from developers is to shape their outgoing traffic, i.e. limit the rate at which their traffic is sent. With Vista you configure this on your QOS2 flow using the QOSSetFlow function. The API is documented both on MSDN and in the header file qos2.h header file. Today, I'll write a bit about it.

 

When shaping traffic, it's important to first discuss some terminology. On Vista, the component that schedules your packet to a specific rate is named PACER. By using QOS2, you're telling PACER that you want to shape your socket's traffic. It will intercept every send you do on this special socket. For each outgoing packet it sees, PACER will determine whether this packet is conformant or non conformant. A packet is conformant if, should it go out right now, the rate of data sent on the flow would not exceed the requested flow rate. A packet is nonconformant if this limit would be broken. To shape traffic is to delay nonconformant packets until they become conformant.

 

With that out of the way, here's the function prototype for QOSSetFlow:

 

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

);

 

This function allows you to change the properties of the QOS2 flow you created with QOSAddSocketToFlow. The Operation parameter will either be QOSSetTrafficType or QOSSetOutgoingRate. If you were to set the outgoing rate, the Buffer parameter would be a QOS_FLOWRATE_OUTGOING structure.

 

typedef struct _QOS_FLOWRATE_OUTGOING

{

UINT64              Bandwidth;

QOS_SHAPING         ShapingBehavior;

QOS_FLOWRATE_REASON Reason;

} QOS_FLOWRATE_OUTGOING, *PQOS_FLOWRATE_OUTGOING;

 

We'll skip the Reason field for now and instead talk about the Bandwidth and the ShapingBehavior fields.

 

Bandwidth

this is the total layer 3 rate in bits/second that you want to shape your traffic to. It is the application's responsibility to include the overhead of IPv4 or IPv6 headers and UDP or TCP headers to its traffic.

 

ShapingBehavior

There are 3 ways to shape your traffic: QOSShapeOnly, QOSShapeAndMark and QOSUseNonConformantMarkings. QOSShapeOnly will shape without marking: if you use this shaping option, your traffic will be shaped but you will lose the DSCP marking. In contrast, QOSShapeAndMark shapes and maintains your DSCP marking. QOSUseNonConformantMarkings does not shape: it will never delay nonconformant traffic. However, only the conformant packets will get the special DSCP mark. The others will get 0, Best Effort.

 

Once you've created a QOS2 flow, to shape your outgoing traffic, call QOSSetFlow with these parameters before doing your Winsock sends.

 

- Mathias Jourdain