JBoss.orgCommunity Documentation

Mobicents Diameter User Guide

by Bartosz Baranowski and Alexandre Mendonca

Abstract

The Mobicents Platform is the first and only open source VoIP platform certified for JAIN SLEE 1.1 and SIP Servlets 1.1 compliance. Mobicents serves as a high-performance core for Service Delivery Platforms (SDPs) and IP Multimedia Subsystems (IMSes) by leveraging J2EE to enable the convergence of data and video in Next-Generation Intelligent Network (NGIN) applications.

The Mobicents Diameter solution provides Mobicents Platform with Authentication, Authorization, and Accounting (AAA) capabilities.


This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information.

In PDF and paper editions, this manual uses typefaces drawn from the Liberation Fonts set. The Liberation Fonts set is also used in HTML editions if the set is installed on your system. If not, alternative but equivalent typefaces are displayed. Note: Red Hat Enterprise Linux 5 and later includes the Liberation Fonts set by default.

Four typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows.

Mono-spaced Bold

Used to highlight system input, including shell commands, file names and paths. Also used to highlight key caps and key-combinations. For example:

The above includes a file name, a shell command and a key cap, all presented in Mono-spaced Bold and all distinguishable thanks to context.

Key-combinations can be distinguished from key caps by the hyphen connecting each part of a key-combination. For example:

The first sentence highlights the particular key cap to press. The second highlights two sets of three key caps, each set pressed simultaneously.

If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph will be presented as above, in Mono-spaced Bold. For example:

Proportional Bold

This denotes words or phrases encountered on a system, including application names; dialogue box text; labelled buttons; check-box and radio button labels; menu titles and sub-menu titles. For example:

The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all presented in Proportional Bold and all distinguishable by context.

Note the > shorthand used to indicate traversal through a menu and its sub-menus. This is to avoid the difficult-to-follow 'Select Mouse from the Preferences sub-menu in the System menu of the main menu bar' approach.

Mono-spaced Bold Italic or Proportional Bold Italic

Whether Mono-spaced Bold or Proportional Bold, the addition of Italics indicates replaceable or variable text. Italics denotes text you do not input literally or displayed text that changes depending on circumstance. For example:

Note the words in bold italics above username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text you enter when issuing a command or for text displayed by the system.

Aside from standard usage for presenting the title of a work, italics denotes the first use of a new and important term. For example:

If you find a typographical error in this manual, or if you have thought of a way to make this manual better, we would love to hear from you! Please submit a report in the the Issue Tracker, against the product Mobicents JAIN SLEE Example, or contact the authors.

When submitting a bug report, be sure to mention the manual's identifier: User_Guide

If you have a suggestion for improving the documentation, try to be as specific as possible when describing it. If you have found an error, please include the section number and some of the surrounding text so we can find it easily.

Diameter is a computer networking protocol for AAA (Authentication, Authorization and Accounting) defined in RFC 3588. It is a successor to RADIUS (and its name is a reference to it, a diameter is twice the radius). Diameter has been desgined to overcome certain RADIUS limitations:

  • No transport reliability and flexibility (Diameter uses TCP/SCTP instead of UDP)

  • No security within protocol (Diameter supports IPSec (mandatory) and TLS (optional))

  • Limited address space for AVPs (Diameter uses 32-bit address space instead of 8-bit)

  • Only stateless mode is possible (Diameter supports both stateful and stateless modes)

  • Static peers (Diameter offers dynamic discovery, using DNS SRV and NAPTR)

  • No peer alignment capabilities (Diameter introduce capabilities negotiation)

  • No support for transport layer failover (Diameter follows RFC3539, which introduces proper procedures)

  • Limited support for roaming (Diameter introduces mechanisms for secure and scalable roaming)

  • No extension possible (Diameter allows extension - new commands and avps to be defined)

Diameter offers all capabilities of RADIUS protocol. Also as a logical successor, it is comptibile with RADIUS.

Diameter also allows to define extensions. Each extension is called "Application".

Each application may introduce new types of messages, AVP codes, and state machines. The Message and AVP codes are assigned by the IANA. Furthermore, each application has its own Application ID and Vendor ID that is used to distinguish between applications. In addition, application code is used to signal to other peers which operations are supported by connecting peer (Capabilities Exchange / Negotiation).

Diameter is a byte based protocol. Each message has a fixed structure, which consists of two parts: header and payload.

Message header structure is common for all messages, it has a fixed length and content. It identifies message (by code, application and certain bit flags) in Diameter scope.

Payload is the message part built of carried AVPs. Its content differs for each command and application (however ALL define Session-Id AVP as mandatory).


