A Quality of Service API Proposal

Bob Riddle and Andy Adamson

 

Abstract

This paper describes an interface that would permit application developers to communicate QoS requirements to an Internet2 network. This interface relies on the existence of both the Bandwidth Broker and PBDS aware edge nodes described in "Differentiated Services for Internet2". We will describe a set of API's that can take advantage of existing interfaces and signaling protocols without being dependent upon any specific implementation.

1. Why another QoS API?

QoS is an end to end proposition with many evolving mechanisms and proposals at each step of the way. A host API abstraction allows the underlying implementation to change without effecting the communication of host QoS requests to other developing components of the Internet2 QoS infrastructure.

One might suggest that there already exists sufficient support to convey QoS requests from the application to the network. Many of these mechanisms are either viewed as proprietary (WinSock2) or make assumptions about the "brand" of network equipment deployed. The current mechanisms also require a high degree of specialized knowledge about the underlying network implementation, requiring the application developer to be something of a network engineer.

While it is prudent to suspect that early implementations of QoS applications will leverage current functionality, such as RSVP and WINSOCK, it seems likely that other signaling protocols and platform support will emerge upon which the QoS application will reside. Thus, an abstraction that permits the application developer to describe the QoS requirements in a way that is independent of the underlying implementation would permit the re-hosting of the application without the necessity of additional application development.

2. What must a QoS API provide?

For such an interface to be useful, it must provide (at a minimum) the following capabilities:

3. Existing QoS API's

It is worth looking briefly at some existing technology before describing another API. Both the RAPI (RSVP API) and the WinSock2 interface provide examples of the minimum (or maximum!) requirements necessary to provide application support for QoS.

RAPI:

RAPI is a library that is linked with the application program. It is relies on RSVP as the signaling protocol and much of the interface reveals its affinity for RSVP. It exports four (4) interfaces to the developer:

rapi_session: sets up a session for " sending and receiving a simplex
data flow and/or receiving such a data flow ". This function is called after
the application establishes a connection with a remote service. The most
interesting parameters are the destination address and the event notification
routine address.

rapi_release: closes the session established by rapi_session and releases
all associated resource reservations.

rapi_send: "an application must issue a rapi_sender call if it intends to send
a flow of data for which receivers may make reservations." Probably the most
interesting data passed is the Tspec (Traffic Spec), although you can also deliver
a structure containing policy data.

rapi_reserve: "the rapi_reserve procedure is called to make, modify, or delete
a resource reservation for a session." The most interesting data elements are the
FlowSpec and the FilterSpec.

So the interaction of a client requesting to reserve bandwidth for reception of data from a server might look something like this:

Client >>>-------- rapi_session --------->>> Server (RSVP PATH?)

(multiple occurrences of the following can occur)

Client <<<---------- rapi_send ----------<<< Server (RSVP RESV?)

Client >>>-------- rapi_reserve --------->>> Server (RSVP PATH?)

(either client or server)

Client >>>-------- rapi_release ---------->>> Server (RSVP Path_Tear/RESV_Tear?)

WinSock2:

WinSock2 is the Windows Socket programming interface. It is modeled after the Berkley sockets implementation and available through a number of vendors. It is the API that Microsoft provides with both Windows 95 and Windows/NT. This API provides QoS extensions that like RAPI are intended to take advantage of an underlying RSVP-like capability. The specification claims "Winsock2 specifies a generic QoS interface that is independent of the underlying QoS service provider (e.g., RSVP, ATM, ST2, etc.) and is useful for writing applications that do not depend on particular QoS features of the underlying service provider". It is the layer upon which Intel has implemented its beta version of RAPI.

There are "convenience" API's as well as IOCTL interfaces the developer can exploit. The convenience routines include:

WSAConnect: Allows the programmer to establish the flowspecs
at connection time. These specs may be renegotiated using the
WSAIoctl call.

WSAGetQoSByName: "initializes a QoS structure based on a
named template, or retrieves an enumeration of the available
template names."

RSVP QoS directives may be passed via the WSAIoctl interface. The following is from the Windows Sockets 2 Protocol Specific-Annex document:

RSVP_REGISTER: An RSVP sender or receiver must register with
RSVP to create a RSVP session before it can make any QoS-related
requests for the session. As part of the call, an application must
indicate whether it wishes to be a sender or a receiver or both.

RSVP_SENDER: A sender uses the call to specify its traffic specifications
(Tspec). The sender of a data flow is identified by its source address (IP
address and port number binding in its data socket) and must be specified
as a parameter. Other optional parameters include a policy object and an
IP TTL (Time To Live) scope for the data packets.

