One document matched: draft-ohba-aaa-diameter-cxxapi-00.txt
Internet-Draft Yoshihiro Ohba
Expires: April, 2003 Victor Fajardo
Dilip Patel
Toshiba America Research, Inc. (TARI)
October 2, 2002
Diameter C++ API
<draft-ohba-aaa-diameter-cxxapi-00.txt>
Status of This Memo
This document is an Internet-Draft and is in full conformance with
all provisions of Section 10 of RFC 2026.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that
other groups may also distribute working documents as Internet-
Drafts.
Internet-Drafts are draft documents, valid for a maximum of six
months, and may be updated, replaced, or obsoleted by other documents
at any time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
Abstract
The Diameter authentication, authorization, and accounting (AAA)
protocol provides support for peering AAA transactions across the
Internet. This document describes a standardized API for the
Diameter protocol. The API is defined for the C++ language. The
intent of the API is to foster source code portability across
multiple programming platforms, leveraging the object-oriented nature
of C++ and reusing what is already defined in the Diameter C API as
much as possible. The C++ API can also be used as a basis to define
more platform-independent API such as Java-based API.
Expires April, 2003 [Page 1]
Internet-Draft Diameter C++ API October 2, 2002
Table of Contents
1. Introduction ........................................... 3
2. Binding Independent Considerations ..................... 3
3. C++ API ................................................ 4
3.1. Constant Types ......................................... 4
3.1.1. IP Address and Port .................................... 4
3.1.2. Command Code ........................................... 4
3.1.3. Vendor Identifier ...................................... 4
3.1.4. Application Identifier ................................. 4
3.1.5. Attribute/Value Pair Code .............................. 4
3.1.6. Session Handle ......................................... 5
3.1.7. Application Handle ..................................... 5
3.1.8. API Return Codes ....................................... 5
3.1.9. AVP Data Type Codes .................................... 6
3.1.10. AVP Flags .............................................. 6
3.1.11. Notification Event Types ............................... 6
3.1.12. Session Event Types .................................... 7
3.1.13. Result Codes ........................................... 7
3.1.14. Application Identifier Values .......................... 8
3.1.15. Accounting Types ....................................... 8
3.1.16. Security Types ......................................... 8
3.1.17. AVP Data Types ......................................... 9
3.2. Class Library Overview ................................ 10
3.2.1. Message Parser ........................................ 10
3.2.1.1. Dictionary Data ....................................... 11
3.2.1.2. Dictionary Manager .................................... 11
3.2.1.3. Parser Data ........................................... 12
3.2.1.3.1. Message Buffer ........................................ 12
3.2.1.3.2. AVP Container Entry ................................... 13
3.2.1.3.3. AVP Container ......................................... 13
3.2.1.3.4. AVP Container List .................................... 14
3.2.1.4. AVP Container Entry Manager ........................... 15
3.2.1.5. AVP Container Manager ................................. 15
3.2.1.6. Diameter Header ....................................... 16
3.2.1.7. Error Status .......................................... 17
3.2.1.8. Parser ................................................ 18
3.2.1.8.1. Diameter Header Parser ................................ 19
3.2.1.8.2. Diameter Payload Parser ............................... 21
3.2.1.9. AAA Message ........................................... 22
3.2.2. Session, Event and Message Control .................... 22
3.2.2.1. Application Core ...................................... 23
3.2.2.2. Event Notification .................................... 24
3.2.2.2.1. Message Subscription Argument ......................... 25
3.2.2.2.2 Message Subscription Base Class ....................... 25
3.2.2.2.3 Derived Subscription Classes .......................... 25
3.2.2.2.4. Event Notification Registrar .......................... 26
3.2.2.3. Session Management .................................... 27
3.2.2.3.1. Session Base Class .................................... 27
3.2.2.3.2. Session Client Class .................................. 28
3.2.2.3.3. Session Server Class .................................. 29
3.2.2.3.4. Session Lookup Class .................................. 30
3.2.2.4 Message Control ....................................... 30
4. Acknowledgments ....................................... 31
5. References ............................................ 31
6. Authors' Information .................................. 31
7. Full Copyright Statement .............................. 32
Expires April, 2003 [Page 2]
Internet-Draft Diameter C++ API October 2, 2002
A. Appendix - Sample Usage ............................... 32
A.1. Parser Usage .......................................... 32
A.1.1. Dictionary Initialization ............................. 32
A.1.2. Input Parser Usage .................................... 32
A.1.3. Output Parser Usage ................................... 34
A.1.4. Relay/Proxy Agent Parser Usage ........................ 36
cxxapi.nroff:2528: warning: `ni' not defined
A.2. Application Usage ..................................... 38
A.2.1. Client Application Usage .............................. 38
A.2.2. Server Application Usage .............................. 40
1. Introduction
Similar to the C language [CAPI], the C++ language API is designed
around callback mechanism (or referred to as event notification
mechanism in this document). Although the C API and C++ API are
functionally equivalent, object-oriented nature of the C++ API better
fits with C++-based application programs than C API for the following
reasons.
First, since classes are defined in a hierarchical manner in the C++
API, it is easy for applications to define a new class for their own
purpose by deriving from the classes defined in the C++ API and
reusing what is already defined.
Second, the exception handling capability of C++ can provide a better
way for handling errors in that applications cannot ignore the
exception (otherwise, program will exit), which would make the
applications easy to find out the place of the error and reduce the
possibility of bugs caused by, either intentionally or
unintentionally, ignoring the error.
Third, there are some restrictions on the callback mechanism in the C
API. In the callback mechanism defined in the C API in which
callback functions are allowed to take only one argument (i.e.,
AAAMessage), it is difficult to extend the callback mechanism so that
callback functions can take arbitrary numbers and types of arguments
without converting them to a pointer to void type, where such
conversion tends to become a place of bugs that are difficult to
find. The C++ API solves this problem based on registering (a
pointer to) a class instance, i.e., a set of variables and associated
functions altogether, allowing flexible and extensible callbacks.
The design policy of the C++ API is (i) reuse what is defined in the
C API as much as possible, and (ii) leverage object-oriented nature
of C++.
The C++ API can also be used as a basis to define more platform-
independent API such as Java-based API.
2. Binding Independent Considerations
All the basic consideration for implementation described in section 2
of [CAPI] are applied to the C++ language API described in this
document.
Expires April, 2003 [Page 3]
Internet-Draft Diameter C++ API October 2, 2002
3. C++ API
3.1. Constant Types
The C++ API requires the C++ STL (Standard Template Library) to reuse
commonly used classes such as vector, list, string, etc.
3.1.1. IP Address and Port
o Synopsis
typedef sockaddr_storage IP_ADDR;
o Description
The same as defined in [CAPI].
3.1.2. Command Code
o Synopsis
typedef uint32_t AAACommandCode;
o Description
The same as defined in [CAPI].
3.1.3. Vendor Identifier
o Synopsis
typedef uint32_t AAAVendorId;
o Description
The same as defined in [CAPI].
3.1.4. Application Identifier
o Synopsis
typedef uint32_t AAAApplicationId;
o Description
AAAApplicationId is an identifier used for specifying an
authentication or accounting application.
3.1.5. Attribute/Value Pair Code
o Synopsis
Expires April, 2003 [Page 4]
Internet-Draft Diameter C++ API October 2, 2002
typedef uint32_t AAA_AVPCode;
o Description
The same as defined in [CAPI].
3.1.6. Session Handle
o Synopsis
typedef void *AAASessionHandle;
o Description
AAASessionHandle is an identifier for a particular AAA session. It
is used in the session APIs and when a message is created.
3.1.7. Application Handle
o Synopsis
typedef void *AAAApplicationHandle;
o Description
AAAApplicationId identifies a particular client session to the
API. The application id is passed to AAAStartSession(), and is
attached to incoming messages, to indicate with which client
session the message is associated.
3.1.8. API Return Codes
o Synopsis
typedef enum {
AAA_ERR_NOT_FOUND = -2,
AAA_ERR_FAILURE = -1,
AAA_ERR_SUCCESS = 0,
AAA_ERR_NOMEM,
AAA_ERR_PROTO,
AAA_ERR_SECURITY,
AAA_ERR_PARAMETER,
AAA_ERR_CONFIG,
AAA_ERR_UNKNOWN_CMD,
AAA_ERR_MISSING_AVP,
AAA_ERR_ALREADY_INIT,
AAA_ERR_TIMED_OUT,
AAA_ERR_CANNOT_SEND_MSG,
AAA_ERR_ALREADY_REGISTERED,
AAA_ERR_CANNOT_REGISTER,
AAA_ERR_NOT_INITIALIZED,
AAA_ERR_NETWORK_ERROR,
AAA_ERR_MSG_UNPROCESSED,
AAA_ERR_INVALID_STATE,
Expires April, 2003 [Page 5]
Internet-Draft Diameter C++ API October 2, 2002
AAA_ERR_PARSING_FAILED,
} AAAReturnCode;
o Description
The same as defined in [CAPI] except that several types are newly
added.
3.1.9. AVP Data Type Codes
o Synopsis
typedef enum {
AAA_AVP_DATA_TYPE,
AAA_AVP_STRING_TYPE,
AAA_AVP_ADDRESS_TYPE,
AAA_AVP_INTEGER32_TYPE,
AAA_AVP_INTEGER64_TYPE,
AAA_AVP_UINTEGER32_TYPE,
AAA_AVP_UINTEGER64_TYPE,
AAA_AVP_UTF8_STRING_TYPE,
AAA_AVP_ENUM_TYPE,
AAA_AVP_DIAMID_TYPE,
AAA_AVP_DIAMURI_TYPE,
AAA_AVP_GROUPED_TYPE,
AAA_AVP_TIME_TYPE,
} AAA_AVPDataType;
o Description
The same as defined in [CAPI] except that several types are newly
added.
3.1.10. AVP Flags
o Synopsis
typedef enum {
AAA_AVP_FLAG_NONE = 0,
AAA_AVP_FLAG_MANDATORY = 0x1,
AAA_AVP_FLAG_RESERVED = 0x2,
AAA_AVP_FLAG_VENDOR_SPECIFIC = 0x4,
AAA_AVP_FLAG_END_TO_END_ENCRYPT = 0x10,
AAA_AVP_FLAG_UNKNOWN = 0x10000,
AAA_AVP_FLAG_ENCRYPT = 0x40000,
} AAA_AVPFlag;
o Description
The same as defined in [CAPI].
3.1.11. Notification Event Types
o Synopsis
Expires April, 2003 [Page 6]
Internet-Draft Diameter C++ API October 2, 2002
typedef enum {
AAA_EVENT_TYPE_MESSAGE = 0,
AAA_EVENT_TYPE_DISCONNECT,
AAA_EVENT_TYPE_TIMEOUT,
AAA_EVENT_TYPE_ABORT_SESSION } AAA_EVENT_TYPE;
o Description
Used with the C++ event subscription classes. These denotes the
predefined events available in the C++ class library.
3.1.12. Session Event Types
o Synopsis
typedef enum {
SESSION_EVENT_AUTH_REQUEST = 0,
SESSION_EVENT_AUTH_SUCCESS,
SESSION_EVENT_AUTH_FAILED,
SESSION_EVENT_NO_SERVICE,
SESSION_EVENT_PROC_ERROR } SESSION_EVENT;
o Description
Used with the C++ session classes. These denotes events that an
application can use to notify the C++ class library of the current
applications state.
3.1.13. Result Codes
o Synopsis
typedef enum {
DIAMETER_MULTI_ROUND_AUTH = 1001
DIAMETER_SUCCESS = 2001
DIAMETER_LIMITED_SUCCESS = 2002
DIAMETER_COMMAND_UNSUPPORTED = 3001
DIAMETER_UNABLE_TO_DELIVER = 3002
DIAMETER_REALM_NOT_SERVED = 3003
DIAMETER_TOO_BUSY = 3004
DIAMETER_LOOP_DETECTED = 3005
DIAMETER_REDIRECT_INDICATION = 3006
DIAMETER_APPLICATION_UNSUPPORTED = 3007
DIAMETER_INVALID_HDR_BITS = 3008
DIAMETER_INVALID_AVP_BITS = 3009
DIAMETER_UNKNOWN_PEER = 3010
DIAMETER_AUTHENTICATION_REJECTED = 4001
DIAMETER_OUT_OF_SPACE = 4002
DIAMETER_AVP_UNSUPPORTED = 5001
DIAMETER_UNKNOWN_SESSION_ID = 5002
DIAMETER_AUTHORIZATION_REJECTED = 5003
DIAMETER_INVALID_AVP_VALUE = 5004
DIAMETER_MISSING_AVP = 5005
DIAMETER_RESOURCES_EXCEEDED = 5006
DIAMETER_CONTRADICTING_AVPS = 5007
Expires April, 2003 [Page 7]
Internet-Draft Diameter C++ API October 2, 2002
DIAMETER_AVP_NOT_ALLOWED = 5008
DIAMETER_AVP_OCCURS_TOO_MANY_TIMES = 5009
DIAMETER_UNSUPPORTED_TRANSFORM = 5010
DIAMETER_NO_COMMON_APPLICATION = 5011
DIAMETER_UNSUPPORTED_VERSION = 5012
DIAMETER_UNABLE_TO_COMPLY = 5013
DIAMETER_INVALID_BIT_IN_HEADER = 5014
DIAMETER_INVALID_AVP_LENGTH = 5015
DIAMETER_INVALID_MESSAGE_LENGTH = 5016
DIAMETER_INVALID_AVP_BIT_COMBO = 5017
} DIAMETER_RESULT_CODE;
o Description
3.1.14. Application Identifier Values
o Synopsis
#define NASREQ 1
#define MOBILE_IP 4
#define RELAY 0xffffffff
o Description
As defined in Section 2.4 of [DIAM].
3.1.15. Accounting Types
o Synopsis
typedef enum {
AAA_ACCT_EVENT = 1,
AAA_ACCT_START = 2,
AAA_ACCT_INTERIM = 3,
AAA_ACCT_STOP = 4
} AAAAcctMessageType;
o Description
The same as defined in [CAPI].
3.1.16. Security Types
o Synopsis
typedef enum {
AAA_SEC_NOT_DEFINED = -2,
AAA_SEC_NOT_CONNECTED = -1,
AAA_SEC_NO_SECURITY = 0,
AAA_SEC_CMS_SECURITY = 1,
AAA_SEC_CMS_PROXIED = 2
} AAASecurityStatus;
o Description
Expires April, 2003 [Page 8]
Internet-Draft Diameter C++ API October 2, 2002
The same as defined in [CAPI].
3.1.17. AVP Data Types
o Synopsis
typedef int32_t diameter_integer32_t;
typedef quad_t diameter_integer64_t;
typedef u_int32_t diameter_unsigned32_t;
typedef u_quad_t diameter_unsigned64_t;
typedef string* diameter_octetstring_t;
typedef diameter_octetstring_t diameter_utf8string_t;
typedef struct {
diameter_octetstring_t fqdn;
u_int16_t port;
u_int8_t transport:2;
u_int8_t protocol:2;
u_int8_t scheme:2;
} diameter_uri_t;
typedef diameter_utf8string_t diameter_identity_t;
typedef diameter_octetstring_t diameter_ipaddress_t;
typedef class AAAAvpContainerList* diameter_grouped_t;
//
// values possible for transport field of diameter_diamident_t
//
// avp_t is a special type used only in this library
// for constructing a raw AVP. When using this type, specify
// "AVP" as the avp_container type.
// The string contains the entire AVP including AVP header.
//
typedef diameter_octetstring_t avp_t;
// values possible for transport field of diameter_uri_t
enum {
TRANSPORT_PROTO_TCP = 0,
TRANSPORT_PROTO_SCTP,
TRANSPORT_PROTO_UDP,
};
// values possible for protocol field of diameter_uri_t
enum {
AAA_PROTO_DIAMETER = 0,
AAA_PROTO_RADIUS,
AAA_PROTO_TACACSPLUS,
};
// values possible for scheme field of diameter_uri_t
enum {
AAA_SCHEME_AAA = 0,
AAA_SCHEME_AAAS
};
o Description
Expires April, 2003 [Page 9]
Internet-Draft Diameter C++ API October 2, 2002
This type is newly defined for the C++ API to contain the value of
an AVP.
3.2. Class Library Overview
The Diameter C++ API consist of two (2) main sections. The first is a
message parser which is responsible solely for composition,
decomposition, verification and manipulation of diameter message. It
is also responsible for loading the XML base dictionary. And the
second is the Session, Event and Message Control section which is
responsible for instantiating user sessions (both server and client),
registering event notifications from the class library and
transmission of messages composed by service specific applications.
The C++ API requires the C++ STL (Standard Template Library) to reuse
commonly used classes such as vector, list, string, etc.
3.2.1. Message Parser
Figure 1 shows the basic parser class structure. The basic parser
class, AAAParser, has three private members: rawData, appData and
dictData. The rawData contains data to be used by lower layer
entities that handle less structured data such as a Diameter header
or a payload represented as a simple octet string. The appData
member contains data to be used by applications that handle more
structured data such as a structured Diameter header object or a list
of AVPs. The dictData contains dictionary data needed for performing
data conversion between the rawData and the appData.
There are two classes, HeaderParser and PayloadParser, derived from
the basic parser class in order to parse Diameter header and payload,
respectively.
AAAParserData AAAParserData AAADictionaryData
(rawData) (appData) (dictData)
| | |
--------------------------------------------
|
AAAParser
Fig. 1. The Basic Parser Class Structure
Figures 1(a) shows the bindings of HeaderParser. A AAAMessageBuffer
class instance is used for storing a Diameter header as raw data. A
AAADiameterHeader instance contains a structured Diameter header in
which each header field is stored in a distinct member variable.
Figures 1(b) shows the bindings of PayloadParser. A AAAMessageBuffer
class instance is used for storing a Diameter payload as raw data.
For rawData, either a list of AVP containers (AAAAvpContainerList) or
an AVP container (AAAAvpContainer) can be specified, depending on
whether the application needs to get or set values for all the AVPs
in the payload or just for a specific type of AVPs.
The HeaderParser and PayloadParser have an option to perform strict
format checking against dictionary so that a mis-specified command
Expires April, 2003 [Page 10]
Internet-Draft Diameter C++ API October 2, 2002
flags (in the case of HeaderParser), a missing AVP or a mis-placed
AVP (in the case of PayloadParser) can be detected by the API in
addition to basic command length or AVP length/flags check, which
would simplify message processing in applications.
AAAMessageBuffer AAADiameterHeader AAADictionaryData
(rawData) (appData) (dictData)
| | |
--------------------------------------------
|
HeaderParser [derived from AAAParser]
Fig. 1(a). HeaderParser Class Bindings
AAAAvpContainerEntry AAAAvpContainerEntry
| |
| |
AAAAvpContainer AAAAvpContainer
| |
| |
AAAAvpContainerList |
| |
+---------+-------+
|
|
AAAMessageBuffer | AAADictionaryData
(rawData) (appData) (dictData)
| | |
--------------------------------------------
|
PayloadParser [derived from AAAParser]
Fig. 1(b). PayloadParser Class Bindings
3.2.1.1. Dictionary Data
The following class is defined as the base class of dictionary data.
Any class that is to be used by the parser as a dictionary entry such
as a command or an AVP dictionary is derived from this class.
o Definition
class AAADictionaryData {};
3.2.1.2. Dictionary Manager
The following class is defined for managing command and AVP
dictionaries.
Expires April, 2003 [Page 11]
Internet-Draft Diameter C++ API October 2, 2002
o Definition
class AAADictionaryManager
{
public:
void init(char *dictFile);
boolean_t getCommandCode(char *commandName,
AAACommandCode *commandCode,
AAAVendorId *vendorId);
};
o Description
void init() -
This function initializes the command and AVP dictionaries based
on an appropriate set of command and AVP dictionary files
described in XML format [XML].
boolean_t getCommandCode() -
Used for translating the command name into a pair of command code
and vendor id. If translation is successful true is returned.
Otherwise, false is returned.
3.2.1.3. Parser Data
The following class is defined as the base class of parser data. Any
class that is to be used by the parser as source data or destination
data must be derived from this class.
o Definition
class AAAParserData {};
3.2.1.3.1. Message Buffer
This class defines a buffer to be used for storing raw data including
Diameter header and payload.
o Definition
class AAAMessageBuffer: public AAAParserData
{
public:
AAAMessageBuffer(char *buf, u_int32_t s, u_int32_t offset=0) {
data = buf; size = s; this->offset = offset;
}
AAAMessageBuffer() { data = NULL; size = 0; offset = 0;}
char *data;
u_int32_t size;
u_int32_t offset;
};
o Description
Expires April, 2003 [Page 12]
Internet-Draft Diameter C++ API October 2, 2002
The definition of this class is straightforward.
3.2.1.3.2. AVP Container Entry
This class is is used as a placeholder to pass an AVP value between
application programs and the API.
o Definition
class AAAAvpContainerEntry : public AAAParserData
{
public:
AAA_AVPDataType type;
union {
avp_t avp_val;
diameter_integer32_t integer32_val;
diameter_integer64_t integer64_val;
diameter_unsigned32_t unsigned32_val;
diameter_unsigned64_t unsigned64_val;
diameter_utf8string_t utf8string_val;
diameter_unsigned32_t enumerated_val;
diameter_octetstring_t octetstring_val;
diameter_identity_t identity_val;
diameter_uri_t uri_val;
diameter_octetstring_t ipaddress_val;
diameter_grouped_t grouped_val;
};
};
3.2.1.3.3. AVP Container
This class is used to hold a list of AAAAvpContainerEntry instances
of the same AVP type.
o Definition
class AAAAvpContainer : public AAAParserData
{
public:
AAAAvpContainer();
~AAAAvpContainer();
void releaseEntries();
int size();
void add(AAAAvpContainerEntry*);
void remove(AAAAvpContainerEntry*);
const char* getAvpName();
void setAvpName(const char*);
AAAAvpContainerEntry* operator[](int);
protected:
char *avpName;
vector<AAAAvpContainerEntry*> entry;
};
o Description
Expires April, 2003 [Page 13]
Internet-Draft Diameter C++ API October 2, 2002
releaseEntries() -
This function returns all the AAAAvpContainerEntry pointers in
the container to the free list. It is the responsibility of
applications to call this function as soon as processing of the
containers are completed.
int size() -
This function returns the number of the AAAAvpContainerEntry
elements in the container.
void add(AAAAvpContainerEntry*) -
This function adds a AAAAvpContainerEntry pointer to the
container.
void remove(AAAAvpContainerEntry*) -
This function removes a AAAAvpContainerEntry pointer from the
container.
const char* getAvpName()
void setAvpName(const char*):
These functions are used to set or get the AVP name.
corresponding to the container.
operator[](int) -
This arry operator returns a pointer to the AAAvpContainerEntry
element at the specified index.
3.2.1.3.4. AVP Container List
This class is used to hold a list of AAAAvpContainer entities of a
Diameter command.
o Definition
class AAAAvpContainerList : public AAAParserData
{
public:
AAAAvpContainerList();
~AAAAvpContainerList();
void add(AAAAvpContainer*);
void remove(AAAAvpContainer*);
void prepend(AAAAvpContainer*);
void releaseContainers();
AAAAvpContainer* search(char*);
protected:
vector<AAAAvpContainer*> avpc_l;
};
o Description
Expires April, 2003 [Page 14]
Internet-Draft Diameter C++ API October 2, 2002
void add(AAAAvpContainer*) -
This function adds the specified container to the internal list.
void remove(AAAAvpContainer*) -
This function removes the specified container from the internal
list.
remove(AAAAvpContainer*) -
This function prepends the specified container to the internal
list.
AAAAvpContainer* search(char*) -
This function searches the internal list for a container
corresponding to the specified name.
void releaseContainers() -
This function returns all the containers in the list to the free
list. It is the responsibility of applications to call this
function as soon as processing of the containers are completed.
3.2.1.4. AVP Container Entry Manager
This class is used to acquire and release an instance of
AAAAvpContainerEntry. A pool of AAAAvpContainerEntry instances are
managed by this class. The pool management policy is invisible to
application. In other words, the API is flexible to apply a number
of pool management policies.
o Definition
class AAAAvpContainerEntryManager
{
public:
AAAAvpContainerEntry *acquire(AAA_AVPDataType);
void release(AAAAvpContainerEntry*);
};
o Description
AAAAvpContainerEntry *acquire(AAA_AVPDataType) -
This function assigns a AAAAvpContainerEntry resource of a
specific type.
void release(AAAAvpContainerEntry*) -
This function release a AAAAvpContainerEntry resource.
3.2.1.5. AVP Container Manager
Expires April, 2003 [Page 15]
Internet-Draft Diameter C++ API October 2, 2002
This class is used to acquire and release an instance of
AAAAvpContainer. A pool of AAAAvpContainer instances are managed by
this class. The pool management policy is invisible to application.
In other words, the API is flexible to apply a number of pool
management policies.
o Definition
class AAAAvpContainerManager
{
public:
AAAAvpContainer *acquire(const char*);
void release(AAAAvpContainer*);
};
o Description
AAAAvpContainer *acquire(const char*) -
This function assigns a AAAAvpContainer resource of a specific
name.
void release(AAAAvpContainer*) -
This function release a AAAAvpContainer resource.
3.2.1.6. Diameter Header
This class is used for handling Diameter header.
o Definition
struct hdr_flag {
u_int8_t r:1;
u_int8_t p:1;
u_int8_t e:1;
u_int8_t rsvd:5;
};
#define HEADER_SIZE 20
class AAADiameterHeader : public AAAParserData
{
public:
AAADiameterHeader(u_int8_t ver,
u_int32_t length,
struct hdr_flag flags,
AAACommandCode code,
AAAApplicationId appId,
u_int32_t hh,
u_int32_t ee)
{
this->ver = ver;
this->length = length;
this->flags = flags;
this->code = code;
Expires April, 2003 [Page 16]
Internet-Draft Diameter C++ API October 2, 2002
this->appId = appId;
this->hh = hh;
this->ee = ee;
}
AAADiameterHeader() {}
u_int8_t ver;
u_int32_t length:24;
struct hdr_flag flags;
AAACommandCode code:24;
AAAApplicationId appId;
u_int32_t hh;
u_int32_t ee;
};
o Description
The definition is straightforward except that hh and ee represents
Hop-by-Hop Identifier and End-to-End Identifier, respectively.
3.2.1.7. Error Status
This definition is used to notify the application of a parser error.
o Definition
enum {
NORMAL = 0,
BUG = 1,
};
// The following error code is defined for error type "BUG"
enum {
MISSING_CONTAINER = 1,
TOO_MUCH_AVP_ENTRIES,
TOO_LESS_AVP_ENTRIES,
PROHIBITED_CONTAINER,
INVALID_CONTAINER_PARAM,
INVALID_CONTAINER_CONTENTS,
UNSUPPORTED_FUNCTIONALITY,
INVALID_PARSER_USAGE
MISSING_AVP_DICTIONARY_ENTRY
};
class AAAErrorStatus
{
private:
int type; // error type (NORMAL or BUG)
int code; // either a diameter result code or a bug_code above
string avp; // errornous AVP
public:
AAAErrorStatus(void)
{
type = NORMAL;
code = DIAMETER_SUCCESS;
};
void get(int&, int&, string&);
Expires April, 2003 [Page 17]
Internet-Draft Diameter C++ API October 2, 2002
void get(int&, int&);
void set(int, int);
void set(int, int, AAADictionaryData*);
};
o Description
There are two types of error categories returned from the
ParseRawToApp() or ParseAppToRaw() member functions of the classes
derived from the AAAParser class. One type (NORMAL) is normal
error which is described in the Diameter specification [DIAM].
The other type (BUG) is related to application problam's misusage
of the Message Parser part of the API. A number of error codes
are defined for BUG type errors.
AAAErrorStatus class is defined to carry error information such as
error type, error code, and contents of an errornous AVP which is
needed for specific errors. The following member functions are
defined for this class.
void get(int& type, int& code, string& avp) -
Used for obtaining the type and code of the error, and errnous
AVP.
void get(int& type, int& code) -
Used for obtaining the type and code the error.
void set(int type, int code, string avp) -
Used by the API for setting the type and code of the error, and
errnous AVP.
void set(int type, int code) -
Used by the API for setting the type and code the error.
3.2.1.8. Parser
This is the base class for parsers.
o Definition
class AAAParser
{
public:
AAAParser() {rawData = appData = NULL; dictData = NULL; }
virtual ~AAAParser() {};
virtual void parseRawToApp()=0;
virtual void parseAppToRaw()=0;
protected:
void setRawData(AAAParserData *data) { rawData = data; }
void setAppData(AAAParserData *data) { appData = data; }
void setDictData(AAADictionaryData* data) { dictData = data; }
AAAParserData *getRawData() { return rawData; }
Expires April, 2003 [Page 18]
Internet-Draft Diameter C++ API October 2, 2002
AAAParserData *getAppData() { return appData; }
AAADictionaryData *getDictData() { return dictData; }
private:
AAAParserData *rawData; // Raw data
AAAParserData *appData; // Application data translated from/to raw data
AAADictionaryData *dictData; // Dictionary data
};
o Description
void parseRawToApp() -
Parse raw data and translate it into application level data.
void parseAppToRaw() -
Parse application level data and translate it into raw data.
void setRawData(AAAParserData*) -
Set raw data to the parser.
void setAppData(AAAParserData*) -
Set application level data to the parser.
void setDictData(AAADictionaryData*) -
Set dictionary data data to the parser.
AAAParserData *getRawData() -
Get raw data from the parser.
AAAParserData *getAppData() -
Get application level data from the parser.
AAADictionaryData* getDictData() -
Get dictionary data data from the parser.
3.2.1.8.1. Diameter Header Parser
This class is derived from AAAParser and used to parse Diameter
headers.
o Definition
enum ParseOption {
PARSE_LOOSE = 0,
PARSE_STRICT = 1,
};
class HeaderParser : public AAAParser
Expires April, 2003 [Page 19]
Internet-Draft Diameter C++ API October 2, 2002
{
public:
HeaderParser() { opt = PARSE_STRICT; };
void setRawData(AAAMessageBuffer*);
void setAppData(AAADiameterHeader*);
void parseRawToApp() throw(AAAErrorStatus);
void parseAppToRaw() throw(AAAErrorStatus);
void setOption(ParseOption);
const char *getCommandName();
AAADictionaryData *getDictData();
private:
ParseOption opt;
};
o Description
void setRawData(AAAMessageBuffer*) -
Set raw data (i.e., AAAMessageBuffer*) to the parser.
void setAppData(AAADiameterHeader*) -
Set application level data (i.e., AAADiameterHeader*) to the
parser.
void parseRawToApp() throw(AAAErrorStatus) -
Parse raw data and translate it into application level data.
AAAErrorStatus is thrown when error occurs.
void parseAppToRaw() throw(AAAErrorStatus) -
Parse application level data and translate it into raw data.
AAAErrorStatus is thrown when error occurs.
void setOption(ParseOption) -
Used to set the parsing option. When ParseOption is PARSE_STRICT
(default), the parser tries to search a command dictionary for an
entry that corresponds to the command code and application
identifier. If such an entry is found, the parser uses the entry
to verify the fields in the header.
const char *getCommandName() -
Used to obtain the command name. A non-null pointer is returned if
and only if ParseOption is PARSE_STRICT and after parseRawToApp()
or parseAppToRaw() is successfully returned.
AAADictionaryData *getDictData() -
Used to obtain the command dictionary. A non-null pointer is
returned if and only if ParseOption is PARSE_STRICT and after
parseRawToApp() or parseAppToRaw() is successfully returned.
Note: setDictData() is automatically called when parseRawToApp() or
Expires April, 2003 [Page 20]
Internet-Draft Diameter C++ API October 2, 2002
parseAppToRaw() is called with ParseOption is set to PARSE_STRICT.
3.2.1.8.2. Diameter Payload Parser
This class is derived from AAAParser and used to parse Diameter
payloads.
o Definition
class PayloadParser : public AAAParser
{
public:
PayloadParser() {};
void setRawData(AAAMessageBuffer*);
void setAppData(AAAAvpContainerList*);
void setAppData(AAAAvpContainer*);
void parseRawToApp() throw(AAAErrorStatus);
void parseAppToRaw() throw(AAAErrorStatus);
void setDictData(AAADictionaryData*);
};
o Description
void setRawData(AAAMessageBuffer*) -
Set raw data (i.e., AAAMessageBuffer*) to the parser.
void setAppData(AAAAvpContainerList*) -
Set application data (i.e., AAAAvpContainerList*) to the parser.
The AAAAvpContainerList SHOULD NOT contain any AAAAvpContainer
instance when non-null dictionary data is specified by
setDictData() (see below).
void parseRawToApp() throw(AAAErrorStatus) -
Parse raw data and translate it into application level data.
AAAErrorStatus is thrown when error occurs.
void parseAppToRaw() throw(AAAErrorStatus) -
Parse application level data and translate it into raw data.
AAAErrorStatus is thrown when error occurs.
void setDictData(AAADictionaryData*) -
This function sets a command dictionary entry which can be obtained
by using HeaderParser::getDictData(). When non-null
AAADictionaryData is set, the specified command dictionary is used
for parsing the payload. Parsing with non-null AAADictionaryData
starts after initializing the offset offset value of the
AAAMessageBuffer to zero. When null AAADictionaryData is set, the
parser will try to use the contents of the AAAAvpContainerList
Expires April, 2003 [Page 21]
Internet-Draft Diameter C++ API October 2, 2002
instance specified by setAppData() as the dictionary to parse the
payload, where specific sets of AVP types need to be parsed are
expected to be specified in the AAAAvpConatinerList instance before
calling parseAppToRaw() or parseRawToApp() functions. Parsing with
null AAADictionaryData starts from the current offset of the
AAAMessageBuffer.
3.2.1.9. AAA Message
This definition is used by the Message Control part of the API as a
binding to the Message Parser part of the API. This class is re-
defined as a replacement of the C-based AAAMessage type definition.
o Definition
class AAAMessage
{
public:
AAADiameterHeader hdr;
AAAAvpContainerList acl;
AAAErrorStatus status;
IP_ADDR originator;
IP_ADDR sender;
time_t secondsTillExpire;
time_t startTime;
void *appHandle;
};
o Description
The hdr member stores the contents of the current Diameter header.
The acl member stores the list of AVPs. The status member stores
the error status to be returned by the Message Parser part of the
API. The other members are the same as defined in AAAMessage type
in [CAPI].
3.2.2. Session, Event and Message Control
Expires April, 2003 [Page 22]
Internet-Draft Diameter C++ API October 2, 2002
AAAMessage
|
|
AAAMessageControl AAAMessageControl AAAMessageArg
| | |
| | |
AAASessionClient AAASessionServer AAASubscription
| | |
| | |
| | AAAEventNotification
| | |
| | |
-----------------------------------------
|
AAAApplicationCore
Fig. 2. Session, Event and Message Control Class Bindings and Hierarchy
As shown in Fig. 2. above, the Session, Event and Message Control
classes are bounded to a single instance of the application core. An
application identifies itself to the diameter class library by this
object. All other classes are services that operates on this object.
Instances of service classes maybe transient but their effect on the
application core is persistent.
Theoretically, this class library could easily be a shared library
with each diameter application creating it's own instance of the
application core. No re-entrancy protection is required since all
application data are localized in the core object and resides within
each application context.
3.2.2.1. Application Core
This class defines the application core. It performs initialization
and configuration of the AAA class library. An instance of this
object must be created for the class library to be usable.
Some of the operations that may be performed by this object includes
opening and loading the AVP and vendor dictionaries, opening and
loading diameter routing tables, opening connections with Diameter
peers, loading Diameter extension libraries.
Expires April, 2003 [Page 23]
Internet-Draft Diameter C++ API October 2, 2002
o Definition
class AAAApplicationCore {
public:
AAAApplicationCore();
AAAApplicationCore(char *configFileName);
~AAAApplicationCore();
AAAReturnCode Open(char *configFileName = NULL);
AAAReturnCode Reload();
const char *GetConfigFileName();
const AAAApplicationHandle GetAppHandle();
private:
AAAApplicationHandle handle;
};
o Description
Open(char *configFileName) -
Loads configuration files performs initialization an. This
functionality is also encapsulated in the constructor for
convenience.
Reload() -
Reloads configuration data into runtime tables and variables (only
those that can be reloaded successfully without requiring a program
restart). This functionality is useful for administratively
changing items like timing variables without disrupting current
operations and sessions.
handle -
The application handle is an opaque data holder for internal use by
this class. It would be a reference to data values loaded retrieved
from the configuration files. It MAY also be a place holder for
instance specific properties like application state, pointers to
tables .. etc. As and example, GetConfigFileName() SHOULD be
implemented to retrieve the filename from the appHandle.
3.2.2.2. Event Notification
The class definitions below provides for event notification including
message delivery to clients. The notification model is simple. All
notifications are delivered via a subscription object. The
subscription object encapsulates different types events specified by
the AAA_EVENT enumeration. Events for message delivery would have
member data variables filled in to carry the message. Other events
that does not require data would not.
A client interested in receiving messages and notifications would
need to implement a derived class from the abstract base class
AAASubscription. An instance of this class would then need to be
subscribed via AAAEventNotification. The derived class needs to be
Expires April, 2003 [Page 24]
Internet-Draft Diameter C++ API October 2, 2002
persistent during the lifetime of the application core or while not
being unsubscribed via AAAEventNotification. The AAAEVentNotification
instance is service class of the application and can therefore be
transient.
3.2.2.2.1. Message Subscription Argument
Base class for encapsulating subscription arguments. Application
clients defining new types of subscriptions will have to derive a
class base on this class if it needs to associate an argument with
the subscription.
o Definition
class AAA_EVENT_ARG {
public: };
3.2.2.2.2 Message Subscription Base Class
This is a base class that encapsulates registration of command
specific messages. An application client needs to define a class
derived from this class and implement it's Event() function. A client
application needs to define different classes for EACH command
message it is interested in. The type of command is dictated by the
values set in AAAMessageArg that is passed to the constructor of the
AAAMessageSubscription.
It is important to note that the event notifier will de-reference the
AAASubscription pointer to an AAAMessageSubscription if the type is
determined to be AAA_EVENT_TYPE_MESSAGE. Also, the application client
is responsible for allocation AAAMessageArg and passing it to the
constructor. This allocated message argument is filled by the
notifier with incoming messages.
o Definition
class AAASubscription {
public:
AAASubscription(AAA_EVENT_TYPE typeArg, AAA_EVENT_ARG* argArg = NULL);
virtual AAAReturnCode Event() = 0;
AAA_EVENT_TYPE GetType();
AAA_EVENT_ARG* GetArg();
protected:
AAA_EVENT_TYPE type;
AAA_EVENT_ARG* arg;
};
o Description
Event() -
This is the virtual method that needs to be implemented by
subscription specific classes.
3.2.2.2.3 Derived Subscription Classes
Expires April, 2003 [Page 25]
Internet-Draft Diameter C++ API October 2, 2002
The classes defined here are derived from AAASubscription to provide
a generic way of responding to AAA_EVENT_- TYPE_DISCONNECT,
AAA_EVENT_TYPETIMEOUT and AAA_EVENT_- _ABORT_SESSION. The proper
event type is designated automatically in the constructor and the
Event() function is a do nothing event that returns success.
Additional classes derived from AAA_EVENT_ARG are also defined to
hold subscription specific information.
o Definition
class AAAMessageArg : public AAA_EVENT_ARG {
public:
AAAMessage message; };
class AAAMessageSubscription : public AAASubscription {
public:
AAAMessageSubscription(AAAMessageArg *messageArg) :
AAASubscription(AAA_EVENT_TYPE_MESSAGE, messageArg) {};
virtual AAAReturnCode Event() = 0; };
class AAASessionArg : public AAA_EVENT_ARG {
public:
AAASessionHandle handle; };
class AAADisconnectSubscription : public AAASubscription {
public:
AAADisconnectSubscription(AAASessionArg *sessionArg) :
AAASubscription(AAA_EVENT_TYPE_DISCONNECT, sessionArg)
{} ;
virtual AAAReturnCode Event()
{ return AAA_ERR_SUCCESS; }; };
class AAATimeoutSubscription : public AAASubscription {
public:
AAATimeoutSubscription(AAASessionArg *sessionArg) :
AAASubscription(AAA_EVENT_TYPE_TIMEOUT, sessionArg) {} ;
virtual AAAReturnCode Event()
{ return AAA_ERR_SUCCESS; }; };
class AAAAbortSessionSubscription : public AAASubscription {
public:
AAAAbortSessionSubscription(AAASessionArg *sessionArg) :
AAASubscription(AAA_EVENT_TYPE_ABORT_SESSION,
sessionArg) {} ;
virtual AAAReturnCode Event()
{ return AAA_ERR_SUCCESS; }; };
3.2.2.2.4. Event Notification Registrar
This is the service class used to subscribe and unsubscribe
AAASubscription based object to the application core. The service
class requires an instance of the application on which to operate on.
Expires April, 2003 [Page 26]
Internet-Draft Diameter C++ API October 2, 2002
o Definition
class AAAEventNotification {
public:
AAAEventNotification(AAAApplicationCore &appCore);
~AAAEventNotification();
AAAReturnCode Subscribe(AAASubscription *subscription);
AAAReturnCode UnSubscribe(AAASubscription *subscription);
private:
AAAApplicationCore *core; };
o Description
Subscribe(AAASubscription *subscription) -
This function is used to register an AAASubscription object to the
application core. An instance of the AAASubscription derived class
must have a valid AAA_EVENT_TYPE defined via the AAASubscription
constructor.
UnSubscribe(AAASubscription *subscription)
This is a symmetric function to Subscribe() and requires the
AAASubscription derived object to be passed to it for de-
registration.
3.2.2.3. Session Management
The class definitions in this section allow the client to open,
close, and manipulate sessions and servers to accept or reject a
session request. As with the event notification class, an instance
of the application core is required. The session management model has
two (2) parts, client and server. Creating a session entity is the
responsibility of both the client and server. The client is the
active entity and can start and end a session. The server can either
accept or reject (via abort) a session request. The server accepts or
rejects a session from incoming messages received from the event
notification subscription.
A base class is provided to encapsulates the session specific
information and would not typically be used directly by the client
application. The client and server derived class provides the
functionality required by the application to act either as a diameter
client or server.
A helper class for searching the internal database for existing
sessions is also provided. Currently, searches can be made based on
messages. However, the class may be extended to allow searches using
other keys or information.
3.2.2.3.1. Session Base Class
The following defines a base class for representing session data
Expires April, 2003 [Page 27]
Internet-Draft Diameter C++ API October 2, 2002
o Definition
class AAASession {
public:
AAASession(AAAApplicationCore &appCore);
virtual ~AAASession();
AAAReturnCode SetMessageTimeout(time_t timeout);
AAAReturnCode SetApplicationId(diameter_unsigned32_t id);
virtual AAAReturnCode Update(SESSION_EVENT event) = 0;
const AAASessionHandle GetSessionHandle();
const AAAApplicationCore *GetAppCore();
protected:
AAASessionHandle handle;
AAAApplicationCore *core; };
o Description
SetMessageTimeout(time_t timeout) -
This function sets the timeout, in seconds, for all AAAMessages in
a particular session.
SetApplicationId(diameter_unsigned32_t id) -
Set's the application to be supported by this instance of the
diameter protocol.
Update(SESSION_EVENT event) -
This functions allows an applications to impose a state transition
whether serving as a diameter client or server.
GetSessionHandle() -
This function returns the session handle instance.
GetAppCore() -
This function returns the application core pointer to which this
session is attached to.
3.2.2.3.2. Session Client Class
Derived class to provide functionality of a diameter client.
Expires April, 2003 [Page 28]
Internet-Draft Diameter C++ API October 2, 2002
o Definition
class AAASessionClient : public AAASession {
public:
AAASessionClient(AAAApplicationCore &appCore);
~AAASessionClient();
AAAReturnCode Start();
AAAReturnCode Update(SESSION_EVENT event);
AAAReturnCode End(); };
o Description
Start() -
This function allows a client to start a session and store session
information in the internal database.
Update(SESSION_EVENT event) -
This functions is a client implementation of the update base
function.
End() -
This function, invoked by a client, terminates a session.
3.2.2.3.3. Session Server Class
Derived class to provide functionality of a diameter server.
o Definition
class AAASessionServer : public AAASession {
public:
AAASessionServer(AAAApplicationCore &appCore);
~AAASessionServer();
AAAReturnCode Accept(AAAMessage *message);
AAAReturnCode Update(SESSION_EVENT event);
AAAReturnCode Abort(); };
o Description
Accept(AAAMessage *message) -
This function, invoked by the server, formally accepts a session
request (transition to an open session) and store the session
information in the internal database.
Update(SESSION_EVENT event) -
This functions is a server implementation of the update base
function.
Abort()
Expires April, 2003 [Page 29]
Internet-Draft Diameter C++ API October 2, 2002
This function allows the server to terminate a session after being
accepted.
3.2.2.3.4. Session Lookup Class
This class allows a diameter client or server application to query
existing sessions in the internal database.
o Definition
class AAASessionLookup {
public:
AAASessionLookup(AAAApplicationCore &appCore);
virtual ~AAASessionLookup();
const AAASession *Query(AAASessionHandle handle);
const AAASession *Query(AAAMessage *message);
protected:
AAAApplicationCore *core; };
o Description
Query(AAASessionHandle handle) -
Searches for an existing session in the internal database based on
a given session handle.
Query(AAAMessage *message) -
Searches for an existing session in the internal database based on
an AAAMessage.
3.2.2.4 Message Control
The class definition in this section allows a client application to
send messages to a destination. It provides diameter client the
functionality to direct a message to a particular server, determine
the server for a message, etc. It also allows a server to respond to
messages received from clients.
The model provided for message control is to associate it with an
existing session since the functionality provided is for delivery of
messages to known entities via established sessions. The message
control class requires an instance of a session and therefore
associates the message control to the application core.
Expires April, 2003 [Page 30]
Internet-Draft Diameter C++ API October 2, 2002
o Definition
class AAAMessageControl {
public:
AAAMessageControl(AAASession &session);
~AAAMessageControl();
AAAReturnCode SetResultCode(AAAMessage *response,
AAAMessage *request,
AAAResultCode resultCode);
AAAReturnCode Send(AAAMessage *message);
protected:
AAASession *session; };
o Description
Send(AAAMessage *message) -
This function sends a message to the server.
SetResultCode(AAAMessage *response, AAAMessage *request,
AAAResultCode resultCode)
This function sets the result code for a response message and makes
all changes based on the original request and the application
defined result code.
4. Acknowledgments
The authors would like to thank Shaun Astarabadi, Shin-ichi Baba,
John-Luc Bakker, Dick Bridges, David Frascone and members of the
ITSUMO Project for their support and valuable comments on this work.
5. References
[CAPI] J. Kempf, et al., "The DIAMETER API", Internet-Draft, Work in
progress, March 2002.
[DIAM] P. Calhoun, et al., "Diameter Base Protocol", Internet-Draft, Work in
progress, July 2002.
[XML] D. Frascone, et al., "Diameter XML Dictionary", Internet-Draft,
Work in progress, February 2002.
6. Authors' Information
Yoshihiro Ohba
Toshiba America Research, Inc.
P.O. Box 136
Convent Station, NJ 07961-0136
USA
Phone: +1 973 829 5174
Fax: +1 973 829 5601
Email: yohba@tari.toshiba.com
Expires April, 2003 [Page 31]
Internet-Draft Diameter C++ API October 2, 2002
Victor Fajardo
Toshiba America Research, Inc.
P.O. Box 136
Convent Station, NJ 07961-0136
USA
Email: vfajardo@optonline.net
Dilip Patel
Toshiba America Research, Inc.
P.O. Box 136
Convent Station, NJ 07961-0136
USA
Email: dilris@yahoo.com
7. Full Copyright Statement
Copyright (C) The Internet Society (2002). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Inter net organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be followed,
or as required to translate it into languages other than English. The
limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns. This
document and the information contained herein is provided on an "AS
IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL
NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY
OR FITNESS FOR A PARTICULAR PURPOSE."
A. Appendix - Sample Usage
A.1. Parser Usage
A.1.1. Dictionary Initialization
The following two lines are expected to exist in program
initialization part.
AAADictionaryManager dm;
dm.init();
A.1.2. Input Parser Usage
The following sample code shows how received octet string data
Expires April, 2003 [Page 32]
Internet-Draft Diameter C++ API October 2, 2002
containing a Diameter message is parsed into high-level data
structures.
void
rtest(char *buf, int size)
{
int i, j;
AAAMessage msg;
HeaderParser hp;
AAAMessageBuffer aBuffer;
aBuffer = AAAMessageBuffer(rbuf, HEADER_SIZE);
hp.setRawData(&aBuffer);
hp.setAppData(&msg.hdr);
hp.setOption(PARSE_STRICT);
try {
hp.parseRawToApp();
}
catch (AAAErrorStatus st) {
cout << "header error" << endl;
exit(1);
}
cout << "received command: " << hp.getCommandName() << endl;
print_header(msg.hdr);
PayloadParser pp;
aBuffer = AAAMessageBuffer(rbuf+HEADER_SIZE, msg.hdr.length - HEADER_SIZE);
pp.setRawData(&aBuffer);
pp.setAppData(&msg.acl);
pp.setDictData(hp.getDictData());
try {
pp.parseRawToApp();
}
catch (AAAErrorStatus st)
{
int code, type;
string avp;
msg.status.get(type, code);
cout << "Disassemble failure. Status code = " << code << endl;
exit(1);
}
cout << "Disassemble success." << endl;
if (AAAAvpContainer* c_prinfo = msg.acl.search("Proxy-Info"))
{
for (i=0; i<c_prinfo->size(); i++)
{
AAAAvpContainerList *acl = (*c_prinfo)[i]->grouped_val;
cout << "Proxy Info = [" << endl;
if (AAAAvpContainer *c_prhost = acl->search("Proxy-Host"))
{
for (j=0; j<c_prhost->size(); j++)
{
Expires April, 2003 [Page 33]
Internet-Draft Diameter C++ API October 2, 2002
diameter_identity_t prhost = (*c_prhost)[j]->identity_val;
cout << "" << "Proxy-Host = "
<< prhost->data() << endl;
}
}
if (AAAAvpContainer *c_prstate = acl->search("Proxy-State"))
{
for (j=0; j<c_prstate->size(); j++)
{
diameter_octetstring_t state =
(*c_prstate)[j]->octetstring_val;
cout << "" << "Proxy-State = " << state->data() << endl;
}
}
cout << "]" << endl;
}
}
if (AAAAvpContainer* c_appid = msg.acl.search("Acct-Application-Id"))
{
for (i=0; i<c_appid->size(); i++)
{
diameter_integer32_t appid = (*c_appid)[i]->integer32_val;
cout << "Acct-Application-Id = " << appid << endl;
}
}
if (AAAAvpContainer* c_dhost = msg.acl.search("Destination-Host"))
{
for (i=0; i<c_dhost->size(); i++)
{
diameter_identity_t dhost = (*c_dhost)[i]->identity_val;
cout << "Destination-Host = " << dhost->data() << endl;
}
}
if (AAAAvpContainer* c_rrecord = msg.acl.search("Route-Record"))
{
for (i=0; i<c_rrecord->size(); i++)
{
diameter_identity_t rrecord = (*c_rrecord)[i]->identity_val;
cout << "Route-Record = " << rrecord->data() << endl;
}
}
if (AAAAvpContainer* c_any = msg.acl.search("AVP"))
{
for (i=0; i<c_any->size(); i++)
{
avp_t any = (*c_any)[i]->avp_val;
cout << "Received one AVP of type
cout << " please parse this AVP by yourself" << endl;
memcpy(rAvp, any->c_str(), rAvp_len = any->length());
}
}
msg.acl.releaseContainers();
}
A.1.3. Output Parser Usage
The following sample code shows how high-level data structures
Expires April, 2003 [Page 34]
Internet-Draft Diameter C++ API October 2, 2002
corresponding to a Diameter message is parsed into octet string data.
// This is a test for NAS to originate a request message
void
stest_nas_request(char *buf, int size)
{
AAAAvpContainerManager cm;
AAAAvpContainerEntryManager em;
AAAAvpContainer *c_appid = cm.acquire("Acct-Application-Id");
AAAAvpContainer *c_dhost = cm.acquire("Destination-Host");
hdr_flag flag = {1,1,0};
AAADiameterHeader h(1, 0, flag, 9999999, 0, 1, 10);
AAAMessage msg;
AAAAvpContainerEntry *e;
cout << __FUNCTION__ << endl;
msg.hdr = h;
HeaderParser hp;
AAAMessageBuffer headerBuffer, payloadBuffer;
headerBuffer = AAAMessageBuffer(buf, HEADER_SIZE);
// The first call of hp.set() checks validity of
// flags and gets a AAACommand structure.
hp.setRawData(&headerBuffer);
hp.setAppData(&msg.hdr);
hp.setOption(PARSE_STRICT);
try {
hp.parseAppToRaw();
}
catch (AAAErrorStatus st) {
cout << "header error" << endl;
exit(1);
}
e = em.acquire(AAA_AVP_INTEGER32_TYPE);
diameter_integer32_t *appid = &e->integer32_val;
c_appid->add(e);
e = em.acquire(AAA_AVP_DIAMID_TYPE);
diameter_identity_t dhost = e->identity_val;
c_dhost->add(e);
msg.acl.add(c_dhost);
msg.acl.add(c_appid);
/* Acct-Application-Id */
*appid = 1;
/* Destination-Host */
dhost->assign("aaa.com");
PayloadParser pp;
payloadBuffer =
AAAMessageBuffer(buf + HEADER_SIZE, size - HEADER_SIZE);
pp.setRawData(&payloadBuffer);
pp.setAppData(&msg.acl);
Expires April, 2003 [Page 35]
Internet-Draft Diameter C++ API October 2, 2002
pp.setDictData(hp.getDictData());
try {
pp.parseAppToRaw();
}
catch (AAAErrorStatus st)
{
cout << "assemble failed" << endl;
exit(1);
}
msg.hdr.length = HEADER_SIZE + payloadBuffer.offset;
// Set the actual message length to header
try {
hp.parseAppToRaw();
}
catch (AAAErrorStatus st)
{
cout << "header error" << endl;
exit(1);
}
cout << "assemble success. total length = "
<< msg.hdr.length << endl;
// release all containers after parse.
msg.acl.releaseContainers();
}
A.1.4. Relay/Proxy Agent Parser Usage
The following sample code shows how a Diameter relay or proxy agent
handles messages, expecically adding Route-Record and Proxy-Info AVPs
without using command dictinoary.
void
stest_proxy_request(char *buf, int size)
{
AAAMessage msg;
HeaderParser hp;
AAAMessageBuffer aBuffer;
AAAAvpContainerManager cm;
AAAAvpContainerEntryManager em;
AAAAvpContainerEntry *e;
cout << __FUNCTION__ << endl;
// parse header
aBuffer = AAAMessageBuffer(buf, HEADER_SIZE);
hp.setRawData(&aBuffer);
hp.setAppData(&msg.hdr);
hp.setOption(PARSE_LOOSE);
try {
hp.parseRawToApp();
Expires April, 2003 [Page 36]
Internet-Draft Diameter C++ API October 2, 2002
}
catch (AAAErrorStatus st) {
cout << "header error" << endl;
exit(1);
}
AAAAvpContainer *c_prinfo = cm.acquire("Proxy-Info");
AAAAvpContainer *c_rrecord = cm.acquire("Route-Record");
AAAAvpContainer *c_any = cm.acquire("AVP"); // wildcard AVP
msg.acl.add(c_rrecord);
msg.acl.add(c_prinfo);
msg.acl.add(c_any);
PayloadParser pp;
aBuffer = AAAMessageBuffer(buf+HEADER_SIZE, msg.hdr.length - HEADER_SIZE);
pp.setRawData(&aBuffer);
pp.setAppData(&msg.acl);
pp.setDictData(NULL); // No dictionary to be used.
try {
pp.parseRawToApp();
}
catch (AAAErrorStatus st)
{
cout << "failed to get specific sets of AVPs." << endl;
exit(1);
}
// add one Route-Record AVP
e = em.acquire(AAA_AVP_DIAMID_TYPE);
c_rrecord->add(e);
diameter_identity_t rrecord = e->identity_val;
rrecord->assign("xxx.com");
// add one Proxy-Info AVP
e = em.acquire(AAA_AVP_GROUPED_TYPE);
diameter_grouped_t group = e->grouped_val;
c_prinfo->add(e);
AAAAvpContainer *c_prhost = cm.acquire("Proxy-Host");
e = em.acquire(AAA_AVP_DIAMID_TYPE);
diameter_identity_t prhost = e->identity_val;
prhost->assign("bbb.ccc.com");
c_prhost->add(e);
group->add(c_prhost);
AAAAvpContainer *c_prstate = cm.acquire("Proxy-State");
e = em.acquire(AAA_AVP_DIAMID_TYPE);
diameter_identity_t prstate = e->identity_val;
prstate->assign("abcde");
c_prstate->add(e);
group->add(c_prstate);
// Move the wildcard AVP container to the head, since this container
// may contain AVPs that are position-constraint.
msg.acl.remove(c_any);
msg.acl.prepend(c_any);
Expires April, 2003 [Page 37]
Internet-Draft Diameter C++ API October 2, 2002
aBuffer = AAAMessageBuffer(buf+HEADER_SIZE, size - HEADER_SIZE);
try {
pp.parseAppToRaw();
}
catch (AAAErrorStatus st)
{
cout << "failed to set specific sets of AVPs." << endl;
exit(1);
}
// adjast the header;
msg.hdr.length = HEADER_SIZE + aBuffer.offset;
aBuffer = AAAMessageBuffer(buf, HEADER_SIZE);
try {
hp.parseAppToRaw();
}
catch (AAAErrorStatus st)
{
cout << "header error" << endl;
}
cout << "setting specific avp success. total length (must be 108) = "
<< msg.hdr.length << endl;
// release container after parse.
msg.acl.releaseContainers();
}
A.2. Application Usage
A.2.1. Client Application Usage
The following is a sample shows how a client application can
start a session, subscribe to a message and send a service
specific request within a threaded context.
// An instance of the client application core
AAAApplicationCore clientCore;
// An implementation of a message subscription
// Note that event needs to be overridden
class ClientMsgSubscription : public AAAMessageSubscription {
public:
ClientMsgSubscription(AAAMessageArg *messageArg) :
AAAMessageSubscription(messageArg) {};
virtual AAAReturnCode Event();
};
// Event implementation
AAAReturnCode ClientMsgSubscription::Event() {
AAAMessageArg *msg = (AAAMessageArg*)arg;
Expires April, 2003 [Page 38]
Internet-Draft Diameter C++ API October 2, 2002
cout << "CLIENT: " << "MsgSubscription: code=" << msg->message.hdr.code;
cout << ", vendor=" << msg->message.hdr.vendor << endl;
//
// Lookup client session can be done via session id AVP of the message
//
AAASessionLookup lookup(clientCore);
AAASessionClient *client = (AAASessionClient*)lookup.Query(&msg->message);
// **** PROCESS MESSAGE HERE ****
//
// containers allocated by parser can now be released here
//
msg->message.acl.releaseContainers();
return (AAA_ERR_SUCCESS);
}
// Sample client thread function
void *clientThread(void *arg)
{
//
// Load configuration file and
// create active instance of
// application core
//
clientCore.Open("client.conf");
clientCore.SetApplicationId(NASREQ);
//
// Setup message arg
//
AAAMessageArg msgArg;
msgArg.message.hdr.code = ...;
msgArg.message.hdr.vendor = 0;
//
// Subscribe to a messsage
//
AAAEventNotification notifier(clientCore);
ClientMsgSubscription msgSub(&msgArg);
notifier.Subscribe(&msgSub);
//
// Initiate a client session
//
AAASessionClient clntSession(clientCore);
clntSession.Start();
//
// Formulate a service specific messasge here
// and transmit
//
....
Expires April, 2003 [Page 39]
Internet-Draft Diameter C++ API October 2, 2002
....
AAAMessageControl msgControl(clntSession);
msgControl.Send(&srvcMsg);
//
// **** INITIATE A SYSTEM SPECIFIC IDLE LOOP HERE
//
...
...
//
// Cleanup session when done
//
clntSession.End();
return (NULL);
}
A.2.2. Server Application Usage
The following is a sample shows how a server application can start a
server session, subscribe to a message and accept (or reject) an
incomming request.
// An instance of the server application core and a server session
AAAApplicationCore serverCore;
AAASessionServer serverSession;
// An implementation of a message subscription
// Note that event needs to be overridden
class ServerMsgSubscription : public AAAMessageSubscription {
public:
ServerMsgSubscription(AAAMessageArg *messageArg) :
AAAMessageSubscription(messageArg) {};
virtual AAAReturnCode Event();
};
// Event implementation
AAAReturnCode ServerMsgSubscription::Event()
{
AAAMessageArg *msg = (AAAMessageArg*)arg;
cout << "SERVER: Event subscribtion: code=" << msg->message.hdr.code;
cout << ", vendor=" << msg->message.hdr.vendor << endl;
//
// Inspect message here and decide wether to accept or reject
//
...
...
//
Expires April, 2003 [Page 40]
Internet-Draft Diameter C++ API October 2, 2002
// A server can accept or reject an incomming service
// specific request within the messsage event context.
//
serverSession.Accept(&msg->message);
//
// containers allocated by parser can now be released here
//
msg->message.acl.releaseContainers();
return (AAA_ERR_SUCCESS);
}
// Sample server thread function
void *serverThread(void *arg)
{
//
// Load configuration file and
// create active instance of
// application core
//
serverCore.Open("server.conf");
serverCore.SetApplicationId(NASREQ);
//
// Setup message arg
//
AAAMessageArg msgArg;
msgArg.message.hdr.code = ...;
msgArg.message.hdr.vendor = 0;
//
// Subscribe to a messsage
//
AAAEventNotification notifier(serverCore);
ClientMsgSubscription msgSub(&msgArg);
notifier.Subscribe(&msgSub);
//
// **** INITIATE A SYSTEM SPECIFIC IDLE LOOP HERE
//
...
...
return (NULL);
}
Expires April, 2003 [Page 41]
| PAFTECH AB 2003-2026 | 2026-04-22 14:12:30 |