Header has following fields:

Message Headers

Version

Indicates the Diameter protocol version. This value is always set to 1.

Message Length

Indicates the Diameter message length, including the header fields.

Flags

Composed by eight bits, to provide information regarding message. First four bits in Flags octet have following meaning:

  • R = Message is a request (1) or an answer (0);

  • P = Message is proxiable (1) and may be proxied, relayed or redirected, otherwise it must be processed locally (0);

  • E = Message is an error message (1) or a regular message(0);

  • T = Message is being potentially re-transmitted (1) or being sent for the first time (0)

The last four bits are reserved for future use, and should be set to 0.

Command Code

Indicates the command associated with the message.

Application-ID

Identifies application to which the message is applicable for. The application can be an authentication, accounting, or vendor specific application. The application-id in the header must be the same as what is contained in any relevant AVPs contained in the message.

Hop-by-Hop ID

Unique ID that is used to match requests and answer. The Answer message must ensure this header field contains the same value present in the corresponding request. This is how answers are routed back to peer which sent message.

End-to-End ID

Time-limited unique ID that is used to to detect duplicate messages. The ID must be unique for at least four minutes. The Answer message originator must ensure that this header contains the same value present in the corresponding request.

Message payload is built up from AVPs. Each AVP has similar structure: header and encoded data. Data can be simple (eg, integer, long) or complex (another encoded AVP).


Payload AVPs

AVP Code

Uniquely identifies the attribute, by combining the specified code with the value contained within the Vendor-ID header field.

AVP numbers 1 to 255 are reserved for RADIUS backwards compatibility, and do not require the Vendor-ID header field. AVP numbers 256 and above are used exclusively for the Diameter protocol, and are allocated by IANA.

Flags

Bit flags, which specify how each attribute must be handled. Flags octet has following structure: V M P r r r r r.

Full description can be found in Section 4.1 of RFC3588.

First three bits have the following meaning:

  • V = If set, indicates that optional octets (Vendor-ID) is present in AVP header.

  • M = If set, it indicates that receiveing peer must understand this AVP or send error answer.

  • P = If set, it indicates the need for encryption for end-to-end security.

The last 5 bits are reserved for future use, and should be set to 0.

AVP Length

Indicates the number of octets in the AVP, including the following information:

  • AVP Code

  • AVP Length

  • AVP Flags

  • Vendor-ID field (if present)

  • AVP Data

Vendor-ID

Optional octet identifying AVP in application space. AVP code and AVP Vendor-ID create unique identifier for AVP.

The Mobicents Diameter Stack is the core component of the presented Diameter solution. It performs all necessary tasks to allow user interact with Diameter network. It manages state of diameter peers and allows to route messages between them. For details please refer to RFC 3588.

Currently the Mobicents Diameter Stack supports the following application sessions:

  • Base

  • Credit Control Application (CCA)

  • Sh

  • Ro

  • Rf

  • Cx/Dx

Mobicents Diameter Stack has been designed to be extensible. In order to achieve that, two set of API are defined by the stack: one which defines basic contracts between user application and stack, second which defines contracts allowing for instance to inject custom objects into stack to perform certain tasks( SessionFactory for instance). ISessionFactory declares additional methods which allow developer to declare custom behaviour (custom application sessions, please refer to Section 2.4.1, “Session Factory” for more detailed information).

Figure 2.1. Mobicents Diameter Stack Extensibility Visualization


General pattern for interface declaration can be understood as follows: Interface ComponentInterface declares minimal set of methods for component to perform its task, and Interface IComponentInterface provides additional behavior methods. Please refer to java doc for list of interfaces and description of method contracts.

Mobicents Diameter Stack supports replication of session data and state. Clustered stack instances can perform operations on session regardless of physical location. Logicaly clustered stack can be imagined as follows:

Figure 2.4. Mobicents Diameter Cluster


Stack replicates only non simple sessions. Thats because simple session do not hold state and can be simply recreated by application. Simple sessions include:

  • RawSession

  • Session

Mobicents Diameter Cluster replicates full state of sessions, however it does not replicated resources which are entirely local to stack instance, like session listeners. Local resources references are recreated once session is being preparepared to be uses in stack instance. Listeners(state and events) are fetched from respective session factory instance. See Section 2.1.3, “Application session factories” for more details.