RSVP_RESERVE: A receiver initiates resource reservation(s) using this
call … an optional parameter includes a policy object.

RSVP_REL_RECEIVER: A receiver uses this call to tear down one or more
reservations for the session.

RSVP_RETRIEVE: An application makes this call when it receives a FD_QoS
event notification. FD_QoS event is signaled when events such as receipt of new
traffic specifications, errors in reservation, or changes in installed flow specifications have occurred.

RSVP_QUERY_ QoS: The call is used to retrieve flow specifications (i.e.,
Tspecs and Rspecs) for one or more current senders in a session.

4. Possible Approaches

If the target signaling protocol is RSVP and the target platforms are Wintel machines, one can construct QoS aware applications using either the native WinSock2 or RAPI support that is currently available. While many find the notion of developing a QoS application (or any application!) on Microsoft based platforms distasteful, this platform is well positioned to begin exploring QoS applications.

Another possibility is to take the RAPI specification and implement a library that is easily ported to a variety of Unix-like operating systems. If Intel could be engaged in a cooperative fashion and code sharing was possible, this might be accomplished with a minimum of development effort.

Another approach would be to synthesize a new API. Such an API could be layered on top of existing support such as RAPI or WinSock2. It could also be indifferent to the eccentricities of the underlying signaling mechanism, trusting the API library to deal with such things. It could also present a much simpler interface to the developer. It could also take advantage of the utility of the proposed Bandwidth Broker.

5. Proposal for a QoS API

The following functions attempt to describe the basic functions required for a QoS aware application. Certain assumptions are made concerning the role and capability of the Bandwidth Broker. No assumptions are made about the underlying implementation, specific protocols, or network configurations.

QoS_Authenticate(Credential, Security_Server) returns QoS_Authenticator

This function, given a legitimate local security credential, will provide a QoS_Authenticator that may be used for authorization decisions by the BB. The acquired credential could also be used in evaluating other resource allocation requests related to QoS.

Credential: this is opaque to the application, a variable length string/structure dependent upon the local authentication service. It could be a kerberos ticket, a X.509 certificate, or some other token that is well known with the local domain.

Security_Server: is the local security service for the domain. For services with the necessary intelligence (Kerberos uses a local configuration file) this could be NULL.

QoS_Authenticator: this is opaque to the application. It could contain a variety of information that is useful for authorization decisions, audit trails, as well as encryption keys for providing secure connections.

QoS_FindProfile(Profile_Name, Profile_Server, QoS_Authenticator) returnsProfile

This function relieves the developer of having to craft a QoS profile for the application. It is envisioned that the knowledgeable QoS experts will create a series of useful profiles (H.323, G.711, TV-Video, AM-Radio, etc.) that will describe the necessary parameters needed to support the QoS signaling. Rather than having a static set of parameters wired into the program, it is more desirable to have profiles that could be easily shared, dynamically altered, and network accessible. Of course, a local (non-network) implementation of this function is possible.

Profile_Name: a string that names the desired profile. A clever name could also reveal something about the attributes of the profile (Video_RSVP instead of just VIDEO). This function might also accept wildcard names (VIDE*) and return an enumerated list of matching profiles.

Profile_Server: could this be the Bandwidth Broker? The underlying library could use LDAP to query a Directory Server. For underlying services with the necessary intelligence it is possible that this could be NULL. One could also imagine a "global" QoS profile server that could be shared among many domains.

QoS_Authenticator: this is opaque to the application. For domains with no interest in user based authorization, this could be NULL.

Profile: there is no reason why this should not be opaque to the developer (or at least many developers). For RSVP based QoS services, this would contain things like the Tspec, Adspec, Flowspec, Filterspec, etc.

QoS_Bind(Destination, Profile, Role,Handler, Source, QoS_Authenticator) returnsQoS_SID

This function creates and binds the application to a QoS session. The underlying implementation will take care of all necessary network communication with the Bandwidth Broker and/or the edge node Router. For an application acting as a RSVP "sender", QoS_Bind would be responsible for sending the Tspec, Adspec, etc. to the network {BB? Leaf/Edge node???}. For an application acting as a RSVP "receiver" QoS_Bind would be responsible for making the reservation request to the network (either to the Bandwidth Broker or to the leaf/edge node router).

Destination: a structure that describes the receiving endpoint. This would include some form of the IP address, port number, and protocol type.

Source: a structure that describes the sending endpoint. This would include some form of the IP address, port number, and protocol type. Unless the host is multi-homed, a NULL value would indicate that the localhost address could be used.

Profile: result returned from QoS_FindProfile

