Figure 1

Figure 1 Creating a QoS Socket
// Create a QoS Socket. The only socket types allowed are SOCK_STREAM and 
// SOCK_DGRAM.
//
// Required for creating QoS TCP connecting socket and listening socket.  
// A socket handle returned from accept call is automatically created 
// from RSVPSP if the listening socket is a QoS socket.
// 
// Required for creating QoS UDP socket.
// 
SOCKET OpenQoSSocket(INT iSocketType)
{
    DWORD bufferSize = 0;
    DWORD numProtocols, i;
    LPWSAPROTOCOL_INFO installedProtocols, qosProtocol; 
    SOCKET fd;
    
    //
    // Call WSAEnumProtocols to determine buffer size required
    //
    numProtocols = WSAEnumProtocols(NULL, NULL, &bufferSize);
    if((numProtocols != SOCKET_ERROR) && (WSAGetLastError() != 
        WSAENOBUFS)){
        DisplayError ( "WSAEnumProtocols Failed", WSAGetLastError() ); 
        return(INVALID_SOCKET);
    } else {
        //
        // Allocate a buffer to hold the list of protocol info structures
        //
        installedProtocols = (LPWSAPROTOCOL_INFO)malloc(bufferSize);
   
        //
        // Enumerate the protocols, find the QoS enabled one
        //
        numProtocols = WSAEnumProtocols(NULL,
                                        installedProtocols,
                                        &bufferSize);
        if(numProtocols == SOCKET_ERROR){
            DisplayError ( "WSAEnumProtocols Failed", WSAGetLastError() 
                         ); 
            return(INVALID_SOCKET);
        } 
        else 
        {
            qosProtocol = installedProtocols;

            for(i=0 ; i< numProtocols ; qosProtocol++, i++)
            {
                if  ((qosProtocol->dwServiceFlags1 & XP1_QOS_SUPPORTED) 
                    && (qosProtocol->iSocketType    == iSocketType) &&
                    (qosProtocol->iAddressFamily == AF_INET))
                {
                    break;
                }              
            }
        }
    
        //
        // Now open the socket.
        //
        fd = WSASocket(0, 
                       iSocketType, 
                       0, 
                       qosProtocol,          // Use the RSVPSP we found
                       0, 
                       WSA_FLAG_OVERLAPPED); // *MUST* be overlapped!
    
        //
        // De-allocate protocol info buffer
        //
        free(installedProtocols);

        return(fd);
    }        
}
Figure 2 PATH Parameters
Parameter
Description
Derived from the Following Winsock Parameter
SenderTspec
QOS parameters of sent traffic
SendingFlowspec
SenderTemplate
Sender's address
Source IP address and port that sending socket is bound to
Session
Destination of sent traffic
Destination IP address, port, and protocol ID that socket is sending to (sockaddr_in)
Figure 3 RESV Parameters
RESV Parameter
Description
Derived from the Following Winsock Parameter
Flowspec
QOS parameters of traffic to be received
ReceivingFlowspec
Filterspec
Sources from which QOS traffic will be received
Addresses of senders from which this socket is receiving
Session
Destination of sent traffic
Local IP address and port to which the receiving socket is bound (unicast session), or multicast session address on which the socket is a leaf (multicast)
Figure 4 Predefined QOS Templates
Template
g711
g723.1
g729
H263QCIF
H263CIF
H261QCIF
H261CIF
GSM6.10
Service type
GU
GU
GU
CTL
CTL
CTL
CTL
GU
Token rate
9250
2200
2000
12000
16000
12000
16000
2150
Bucket size
680
136
80
6000
8192
6000
8192
172
Peak bandwidth
13875
3300
4000
QNS
QNS
QNS
QNS
4300
Maximum SDU
340
68
40
2500
8192
2500
8192
86
Minimum policed size
340
68
40
80
80
80
80
86
Latency
QNS
QNS
QNS
QNS
QNS
QNS
QNS
QNS
* GU = SERVICETYPE_GUARANTEED
QNS = QOS_NOT_SPECIFIED
CTL = SERVICETYPE_CONTROLLEDLOAD
the unit of data is bytes
Figure 5 FD_QOS Status Codes
FD_QOS Status
Could Occur on Sender
Could Occur on Receiver
RSVP Messages Arrived
WSA_QOS_RECEIVERS
Yes
No
First RESV or change in RESV
WSA_QOS_SENDERS
No
Yes
First PATH or change in PATH
WSA_QOS_NO_SENDERS
No
Yes
Last sender's PATH_TEAR
WSA_QOS_NO_RECEIVERS
Yes
No
Last receiver's RESV_TEAR
WSA_QOS_REQUEST_CONFIRMED
No
Yes
RESV_CONFIRM
WSA_QOS_ADMISSION_FAILURE
Yes
Yes
RESV_ERR
WSA_QOS_POLICY_FAILURE
Yes
Yes
RESV_ERR or PATH_ERR
WSA_QOS_BAD_STYLE
No
Yes
RESV_ERR
WSA_QOS_BAD_OBJECT
Yes
Yes
NA
WSA_QOS_TRAFFIC_CTRL_ERROR
Yes
No
RESV-ERR
WSA_QOS_GENERIC_ERROR
Yes
Yes
NA
WSA_QOS_ESERVICETYPE
Yes
Yes
NA
WSA_QOS_EFLOWSPEC
Yes
Yes
NA
WSA_QOS_EPROVSPECBUF
Yes
Yes
NA
WSA_QOS_EFILTERSTYLE
No
Yes
NA
WSA_QOS_EFILTERTYPE
No
Yes
NA
WSA_QOS_EFILTERCOUNT
No
Yes
NA
WSA_QOS_EOBJLENGTH
Yes
Yes
NA
WSA_QOS_EFLOWCOUNT
Yes
Yes
NA
WSA_QOS_EUNKOWNPSOBJ
Yes
Yes
NA
WSA_QOS_EPOLICYOBJ
Yes
Yes
NA
WSA_QOS_EFLOWDESC
Yes
Yes
NA
WSA_QOS_EPSFLOWSPEC
Yes
Yes
NA
WSA_QOS_ESDMODEOBJ
Yes
No
NA
WSA_QOS_ESHAPERATEOBJ
Yes
No
NA
WSA_QOS_RESERVED_PETYPE
Yes
Yes
NA
Figure 6 FD_QOS Notifications