This section provides instructions on how to obtain and build the Mobicents Diameter Stack from source code.

  1. Downloading the source code

    Use SVN to checkout a specific release source, the base URL is http://mobicents.googlecode.com/svn/tags/servers/diameter/core/jdiameter, then add the specific release version, lets consider 1.3.0.FINAL.

    [usr]$ svn co http://mobicents.googlecode.com/svn/tags/servers/diameter/core/jdiameter/1.3.0.FINAL jdiameter-1.3.0.FINAL
  2. Building the source code

    Important

    Maven 2.0.9 (or higher) is used to build the release. Instructions for using Maven2, including install, can be found at http://maven.apache.org

    Use Maven to build the deployable unit binary.

    						[usr]$ cd jdiameter-1.3.0.FINAL
    						[usr]$ mvn install
    					

    Once the process finishes you should have the JAR files deployed in maven archive.

Similar process as for Section 2.2.2.1, “Release Source Code Building”, the only change is the SVN source code URL, which is http://mobicents.googlecode.com/svn/trunk/servers/diameter/core/jdiameter.

The stack is initially configured by parsing an XML file. The top level structure of the file is described below. Further explanation of each child element, and the applicable attributes is provided later in this section.


<Configuration xmlns="http://www.jdiameter.org/jdiameter-server">

    <LocalPeer></LocalPeer>
    <Parameters></Parameters>
    <Network></Network>
    <Extensions></Extensions>

</Configuration>

<LocalPeer>
    <URI value="aaa://localhost:1812"/>
    <IPAddresses>
        <IPAddress value="127.0.0.1"/>
    </IPAddresses>

    <Realm value="mobicents.org"/>
    <VendorID value="193"/>
    <ProductName value="jDiameter"/>
    <FirmwareRevision value="1"/>

    <OverloadMonitor>
        <Entry index="1" lowThreshold="0.5" highThreshold="0.6">
            <ApplicationID>
                <VendorId value="193"/>
                <AuthApplId value="0"/>
                <AcctApplId value="19302"/>
            </ApplicationID>
        </Entry>
    </OverloadMonitor>
    <Applications>
        <ApplicationID>
            <VendorId value="193"/>
            <AuthApplId value="0"/>
            <AcctApplId value="19302"/>
        </ApplicationID>
    </Applications>
</LocalPeer>

The <LocalPeer> element contains parameters which affect the local Diameter peer. The available elements and attributes are listed for reference.

<LocalPeer> Elements and Attributes

<URI>

Specifies the URI for the local peer. URI has following format: "aaa://FQDN:port".

<IPAddresses>

Contains one or more child <IPAddress> elements which contain a single, valid IP address for the local peer, stored in the value attribute of IPAddress.

<Realm>

Specifies the realm of the local peer, using the value attribute.

<VendorID>

Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA.

<ProductName>

Specifies the name of the local peer product name.

<FirmwareRevision>

Specifies the version of the firmware.

<OverloadMonitor>

Optional parent element containing child elements which specify settings relating to the Overload Monitor.

<Entry>

Supports child elements of type <ApplicationID>, which specify the id of the tracked application(s). It also supports following properties:

<ApplicationID>

Parent element containing child elements which specify information about the application. Child elements are: VendorId, AuthAppId and AcctAppId. Together they create an unique application identifier.

<VendorId>

Specifies vendor id for application definition. It supports a single property: "value"

<AuthAppId>

The Authentication Application ID for application definition. It supports a single property: "value"

<AcctAplId>

The Account Application ID for application defitniion. It supports a single property: "value"

<Applications>

Contains a child element <ApplicationID>, which defines the list of default supported applications. It is used for server side. When stack is configured to accept incoming calls and there is empty list of preconfigured peers (server is configured to accept any connection).


<Parameters>

    <AcceptUndefinedPeer value="true"/>
    <DuplicateProtection value="true"/>
    <DuplicateTimer value="240000"/>
    <UseUriAsFqdn value="true"/> <!-- Needed for Ericsson SDK Emulator -->
    <QueueSize value="10000"/>
    <MessageTimeOut value="60000"/>
    <StopTimeOut value="10000"/>
    <CeaTimeOut value="10000"/>
    <IacTimeOut value="30000"/>
    <DwaTimeOut value="10000"/>
    <DpaTimeOut value="5000"/>
    <RecTimeOut value="10000"/>

    <Concurrent>
        <Entity name="ThreadGroup" size="64"/>
        <Entity name="ProcessingMessageTimer" size="1"/>
        <Entity name="DuplicationMessageTimer" size="1"/>
        <Entity name="RedirectMessageTimer" size="1"/>
        <Entity name="PeerOverloadTimer" size="1"/>
        <Entity name="ConnectionTimer" size="1"/>
        <Entity name="StatisticTimer" size="1"/>
        <Entity name="ApplicationSession" size="16"/>
    </Concurrent>

</Parameters>