Role: possible values are Talk, Listen, and Converse. Talk corresponds to the RSVP notion of a sender, while Listen would relate to the RSVP definition of a receiver. Converse indicates that the application would like to have QoS attributes assigned to both inbound and outbound messages.

Handler: the location of a routine that is capable of handling asynchronous notification events related to the QoS session.

QoS_Authenticator: this is opaque to the application. For domains with no interest in user based authorization, this could be NULL.

QoS_SID: a structure that contains a unique QoS session identifier that is required by other QoS functions. This structure also contains the transformed results of the Profile parameters.

QoS_Rebind(QoS_SID, Profile, Role,QoS_Authenticator)

This function allows the application to change the QoS specifications set originally by the QoS_Bind.

QoS_SID: a structure that contains a unique QoS session identifier that is required by other QoS functions. This structure also contains the transformed results of the Profile parameters.

Profile: result returned from QoS_FindProfile.

Role: possible values are Talk, Listen, and Converse. Talk corresponds to the RSVP notion of a sender, while Listen would relate to the RSVP definition of a receiver. Converse indicates that the application would like to have QoS attributes assigned to both inbound and outbound messages.

QoS_Authenticator: this is opaque to the application. For domains with no interest in user based authorization, this could be NULL.

QoS_Unbind(QoS_SID, QoS_Authenticator)

This function tears down the QoS session and releases all acquire QoS resources.

QoS_SID: a structure that contains a unique QoS session identifier that is required by other QoS functions. This structure also contains the transformed results of the Profile parameters.

QoS_Authenticator: this is opaque to the application. For domains with no interest in user based authorization, this could be NULL.

6. Architecture

The following diagram shows the placement in the architecture of the proposed QOS_API. The QOS_API calls are instantiated in XXX_QOS libs. There are two sets of external libraries that the XXX_QOS libraries abstract, and therefore need to bind to. The RSVP libraries and the Authentication libraries.

 ---------------------------------------------------------------- ----------
 | Application |
 | QOS_API calls |
 ---------------------------------------------------------------- ----------
 | Kerberos_Rapi_QOS.lib | SSL_Winsock_QOS.dll | XXX_QOS.lib |
 ---------------------------------------------------------------- ----------
 | rapi.lib | Kerberos libs | Winsock ioctl's | SSL.lib | ...... |
 ---------------------------------------------------------------- ----------
 | Operating System |
 ---------------------------------------------------------------- ----------

So, for example, the Kerberos_Rapi_QOS.lib's QOS_Authenticate() procedure will call the Kerberos.lib interface to obtain credentials, and QOS_Bind(),QOS_Rebind, and QOS_Unbind procedures will make calls into the rapi.lib which implements the rapi interface. Similarly, the SSL_Windsock_QOS.dll QOS_Authenticate() procedure will make calls into the SSL library to obtain credentials, and QOS_Bind(), QOS_Rebind, and QOS_Unbind procedures will make the appropriate winsock2 ioctl's to trigger the Winsock2 RSVP functionality. Note that the QOS_FindProfile() is independent of either the authentication or rsvp implementation.

6.1 Structures

QOS_SID:

int int_r_sid[MAXSID] // recv session id's
int int_s_sid[MAXSID] // send session id's

QOS_Authenticator:

needs to be able to hold creds from different security realms.
i.e. x-509 certs, kerberos keys, etc.
 

6.2 Communications

6.2.1 The Profile

6.2.1.1 RSVP Flowspec parameters:

 Note that this is opaque to RSVP, so
 a single definition will work across all RSVP implementations.
 *ADSPEC - info necessary to construct a default adspec
 to pass to the BB/Edge Router. The exact info depends on
 the implementation at the BB/Edge Router. See RFC 2210 for
 more detail.
 *TSPEC - there are two TSPECs defined in RFC 2210. One for the
 Controlled-Load service, and one for the Guaranteed service.
 A profile would contain values for which ever type(s) of
 QoS service are available on Internet2 nets.
 

6.2.1.2 RSVP Filterspec information

6.2.1.3 other RSVP variables

 int styleid
 wildcard => 1 flowspec, 1 filterspec.
 fixed => 1 to 1 flowspec to filterspec.
 se => 1 flowspec,1 to many filterspec.
 * RAPI specific
 // for now, one profile per rsvp session. so, if your application needs
 // more than one rsvp session, call the qos routines multiple times.
 int rapi_session_flags; RAPI_GPI_SESSION,RAPI_USE_INTSERV
 int rapi_reserve_flags; RAPI_REQ_CONFIRM
 // number of rapi api sessions for this rsvp session.
 int rapi_num_recv_sessions; number of api recv sessions to create
 multiple api sessions on one rsvp receiver session
 -> all in same multicast group -> receive same data
 -> all have same reservation paramaters.
 int rapi_num_send_sessions = 2; // Video stream, and Audio stream
 number of api send sessions to create
 - multiple senders per rsvp session -> multiple
 api sessions -> different reservation parameters
 so, need multiple reservation parameters defined
 in this profile.
 * WINSOCK specific
 //haven't completed....
 