WSAAsyncSelect (msgWnd) The msgWnd message is dispatched by the Window message pump, and the HIWORD(lParam) of the message has a FD_QOS bit set. The application then needs to call WSAIoctl (SIO_GET_QOS) to receive a QOS structure containing an RSVP_STATUS_INFO object (in the ProviderSpecific buffer) whose StatusCode field indicates the event that triggers the FD_QOS notification. Alternatively, the status code is also carried in WSAGETSELECTERROR(lParam) of the msg.

WSAEventSelect (hevent) The hevent is signaled, and WSAEnumNetworkEvents indicates that the NetworkEvents.lNetworkEvents field has a FD_QOS bit set. The application then needs to call WSAIoctl(SIO_GET_QOS) to receive a QOS structure containing an RSVP_STATUS_INFO object (in the ProviderSpecific buffer) whose StatusCode field indicates the condition that triggers the FD_QOS notification. Alternatively, the status code is also carried in NetworkEvents.iErrorCode(FD_QOS_BIT).

Overlapped WSAIoctl (SIO_GET_QOS) with APC completion routine Completion routine is called after the thread is in an alterable wait state. The buffer provided in the original overlapped WSAIoctl(SIO_GET_QOS) is filled with the QOS structure. The status of the FD_QOS notification can be found from the RSVP_STATUS_INFO object (in the ProviderSpecific buffer) of the QOS structure. Alternatively, the status code is also indicated in the dwError parameter of the completion routine.

Overlapped WSAIoctl (SIO_GET_QOS) with hevent The hevent is signaled or WSAGetOverlappedResult indicates the completion of the overlapped call. The buffer provided in the original overlapped WSAIoctl(SIO_GET_QOS) is filled with the QOS structure. The status of the FD_QOS notification can be found from the RSVP_STATUS_INFO object (in the ProviderSpecificBuffer) of the QOS structure.