The <Parameters> element contains elements which specify parameters for the Diameter stack. The available elements and attributes are listed for reference. If not specified otherwise each tag supports a single property "value" which indicates value of tag.

<Parameters> Elements and Attributes

<AcceptUndefinedPeer>

Specifies whether the stack will accept connections from unidentified peers. The default value is false.

<DuplicateProtection>

Specifies whether duplicate message protection is enabled. The default value is false.

<DuplicateTimer>

Specifies the time each duplicate message is valid for. The default, minimum value is 240000 (4 minutes in milliseconds)

<UseUriAsFqdn>

Determines as URI should be used as FQDN, if set to true stack expects destination/origin host in format of "aaa://isdn.domain.com:3868" instead of proper "isdn.domain.com". Default value is false.

<QueueSize>

Determines how many tasks peer state machine can have before rejecting next task. This queue contains FSM event and messaging.

<MessageTimeOut>

Determines timeout for other than protocol FSM messages. Delay is in milliseconds.

<StopTimeOut>

Determines how long stack waits for all resources to stop gracefully. Delays is in milliseconds.

<CeaTimeOut>

Determines how long it takes for CER/CEA exchange to timeout if there is no response. Delay is in milliseconds.

<IacTimeOut>

Determines how long to retry communication with a peer that stopped answering DWR messages. The delay is in milliseconds

<DwaTimeOut>

Determines how long it takes for DWR/DWA exchange to timeout if there is no response. Delay is in milliseconds.

<DpaTimeOut>

Determines how long it takes for DPR/DPA exchange to timeout if there is no response. Delay is in milliseconds.

<RecTimeOut>

Determines how long it takes for reconnection procedure to timeout. Delay is in milliseconds.

<Concurrent />

Controls thread pool sizes for different aspects of stack. Supports multiple Entity child elements. Entity elements configure thread groups

Entity element supports following properties:

Default supported entities are as follows:


<Network>

    <Peers>
        <!-- This peer is a server, if it's a client attempt_connect should be set to false -->
        <Peer name="aaa://127.0.0.1:3868" attempt_connect="true" rating="1"/>
    </Peers>

    <Realms>
        <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" dynamic="false" exp_time="1">
            <ApplicationID>
                <VendorId value="193"/>
                <AuthApplId value="0"/>
                <AcctApplId value="19302"/>
            </ApplicationID>
        </Realm>
    </Realms>

</Network>

The <Network> element contains elements which specify parameters for external peers. The available elements and attributes are listed for reference.

An example configuration file for a server supporting the CCA, Sh and Ro Applications:


<?xml version="1.0"?>
<Configuration xmlns="http://www.jdiameter.org/jdiameter-server">

    <LocalPeer>
        <URI value="aaa://127.0.0.1:3868" />
        <Realm value="mobicents.org" />
        <VendorID value="193" />
        <ProductName value="jDiameter" />
        <FirmwareRevision value="1" />
        <OverloadMonitor>
            <Entry index="1" lowThreshold="0.5" highThreshold="0.6">
                <ApplicationID>
                    <VendorId value="193" />
                    <AuthApplId value="0" />
                    <AcctApplId value="19302" />
                </ApplicationID>
            </Entry>
        </OverloadMonitor>
    </LocalPeer>

    <Parameters>
        <AcceptUndefinedPeer value="true" />
        <DuplicateProtection value="true" />
        <DuplicateTimer value="240000" />
        <UseUriAsFqdn value="false" /> <!-- Needed for Ericsson Emulator (set to true) -->
        <QueueSize value="10000" />
        <MessageTimeOut value="60000" />
        <StopTimeOut value="10000" />
        <CeaTimeOut value="10000" />
        <IacTimeOut value="30000" />
        <DwaTimeOut value="10000" />
        <DpaTimeOut value="5000" />
        <RecTimeOut value="10000" />
        <Concurrent>
             <Entity name="ThreadGroup" size="64"/>
             <Entity name="ProcessingMessageTimer" size="1"/>
             <Entity name="DuplicationMessageTimer" size="1"/>
             <Entity name="RedirectMessageTimer" size="1"/>
             <Entity name="PeerOverloadTimer" size="1"/>
             <Entity name="ConnectionTimer" size="1"/>
             <Entity name="StatisticTimer" size="1"/>
             <Entity name="ApplicationSession" size="16"/>
        </Concurrent>
    </Parameters>

    <Network>
        <Peers>
            <Peer name="aaa://127.0.0.1:1218" attempt_connect="false" rating="1" />
        </Peers>
        <Realms>
            <!-- CCA -->
            <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" 
                dynamic="false" exp_time="1">
                <ApplicationID>
                    <VendorId value="0" />
                    <AuthApplId value="4" />
                    <AcctApplId value="0" />
                </ApplicationID>
            </Realm>
            
            <!-- Sh -->
            <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" 
                dynamic="false" exp_time="1">
                <ApplicationID>
                    <VendorId value="10415" />
                    <AuthApplId value="16777217" />
                    <AcctApplId value="0" />
                </ApplicationID>
            </Realm>

            <!-- Ro -->
            <Realm name="mobicents.org" peers="127.0.0.1" local_action="LOCAL" 
                dynamic="false" exp_time="1">
                <ApplicationID>
                    <VendorId value="10415" />
                    <AuthApplId value="4" />
                    <AcctApplId value="0" />
                </ApplicationID>
            </Realm>
        </Realms>
    </Network>

    <Extensions />