6.2.1.4 Configuration parameters for BB, Edge Router, or other Internet2

QoS infrastructure components.
 * holding queue size for shaping prior to joining Premium service.
 - 2xbw-delay product queue for a TCP connection
 - a max frame size queue for a video flow
 

6.3 an RAPI example

Here is an example of how a RAPI_QOS library could be constructed:

QOS_SID
 QOS_Bind(Destination, Profile,Role,Handler,Source,QOS_Authenticator)
 {
 // create a rapi session. call either rapi_sender or rapi_reserve() or both.
 //unsigned int
 //rapi_session(
 // struct sockaddr *Dest =>QoS_Bind.Destination.IP Address
 // QoS_Bind.Destination.Port
 // (Need sin_family)
 // int Protid =>QoS_Bind.Destination.Protocol_Type
 // int flags =>QoS_Bind.Profile
 // int (*Event_rtn) =>QoS_Bind.Handler
 // void *Event_arg =>QoS_Bind.Profile? or local struct.
 // int *errnop =>local int.
 // )
 //
 int async_err,synch_err;
 struct QOS_SID;
 struct sockaddr_in recv_addr;
 struct sockaddr_in laddr;
 struct rapi_event_arg; //NOTE: this might come from the Profile.
 // transfer destination information to sockaddr struct.
 recv_addr.sin_family = Destination.family; //AF_INET
 recv_addr.sin_port = htonl(Destination.port);
 recv_addr.sin_addr.s_addr = Destination.addr;
 // receiver rapi session creation. multiple sessions use same
 // reservation paramaters
 for(i=0; i < rapi_num_recv_sessions;i++){
 QOS_SID.int_r_sid[i] = rapi_session((struct sockaddr *)&recv_addr,
 Destination.protocol_type,
 Profile.rapi_session_flags,
 Handler,
 (void *)&rapi_r_event_arg[i],
 &async_err);
 }
 // sender rapi session creation. multiple sessions use distinct
 // reservation paramaters. currently storing only 1 set of reservation
 // parameters in profile.
 for(i=0; i < rapi_num_send_sessions;i++){
 QOS_SID.int_s_sid[i] = rapi_session((struct sockaddr *)&recv_addr,
 Destination.protocol_type,
 Profile.rapi_session_flags,
 Handler,
 (void *)&rapi_s_event_arg[i],
 &async_err);
 }
 // stuff local machine info
 laddr.sin_family = AF_INET;
 laddr.sin_port = 0; // or nailed down port from Profile
 laddr.sin_addr.s_addr = INADDR_ANY;
 //
 if ((Role == Talk) || (Role == Converse)){
 for(i=0;i<rapi_num_recv_sessions;i++){
 synch_err = rapi_reserve(QOS_SID.int_s_sid[0],
 Profile.rapi_reserve_flags,
 recv_addr,
 Profile.rapi_styleid,
 Profile.rapi_style_ext,
 Profile.rapi_rcvr_policy,
 Profile.rapi_filter_spec_no,
 Profile.rapi_filter_spec_list,
 Profile.rapi_flow_spec_no,
 Profile.rapi_flow_spec_list)
 }
 if(sync_err != 0) // do something!
 }
 

if ((Role == Listen) || (Role == Converse)) {
 // need multiple sender Profile fields...
 // i.e. bundle all rapi_xxx sender profile stuff into
 // a structure, and init an array of structs of size
 // rapi_num_send_sessions.
 for(i=0;i<rapi_num_send_sessions;i++){
 synch_err = rapi_sender(QOS_SID.int_r_sid[i],
 0, // no rapi_sender flags defined
 (struct sockaddr *)&laddr,
 &Profile.rapi_sender_template,
 &Profile.rapi_sender_tspec,
 &Profile.rapi_sender_adspec,
 &Profile.rapi_sender_policy,
 Profile.Mcast_ttl)
 }
 }
 }

7. To Do:

Define the Profile structure required to support RSVP as the signaling protocol describe events (errors) and function return codes.

Author's Address

Bob Riddle <bdr@internet2.edu>
UCAID
3025 Boardwalk, Suite 100
Ann Arbor, Michigan
Phone: +1 734/913.4250

Andy Adamson <andros@umich.edu>
CITI
519 W. Williams, 1213
Ann Arbor, Michigan
Phone: +1 313/764-9465