INTERNET DRAFT James Kempf Category: Informational Pat Calhoun Title: draft-ietf-aaa-diameter-api-01.txt David Frascone Date: July 2001 Sun Microsystems, Inc. The DIAMETER API Status of this Memo This document is a working group contribution for consideration by the AAA Working Group of the Internet Engineering Task Force. Distribution of this memo is unlimited. This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026. 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. Copyright (C) The Internet Society 2001. All Rights Reserved. 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 in both the C and Java languages. The intent of the API is to foster source code portability across multiple programming platforms. Kempf, Calhoun, Frascone expires January 2002 [Page 1] INTERNET DRAFT July 2001 Table of Contents 1.0 Introduction 2.0 Binding Independent Considerations 2.1 Multithreading 2.2 Error Reporting 2.3 String Format 2.4 Handling Connections with Other Servers/Peers 2.5 Command Dictionary File 3.0 C API 3.1 Constant Types 3.1.1 IP Address and Port 3.1.2 Command Code 3.1.3 Vendor Identifier 3.1.4 Extension Identifier 3.1.5 Attribute/Value Pair Code 3.1.6 Value Type Identifier 3.1.7 Server Type 3.1.8 Session Identifier 3.1.9 Message Identifier 3.1.10 Callback Handle 3.1.11 Application Identifier 3.1.12 API Return Codes 3.1.13 Callback Location Codes 3.1.14 AVP Data Type Codes 3.1.15 AVP Flags 3.1.16 Domain Interconnection Types 3.1.17 Message Flags 3.1.18 Result Codes 3.1.19 Search Direction Type 3.1.20 Accounting 3.2 Structure Definitions 3.2.1 Dictionary Entry Definition 3.2.2 AVP Definition 3.2.3 AVP List 3.2.4 Message Definition 3.3 Macros and Preprocessor Definitions 3.4 Functions 3.4.1 Initialization and Configuration 3.4.2 Registering Commands 3.4.3 Session and Server Management 3.4.4 Dictionary Lookup 3.4.5 Message Management 3.4.6 Message Control 3.4.7 Accounting 3.5 Implementation Notes 3.5.1 Grouped AVPs 3.5.2 Extended AAA_AVP structure Kempf, Calhoun, Frascone expires January 2002 [Page 2] INTERNET DRAFT July 2001 3.5.3 Avoiding AVP Copying 4.0 Java API 4.1 Introduction 4.1.1 Client API Overview 4.1.2 Server API Overview 4.1.3 Reflection Classes Overview 4.1.4 Packages and Properties 4.2 Errors and Exceptions 4.2.1 Class AAAException 4.2.2 Class AAAMessageException 4.3 Library Management and Dictionary Management 4.3.1 Class AAA 4.3.2 Class AAACommandDictionary 4.3.3 Class AVPDescriptor 4.3.4 Class AAACommandDescriptor 4.2.5 Class AAAExtension 4.4 Messages and AVPs 4.4.1 Class AAAMessage 4.4.2 Class AVP 4.4.3 Class EncapsulatingAVP 4.5 Session Management 4.5.1 Class AAASessionManager 4.5.2 Class AAAClientSessionManager 4.5.3 Class AAAServerSessionManager 4.5.4 Class UnsolicitedExceptionHandler 4.5.5 Class AAAMessageListener 4.6 Server API 4.6.1 Class AAAServer 4.6.2 Interface AAAMessageListenerFactory 4.7 Implementation Considerations 4.7.1 Dynamic Linking of Command Handling Classes 4.7.2 State Machine Maintenance 4.7.3 Server-side Access to Session Identifiers 4.7.4 Server Proxy and Redirect Implementation 5.0 Security Considerations 6.0 References 7.0 Authors' Addresses 8.0 Full Copyright Statement 1.0 Introduction The Diameter authentication, authorization and accounting (AAA) protocol provides scalable AAA support for peering transactions across the Internet [1]. This document describes standardized APIs in C and Java for applications to access the Diameter protocol. While a standardized API is not strictly necessary for protocol interoperability, it does help to promote the use and deployment of a Kempf, Calhoun, Frascone expires January 2002 [Page 3] INTERNET DRAFT July 2001 protocol by reducing the amount of work necessary to develop and access applications that use the protocol. The Diameter protocol provides a basic attribute/value pair (AVP) data format, which particular application profiles extend. Processing of the extensions is handled by code specific to the application profile. Application profile customizability is reflected into the API as callback functions for C. The callbacks implement the application profile processing for incoming messages. For outgoing calls, the C API provides an asynchronous model, leaving processing of the return message to the callbacks. In the Java API, the outgoing message and incoming reply are processed synchronously on the client side, and asynchronously on the server side. For the most part, the API hides the details of establishing peering and redirect connections, parsing and creating Diameter messages, and other work necessary to set up and maintain a redirect or peering session. The application profile code need only be concerned with processing of the AVPs defined in the application profile. 2.0 Binding Independent Considerations This section discusses a number of implementation considerations for both the C and Java language bindings with language specific notes where appropriate. 2.1 Multithreading Both C and Java APIs are expected to be thread-safe. Access to data structures shared among threads must be co-ordinated to avoid corruption or invalid access. In addition, API implementors are encouraged to provide the maximum amount of parallel processing within their library implementations by allowing multiple threads in the API library at once. 2.2 Error Reporting The APIs report errors resulting from client calls through language specific mechanisms. The functions in the C API return a error code, while the Java methods throw exceptions. API implementors are additionally encouraged to log errors using the appropriate platform specific error logging technique, especially for errors that result from network processing or other causes that are not directly related to an API function or method call. The Java API provides a callback to handle exceptions that occur during processing of unsolicited messages. This can be used on the server side to report errors Kempf, Calhoun, Frascone expires January 2002 [Page 4] INTERNET DRAFT July 2001 occuring during message parsing to a log file, and on the client side to report errors in a client-specific way for unsolicited messages. Error messages received in response to a message are reported directly to the client application code in Java by means of an exception. 2.3 String Format C API clients are required to format strings as UTF-8 if the string contains 16 bit characters. Since the ASCII characters and the UTF-8 8 bit characters have the same codes, ASCII can be used for UTF-8 if no wide characters are in the string. All strings passed through the C API are standard null-terminated C strings. Processing to remove the null terminator for transmission on the wire is done by the library. Strings passed through the Java API are Unicode strings. The library takes care of conversion to UTF-8. 2.4 Handling Connections with Other Servers/Peers Both the C and Java API contain support for making a connection with an arbitrary Diameter peer. The C API support allows an API client to set the server address in a message (AAASetServer()). The Java API allows the client to start a session with a specific server, and the session id is used to send messages (AAASessionManager.send()) If a message is not sent to a particular server in C, the API library is required to infer the servers by either looking in the configuration files or dynamically determining the servers that support the extension. Dynamic determination is possible using means such as SLP [6]. 2.5 Command Dictionary File The commands that can be parsed by the local Diameter client library or server are defined in a command dictionary file containing the command definitions including AVPs. The location and name of the command dictionary file is platform-specific. This file is read and parsed to drive creation of a command dictionary which is used by the library to parse commands. The syntax for the command dictionary file is in XML and a DTD described it is available in [7]. XML was selected as the definition language because support for XML parsing is available as an extension to the standard Java APIs [8] and as a wide variety of public-domain C libraries, simplifying implementation. Both APIs also support programmatic definition of commands, AVPs, and extensions so programs can add commands not in the dictionary for purposes of experimentation and implementing the Kempf, Calhoun, Frascone expires January 2002 [Page 5] INTERNET DRAFT July 2001 library. 3.0 C API The C language API is designed around callbacks. An application profile defines a collection of Diameter commands, and a library of callbacks for processing those commands. Each command is processed by a callback. Callbacks can also be defined that handle all commands. The API provides functions for managing callbacks, including registration and deregistration. When an incoming Diameter command arrives, the command is parsed and passed to the appropriate callback. The callback receives as a parameter the message struct, which contains the AVPs for the command. The callback code can process the command by stepping through the AVPs. For outgoing requests, the API provides functions for creating messages and adding AVPs. A collection of functions also provides access to the AVP dictionary. Unless otherwise noted, parameters to API functions and callbacks are non-NULL. Some parameters may have other restrictions. If a parameter fails to satisfy the restrictions on its value, the function returns AAA_ERR_PARAMETER. 3.1 Constant Types 3.1.1 IP Address and Port 3.1.1.1 Synopsis typedef sockaddr_storage IP_ADDR; 3.1.1.2 Description IP_ADDR provides a way of referring to an IPv4 address, IPv6 address, and IP port. The default implementation (shown here) is defined in the Basic Socket Interface Extensions for IPv6 RFC[10]. 3.1.2 Command Code 3.1.2.1 Synopsis Kempf, Calhoun, Frascone expires January 2002 [Page 6] INTERNET DRAFT July 2001 typedef uint32_t AAACommandCode; 3.1.2.2 Description AAACommandCode provides a way of referring to the AAA command code of a command. It is used when registering callbacks, among others. 3.1.3 Vendor Identifier 3.1.3.1 Synopsis typedef uint32_t AAAVendorId; 3.1.3.2 Description AAAVendorId provides a way of referring to the vendor identification code. It is used when registering callbacks, among others. Note that vendor id 0 is reserved and is defined by the preprocessor constant AAA_NO_VENDOR_ID. 3.1.4 Extension Identifier 3.1.4.1 Synopsis typedef uint32_t AAAExtensionId; 3.1.4.2 Description AAAExtensionId provides a way of referring to an application profile extension, for registering callbacks and other purposes. 3.1.5 Attribute/Value Pair Code 3.1.5.1 Synopsis typedef uint32_t AAA_AVPCode; 3.1.5.2 Description Kempf, Calhoun, Frascone expires January 2002 [Page 7] INTERNET DRAFT July 2001 AAA_AVPCode provides a way of referring to the code number of an AVP. It is used as a parameter to the dictionary functions, and a field in the AVP struct. 3.1.6 Value Type Identifier 3.1.6.1 Synopsis typedef int32_t AAAValue 3.1.6.2 Description AAAValue provides a way of referring to particular dictionary-defined values. It is used in the dictionary API. 3.1.7 Server Type 3.1.7.1 Synopsis typedef void AAAServer; 3.1.7.2 Description AAAServer is an identifier for a particular serving peer. It is used in the server access functions. 3.1.8 Session Identifier 3.1.8.1 Synopsis typedef void AAASessionId; 3.1.8.2 Description AAASessionId is an identifier for a particular AAA session. It is used in the session APIs and when a message is created. 3.1.9 Message Identifier Kempf, Calhoun, Frascone expires January 2002 [Page 8] INTERNET DRAFT July 2001 3.1.9.1 Synopsis typedef uint32_t AAAMsgIdentifier; 3.1.9.2 Description AAAMsgIdentifier is a unique identifier for an AAA message. Each individual message is marked with an identifier. 3.1.10 Callback Handle 3.1.10.1 Synopsis typedef void AAACallbackHandle; 3.1.10.2 Description AAACallbackHandle is a type for representing the callback handle returned to the client when a callback is registered. 3.1.11 Application Identifier 3.1.11.1 Synopsis typedef void* AAAApplicationId; 3.1.11.2 Definition 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.12 API Return Codes The following status codes are returned by functions in the AAA API: typedef enum { AAA_ERR_NOT_FOUND = -2, AAA_ERR_FAILURE = -1, Kempf, Calhoun, Frascone expires January 2002 [Page 9] INTERNET DRAFT July 2001 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, } AAAReturnCode; Note that these status codes are separate from the codes returned by remote AAA servers. The following is a description of the error codes and the reasons why they can be returned: AAA_ERR_NOT_FOUND - This code is returned if a handle or id was not found. AAA_ERR_FAILURE - This code is returned if an unspecified failure occurred during an AAA operation. AAA_ERR_SUCCESS - This code is returned if the AAA operation succeeded. AAA_ERR_NOMEM - This code is returned if the operation caused memory to be exhausted. AAA_ERR_PROTO - This code is returned if a AAA protocol error occurred. AAA_ERR_SECURITY - This code is returned if a security check failed or another security error occurred. AAA_ERR_PARAMETER - This code is returned if an invalid parameter was passed to an AAA function. AAA_ERR_CONFIG - This code is returned if an error was encountered in a configuration file during library initialization. Kempf, Calhoun, Frascone expires January 2002 [Page 10] INTERNET DRAFT July 2001 AAA_ERR_UNKNOWN_CMD - This code is returned if the library received a AAA command that is not in the set of registered AAA commands. AAA_ERR_MISSING_AVP - This code is returned if a command was received without a required AVP. AAA_ERR_ALREADY_INIT - This code is returned if an attempt is made to initialize the AAA library when it has already been initialized. AAA_ERR_TIMED_OUT - This code is returned when a network operation times out. AAA_ERR_CANNOT_SEND_MSG - This code is returned if the library can't send a message. It is also of used to application profile extensions that encounter the same error condition. AAA_ERR_ALREADY_REGISTERED - This code is returned by the command registration functions if the command was already registered. AAA_ERR_CANNOT_REGISTER - This code is returned by the command registration functions if the command could not be registered. AAA_ERR_NOT_INITIALIZED - This code is returned by any function in the API except AAAOpen() if the library hasn't been initialized. AAA_ERR_NETWORK_ERROR - This code is returned by any function if an error in networking occurs. In addition to returning the error code, functions are required to log errors using the platform dependent logging facility. 3.1.13 Callback Location Codes The following are codes used to indicate where a callback should be installed in callback chain for processing: typedef enum { AAA_APP_INSTALL_FIRST, AAA_APP_INSTALL_ANYWHERE, AAA_APP_INSTALL_LAST } AAACallbackLocation; Kempf, Calhoun, Frascone expires January 2002 [Page 11] INTERNET DRAFT July 2001 Callbacks installed with AAA_APP_INSTALL_FIRST and AAA_APP_INSTALL_LAST operate on all commands, callbacks installed with AAA_APP_INSTALL_ANYWHERE just operate on the command for which they are installed. The codes have the following semantics: AAA_APP_INSTALL_FIRST - Install this callback as the first callback in the chain. If subsequent callbacks are installed with this code, then AAA_ERR_ALREADY_REGISTERED is returned. AAA_APP_INSTALL_ANYWHERE - Install this callback anywhere in the callback chain. AAA_APP_INSTALL_LAST - Install this callback as the last callback in the chain. If subsequent callbacks are installed with this code, then AAA_ERR_ALREADY_REGISTERED is returned. 3.1.14 AVP Data Type Codes The following are AVP data type codes. They correspond directly to the AVP data types outline in the Diameter specification [1]: typedef enum { AAA_AVP_DATA_TYPE, AAA_AVP_STRING_TYPE, AAA_AVP_ADDRESS_TYPE, AAA_AVP_INTEGER32_TYPE, AAA_AVP_INTEGER64_TYPE, AAA_AVP_TIME_TYPE, } AAA_AVPDataType; 3.1.15 AVP Flags The following are used for AVP header flags and for flags in the AVP wrapper struct and AVP dictionary definitions. The first six correspond to the AVP flags defined in the Diameter specification [1]. Some of these are also used in the wrapper struct and dictionary definitions also. The last four are used only in AAA_AVP and AAADictionaryEntry: typedef enum { AAA_AVP_FLAG_NONE = 0, Kempf, Calhoun, Frascone expires January 2002 [Page 12] INTERNET DRAFT July 2001 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; The semantics of the flags are as follows: AAA_AVP_FLAG_NONE -Indicates that no AVP flags are set. AAA_AVP_FLAG_MANDATORY - Represents the 'M' flag in the Diameter AVP header [1], meaning the AVP is mandatory. AAA_AVP_FLAG_RESERVED - Represents the 'R' flag in the Diameter AVP header [1]. This flag is reserved and should not be set. AAA_AVP_FLAG_VENDOR_SPECIFIC - Represents the 'V' flag in the Diameter AVP header [1], meaning that the AVP is vendor specific. If this flag is set, the header will contain a vendor identifier. AAA_AVP_FLAG_END_TO_END_ENCRYPT - Represents the 'P' flag in the Diameter AVP header [1], meaning that the AVP is end-to-end encrypted [3]. AAA_AVP_FLAG_UNKNOWN - Indicates that the AVP was not located in the AVP dictionary. This flag is only used in AAA_AVP. AAA_AVP_FLAG_ENCRYPT - Indicates that the AVP was either marked as AAA_AVP_FLAG_END_TO_END_ENCRYPT or that it was hop-by-hop encrypted (and thus that the AAA_AVP_FLAG_END_TO_END_ENCRYPT flag is not set on in the AVP header). If the AVP is not end-to-end encrypted, then it will be either one of the two standard hop-by-hop encrypted AVPs, Integrity-Check-Value and Encrypted-Payload [1]. This flag is only used in AAA_AVP. 3.1.16 Domain Interconnection Types Kempf, Calhoun, Frascone expires January 2002 [Page 13] INTERNET DRAFT July 2001 The following domain interconnection types are returned by AAAGetDomainInternconnectType(). They indicate the type of domain interconnection: typedef enum { AAA_DOMAIN_LOCAL, AAA_DOMAIN_PROXY, AAA_DOMAIN_BROKER, AAA_DOMAIN_FORWARD } AAADomainInterconnect; The flags have the following semantics: AAA_DOMAIN_LOCAL - The domain name is for the local domain. AAA_DOMAIN_PROXY - The domain name is for a proxy domain. A proxy is a server that simply forwards the request based on the user's identity or through some other means. The routing method used for a proxy is the Proxy-State method, requiring routing through a fixed chain of proxies [1]. AAA_DOMAIN_BROKER - The domain name is for a broker domain. A broker is a server that provides redirect services, allowing all servers in a roaming consortium to interact directly. AAA_DOMAIN_FORWARD - The domain name is for a forwarding domain. A forwarding domain is a proxy that uses Destination-NAI routing. With Destination-NAI routing, there is no set sequence of proxies through which messages must be routed [1]. 3.1.17 Message Flags The following type is for the AAA message flags. Currently, there are no message flags defined in the Diameter protocol [1]: typedef uint8_t AAAMsgFlag; 3.1.18 Result Codes The following are the result codes returned from remote servers as part of messages. They correspond directly to the result codes in the Diameter specification [1]: Kempf, Calhoun, Frascone expires January 2002 [Page 14] INTERNET DRAFT July 2001 typedef enum { AAA_SUCCESS = 0, AAA_FAILURE, AAA_POOR_REQUEST, AAA_INVALID_AUTH, AAA_UNKNOWN_SESSION_ID, AAA_USER_UNKNOWN, AAA_COMMAND_UNSUPPORTED, AAA_TIMEOUT, AAA_AVP_UNSUPPORTED, AAA_REDIRECT_INDICATION, AAA_REALM_NOT_SERVED, AAA_UNSUPPORTED_TRANSFORM, AAA_AUTHENTICATION_REJECTED, AAA_AUTHORIZATION_REJECTED, AAA_INVALID_AVP_VALUE, AAA_MISSING_AVP, AAA_UNABLE_TO_DELIVER } AAAResultCode; 3.1.19 Search Direction Type The following type allows the client to specify which direction to search for an AVP in the AVP list: typedef enum { AAA_FORWARD_SEARCH = 0, AAA_BACKWARD_SEARCH } AAASearchType; 3.1.20 Accounting Types The following type allows the client to specify which direction to search for an AVP in the AVP list: typedef enum { AAA_ACCT_EVENT = 1, AAA_ACCT_START = 2, AAA_ACCT_INTERIM = 3, AAA_ACCT_STOP = 4 } AAAAcctMessageType; 3.2 Structure Definitions Kempf, Calhoun, Frascone expires January 2002 [Page 15] INTERNET DRAFT July 2001 3.2.1 Dictionary Entry Definition The following structure is returned by the dictionary entry lookup functions. It contains information about a particular AVP in the dictionary: typedef struct dictionaryEntry { AAA_AVPCode avpCode; char* avpName; AAA_AVPDataType avpType; AAAVendorId vendorId; AAA_AVPFlag flags; } AAADictionaryEntry; 3.2.2 AVP Definition The following structure contains a message AVP in parsed form: typedef struct avp { enum { AAA_RADIUS, AAA_DIAMETER } packetType; AAA_AVPCode code; uint16_t length; AAA_AVPFlag flags; AAA_AVPDataType type; AAAVendorId vendorId; void* data; } AAA_AVP; The fields have the following definitions: packetType - Indicates whether the message is for Diameter or for Radius compatibility. If the AVP is for Radius, then the code, length, type, and data fields are the only valid fields in the structure; the other fields are all null. code - The AVP code. The type of the AVP can be determined by matching the AVP code with an AVP description from the dictionary. length - The length of the AVP's data field. flags - The AVP flags. Kempf, Calhoun, Frascone expires January 2002 [Page 16] INTERNET DRAFT July 2001 type - The data type of the AVP's data. vendorId - The vendor id, if the AVP is vendor-specific. If the AVP is standardized, the vendorId field is set to AAA_NO_VENDOR_ID. data - The AVP data, in host byte order. 3.2.3 AVP List The following structure is used for represnting lists of AVPs on the message: typedef struct avpList{ AAA_AVP *head; AAA_AVP *tail; } AAA_AVP_LIST; AVPs are kept in ordered lists. The client can use a search direction to indicated in which direction to search when trying to find an AVP. 3.2.4 Message Definition The following structure contains the full AAA message: typedef struct message { AAAMsgFlag flags; AAACommandCode commandCode; AAAVendorId vendorId; AAAResultCode resultCode; IP_ADDR originator; IP_ADDR sender; AAA_AVP_LIST *avpList; AAA_AVP *proxyAVP; AAAMsgIdentifier identifier; time_t secondsTillExpire; time_t startTime; void *appHandle; } AAAMessage; The fields have the following definition: flags - The message flags. Currently this field is always zero, since there are no flags defined for a Diameter message at this time. Kempf, Calhoun, Frascone expires January 2002 [Page 17] INTERNET DRAFT July 2001 commandCode - The command's message code. vendorId - The vendor id of the vendor that defined the message. resultCode - Code indicating the result of the client's request. This code is sent by the peer over the wire. originatorVersion - The IP version of the originator's address. originator - The IP address of the message's originator. senderVersion - The IP version of the sender's address. sender - The IP address of the message's previous hop sender. This is only the same as originator if no proxy or broker peers are being used. port - The port on which the message was received. avpList - The list of AVPs in the message. proxyAVP - The proxy's AVP, if any. Otherwise NULL. identifier - The message's unique identifier. secondsTillExpire - Number of seconds until the message expires. startTime - The number of seconds at which the message was started. appHandle - An identifier indicating for which client session the message is. 3.3 Macros and Preprocessor Definitions The following definition reserves the vendor id of 0: #define AAA_NO_VENDOR_ID 0 3.4 Functions 3.4.1 Initialization and Configuration This section contains definitions that perform initialization and configuration of the AAA library. Kempf, Calhoun, Frascone expires January 2002 [Page 18] INTERNET DRAFT July 2001 3.4.1.1 AAAOpen() The following function is used to open and configure the AAA library: AAAReturnCode AAAOpen(char *configFileName); This function must be called before any other AAA function is called. Some of the operations that may be performed by AAAOpen() are: opening and loading the AVP and vendor dictionaries, opening connections with Diameter peers, loading Diameter extension libraries, and registering Diameter callbacks. After AAAOpen() returns, the library must be ready for the client to open a session. Parameters are: configFileName - The global configuration file name. If NULL or the empty string, use the default for this platform. The global configuration file must contain the vendor and AVP dictionary file names, and may contain other platform-specific information needed to initialize and configure the Diameter peer. Return values are: AAA_ERR_SUCCESS - If initialization succeeded. AAA_ERR_ALREADY_INIT - If the library is already initialized. AAA_ERR_NETWORK_ERROR - If the host name can't be determined. AAA_ERR_NOMEM - If no memory was available. AAA_ERR_CONFIG - If processing the dictionary or configuration information failed. 3.4.1.2 AAAClose() The following function closes the AAA library: AAAReturnCode AAAClose(); After this function is called, all other AAA functions are no longer operative. Return values are: Kempf, Calhoun, Frascone expires January 2002 [Page 19] INTERNET DRAFT July 2001 AAA_ERR_SUCCESS - If finalization succeeded. AAA_ERR_NOT_INIITIALIZED - If AAA was not initialized. 3.4.1.3 AAAGetDefaultConfigFileName() The following returns the default configuration file name on the platform: const char *AAAGetDefaultConfigFileName(); The return value is a pointer to the full pathname for the file. The pointer value should not be deallocated because it is constant and does not change. 3.4.2 Registering Commands The functions in this section are used to register callback functions defined in a Diameter application profile extension library. The following typedef defines the interface between callback functions and the AAA library functions: typedef AAAReturnCode (*func)(AAAMessage *message) AAACallback; Authors of Diameter extensions must define command callback functions having this interface. Parameters are: message - The AAAMessage to be processed. The return value is a status code giving the operation status. 3.4.2.1 AAARegisterCommandCallback() The following function is used to register command callbacks for processing AAA commands: AAACallbackHandle * AAARegisterCommandCallback(AAACommandCode commandCode, AAAVendorId vendorId, char *commandName, AAAExtensionId extensionId, AAACallback callback, AAACallbackLocation position); Kempf, Calhoun, Frascone expires January 2002 [Page 20] INTERNET DRAFT July 2001 Parameters are: commandCode - The code of the command processed by the callback. vendorId - The vendor id of the command. commandName - A pointer to the name of the command. extensionId - The id of the extension to which this command belongs. callback - The callback function to perform processing. position - The position of the callback in the chain. The return value is a handle used when deregistering the callback, or NULL if an error occurred while registering the callback. 3.4.2.2 AAARegisterNoncommandCallback() The following callback registers an AAA callback to process all messages. The callback is not associated with any command, but rather will process all messages as they come down the callback chain: AAACallbackHandle AAARegisterNoncommandCallback(AAACallback callback, AAACallbackLocation position); Parameters are: callback - The callback function to perform processing. position - The position of the callback in the chain. The return value is a handle used when deregistering the callback, or NULL if an error occurred while registering the callback. 3.4.2.3 AAADeregisterCommandCallback() The following function deregisters a command callback: AAAReturnCode AAADeregisterCommandCallback(AAACallbackHandle *handle); Parameters are: Kempf, Calhoun, Frascone expires January 2002 [Page 21] INTERNET DRAFT July 2001 handle - The handle returned when the callback was registered. The return values are: AAA_ERR_SUCCESS - Returned upon completion. AAA_ERR_FAILURE - if the callback is not registered. 3.4.2.4 AAADeregisterNoncommandCallback() The following function is used to deregister a noncommand callback: AAAReturnCode AAADeregisterNoncommandCallback(AAACallbackHandle *handle); handle - The handle returned when the callback was registered. Return values are: AAA_ERR_SUCCESS - Returned upon completion. AAA_ERR_FAILURE - If the callback is not registered. 3.4.2.5 AAARegisterExtension() The following function is used to register a Diameter extension id. This function is typically called when registering non-command specific callbacks. Extension ids for c ommand-specific callbacks are registered when the callback is registered: AAAReturnCode AAARegisterExtension(AAAExtensionId extensionId); The parameters are: extensionId - The extension id. The return codes are: AAA_ERR_SUCCESS - If the registration was successful. AAA_ERR_NOMEM - if a memory allocation failure occurred. 3.4.3 Session and Server Management Kempf, Calhoun, Frascone expires January 2002 [Page 22] INTERNET DRAFT July 2001 The functions in this section allow the client to open, close, and register sessions, and to obtain server identifiers. 3.4.3.1 AAAStartSession() The following function allows a client to start a session and identify it: AAAReturnCode AAAStartSession(AAASessionId **sessionId, AAAApplicationId appHandle, char *userName); Parameters are: sessionId - On return, a pointer to the session id for this session. appHandle - An identifier for the client application starting the session. This identifier is attached to messages so that the client callbacks can tell which messages belong to it. userName - The NAI of the user. Return values are: AAA_ERR_SUCCESS - If the session was successfully started. AAA_ERR_NOMEM - If a memory allocation failure occurred. 3.4.3.2 AAARegisterPeerSession() The following function allows a client to register a peer session that it has discovered through some other means, for example, by receiving an unsolicited message. AAAReturnCode AAARegisterPeerSession(AAASessionId **sessionId, AAAApplicationId *appHandle, AAAMessage *message, char *userName, char *hostName); The parameters are: sessionId - On return, a pointer to the local session id for the session. Kempf, Calhoun, Frascone expires January 2002 [Page 23] INTERNET DRAFT July 2001 appHandle - An identifier for the client application starting the session. This identifier is attached to messages so that the client callbacks can tell which messages belong to it. message - The message from the peer containing the session id. userName - The NAI of the user. hostName - The originator of the Diameter message Return values are: AAA_ERR_SUCCESS - If the session was successfully registered. AAA_ERR_NOMEM - If a memory allocation failure occurred. 3.4.3.3 AAAEndSession() The following function terminates a session: AAAReturnCode AAAEndSession(AAASessionId *sessionId); The parameters are: sessionId - A pointer to the session id for the session. Return values are: AAA_ERR_SUCCESS - If the session was successfully closed. AAA_ERR_NOT_FOUND - If the handle is invalid. 3.4.3.4 AAALookupServer() The function looks up the AAA server based on IP address and port number. Server connections are created from the configuration file: AAAServer *AAALookupServer(IP_ADDR ipAddr); The parameters are: ipAddr - The IP address/Port/Family of the server. The return value is either a valid server pointer or the NULL if the server can't be found. Kempf, Calhoun, Frascone expires January 2002 [Page 24] INTERNET DRAFT July 2001 3.4.3.5 AAASetSessionMessageTimeout() The following function sets the timeout, in seconds, for all AAAMessages in a particular session: AAAReturnCode AAASetSessionMessageTimeout(AAASessionId *id, time_t timeout); The parameters are: id - The session id for the session whose timeout should be changed. timeout - The session timeout. The default timeout is 120 seconds. The return values are: AAA_ERR_SUCCESS - If setting the timeout succeeded. AAA_ERR_FAILURE - If the setting the timeout failed. 3.4.3.6 AAAGetDomainInterconnectType() The following function returns the domain interconnect type for a particular domain name and type of service: AAAResultCode AAAGetDomainInterconnectType(AAAMessage *message, char *domainName, char *type); The parameters are: domainName - The name of the domain. type - The type of service. This must be one of the strings "LOCAL", "PROXY", or "BROKER". 3.4.4 Dictionary Lookup The functions in this section are used to look up AVPs and commands in the dictionary. The client is responsible for supplying the structure memory into which the dictionary information is copied. 3.4.4.1 AAADictionaryEntryFromAVPCode() Kempf, Calhoun, Frascone expires January 2002 [Page 25] INTERNET DRAFT July 2001 This function looks up a dictionary entry using a command code and a vendor id: AAAReturnCode AAADictionaryEntryFromAVPCode(AAA_AVPCode avpCode, AAAVendorId vendorId, AAADictionaryEntry *entry); The parameters are: avpCode - The code number of the AVP. vendorId - The vendor id of the AVP. entry - an AAADictionaryEntry structure for returning the entry. The return value is one of: AAA_ERR_SUCCESS - If the query succeeded. AAA_ERR_FAILURE - If no matching dictionary entry was found. 3.4.4.2 AAADictionaryEntryFromName() This function looks up a dictionary entry using command code name and vendor id: AAAReturnCode AAADictionaryEntryFromName(char *avpName, AAAVendorId vendorId, AAADictionaryEntry *entry); The parameters are: avpName - The name of the AVP. vendorId - The vendor id of the AVP. entry - an AAADictionaryEntry structure for returning the entry. The return value is one of: AAA_ERR_SUCCESS - If the query succeeded. AAA_ERR_FAILURE - If no matching dictionary entry was found. Kempf, Calhoun, Frascone expires January 2002 [Page 26] INTERNET DRAFT July 2001 3.4.4.3 AAAValueFromName() This function looks up an AVP value using the AVP name and vendor name: AAAValue AAAValueFromName(char *avpName, char *vendorName, char *valueName); The parameters are: avpName - The name of the AVP. vendorName - The name of the vendor. valueName - The name of the value. The return value is the id of the AVP, or AAA_ERR_NOT_FOUND if no match was found. 3.4.4.4 AAAValueFromAVPCode() This function looks up an AVP value using the AVP id and vendor id, and the value name: AAAValue AAAValueFromAVPCode(AAA_AVPCode avpCode, AAAVendorId vendorId, char *valueName); The parameters are: avpCode - The code of the AVP. vendorId - The id of the vendor. valueName - The name of the value. The return value is id of the AVP, or AAA_ERR_NOT_FOUND if no match was found. 3.4.4.5 AAALookupValueNameUsingValue() This function returns the AVP value name: const char *AAALookupValueNameUsingValue(AAA_AVPCode avpCode, AAAVendorId vendorId, Kempf, Calhoun, Frascone expires January 2002 [Page 27] INTERNET DRAFT July 2001 AAAValue value); The parameters are: avpCode - The code of the AVP. vendorId - The id of the vendor. value - The value. The value name is returned, or NULL if no match occurred. 3.4.4.6 AAAGetCommandCode() This function returns the command code and vendor id based on a string: boolean_t AAAGetCommandCode(char *commandName, AAACommandCode *commandCode, AAAVendorId *vendorId); The parameters are: commandName - A string containing the command name. commandCode - Pointer that on return holds the command code if the command was found. vendorId - Pointer that on return holds the vendor id if the command was found. The return value is _B_TRUE if the command was found. 3.4.5 Message Management The functions in this section allow the client to create messages, add AVPs, and traverse AVP lists. 3.4.5.1 AAANewMessage() This function allocates an AAAMessage and returns a pointer to it. If a command code is provided, this function adds the command code AVP. If the session identifier handle is provided, the Session-Id AVP is also added. Lastly, if this message is allocated in response to a request, the request's message can be provided, and the new message Kempf, Calhoun, Frascone expires January 2002 [Page 28] INTERNET DRAFT July 2001 is initialized to match the request, for fields such as the identifier, the server identifier, etc. If this is a new message, the request parameter is NULL: AAAMessage *AAANewMessage(AAACommandCode commandCode, AAAVendorId vendorId, AAASessionId *sessionId, AAAExtensionId extensionId, AAAMessage *request); The parameters are: commandCode - The command code. vendorId - The vendor identifier. sessionId - Session identifier. extensionId - The extension identifier. request - A pointer to a request message, if this message is being allocated in response to a request. The function returns a pointer to the message or NULL if a failure occurred. 3.4.5.2 AAAFreeMessage() This function frees a message allocated through AAANewMessage(): AAAReturnCode AAAFreeMessage(AAAMessage **message); The parameters are: message - A pointer to a pointer to the allocated message. The return value is the AAA status code AAA_ERR_SUCCESS. 3.4.5.3 AAARespondToMessage() This function is called to set the AAA Message to the appropriate values, and to inform the library that this message is a locally generated response AAAReturnCode AAARespondToMessage(AAAMessage* message, AAACommandCode commandCode, Kempf, Calhoun, Frascone expires January 2002 [Page 29] INTERNET DRAFT July 2001 AAAVendorId vendorId, AAAResultCode resultCode); The parameters are: message - The AAAMessage to respond to. commandCode - The command code of the response. vendorId - The vendor identifier (of the command code). resultCode - The result code of the response. The function returns AAA_ERR_SUCCESS upon completion, or AAA_ERR_PARAMETER if a NULL pointer was provided. 3.4.5.4 AAAAddProxyState() This function will add a Proxy-State AVP to a message, that contains the FQDN of the source of the message. AAAReturnCode AAAAddProxyState(AAAMessage *message) The parameters are: message - The AAAMessage to add state to. The function returns AAA_ERR_SUCCESS upon completion, or AAA_ERR_FAILURE if an error occured. 3.4.5.5 AAACreateAVP() This function creates an AVP and returns a pointer to it. The AVP is initialized from the arguments: AAAReturnCode AAACreateAVP(AAA_AVP **avp, AAA_AVPCode code, AAA_AVPFlag flags, AAAVendorId vendorId, char *data, size_t length); The parameters are: Kempf, Calhoun, Frascone expires January 2002 [Page 30] INTERNET DRAFT July 2001 avp - On return, contains a pointer to the allocated AVP, or NULL if no AVP was allocated. code - The AVP's code. flags - Any AVP flags that must be passed. vendorId - The vendor id of the AVP. If no vendor id, then AAA_NO_VENDOR_ID. data - A buffer containing the AVP data. length - The length of the data buffer. Return values are: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. AAA_ERR_PROTO - If a protocol error occurred. AAA_ERR_NOMEM - Indicating a memory failure. 3.4.5.6 AAACreateAndAddAVPToList() This function creates an AVP and adds it to an AVP list. It returns a pointer to the list in the avpList argument. The AVP is initialized from the arguments: AAAReturnCode AAACreateAndAddAVPToList(AAA_AVP_LIST **avpList, AAA_AVPCode code, AAA_AVPFlag flags, AAAVendorId vendorId, char *data, size_t length); The parameters are: avpList - The list to which the AVP should be added. code - The AVP's code. flags - Any AVP flags that must be passed. vendorId - The vendor id of the AVP. If no vendor id, then AAA_NO_VENDOR_ID. Kempf, Calhoun, Frascone expires January 2002 [Page 31] INTERNET DRAFT July 2001 data - A buffer containing the AVP data. length - The length of the data buffer. Return values are: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. AAA_ERR_NOMEM - Indicating a memory failure. 3.4.5.7 AAAAddAVPToList() AAAReturnCode AAAAddAVPToList(AAA_AVP_LIST **avpList, AAA_AVP *avp, AAA_AVP *position); Insert the AVP avp into this avpList after position. If position is NULL, the AVP is added to the beginning of the list. If *avpList is NULL, a list will be allocated, and *avpList will point to it. The parameters are: avpList - Pointer to a pointer for list. If *avpList is NULL, list memory is allocated. avp - AAA_AVP to add to list. position - AAA_AVP pointer to add data after, or NULL if the new AVP should go at the beginning of the list. The return value is one of: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. AAA_ERR_NOMEM - Indicates a memory failure. 3.4.5.8 AAAFindMatchingAVP() This function finds an AVP with matching code and vendor id. If none match, the function returns NULL: Kempf, Calhoun, Frascone expires January 2002 [Page 32] INTERNET DRAFT July 2001 AAA_AVP *AAAFindMatchingAVP(AAA_AVP_LIST *avpList, AAA_AVP *startAvp, AAA_AVPCode avpCode, AAAVendorId vendorId, AAASearchType searchType); The parameters are: avp - A pointer to the head of the AVP list. avpCode - The code of the sought after AVP. vendorId - The vendor id of the sought after AVP. The return value is a pointer to the found AVP, or NULL if none is found. 3.4.5.9 AAAJoinAVPLists() The following function joins together two AVP lists: AAAReturnCode AAAJoinAVPLists(AAA_AVP_LIST *dest, AAA_AVP_LIST *source, AAA_AVP *position); The parameters are: dest - The destination list (All of the avps in sourc will be moved here). source - The source list to be added to dest. position - The position to add the AVPs to, or NULL for the beginning of the list. The return value is one of: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. 3.4.5.10 AAARemoveAVPFromList() This function removes an AVP from a list: AAAReturnCode AAARemoveAVPFromList(AAA_AVP_LIST *avpList, Kempf, Calhoun, Frascone expires January 2002 [Page 33] INTERNET DRAFT July 2001 AAA_AVP *avp); The parameters are: avpList - The head of the list from which to remove the AVP. avp - Contains a pointer to the AVP to remove. The return value is one of: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. 3.4.5.11 AAAFreeAVP() The function frees an AVP: AAAReturnCode AAAFreeAVP(AAA_AVP **avp); The parameters are: avp - Contains a pointer to a pointer to the AVP to free. The return value is one of: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. 3.4.5.12 AAAGetFirstAVP() This function returns a pointer to the first AVP in the list: AAA_AVP *AAAGetFirstAVP(AAA_AVP_LIST *avpList); The parameters are: avpList - A pointer to the list. The return value is a pointer to the found AVP, or NULL if none is found. 3.4.5.13 AAAGetLastAVP() Kempf, Calhoun, Frascone expires January 2002 [Page 34] INTERNET DRAFT July 2001 This function returns a pointer to the last AVP in the list: AAA_AVP *AAAGetLastAVP(AAA_AVP_LIST *avpList); The parameters are: avpList - A pointer to the list. The function returns a pointer to the found AVP, or NULL if none is found. 3.4.5.14 AAAGetNextAVP() This function returns a pointer to the next AVP in the list. AAA_AVP *AAAGetNextAVP(AAA_AVP *avp); The parameters are: avp - A pointer to the AVP prior to the one sought. The return value is the next AVP in the list, or NULL if the parameter is the last element in the list. 3.4.5.15 AAAGetPrevAVP() This function returns a pointer to the previous AVP in the list: AAA_AVP *AAAGetPrevAVP(AAA_AVP *avp); The parameters are: avp - A pointer to the AVP after the one sought. The return value is the previous AVP in the list or NULL if the parameter is the first element in the list. 3.4.5.16 AAAConvertAVPToString() This function converts the data in the AVP to a format suitable for log or display functions. char *AAAConvertAVPToString(AAA_AVP *avp, char *dest, size_t destLen); The parameters are: Kempf, Calhoun, Frascone expires January 2002 [Page 35] INTERNET DRAFT July 2001 avp - The AVP to display. dest - A used supplied destination buffer. destLen - The length of the user supplied buffer. The return value is the passed in destination buffer. 3.4.5.17 AAASetMessageResultCode() This function decapsulates an encapsulated AVP, and populates the list with the correct pointers. AAAResultCode AAASetMessageResultCode(AAAMessage *message, AAAResultCode resultCode); The parameters are: message - A pointer to the allocated message. resultCode - The AAA Result Code The return value is one of: AAA_ERR_SUCCESS - Upon success. AAA_ERR_PARAMETER - If an invalid parameter was passed. 3.4.6 Message Control The following functions allow the client to direct a message to a particular server, determine the server for a message, etc. 3.4.6.1 AAASetServer() This function sets the server to which the message is sent: AAAReturnCode AAASetServer(AAAMessage *message, IP_ADDR host); The parameters are: message - The message to be sent. ipVersion - The version number of the IP address. host - The IP address / port / family of the server. Kempf, Calhoun, Frascone expires January 2002 [Page 36] INTERNET DRAFT July 2001 The return value is AAA_ERR_SUCCESS - If the server was found. AAA_ERR_NOT_FOUND - If the server was not found. 3.4.6.2 AAASendMessage() The following function sends a message to the server assigned to the message by AAASetServer(). The message identifier is assigned to the message. If no server id has been assigned to the message, a server id is selected. If no servers are currently active, the message is queued for later sending. AAAReturnCode AAASendMessage(AAAMessage *message); The parameter is the message to send. The return codes are: AAA_ERR_SUCCESS - Upon completion. AAA_ERR_FAILURE - If an error occurred. 3.4.7 Accounting The following functions allow the client to direct a message to a particular server, determine the server for a message, etc. 3.4.7.1 AAASendAcctRequest() The following function sends an accounting message to an accounting server. AAAReturnCode AAASendAcctRequest(AAASessionId *aaaSessionId, AAAExtensionId extensionId, AAA_AVP_LIST *acctAvpList, AAAAcctMessageType msgType) The parameters are: aaaSessionId - The session id that this accounting data corresponds to. extensionId - The extension type associated with this accounting Kempf, Calhoun, Frascone expires January 2002 [Page 37] INTERNET DRAFT July 2001 message. acctAvpList - A list of AVPs to send in the accounting message. msgType - The type of accounting message. The return codes are: AAA_ERR_SUCCESS - Upon completion. AAA_ERR_PARAMETER - If a parameter is invalid. 3.5 Implementation Notes The following are some implementation notes that library designers may want to keep in mind. 3.5.1 Grouped AVPs In order to create grouped AVPs, an application creates an AAA_AVP_LIST that is not attached to an AAAMessage structure (also known as an orphaned AAA_AVP_LIST). All of the necessary AVPs within the Group are added to the orphaned AAA_AVP_LIST using the existing list manipulation functions. Lastly, the grouped AVP is added to the AAAMessage structure. The following is an example that adds a Proxy-State Grouped AVP to an existing AAAMessage structure. int addProxyState(AAAMessage *message, ipaddr_t *ourAddress, void *state, size_t stateLen) { AAA_AVP_LIST *avpList = NULL; /* * Add the Proxy-Address AVP to the AAAList */ if (AAACreateAndAddAVPToList(&avpList, DIAM_AVP_PROXY_ADDRESS, AAA_AVPI_FLAG_NONE, NO_VENDOR_ID, (char *) ourAddress, sizeof (ipaddr_t))) { loggerSyslog(LOG_AVP_PROBLEMS, "Unable to add Proxy-Address AVP"); return (AAA_ERR_FAILURE); } /* Kempf, Calhoun, Frascone expires January 2002 [Page 38] INTERNET DRAFT July 2001 * Now we add the Proxy-Info AVP to the AAAList */ if (AAACreateAndAddAVPToList(&avpList, DIAM_AVP_PROXY_INFO, AAA_AVPI_FLAG_NONE, NO_VENDOR_ID, state, stateLen)) { loggerSyslog(LOG_AVP_PROBLEMS, "Unable to add Proxy-Info AVP"); return (AAA_ERR_FAILURE); } /* * Now the AAAList is added to the AAAMessage as * a Proxy-State AVP. */ if (AAACreateAndAddAVPToList(&message->avpList, DIAM_AVP_PROXY_STATE, AAA_AVPI_FLAG_NONE, NO_VENDOR_ID, (char *)avpList, AAA_AVP_GROUPED_LENGTH)) { loggerSyslog(LOG_AVP_PROBLEMS, "Unable to add Proxy-State AVP"); return (AAA_ERR_FAILURE); } return (AAA_ERR_SUCCESS); } As shown above, the procedures is to create a new AAA_AVP_LIST structure, adding all of the necessary AVPs that are within the Grouped AVP, then calling AAACreateAndAddAVPToList() to add the AAA_AVP_LIST as a Grouped AVP to the AAAMessage. Note that the AAA_AVP_LIST pointed to by orphaned avpList MUST NOT be accessed by the application after the Grouped avp has been created. The list will be freed along with the AVP by the AAA Library. In order to parse a Grouped AVP, the AAA_AVP data field contains a pointer to an AAA_AVP_LIST, as shown below. boolean_t isProxyStateOurs(AAA_AVP *proxyState, ipaddr_t *ourAddress) { AAA_AVP_LIST *avpList; AAA_AVP *proxyAddress; AAA_AVP *proxyInfo; ipaddr_t *proxyAddress; /* * Get the pointer to the Grouped AAA_AVP_LIST */ Kempf, Calhoun, Frascone expires January 2002 [Page 39] INTERNET DRAFT July 2001 avpList = (AAA_AVP_LIST *)proxyState->data; /* * First, for the Proxy-Address, and see if it is ours. */ if ((proxyAddress = AAAFindMatchingAVP(avpList, NULL, DIAM_AVP_PROXY_ADDRESS, NO_VENDOR_ID, AAA_FORWARD_SEARCH)) != NULL) { /* * Check if this one is ours. */ address2 = (ipaddr_t *)proxyAddress->data; if (*address2 == *address) { /* * This one is ours... return TRUE */ return (B_TRUE); } } return (B_FALSE); } 3.5.2 Extended AAA_AVP structure The AAA_AVP structure that is defined in this specification is a subset of the structure used by the internal library. The internal structure, known as the extended AAA_AVP, may contain many private fields, such as pointers to AAA_AVPs. Applications do not directly access the next (and previous) AAA_AVP pointers directly, but instead access them via the AAAGetNextAVP() and AAAGetPreviousAVP() functions. The following is an example of an extended AAA_AVP structure: typedef struct { // API Public variables here } AAA_AVP; typedef struct xavp { AAA_AVP avp; struct xavp *next; struct xavp *prev; int privateFlags; } Extended_AAA_Avp; Of course, when AAACreateAVP is called, sufficient memory is Kempf, Calhoun, Frascone expires January 2002 [Page 40] INTERNET DRAFT July 2001 allocated for the extended AAA_AVP structure, however the function returns a pointer to the AAA_AVP. 3.5.3 Avoiding AVP Copying The AAA_AVP struct does not provide an exact mapping to the Diameter protocol AVP packet format; however, library implementors can avoid having to copy the AVP data by putting a pointer to a packet format structure into a hidden part of the AAA_AVP struct. A pointer to the AVP data is then deposited into the AAA_AVP data field. This allows proper deallocation of the packet format structure when the AAA_AVP structure is deallocated. 3.5.4 Callback Processing Order The C API allows API clients to register message processors, or callbacks, that are invoked before and after the bulk of the processing functions for a message. Only one pre- or post-processor is allowed for all incoming messages, regardless of command or extension type. If the API client adds another, any existing pre- and post-processors are removed. Message processing can be best explained by the following diagram: +-------+ +-------+ +-------+ +-------+ | First | | Any | | Any | | Last | Apps +-------+ +-------+ +-------+ +-------+ ^ ^ ^ ^ 1 | 2 | 3 | 4 | +-------------------------------------------------+ | AAA Library | +-------------------------------------------------+ ^ | MSG In the above diagram, "First", "Any", and "Last" are added by the API client. The message processor labeled "First" is given access to the message before any other, the message processor "Last" after all others are finished. There is no guarantee on ordering for the other message processors. If the client adds a new "First" or "Last" message processor, the existing ones removed. There is one "First" and "Last" processor for all commands regardless of type; whereas, the "Any" processors are command-specific. If one of the "Any" processors completes successfully, the message is not passed on any further. A successful completion means the success Kempf, Calhoun, Frascone expires January 2002 [Page 41] INTERNET DRAFT July 2001 return code is returned from the C API callback, but the callback is responsible for freeing the message before returning. 4.0 Java API 4.1 Introduction The Java API provides a synchronous message sending model for clients and an asynchronous model for servers. A collection of reflection classes provide information about defined Diameter extensions, commands, and AVPs. The next three sections provide an overview of these three aspects of the API. 4.1.1 Client API Overview The advantage of a synchronous approach for the client API is that the client application code sees RPC-like semantics when sending a Diameter message (i.e. send request, get response) which considerably simplifies reasoning about code and debugging. However, because clients must maintain the session state machine in Section 11.1 of [1], and because it is possible for the client to receive an unsolicited message from the server (such as Session-Termination-Ind, Section 11.7.1 of [1]) at any time, the client API library implementation still needs to maintain at least one "hidden" thread per outstanding server connection to handle the state machine. Since most clients will likely only maintain a connection with their local AAA server, that thread is likely to be the only one the client library must maintain, thus reducing the processing load for clients. Sessions with Diameter servers are initiated in the following way. The API supports a superclass, AAASessionManager, that includes methods for managing sessions and sending messages that are common to both clients and servers. The AAAClientSessionManager contains methods that are specific for client-side session management. The AAAClientSessionManager implementation performs Diameter server discovery according to the procedure outlined in Section 2.3 of [1], guided by the properties described in Section 4.1.4 below. These servers are made available to the the client via AAAClientSessionManager.getConfiguredHosts(). The client then opens a session with a Diameter server by calling the AAASessionManager.startSession() method, passing in the host address of the Diameter server to contact and a command dictionary object used to drive parsing of Diameter commands for the session. The client can also dynamically open a session with a server by instead passing the NAI to AAASessionManager.findServerAddress() to determine the address, then passing the result to AAASessionManager.startSession(). The session id is a small integer, and it maps to the Diameter user session id as described in Section Kempf, Calhoun, Frascone expires January 2002 [Page 42] INTERNET DRAFT July 2001 11.2 of [1]. The integers only identify sessions within this instance of the Java virtual machine, a String containing the network format of the session identifier can be determined by passing the integer session identifier to the AAASessionManager.getNetworkSessionId() method. Once a session has been initiated, the client can construct and send Diameter messages. The client application code constructs an AAAMessage for the Diameter command it wants to send. The AAASessionManager class supports an instance method, AAASessionManager.send(), that synchronously sends the message, and waits until a reply message is received, returning the reply message to the client, or throwing an exception with an error reply message if an error message is returned. The client can also use the AAASessionManager.notify() method to asynchronously send a message, but this method is primarily for use by Diameter extensions in servers. The client application code registers a callback with AAAClientSessionManager only to handle unsolicited messages that arrive for a particular session. This callback is called by the state machine thread handler when an unsolicited message arrives that is session-specific. For example, if the state machine thread handler receives a Session-Termination-Ind for a particular session, the message is passed to the callback for the identified session. Exactly how the client handles a session termination (terminating a thread, sending an error event notification, etc.) is up to the client. The API libary is required to handle all non-session related unsolicited messages transparently to the API client. The library is also required to handle redirects (Section 12.3 of [1]) transparently to the client. 4.1.2 Server API Overview The server API supports an asynchronous model of message processing. A Diameter server application extension registers AAAMessageListener objects to handle particular Diameter commands. A client with an open session to the server sends Diameter messages. These are parsed and processed by the appropriate AAAMessageListener. The registered AAAMessageListener objects return an AAAMessage object to the server message handling code, which is returned to the client. If the return value of the AAAMessageListener.processMessage() is null, no message is returned to the client. The server can also send an asynchronous message to the client, for example a Session-Termination-Ind, through the AAASessionManager.notify() method. This method sends the message and returns without waiting for the client to respond. The server uses the AAAServerSessionManager object to handle sessions Kempf, Calhoun, Frascone expires January 2002 [Page 43] INTERNET DRAFT July 2001 with clients. Sessions are automatically created by incoming requests and registered in the AAAServerSessionManager. The server API also supports methods to load extension code when messages are received. This allows the server to start with the base Diameter protocol and grow only as needed to support clients. 4.1.3 Reflection Classes Overview The client and server APIs share a set of reflection classes that describe Diameter extensions, commands, and AVPs. The reflection classes are organized around AAACommandDictionary. This class provides a dictionary of all defined commands that can be parsed by the Java APIs. Each AAACommandDescriptor object provides basic information on the command (command code and vendor id), information on the extension of which the command is part (name, code, and vendor id), and information on mandatory, optional and disallowed AVPs. The commands in the command dictionary determine what messages the client and server APIs can legally parse, but to actually make use of the commands, the client or server must naturally have code to process the commands. If the server library receives a command with a code that is not known, DIAMETER_COMMAND_UNSUPPORTED in a Device-Status- Ind message is returned to the client by the library. Note that it is not possible for a client to create a Diameter command that the local client can't parse, because AAAMessage creation requires an AAACommandDescriptor object for a defined command. 4.1.4 Packages and Properties All Java Diameter API classes are within the same package. The package name is org.ietf.aaa. This follows the Java convention of prepending the name of the organization responsible for the API to the package. A single package name for all Diameter API implementations precludes running multiple library implementations within a single Java virtual machine. The following Java properties (accessable through java.lang.System.getProperties()) are used for configuration. These properties must be set before the API library is loaded, and remain valid throughout the session. Typically, the properties are set in a platform-specific configuration file, or on the command line when the program begins executing: org.ietf.aaa.CommandDictionaryFile - A String containing the platform specific command dictionary file name. This property is used by the client library to initialize the global command Kempf, Calhoun, Frascone expires January 2002 [Page 44] INTERNET DRAFT July 2001 dictionary.. org.ietf.aaa.maxWait - A String containing a positive integer giving the default maximum time the session manager must wait for a return value, in milliseconds. This value includes the time after the Diameter server indicates that it is busy by sending a Device-Status-Ind with DIAMETER_STILL_WORKING status code. Client library implementations should use some fraction of org.ietf.aaa.maxWait when sending the Max-Wait-Time AVP value to the server. org.ietf.aaa.client.initServers - A String containing a comma separated list of statically configured Diameter servers along with their extensions, if known. The syntax of the string in ABNF [2] form is: server-list = server-rec / server-rec "," server-list server-rec = host ":" ext-list / host ext-list = ext-name / ext-name 1*sep ext-list sep = " " host = hostname / hostnumber hostname = *( domainlabel "." ) toplabel alphanum = ALPHA / DIGIT domainlabel = alphanum / alphanum *stdchar alphanum toplabel = ALPHA / ALPHA *stdchar alphanum hostnumber = ipv4-number / ipv6-number ipv4-number = 1*3DIGIT 3("." 1*3DIGIT) ipv6-addr = "[" num-addr "]" num-addr = ; Text represented IPv6 address syntax is as ; specified in RFC 2373 [9], Section 2.2, ext-name = 1*stdchar stdchar = alphanum / "-" alphanum = ALPHA / DIGIT For example: org.ietf.aaa.client.initServers = default-aaa,nas-sever.wireless:NASReq Accounting org.ietf.aaa.client.initExtensions - A String containing a comma separated list of Diameter extensions for which the library should perform dynamic SLP [4] discovery when it initializes. For example: org.ietf.aaa.client.initExtensions = NASReq,Mobile-IP,VoIP,Accounting org.ietf.aaa.client.initDomains - A String containing a comma Kempf, Calhoun, Frascone expires January 2002 [Page 45] INTERNET DRAFT July 2001 separated list of fully qualified domain names for which the library should perform DNS SRV RR [5] discovery when it intializes. For example: org.ietf.aaa.client.initDomains = femeto.org,letmein.com org.ietf.aaa.server.proxyMap - A String containing a comma separated list of proxy/client list pairs. The list has the following format: proxyMap = host / proxyMapList proxyMapList = proxyClientList / proxyClientList "," proxyMapList proxyClientList = proxy ":" clientList clientList = client / client 1*sep clientList sep = " " proxy = host client = host FQHN = ;see definition for org.ietf.aaa.client.initServers For example: org.ietf.aaa.server.proxyMap = out.femeto.org:client1 client2,out2.femeto.org:client3 If only one host name appears on the proxy map list, that host is the proxy for all incoming clients. org.ietf.aaa.server.redirectMap - A String containing a comma separated list of redirect server/client pairs. The format of the list is exactly the same as for the org.ietf.aaa.server.proxyMap property. The host name before the colon indicates the redirect server, the host names after indicate the clients who have that server as the redirect. The org.ietf.aaa.client.initServers, org.ietf.client.initExtensions, and org.ietf.client.initDomains properties are client side only properties, while org.ietf.aaa.server.proxyMap and org.ietf.aaa.server.redirectMap are server side only properties. Both of these need to be set prior to loading the libraries. 4.2 Errors and Exceptions If any fatal errors occur during API library intitialization, an AAAException is thrown with the INIT_FAILURE status code. Errors may include improperly set configuration properties, inability to perform service discovery, etc. An exception of this nature will typically cause termination of program execution. Kempf, Calhoun, Frascone expires January 2002 [Page 46] INTERNET DRAFT July 2001 In general, parameters to API methods are required to be non-null and String parameters must be non-empty, but the API description indicates if a null parameter or empty String is acceptable. Parameters must be checked by the API library before use and a java.lang.IllegalArgumentException exception thrown if any parameter is not acceptable. Since this class is a subclass of java.lang.RuntimeException, clients are reminded to check for IllegalArgumentException even though it is not listed in the method API description. The documentation below only lists IllegalArgumentException if it is returned for a reason other than a null parameter. Unlike most Java packages, the Diameter API does not encode every error condition into a separate subclass of java.lang.Exception. When there are a large number of exceptional conditions (as in the Diameter API), the result is a proliferation of exception classes. In the Diameter API, the exception conditions are represented by error codes that are defined as constants in the org.ietf.aaa.AAAException class. The API also defines an AAAMessageException message that is thrown when the AAASessionManager.send() method receives a Device- Status-Ind (Section 9.1 of [1]) or Message-Reject-Ind (Section 10.1 of [1]) that is not handled internally by the API library. The exception object contains the returned AAAMessage. The client API library is required to handle the following Diameter events received in Device-Status-Ind transparently to the client application code and must not throw an exception: DIAMETER_REDIRECT_INDICATION, and DIAMETER_TIME_INVALID. The client API library is required to handle a Device-Status-Ind with DIAMETER_STILL_WORKING by continuing to wait for the return value until one of the following occurs: - The return message is received. In this case, the message is returned to the client application code, - A Device-Status-Ind with DIAMETER_CANNOT_PROCESS_IN_TIME status is received. In this case, a AAAMessageException is thrown with the message object. - The session-specific timeout set through AAASessionManager.setSessionTimeout() or the library timeout specified by the org.ietf.aaa.maxWait property expires. An AAAException message is thrown with AAAException.NETWORK_TIMEOUT status code. In this case, the state machine thread handler may need to discard a return message, should one arrive after the exception is thrown. Kempf, Calhoun, Frascone expires January 2002 [Page 47] INTERNET DRAFT July 2001 4.2.1 Class AAAException 4.2.1.1 Synopsis public class AAAException extends java.lang.Exception 4.2.1.2 Description The AAAException class is the class for returning AAA exceptions not associated with received Device-Status-Ind and Message-Reject-Ind messages. These messages are typically internal errors, initialization errors, networking errors, or errors in command parsing. The error code indicates the exact nature of the exception, along with text in the exception message. 4.2.1.3 Fields public static final short FAILURE = 1 public static final short SECURITY = 2 public static final short MISSING_AVP = 3 public static final short DISALLOWED_AVP = 4 public static final short INIT_FAILURE = 5 public static final short NETWORK_TIMEOUT = 6 public static final short NETWORK_ERROR = 7 public static final short SESSION_INVALID = 8 public static final short PARSE_ERROR = 9 public static final short VERSION_ERROR = 10 public static final short MESSAGE_ERROR = 11 Note that these status codes are separate from the codes returned by remote AAA servers. FAILURE - This code indicates an unspecified failure occurred during an AAA operation. SECURITY - This code indicates a security check failed or another security error occurred. MISSING_AVP - This code indicates the client tried to send an AVP without a required AVP, or a command was received without a required AVP. DISALLOWED_AVP - This code indicates the client tried to send an AVP with a disallowed AVP, or a command was received with a disallowed AVP. INIT_FAILURE - This code indicates that a fatal error occured when the library was initialised after loading. Kempf, Calhoun, Frascone expires January 2002 [Page 48] INTERNET DRAFT July 2001 NETWORK_TIMEOUT - This code indicates that a network timeout occured. The timeout can be either a transport layer timeout, or the org.ietf.aaa.maxWait Diameter processing timeout or a session timeout was exceeded. NETWORK_ERROR - This code indicates that an error in networking occured, other than a timeout. PARSE_ERROR - This code indicates that a parse error occured during input deserialization of a message or AVP. VERSION_ERROR - This code indicates that the version number on an incoming message does not correspond to a version number that this library handles. MESSAGE_ERR - This code indicates that the exception is an AAAMessageException subclass. The exact nature of the error is determined by the message object contained in the exception. 4.2.1.4 Instance Methods public short getCode() Return the exception error code. 4.2.2 Class AAAMessageException 4.2.2.1 Synopsis public class AAAMessageException extends AAAException 4.2.2.2 Description The AAAMessageException class is thrown from the AAASessionHandler.send() method when an message is received with the 'F' bit set or with the 'A' bit set and a Result-Code AVP with status code that does not correspond to SUCCESS or with a Failed-Command- Code AVP that is not handled internally by the library. The message object is contained in the exception. 4.2.2.3 Fields The following constants correspond to the Diameter Result-Code or Failed-Command-Code AVP values and indicate the result status of a command. No constants are provided for those messages which the library is expected to handle internally. public static short UNSUPPORTED_TRANSFORM = 4001 Kempf, Calhoun, Frascone expires January 2002 [Page 49] INTERNET DRAFT July 2001 public static short INVALID_RECORD_ROUTE = 5001 public static short COMMAND_UNSUPPORTED = 5002 public static short UNABLE_TO_DELIVER = 5003 public static short REALM_NOT_SERVED = 5004 public static short TOO_BUSY = 5005 public static short CANNOT_PROCESS_IN_TIME = 5006 public static short NO_COMMON_EXTENSION = 5007 public static short UNSUPPORTED_VERSION = 5008 public static short SUCCESS = 2001 public static short AUTHENTICATION_REJECTED = 4001 public static short NO_END_2_END_SECURITY = 4002 public static short OUT_OF_SPACE = 4003 public static short USER_UNKNOWN = 5001 public static short AVP_UNSUPPORTED = 5002 public static short UNKNOWN_SESSION_ID = 5003 public static short AUTHORIZATION_REJECTED = 5004 public static short INVALID_AVP_VALUE = 5005 public static short MISSING_AVP = 5006 public static short INVALID_CMS_DATA = 5007 public static short LOOP_DETECTED = 5008 public static short AUTHORIZATION_FAILED = 5009 public static short CONTRADICTING_AVPS = 5010 public static short AVP_NOT_ALLOWED = 5011 public static short AVP_OCCURS_TOO_MANY_TIMES = 5012 public static short VENDOR_ID_UNSUPPORTED = 5013 More information on these command codes and recommended client application code responses can be found in Section 10 of [1]. 4.2.2.4 Instance Methods AAAMessage getStatusMessage() Return the AAAMessage object containing the status message. 4.3 Library Management and Dictionary Management The Java API provides a set of reflective classes that model Diameter extensions, commands, and AVP descriptions. These classes are used by the API itself to perform checking, and they are available to the clients that want to do additional checking or discover what commands and extensions are available. The reflective class objects are available through the AAACommandDictionary. 4.3.1 Class AAA 4.3.1.1 Synopsis Kempf, Calhoun, Frascone expires January 2002 [Page 50] INTERNET DRAFT July 2001 abstract public class AAA extends java.lang.Object 4.3.1.2 Description The AAA class provides useful constants for the Diameter Java API. 4.3.1.3 Fields public static final int NO_SESSION_CODE = 0 A constant which will never be returned as a session code. public static final long NO_VENDOR_CODE = 0 A constant which will never be returned as a vendor code. public static final long NO_COMMAND_CODE = 0 A constant which will never be used as a command code code. public static final long NO_EXTENSION_CODE = 0 A constant which will never be used as an extension code public static final long NO_AVP_CODE = 0 A constant which will never be used as an AVP code. 4.3.2 Class AAACommandDictionary 4.3.2.1 Synopsis public class AAACommandDictionary extends java.lang.Object 4.3.2.2 Description The AAACommandDictionary class provides a complete reference for a collection of Diameter commands defined either through a command dictionary file or programmatically. The AAACommandDescriptors contained in the dictionary describe their AVPs and the extension of which they are part. The dictionary is used by the API library to guide command parsing, and can be used by server extension code and client library code to construct return commands. 4.3.2.3 Class Methods public static AAACommandDictionary getAAACommandDictionary() Kempf, Calhoun, Frascone expires January 2002 [Page 51] INTERNET DRAFT July 2001 throws AAAException Return the global command dictionary. If the dictionary doesn't exist yet, create it. Exceptions are: AAAException - Thrown with code INIT_FAILURE if an exception occured parsing the dictionary file or the dictionary could not otherwise be initialized. 4.3.2.4 Instance Methods public AVPCommandDescriptor findCommand(java.lang.String name) Return an AAACommandDescriptor for the command matching the name, or null if none. Parameters: name - The name of the command to match. The return value is the AAACommandDescriptor matching the name, or null if none. public AAACommandDescriptor findCommand(long code) Return an AAACommandDescriptor for the command matching the code, or null if none. Parameters: code - The code of the command to match. The return value is the AAACommandDescriptor matching the code, or null if none. 4.3.3 Class AVPDescriptor 4.3.3.1 Synopsis public class AVPDescriptor extends java.lang.Object 4.3.3.2 Description An AVPDescriptor object contains a description of an AVP. 4.3.3.3 Fields Kempf, Calhoun, Frascone expires January 2002 [Page 52] INTERNET DRAFT July 2001 public long code The AVP's code. public long vendorCode The AVP vendor's code. If global, then NO_VENDOR_CODE. public java.lang.String name The AVP's name. public java.lang.String vendorName The AVP's vendor name, If global, then the empty string (""). public java.lang.String type The name of the Java class for the AVP's type. This will be one of: "B[" - a byte array, corresponds to the Diameter OctetString type. "java.net.InetAddress" - An IP address, corresponds to the Diameter Address type. "java.lang.Integer" - A signed integer, corresponds to the Diameter Integer32 type. "java.lang.Long" - A signed long, corresponds to the Diameter Integer64 type. "org.ietf.aaa.UnsignedInteger" - An unsigned integer, corresponds to the Diameter Unsigned32 type. "java.math.BigInteger" - An unsigned long, corresponds to the Diameter Unsigned64 type. "java.lang.Float" - A floating point number, correspnds to the Diameter Float32 type. "java.lang.Double" - A double precision floating point number, corresponds to the Diameter Float64 type. "java.math.BigDecimal" - A quadruple precision floating point number, corresponds to the Diameter Float128 type. "java.util.Map" - The AVP is of Diameter type Grouped. The Map object contains a map of the contained AVPs with the AVP name as Kempf, Calhoun, Frascone expires January 2002 [Page 53] INTERNET DRAFT July 2001 the key and the AVP as the value. If any of the contained AVPs are of type Grouped, the value is another Map object. 4.3.3.4 Constructor public AVPDescriptor(long code, long vendorCode, java.lang.String name, java.lang.String vendorName, java.lang.String type, boolean isMandatory, boolean isEndToEndEncrypted) Create an AVPDescriptor object with the given fields. Parameters are: code - The AVP's code. vendorCode - The AVP's vendor code. name - The AVP's name. vendorName - The AVP's vendor name. type - The AVP's type. isMandatory - True if the AVP is mandatory for the command. isEndToEndEncryptable - True if the AVP can be end-to-end encrypted for the command. 4.3.3.5 Instance Methods public boolean isMandatory() Return true if this AVP is mandatory. public boolean isEndToEndEncryptable() Return true if this AVP can be encrypted end-to-end. public java.lang.String toString() Return a nicely formatted string describing the object. 4.3.4 Class AAACommandDescriptor Kempf, Calhoun, Frascone expires January 2002 [Page 54] INTERNET DRAFT July 2001 4.3.4.1 Synopsis public class AAACommandDescriptor extends java.lang.Object 4.3.4.2 Definition The AAACommandDescriptor class describes a Diameter command in an application profile extension. The AAACommandDescriptor maintains the singleton pattern. There is only one command descriptor object per registered command, and command descriptor objects can only be programmatically created through the AAAExtensionDescriptor object. 4.3.4.3 Fields The following fields indicate the kind of command, and correspond to flag settings described in Section 3.0 of [1]: public static final byte REQUEST = 0x01 public static final byte INDICATION = 0x02 public static final byte ANSWER = 0x04 public static final byte FAILED = 0x08 4.3.4.4 Instance Methods public String getName() Return the command's name. public long getCode() Return the command's code. public byte getCommandType() Returns the command's type, one of INDICATION, REQUEST, ANSWER, QUERY, REPLY defined above. public String getVendorName() Return the command's vendor name, or the empty string, "", if the command is global. public long getVendorCode() Return the command's vendor code, or NO_VENDOR_CODE if the command is global. Kempf, Calhoun, Frascone expires January 2002 [Page 55] INTERNET DRAFT July 2001 public AAAExtensionDescriptor getExtension() Return the extension descriptor with which the command is registered. public java.util.Map getAVPDictionary() Return a dictionary with java.lang.Integer AVP codes as keys and AVPDescriptor objects as values for AVPs in the command. If any of the AVPs is Grouped, then the value is a Map containing the descriptors for the AVPs in the Grouped. public java.util.Map getDisallowedAVPDictionary() Return a dictionary with String AVP names as keys and AVPDescriptor objects as values for disallowed AVPs in the command. If any of the AVPs is Grouped, then the value is a Map containing the descriptors for the AVPs in the Grouped. public java.lang.String toString() Return a nicely formatted string describing the object. 4.3.5 AAAExtensionDescriptor 4.3.5.1 Synopsis public class AAAExtensionDescriptor extends java.lang.Object 4.3.5.2 Description The AAAExtensionDescriptor class provides a model for an AAA application profile extension. AAAExtensionDescriptor maintains a singleton pattern, so there is only one instance of each AAAExtensionDescriptor object defined per virtual machine. AAAExtensionDescriptor manages AAACommandDescriptor objects describing the messages that make up the extension. 4.3.5.3 Class Methods public static AAAExtensionDescriptor getExtension(java.lang.String name) Return the extension descriptor corresponding to the name, or null if none. Parameters are: name - The name of the extension to return. Kempf, Calhoun, Frascone expires January 2002 [Page 56] INTERNET DRAFT July 2001 public static java.util.Iterator getRegisteredExtensions() Return an iterator containing all the registered extension descriptors. public static AAAExtensionDescriptor registerExtension(long code, long vendorCode, java.lang.String name, java.lang.String vendorName) Return an extension descriptor matching the parameters. The object is created if it does not yet exist. The parameters are: code - The Diameter extension code. vendorCode -The vendor code. name - The extension name. vendorName - Name of the vendor for this extension, or empty string if global. 4.3.6.4 Instance Methods public long getCode() Return the extension code for this extension. public long getVendorCode() Return the vendor code for this extension. public java.lang.String getName() Return the extension name. public java.lang.String getVendorName() Return the vendor name for this extension, or the empty string if the extension is global. Kempf, Calhoun, Frascone expires January 2002 [Page 57] INTERNET DRAFT July 2001 public AAACommandDescriptor registerCommand(long code, long vendorCode, java.lang.String name, java.util.Map AVPDictionary, java.util.Map disallowedAVPDictionary) Register the command with name and code, and having the AVP dictionary and disallowed AVP names, as belonging to this extension. Returns the AAACommandDescriptor object describing the command. If the command has already been registered, the existing object is returned. If not, the object is created. If there is an existing object, both the AVP dictionary and the disallowed AVP dictionary are checked and a new descriptor object is created if the parameters differ from the existing object. The parameter is: code - The command code. vendorCode - The vendor code. name - String with the command's name. AVPDictonary - A Map of AVP name Strings to AVPDescriptor objects for required and allowed AVPs. Grouped AVPs are represented by Maps. The dictionary has the AVP name as the key and the AVPDescriptor or Map as the value. disallowedAVPDictionary - A Map containing disallowed AVPDescriptor objects for disallowed AVPs. Grouped AVPs are represented by Maps. The dictionary has the AVP name as the key and the AVPDescriptor or Map as the value. The return value is the registered command object. public void deregisterCommand(java.lang.String name) Deregister the command object having the given name. If no command having the given name is registered, java.lang.IllegalArgumentException is thrown. The parameter is: name - Name of the command to deregister Exceptions thrown: Kempf, Calhoun, Frascone expires January 2002 [Page 58] INTERNET DRAFT July 2001 java.lang.IllegalArgumentException - Thrown if the name is not registered. public AAACommandDescriptor getCommand(java.lang.String name) Get the command descriptor object corresponding to the name. If no such command is registered, return null. The parameter is: name - Name of the command. The return value is the command object, or null if none. public java.util.Iterator getRegisteredCommandNames() Return an iterator of names for registered commands. If no commands are registered, then return an empty Iterator. public java.lang.String toString() Return a nicely formatted description of the extension descriptor. 4.3.7 UnsignedInteger 4.3.7.1 Synopsis public UnsignedInteger extends java.lang.Number 4.3.7.2 Description UnsignedInteger represents a Diameter Unsigned32 type. Since Java integers are signed, this class is necessary to distinguish the Unsigned32 from Integer32 Diameter types. The interface is exactly the same as the java.lang.Integer class, and most of the methods are simply passthroughs to an object of that class. Note that it is possible to get the actual unsigned value by using the UnsignedInteger.getLong() method. 4.4 Messages and AVPs 4.4.1 Class AAAMessage 4.4.1.1 Synopsis public class AAAMessage extends java.lang.Object implements java.io.Externalizable Kempf, Calhoun, Frascone expires January 2002 [Page 59] INTERNET DRAFT July 2001 4.4.1.2 Definition The AAAMessage object represents an incoming or outgoing message. An instance of an AAAMessage consists of a map with AVP names as keys and AVP objects as values. Accessors are also available for other information, including the AAACommandDescriptor that describes the message. The API library uses the java.io.Externalizable interface methods Externalizable.writeExternal() and Externalizable.readExternal() internally to serialize and deserialize the message in the proper Diameter format. 4.4.1.3 Constructor public AAAMessage(AAACommandDescriptor descriptor) Create an AAAMessage object. The message has an empty AVP map and the hop-by-hop and end-to-end identifiers are initialized to sequentially generated random values. Parameters are: descriptor - The AAACommandDescriptor object giving the message's command type. 4.4.1.4 Instance Methods public int getLength() Return the message length. public int getHopByHopIdentifier() Return the message's hop-by-hop identifier. public int getEndToEndIdentifier() Return the message's end-to-end identifier. public String getDescriptor() Return the message's command descriptor. public java.util.Map getAVPMap() Return a Map of AVP objects for the message. Keys are the AVP String names, values are AVP objects. public java.lang.String toString() Kempf, Calhoun, Frascone expires January 2002 [Page 60] INTERNET DRAFT July 2001 Return a nicely formatted string describing the object. 4.4.2 Class AVP 4.4.2.1 Synopsis public class AVP extends java.lang.Object implements java.io.Externalizable 4.4.2.2 Description The AVP class models a Diameter AVP (attribute/value pair) object. An AVP may be created with data having one of the types described in Section 4.3.3. 4.4.2.3 Constructor public AVP(AVPDescriptor descriptor, java.lang.Object data, boolean encrypt) Create a new AVP object. Parameters are: descriptor - An AVPDescriptor object describing the AVP. data - The AVP's data. If the type of data does not match the type of the AVP, java.lang.IllegalArgumentException is thrown. encrypt - Set to true if the AVP should be encrypted and its 'P' flag set [1]. Exceptions thrown: java.lang.IllegalArgumentException - Thrown if either parameter is null, or if the data type does not match the descriptor's AVP type. 4.4.2.4 Instance Methods public AVPDescriptor getDescriptor() Return the AVP's descriptor. public java.lang.Object getData() Kempf, Calhoun, Frascone expires January 2002 [Page 61] INTERNET DRAFT July 2001 Return the AVP data as the appropriate Java object. public boolean isEndtoEndEncrypted() Return true if the AVP encryption flag is set. java.lang.String toString() Return a nicely formatted string describing the object. 4.5 Session Management 4.5.1 Class AAASessionManager 4.5.1.1 Synopsis abstract public class AAASessionManager extends java.lang.Object 4.5.1.2 Description The AAASessionManager class is the abstract superclass for client and server side session managers. It contains basic methods common to client and server side for managing sessions. An AAAMessage object is sent to the Diameter server using the AAASessionManager.send() method. The AAASessionManager.send() method is synchronous, and returns the reply message from the server, or an AAAException is thrown if the server does not reply within the session timeout. The AAASessionManager.notify() method is used to asynchronously send a message to the Diameter server, or to a client. It is primarily of interest to server side Diameter extensions. 4.5.1.3 Instance Methods public int startSession(InetAddress host) Open a new AAA session. The session is established with the indicated host. This method performs the necessary Diameter messaging for the state machine described in Section 8.0 of [1] in order to bring up a Diameter connection, in addition to standard network sockets bring up. Parameters: host - The host with which the session should be established. dictionary - The command dictionary to use when parsing and Kempf, Calhoun, Frascone expires January 2002 [Page 62] INTERNET DRAFT July 2001 checking commands. Return value is the session code. If a session can't be opened, returns NO_SESSION_CODE. Exceptions thrown: java.lang.IllegalArgumentException - Thrown if the host already has a session already open or the parameter is null. public InetAddress findServerAddress(String NAI) Find the Diameter server address corresponding to the NAI. Parameters: NAI - The Network Access Identifier [6] Return value is the InetAddress object for the NAI realm's Diameter server, or null if no Diameter server is available. Exceptions thrown: AAAException - Thrown with the error code NETWORK_ERROR if an exception occurs during resolution of the Diameter server's name. public void endSession(int sessionCode) Close the indicated session. This message performs the necessary Diameter messaging according to the state machine in Section 8.0 of [1] to terminate the session, in addition to standard network sockets teardown. Parameters: sessionId - The session code of the session to close. Exceptions thrown: java.lang.IllegalArgumentException - Thrown if sessionCode does not indicate a valid, open session. public String getNetworkSessionId(int sessionCode) Return the network session identifier (see Section 11.2 of [1]) corresonding to the session code. Parameters are: Kempf, Calhoun, Frascone expires January 2002 [Page 63] INTERNET DRAFT July 2001 sessionCode - The session code. Return value is the network session identifier, as a String. Exceptions thrown: java.lang.IllegalArgumentException - Thrown if sessionCode is invalid. public void setSessionTimeout(int sessionCode,int timeout) Set the timeout on a particular session. The timeout determines how long the session manager waits for a reply before giving up. By default, the value in org.ietf.aaa.maxWait is used for the session timeout. Parameters are: sessionCode - The session code. timeout - The new timeout, in milliseconds. public AAAMessage send(int sessionCode,AAAMessage message) throws AAAException, AAAMessageException Send the message to the server having the session identified by the session code, wait for the return message, and return it. Note that the AAASessionManager.send() method is required to handle the details of redirection. If the return message is a Device- Status-Ind command with the DIAMETER_REDIRECT_INDICATION [1] DSI- Event status code set, then the API library must perform the redirection transparently to the API client. The API library may also update the session description associated with the session id in order to avoid incurring the overhead of a redirection on future attempts involving the session. Parameters are: sessionCode - The session code. message - The message to send. The return value is the returned message. Exceptions thrown: AAAException - Thrown with one of the following error codes: Kempf, Calhoun, Frascone expires January 2002 [Page 64] INTERNET DRAFT July 2001 FAILURE, SECURITY, MISSING_AVP, DISALLOWED_AVP, NETWORK_TIMEOUT NETWORK_ERROR, SESSION_INVALID, PARSE_ERROR, VERSION_ERROR. AAAMessageException - Thrown with the returned error command object. public void notify(int sessionCode,AAAMessage message) throws AAAException Send the message to the server having the session identified by the session code, but do not wait for a response. Asynchronous message sending is primarily of interest to servers, but may be used by clients as well. Parameters are: sessionCode - The session code. message - The message to send. Exceptions thrown: AAAException - Thrown with one of the following error codes: FAILURE, SECURITY, MISSING_AVP, DISALLOWED_AVP, NETWORK_TIMEOUT NETWORK_ERROR, SESSION_INVALID, PARSE_ERROR, VERSION_ERROR. 4.5.2 Class AAAClientSessionManager 4.5.2.1 Synopsis public class AAAClientSessionManager extends AAASessionManager 4.5.2.2 Description The AAAClientSessionManager class provides session management services for the client side API. A client can either establish a session with a server discovered during service discovery or with a server whose NAI was discovered during execution. The API allows clients to specify that a server must support particular extensions. Client application code can register unsolicited message handlers to handle unsolicited messages and an exception handler to handle exceptions during receipt of unsolicited messages. If no message handler or exception handler is registered, the behavior is defined by the library implementation, but the implementation should not terminate the application. Examples of acceptable behaviors include printing a message to the standard output or to a log file. Kempf, Calhoun, Frascone expires January 2002 [Page 65] INTERNET DRAFT July 2001 4.5.2.3 Class Methods public static AAAClientSessionManager getClientSessionManager() Return the distinguished session manager object for the Diameter client API library. There will be only one session manager object per virtual machine. public static registerUnsolicitedExceptionHandler(UnsolicitedExceptionHandler handler) Register a handler for exceptions that occur during input of unsolicited messages, for example, a network error while reading the message. This handler is global for all sessions and all client application code in this executing instance of the Java virtual machine. Parameters are: handler - The handler. 4.5.2.4 Instance Methods public void registerUnsolicitedMessageListener(int sessionCode, AAAMessageListener listener) Register a listener for handling unsolicited messages associated with a particular session. If a listener already exists for this session, replace it. The value returned by the listener is ignored. Parameters are: sessionCode - The session code. listener - The listener. public InetAddress[] getConfiguredHosts(java.util.Iterator supportedExtensions) Return an array of InetAddress objects for configured AAA servers. If the supportedExtensions parameter is not null, only return servers supporting the indicated extensions are returned. If no servers match the extensions or are configured, return an empty array. Parameters are: supportedExtensions - Iterator with Strings containing names of Kempf, Calhoun, Frascone expires January 2002 [Page 66] INTERNET DRAFT July 2001 extensions that the the server must support. If null or empty, return all configured servers. Return value is an array of InetAddress objects for servers, or an empty array if no servers match the extensions or are configured at all. 4.5.3 Class AAAServerSessionManager 4.5.3.1 Synopsis public class AAAServerSessionManager extends AAASessionManager 4.5.3.2 Description The AAAServerSessionManager provides session management services to the server API. There are no additional methods required besides the methods provided by the base class. 4.5.3.3 Class Methods public static AAAServerSessionManager getServerSessionManager() Return the distinguished session manager object for the Diameter server API library. There will be only one session manager object per virtual machine. 4.5.4 Interface UnsolicitedExceptionHandler 4.5.4.1 Synopsis public interface UnsolicitedExceptionHandler 4.5.4.2 Description Instances of classes that implement the UnsolicitedExceptionHandler interface handle exceptions that occur during processing of unsolicited messages. 4.5.4.3 Instance Methods public void processUnsolicitedException(java.lang.Exception exception); Handle an exception that occured during processing of an unsolicited message. Parameters are: Kempf, Calhoun, Frascone expires January 2002 [Page 67] INTERNET DRAFT July 2001 exception - The exception. 4.5.5 Interface AAAMessageListener 4.5.5.1 Synopsis public interface AAAMessageListener 4.5.5.2 Description Instances of classes that implement the AAAMessageListener interface handle incoming messages. 4.5.5.3 Instance Methods public AAAMessage processMessage(int sessionCode, AAAMessage message); Process a message for a particular session. Parameters are: sessionCode - The session code. message - The message. 4.6 Server API The Diameter server API provides a way for Diameter extensions to register listeners for Diameter commands. Implementations of server API classes need not be present unless the Java virtual machine supports server capability. In addition to the AAAServer class, the AAAServerSessionManager is also included in the server API. 4.6.1 Class AAAServer 4.6.1.1 Synopsis abstract public AAAServer extends AAA 4.6.1.2 Description The AAAServer class provides a means to extend the Diameter server by registering listener objects to handle commands. The class also provides methods to allow dynamic linking of command class handling code when a command is received. In addition, the AAAServer class maintains the proxy and redirect Kempf, Calhoun, Frascone expires January 2002 [Page 68] INTERNET DRAFT July 2001 maps. When the AAAServer class is loaded, it initializes the proxy and redirect maps from the properties org.ietf.aaa.server.proxyMap and org.ietf.aaa.server.redirectMap. If a command comes from a client that requires proxying or redirecting, the AAAServer class takes care of sending the proper commands to the client or proxy to cause the redirect or proxying to happen. 4.6.1.3 Class Methods public static void initialize(java.util.Iterator commandPackages) Initialize the server, and register the Iterator containing Strings with the package names to use when looking for the command handling class code. These names are concatenated with the command names to form a class name that is used to dynamically link code for handling the command. Parameters are: commandPackages - an Iterator of String package names used to form class names from command names when dynamically linking command code. public static void loadCommand(String commandName) throws AAAException Form the command class name by concatenating the command name with one of the command packages passed in on initialization of the server, then dynamically link the class. If the command class supports the AAAMessageListenerFactory interface and a no-argument constructor, use the Class.new() method to create an instance of the AAAMessageListenerFactory and obtain a message listener from the factory. Register the message listener for the command. If the command class does not support the AAAMessageListenerFactory interface, the message listener must be registered by the loading code. Note that dyanmic loading and automatic listener registration requires the command descriptor to be available from the command dictionary, otherwise, the mapping between the command code and command name cannot be performed. Parameters are: commandName - The String name of the command Exceptions thrown: Kempf, Calhoun, Frascone expires January 2002 [Page 69] INTERNET DRAFT July 2001 AAAException - Thrown with FAILURE if the code couldn't be loaded. public void registerCommandListener(AAACommandDescriptor descriptor, AAAMessageListener listener) Register a message listener for the command. If an existing listener is registered, replace it. To unregister a listener for a command, use null for the listener. Parameters are: descriptor - The command descriptor for the command for which the listener is registered. listener - The listener to register. public static Map getProxyMap() Return the proxy map. The proxy map has client InetAddress objects as keys and the server InetAddress objects to which the client messages should be proxied as values. The calling code can modify the proxy behavior by modifying the map. The proxy map is initialized from the org.ietf.aaa.server.proxyMap property. public static Map getRedirectMap() Return the redirect map. The redirect map has client InetAddress objects as keys and the server InetAddress objects to which the client messages should be redirected as values. The calling code can modify the redirect behavior by modifying the map. The redirect map is initialized from the org.ietf.aaa.server.redirectMap property. 4.6.2 Interface AAAMessageListenerFactory 4.6.2.1 Synopsis public interface AAAMessageListenerFactory 4.6.2.2 Description The AAAMessageListenerFactory interface is supported by command handling classes to allow automatic registration of their message listeners upon dynamic linking. A command handling class must support both the AAAMessageListenerFactory interface and a no- argument constructor in order to allow automatic registration. 4.6.2.3 Instance Methods Kempf, Calhoun, Frascone expires January 2002 [Page 70] INTERNET DRAFT July 2001 AAAMessageListener getMessageListener() Return a message listener to handle the command messages. 4.7 Implementation Considerations 4.7.1 Dynamic Linking of Command Handling Classes The server side API is designed so command handling classes can be dynamically linked when the command arrives rather than having to be preloaded (though they may be preloaded to speed response time). The following design rules must be followed when writing the command handling class: 1) The class must be defined in the dictionary file used to create the command dictionary. The name of the class must correspond to the name of the command as defined in the dictionary file, and the class' package must be one of the packages used to initialize the server. In the server, the command dictionary is created from the org.ietf.aaa.defaultCommandDictionaryFile property. 2) The class must support a no-argument constructor so the command handler loading procedure can construct an instance of the class by calling the Class.newInstance() method. 3) The class must support the AAAMessageListenerFactory interface, so the command handler loading procedure can call the AAAMessageListenerFactory.getMessageListener() on the command handler object created by calling the Class.newInstance() method. If the command handler class does not abide by these design rules, it is up to the command handler itself to create and register the command listener in link time (class static) code. Note, however, that if the command is not defined in the command dictionary, the command handling code cannot even be linked because no mapping between the command code and command name is possible. 4.7.2 State Machine Maintenance The Diameter spec specifies two state machines, a peer state machine (Section 8.0 of [1]) and a session state machine (Section 11.1 of [1]). On the client side, AAAClientSessionManager maintains both the peer state machine and the session state machine. The peer state machine is started when the first session is created. Although implementation techniques may vary, a minimum of one thread per server is expected to be required to maintain a blocking receive on a socket for the Kempf, Calhoun, Frascone expires January 2002 [Page 71] INTERNET DRAFT July 2001 server. This allows the server to send unsolicited messages. On the server side, AAAServer maintains the peer state machine while AAAServerSessionManager maintains session state machine for specific sessions. 4.7.3 Server-side Access to Session Identifiers On the server, application profile message listeners can obtain session identifiers through the AAAServerSessionManager object. These can be used to, for example, send unsolicited messages to clients. Normal request/response callback processing should not require the message listeners to actually send any messages to the client, because the message returned as the value of the callback is returned to the client. 4.7.4 Server Proxy and Redirect Implementation The properties org.ietf.aaa.server.proxyMap and org.ietf.aaa.server.redirectMap contain maps of client addresses to proxy or redirect servers that can be used to implement proxy or redirect functionality. The server code can also programmatically modify the proxy and redirect maps by getting the maps from the AAAServer and modifying the maps directly. The maps contain a client address as key with the proxy or redirect address as the value, for convenient use when processing a client message. A wildcard proxy or redirect (i.e. a proxy or redirect for all clients) can be indicated in the properties by including a single address in the property. This causes proxies or redirects for all clients. A wildcard proxy or redirect is indicated in the maps by a single address bound to null as the value. An empty Map indicates that there are no proxies or redirects for this server. 5.0 Security Considerations This document describes an API and therefore depends on the security mechanisms defined in the Diameter protocol [1]. 6.0 References [1] Calhoun, P., et. al., "The DIAMETER Base Protocol," draft-ietf- aaa-diameter-01.txt, a work in progress. [2] Crocker, D. and Overell, P., "Augmented BNF Syntax Specifications: ABNF", RFC 2234, November, 1997. Kempf, Calhoun, Frascone expires January 2002 [Page 72] INTERNET DRAFT July 2001 [3] Calhoun, P., Bulley, W., and Farrell, S. "DIAMETER Strong Security Extension", draft-calhoun-diameter-strong-crypto-07.txt, a work in progress. [4] Guttman, E., Perkins, C., Veizades, J., and Day, M., "Service Loca- tion Protocol, Version 2," RFC 2608, June, 1999. [5] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000. [6] Aboba, Beadles "The Network Access Identifier." RFC 2486. January 1999. [7] http://www.diameter.org/XML/ [8] http://www.javasoft.com/xml/jaxp-docs-1.1/readme.html [9] Hinden, R., Carpenter, B., "Format for Literal IPv6 Addresses in URL's", RFC 2732, December, 1999. [10] Gilligan, R., et. al., "Basic Socket Interface Extensions for IPv6", RFC 2553, March, 1999. 7.0 Authors' Addresses Questions about this memo can be directed to: James Kempf Sun Labs California Sun Microsystems, Inc. 901 San Antonio Rd., UMTV29-235 Palo Alto, CA, 94303 USA Phone: +1 650 336 1684 Fax: +1 650 691 0893 E-Mail: james.kempf@sun.com Pat Calhoun Sun Labs California Sun Microsystems, Inc. 901 San Antonio Rd., UMTV29-235 Palo Alto, CA, 94303 USA Phone: +1 925 484 1853 Fax: +1 650 691 0893 E-Mail: pat.calhoun@sun.com Kempf, Calhoun, Frascone expires January 2002 [Page 73] INTERNET DRAFT July 2001 David Frascone Sun Labs California 1600 North Dallas Parkway, Suite 700 Dallas, TX 75248 Phone: +1 972 386 1283 E-Mail: codemonkey@sun.com 8.0 Full Copyright Statement Copyright (C) The Internet Society (2000). 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 restric- tion of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this docu- ment 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 pro- cess must be followed, or as required to translate it into languages other than English. The limited permis- sions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. This document and the information con- tained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRAN- TIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WAR- RANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE." Kempf, Calhoun, Frascone expires January 2002 [Page 74]