</Configuration>

To enable stack clsuter mode you need following:

Mobicents Diameter stack is built with the following basic components:

SessionFactory provides stack user access to session objects. It manages registered application session factories, in order to allow creation of specific application sessions. An Session Factory instance can be obtained from stack with use of getSessionFactory() method. Base SessionFactory interface is defined as follows:

package org.jdiameter.api;


import org.jdiameter.api.app.AppSession;
public interface SessionFactory {
    RawSession getNewRawSession() throws InternalException;
    Session getNewSession() throws InternalException;
    Session getNewSession(String sessionId) throws InternalException;
    <extends AppSession> T getNewAppSession(ApplicationId applicationId, 
        Class<? extends AppSession> userSession) throws InternalException;
    <extends AppSession> T getNewAppSession(String sessionId, ApplicationId
        applicationId, Class<? extends AppSession> userSession) throws InternalException;
}

However, since stack is extensible, it is safe to cast SessionFactory object to this interface:

package org.jdiameter.client.api;



public interface ISessionFactory extends SessionFactory {
    <extends AppSession> T getNewAppSession(String sessionId, 
        ApplicationId applicationId, java.lang.Class<? extends AppSession> 
        aClass, Object... args) throws InternalException;
    void registerAppFacory(Class<? extends AppSession> sessionClass, 
        IAppSessionFactory factory);
    void unRegisterAppFacory(Class<? extends AppSession> sessionClass);
    IConcurrentFactory getConcurrentFactory();
}
RawSession getNewRawSession() throws InternalException;

This method creates RawSession. Raw sessions are meant as handles for code performing part of routing decision on stacks behalf, such as rely agents for instance.

Session getNewSession() throws InternalException;

This method creates session which acts as endpoint for peer communication(for given session ID). It declares method which work with Request and Answer objects. Session created with this method has autogenerated ID. It should be considered as client session.

Session getNewSession(String sessionId) throws InternalException;

As above, however created session has Id equal to passsed as argument. Created session should be considered as server session.

<T extends AppSession> T getNewAppSession(ApplicationId applicationId, Class<? extends AppSession> userSession) throws InternalException;

This method creates new specific application session, identified by application Id and class of session passed. Session Id is generated by implementation. New application session should be considered as client session. It is safe to type cast return value to class passed as argument. This method delegates call to specific application session factory.

<T extends AppSession> T getNewAppSession(String sessionId, ApplicationId applicationId, Class<? extends AppSession> userSession) throws InternalException;

As above, however session Id is equal to argument passed. New session should be considered as server session.

<T extends AppSession> T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class<? extends AppSession> aClass, Object... args) throws InternalException;

As above, however it allows to pass some additional argument. Passed values are implementation specifc.

void registerAppFacory(Class<? extends AppSession> sessionClass, IAppSessionFactory factory);

registers factory for certain sessionClass. This factory will receive delegated call when ever getNewAppSession method is called with application class matching one from register method.

void unRegisterAppFacory(Class<? extends AppSession> sessionClass);

removes application session factory registered for sessionClass.



RawSession, Session and ApplicationSession provide means of disspatching and receiving messages. Specific implementation of ApplicationSession may provide non standard methods.

RawSession and Session life span is controlled entirelly by application. However ApplicationSession life time depends on implemented state machine.

RawSession is defined as follows:

public interface BaseSession extends Wrapper, Serializable {

 
    long getCreationTime();
    long getLastAccessedTime();
    boolean isValid();
    Future<Message> send(Message message) throws InternalException, 
        IllegalDiameterStateException, RouteException, OverloadException;
    Future<Message> send(Message message, long timeOut, TimeUnit timeUnit) 
        throws InternalException, IllegalDiameterStateException, RouteException, OverloadException;
    void release();
}
public interface RawSession extends BaseSession {
    Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);
    Message createMessage(int commandCode, ApplicationId applicationId, 
        long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);
    Message createMessage(Message message, boolean copyAvps);
    void send(Message message, EventListener<Message, Message> listener) 
        throws InternalException, IllegalDiameterStateException, RouteException, OverloadException;
    void send(Message message, EventListener<Message, Message> listener,
        long timeOut, TimeUnit timeUnit) throws InternalException, 
        IllegalDiameterStateException, RouteException, OverloadException;
}
long getCreationTime();