Overlapped WSAIoctl (SIO_GET_QOS) with the socket handle added to an I/O completion port The overlapped structure should be padded with an extra field to identify the particular overlapped SIO_GET_QOS request. When GetQueuedCompletionStatus is returned, the returned overlapped structure can identify if it's a completion for the overlapped SIO_GET_QOS request by examining this extended field. The buffer provided in the original overlapped WSAIoctl(SIO_GET_QOS) is filled with the QOS structure. The status of the FD_QOS notification can be found from the RSVP_STATUS_INFO object in the QOS structure. Figure 8 Mapping Service Type to Traffic Control Parameters
Service Type
SD Mode
DSCP Hex Value*
802.1p**
SERVICETYPE_NETWORK_CONTROL
Borrow
30 (6)
7
SERVICETYPE_GUARANTEED
Shape
28 (5)
5
SERVICETYPE_CONTROLLEDLOAD
Borrow
18 (3)
3
SERVICETYPE_QUALITATIVE
Borrow
0 (0)
0
SERVICETYPE_BESTEFFORT
Borrow
0 (0)
0
Non-conforming (packets failed in conformance check)
Borrow
0 (0)
1
*equivalent IP precedence value is listed in parentheses
**marked only if NIC support 802.1p
Figure 9 Effects of a Low TokenRate
SD Mode
Effect
Borrow Mode
Priority of much of the application's traffic will be reduced to best effort and they may also be reduced by telecom provider's network that can change the packet's priority based on their policy
Shape Mode
Application's traffic will back-up in Shaper, consuming valuable memory resources and causing traffic submitted to the network to become progressively more stale
Discard Mode
Much of the application's traffic will be discarded
Figure 10 Effects of a Small TokenBucketSize
SD Mode
Effect
Borrow Mode
Priority of much of the application's traffic will be reduced to best effort and possibly in the external network
Shape Mode
Application's traffic will be smoothed in the Shaper. Bursts limited to the TokenBucketSize will be delivered to the network at a rate limited by the TokenRate. Traffic submitted to the network may be smoothed further, depending on the PeakBandwidth associated with the flow and the PipeMtuSize (see the subsequent section on the effect of the PeakBandwidth parameter)
Discard Mode
Much of the application's traffic will be discarded
Figure 11 Commonly Used Provider-specific Object Types

QOS_OBJECT_DESTADDR The corresponding structure for this object type is QOS_DESTADDR. As mentioned earlier, this object is used on an unconnected UDP socket to specify the destination address. On an unconnected UDP socket, a QOS_DESTADDR object is required in a QOS structure to call WSAIoctl(SIO_SET_QOS) to emit a PATH message

QOS_OBJECT_SD_MODE The corresponding structure is QOS_SD_MODE. The QOS_SD_MODE object can be specified in a QOS structure to request the BORROW, SHAPE, or DISCARD behavior in the QoS PS for the nonconformant portion of the traffic

RSVP_OBJECT_STATUS_INFO The corresponding structure is RSVP_STATUS_INFO. The RSVP_STATUS_INFO object is returned in the QOS structure with a WSAIoctl(SIO_GET_QOS) call. It allows senders or receivers to find out the RSVP signaling status and extended provider-specific errors

RSVP_OBJECT_ADSPEC The corresponding structure is RSVP_ADSPEC. Only receivers can retrieve an RSVP_ADSPEC object from the QOS structure returned in WSAIoctl(SIO_GET_QOS) when PATH messages arrive

RSVP_OBJECT_RESERVE_INFO The corresponding structure is RSVP_RESERVE_INFO. Receivers can use this object to request RESV confirmation, and also change the default reservation styles. Senders can use this object to supply Policy data objects such as Application ID Figure 12 Setting a QOS_DESTADDR Object
QOS_DESTADDR QosDestaddr;
    QOS *pQos;
      
pQoS = (QOS *) malloc (2048); //Need sufficiently large contiguous buffer
      
//fill the FLOWSPEC…

ZeroMemory((char *)&QosDestaddr, sizeof(QosDestaddr));
QosDestaddr.ObjectHdr.ObjectType   = QOS_OBJECT_DESTADDR;
QosDestaddr.ObjectHdr.ObjectLength = sizeof(QosDestaddr);
QosDestaddr.SocketAddress = (SOCKADDR *)&g_destaddr;
QosDestaddr.SocketAddressLength = sizeof(g_destaddr);

pQos->ProviderSpecific.len = sizeof( QosDestaddr ) ;
pQos->ProviderSpecific.buf =  (char *)pQos + sizeof( *pQos );
    
CopyMemory( pQos->ProviderSpecific.buf, &QosDestaddr,
           sizeof( QosDestaddr ) );
Figure 13 Setting an RSVP_RESERVE_INFO Object
RSVP_RESERVE_INFORsvpResv;
QOS*pQos;

pQoS=(QOS*)malloc(2048);//Needsufficientlylargecontiguousbuffer

//filltheFLOWSPEC…

ZeroMemory((char*)&RsvpResv,sizeof(RsvpResv));
RsvpResv.ObjectHdr.ObjectType=RSVP_OBJECT_RESERVE_INFO;
RsvpResv.ObjectHdr.ObjectLength=sizeof(RsvpResv);
RsvpResv.Style=RSVP_DEFAULT_STYLE;
RsvpResv.ConfirmRequest=1;
RsvpResv.PolicyElementList=NULL;
RsvpResv.NumFlowDesc=0;
RsvpResv.FlowDescList=NULL;

pQos->ProviderSpecific.len=RsvpResv.ObjectHdr.ObjectLength;
pQos->ProviderSpecific.buf=(char*)pQos+sizeof(*pQos);

CopyMemory(pQos->ProviderSpecific.buf,&RsvpResv,sizeof(RsvpResv));