Returns time stamp of this session creation

long getLastAccessedTime();

Returns last time stamp indicating send or receive operation

boolean isValid();

Returns true when this session is still valid (ie, release() has not been called)

void release();

Application calls this method to inform that session should free any associated resource - it shall not be used anymore

Future<Message> send(Message message)

Sends message in async mode. Provided Future reference provides means of accessing answer once its received

void send(Message message, EventListener<Message, Message> listener, long timeOut, TimeUnit timeUnit)

As above. Allows to specif time out value for send operation

Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);

Creates a Diameter message. It should be explicitly set either as request or answer. Passed parameters are used to build message

Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);

Same as above, however it allow to also set Hop-by-Hop and End-to-End Identifiers in message header. This method should be used to create answers

Message createMessage(Message message, boolean copyAvps);

Clones message and returns created object

void send(Message message, EventListener<Message, Message> listener)

Sends message, answer will be delivered to the specified listener

void send(Message message, EventListener<Message, Message> listener, long timeOut, TimeUnit timeUnit)

As above, it allows to pass answer wait timeout

Session defines similar methods, with exactly the same purpose:

public interface Session extends BaseSession {

    String getSessionId();
    void setRequestListener(NetworkReqListener listener);
    Request createRequest(int commandCode, ApplicationId appId, String destRealm);
    Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost);
    Request createRequest(Request prevRequest);
    void send(Message message, EventListener<Request, Answer> listener) 
        throws InternalException, IllegalDiameterStateException, RouteException, OverloadException;
    void send(Message message, EventListener<Request, Answer> listener, long timeOut,
        TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, 
        RouteException, OverloadException;
}

Validator is one of the Stack features. The primary purpose of the Validator is to detect malformed messages, such as an Answer message containing a Destination-Host Attribute Value Pair (AVP).

The Validator is capable of validating multi-leveled, grouped AVPs, excluding the following content types:

That is, it is capable of checking structural integrity, not content.

Validator performs the following checks:

Validator is called by stack implementation. It is invoked after message is received and before it is dispatched to remote peer. Note that latter means that if peer does not exist in local peer table validator is not called, as stack fails before calling it.

Validator is configured with a single XML file. This file contains the structure definition for messages and AVPs.

Upon creation of Diameter Stack, the validator is initialized. It performs initialization by looking up dictionary.xml file in classpath.

Configuration file structure is the following:



<dictonary>
    <validator enabled="true|false" sendLevel="OFF|MESSAGE|ALL" receiveLevel="OFF|MESSAGE|ALL" />
    <vendor name="" vendor-id="" code=""/>
    <typedefn type-name="" type-parent=""/>
    <application id="" name="">
        <avp ...>
            <type type-name=""/>
            <enum name="" code=""/>
            <grouped>
                <gavp name=""/>
            <grouped/>
        <avp/>
        <command name="" code="" request="true|false"/>
        <avp ...>
            <type type-name=""/>
            <enum name="" code=""/>
            <grouped>
                <gavp name=""/>
            <grouped/>
        <avp/>
    <application>
<dictionary/>
<dictionary>

The root element, which contains the child elements comprising the validator and dictionary components. This element does not support any attributes.

<validator>

Specifies whether message validation is activated for sent and received stack messages. The element supports the following optional attributes:

<vendor>

Optional element, which specifies the mapping between the vendor name, vendor ID, and vendor code. The element supports the following required attributes:


<typedefn>

Defines the simple Attribute Value Pair (AVP) types. The element supports the following required attributes:

type-name

Specifies a type name in accordance with the acceptable base types defined in RFC 3588. For example; "Enumerated", "OctetString", "Integer32".

type-parent

Specifies the parent type name used to define the base characteristics of the type. The values are restricted to defined <typedefn> elements. For example; "OctetString", "UTF8String", "IPAddress".


<application>

Defines the specific applications used within the dictionary. Two child elements are supported by <application>: <avp> and <command>. The <application> element supports the following attributes:

id

Specifies the unique ID allocated to the application. The attribute is used in all messages and forms part of the message header.

name

Optional attribute, which specifies the logical name of the application.

uri

Optional attribute, which specifies a link to additional application information.


<avp>

Element containing information necessary to configure the Attribute Value Pairs. Table 2.2, “<avp> Attributes” contains the complete list of supported attributes, and their available values (if applicable).

The <avp> element supports a number of child elements, which are used to set finer parameters for the individual AVP. The supported elements are <type>, <enum>, and <grouped>.

Note

Different sets of elements are supported by <avp> depending on its position in the dictionary.xml file.


<type>

Child element of <avp>, which is used to match the AVP with the AVP type as defined in the <typedefn> element. The element supports the following mandatory attribute:

type-name

Specifies the type name, which is used to match to the type-name value specified in the <typedefn> element.

Note

<type> is ignored if the <avp> element contains the <grouped> element.

<enum>

Child element of <avp>, which specifies the enumeration value for the specified AVP. <enum> is used only when the type-name attribute of <type> is specified. The element supports the following mandatory attributes:

name

Specifies the name of a constant value that applies to the AVP.

code

Specifies the integer value associated with the name of the constant. The value is passed as a value of the AVP, and maps to the name attribute.

Note

<enum> is ignored if the <avp> element contains the <grouped> element.

<grouped>

Child element of <avp>, which specifies the AVP is a grouped type. A grouped AVP is one that has no <typedefn> element present. The element does not support any attributes, however the <gavp> element is allowed as a child element.

<gavp>

Child element of <grouped>, which specifies a reference to a grouped AVP. The element supports one mandatory attribute:

name

Specifies the name of the grouped AVP member. The value must match the defined AVP name.



<command>

Specifies the command for the application. The element supports the <avp> element, which specifies the structure of the command. The element supports the following attributes:

name

Optional parameter, which specifies the message name for descriptive purposes.

code

Mandatory parameter, which specifies the integer code of the message.

request

Mandatory parameter, which specifies whether the declared command is a request or answer. The available values are "true" (request) or "false" (answer).

Note

If the <avp> element is specified in <command> it does not support any child elements. The <avp> element only refers to defined AVPs when used in this context.


Validator API defines methods to access its data base of AVP and check if AVP and message has proper structure.

Currently Validator is message oriented, that is it declared methods which center on message consitency checks. Class containing all validation logic is org.jdiameter.common.impl.validation.DiameterMessageValidator. It exposes the following methods:

Current implementation provides more methods, however those are out of scope for this documentation.

Simple example of validator use case look as follows:


The Mobicents Diameter Multiplexer (MUX) is designed as a stack wrapper. It serves two purposes:

Expose stack

It exposes the Diameter Stack and allows it to be shared between multiple listeners. The stack follows the MUX life cycle, ie, it is created and destroyed with the MUX.

Expose management operations

It exposes management operations for JMX clients, one of them being the Jopr Console. For specifc information please refer to the Mobicents Diameter Management Console User Guide.

This section provides instructions on how to obtain and build the Mobicents Diameter MUX from source code.

  1. Downloading the source code

    Use SVN to checkout a specific release source, the base URL is http://mobicents.googlecode.com/svn/tags/servers/diameter/core/mux, then add the specific release version, lets consider 1.3.0.FINAL.

    [usr]$ svn co http://mobicents.googlecode.com/svn/tags/servers/diameter/core/mux/1.3.0.FINAL mux-1.3.0.FINAL
  2. Building the source code

    Important

    Maven 2.0.9 (or higher) is used to build the release. Instructions for using Maven2, including install, can be found at http://maven.apache.org.

    Use Maven to build the deployable unit binary.

    						[usr]$ cd mux-1.3.0.FINAL
    						[usr]$ mvn install
    					

    Once the process finishes you should have the SAR built. If JBOSS_HOME environment variable is set, after execution SAR will be deployed in container.

Note

By default Mobicents Diameter MUX; deploys in JBoss Application Server v4.x SAR. To change it run maven with profile switch: -Pjboss5

Similar process as for Section 3.2.2.1, “Release Source Code Building”, the only change is the SVN source code URL, which is http://mobicents.googlecode.com/svn/trunk/servers/diameter/core/mux.

Mobicents Diameter MUX capabilities are defined by a MBean interface: org.mobicents.diameter.stack.DiameterStackMultiplexerMBean. This interface defines two types of methods:

The following methods are of interest to Mobicents Diameter MUX user:

Listener interface is defined as follows:



package org.mobicents.diameter.stack;
import java.io.Serializable;
import org.jdiameter.api.Answer;
import org.jdiameter.api.EventListener;
import org.jdiameter.api.NetworkReqListener;
import org.jdiameter.api.Request;
public interface DiameterListener extends NetworkReqListener, Serializable, 
    EventListener<Request, Answer>
{
}
    

MUX can be used as follows:

public class DiameterActor implements DiameterListener

{
    private ObjectName diameterMultiplexerObjectName = null;
    private DiameterStackMultiplexerMBean diameterMux = null;
    private synchronized void initStack() throws Exception {
        this.diameterMultiplexerObjectName = 
            new ObjectName("diameter.mobicents:service=DiameterStackMultiplexer");
        Object[] params = new Object[]{};
        String[] signature = new String[]{};
        String operation = "getMultiplexerMBean";
        this.diameterMux=mbeanServer.invoke(this.diameterMultiplexerObjectName, operation,
            params, signature);
        long acctAppIds = new long[]{19312L};
        long acctVendorIds = new long[]{193L};
        long authAppIds = new long[]{4L};
        long authVendorIds = new long[]{0L};
        List<ApplicationId> appIds = new ArrayList<ApplicationId>();
        for(int index = 0;index<acctAppIds.length;index++) {
            appIds.add(ApplicationId.createByAccAppId(acctVendorIds[index], acctAppIds[index]));
        }
        for(int index = 0;index<authAppIds.length;index++) {
            appIds.add(ApplicationId.createByAuthAppId(authVendorIds[index], authAppIds[index]));
        }
        this.diameterMux.registerListener(this, appIds.toArray(new ApplicationId[appIds.size()]));
        this.stack = this.diameterMux.getStack();
        this.messageTimeout = stack.getMetaData().getConfiguration().getLongValue(
            MessageTimeOut.ordinal(), (Long) MessageTimeOut.defValue());
    }
}

Dictionary is part of Diameter MUX package. Its purpose is to provide unified access to information regarding AVP structure, content and definition. Dictionary is configured via a XML file, dictionary.xml.

The Dictionary logic is contained in org.mobicents.diameter.dictionary.AvpDictionary class. It exposes the following methods:

Dictionary uses a POJO class (org.mobicents.diameter.dictionary.AvpRepresentation) to provide access to stored information. It exposes the following methods:

The Mobicents Diameter MUX Dictionary can be used as follows:

public static void addAvp(Message msg, int avpCode, long vendorId, AvpSet set, Object avp) {

    AvpRepresentation avpRep = AvpDictionary.INSTANCE.getAvp(avpCode, vendorId);
    if(avpRep != null) {
        DiameterAvpType avpType = DiameterAvpType.fromString(avpRep.getType());
        boolean isMandatoryAvp = avpRep.isMandatory();
        boolean isProtectedAvp = avpRep.isProtected();
        if(avp instanceof byte[]) {
            setAvpAsRaw(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp, (byte[]) avp);
        }
        else
        {
            switch (avpType.getType()) {
            case DiameterAvpType._ADDRESS:
            case DiameterAvpType._DIAMETER_IDENTITY:
            case DiameterAvpType._DIAMETER_URI:
            case DiameterAvpType._IP_FILTER_RULE:
            case DiameterAvpType._OCTET_STRING:
            case DiameterAvpType._QOS_FILTER_RULE:
                setAvpAsOctetString(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    avp.toString());
                break;
            case DiameterAvpType._ENUMERATED:
            case DiameterAvpType._INTEGER_32:
                setAvpAsInteger32(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Integer) avp);
                break;
            case DiameterAvpType._FLOAT_32:
                setAvpAsFloat32(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Float) avp);
                break;
            case DiameterAvpType._FLOAT_64:
                setAvpAsFloat64(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Float) avp);
                break;
            case DiameterAvpType._GROUPED:
                setAvpAsGrouped(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (DiameterAvp[]) avp);
                break;
            case DiameterAvpType._INTEGER_64:
                setAvpAsInteger64(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Long) avp);
                break;
            case DiameterAvpType._TIME:
                setAvpAsTime(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Date) avp);
                break;
            case DiameterAvpType._UNSIGNED_32:
                setAvpAsUnsigned32(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Long) avp);
                break;
            case DiameterAvpType._UNSIGNED_64:
                setAvpAsUnsigned64(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (Long) avp);
                break;
            case DiameterAvpType._UTF8_STRING:
                setAvpAsUTF8String(msg, avpCode, vendorId, set, isMandatoryAvp, isProtectedAvp,
                    (String) avp);
                break;
            }
        }
    }
}

Revision History
Revision 1.0Thu Mar 11 2010Bartosz Baranowski, Alexandre Mendonça
Creation of the Mobicents Diameter User Guide.
Revision 1.0Mon July 12 2010Bartosz Baranowski, Alexandre Mendonça
Creation of the Mobicents Diameter User Guide.