JBoss.orgCommunity Documentation
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).
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 performs the following tasks:
Manage connections to remote peers
Manage sessions objects
Route messages on behalf of sessions
Receive and deliver messages to assigned listeners (usually session object)
Sessions use stack and services it provides to communicate with remote peers. Application is only place which holds reference to sessions. It can be seen as follows:
Application session factories perform two tasks:
server stack as factory for sessions
server session objects as holders for session related resources, like state change listener, event listeners, context
Generally application session factory and user application relation can be imagined as follows:
Session context is callback interface defined by some sessions.
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:
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.
Ensure that the following requirements have been met before continuing with the install.
This section provides instructions on how to obtain and build the Mobicents Diameter Stack from source code.
Downloading the source code
Subversion is used to manage its source code. Instructions for using Subversion, including install, can be found at http://svnbook.red-bean.com
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
Building the source code
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
Specifies the URI for the local peer. URI has following format: "aaa://FQDN:port".
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.
Specifies the realm of the local peer, using the value
attribute.
Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA.
Specifies the name of the local peer product name.
Specifies the version of the firmware.
Optional parent element containing child elements which specify settings relating to the Overload Monitor.
Supports child elements of type <ApplicationID>, which specify the id of the tracked application(s). It also supports following properties:
Defines the index of this overload monitor, so priorities/orders can be specified.
The low threshold for activation of the overload monitor.
The high threshold for activation of the overload monitor.
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.
Specifies vendor id for application definition. It supports a single property: "value"
The Authentication Application ID for application definition. It supports a single property: "value"
The Account Application ID for application defitniion. It supports a single property: "value"
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
Specifies whether the stack will accept connections from unidentified peers. The default value is false
.
Specifies whether duplicate message protection is enabled. The default value is false
.
Specifies the time each duplicate message is valid for. The default, minimum value is 240000
(4 minutes in milliseconds)
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
.
Determines how many tasks peer state machine can have before rejecting next task. This queue contains FSM event and messaging.
Determines timeout for other than protocol FSM messages. Delay is in milliseconds.
Determines how long stack waits for all resources to stop gracefully. Delays is in milliseconds.
Determines how long it takes for CER/CEA exchange to timeout if there is no response. Delay is in milliseconds.
Determines how long to retry communication with a peer that stopped answering DWR messages. The delay is in milliseconds
Determines how long it takes for DWR/DWA exchange to timeout if there is no response. Delay is in milliseconds.
Determines how long it takes for DPR/DPA exchange to timeout if there is no response. Delay is in milliseconds.
Determines how long it takes for reconnection procedure to timeout. Delay is in milliseconds.
Controls thread pool sizes for different aspects of stack. Supports multiple Entity
child elements. Entity
elements configure thread groups
Entity element supports following properties:
Specifies the name of the entity.
Thread pool size of entity.
Default supported entities are as follows:
Specifies maximum thread count in other entities
Specifies thread count for message processing task.
Specifies thread pool for identifying duplicate messages.
Specifies thread pool for redirecting messages, which do not need any further processing (ie, relaying).
Specifies thread pool for overload monitor tasks.
Specifies thread pool for managing tasks regarding peer connection FSM.
Specifies thread pool for statistic gathering tasks.
Specifies thread pool for managing invocation of application session FSM, which will invoke listeners.
<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.
<Network> Elements and Attributes
Parent element containing child elements which specify external peers and the way they connect.
Specifies the name of the external peer, whether the peer should be treated as a server or client, and what rating the peer has externally.
Peer supports following properties:
Specifies name of peer in for of URI. structure looks as follows "aaa://[fqdn|ip]:port", for example "aaa://192.168.1.1:3868"
Determines if stack should try to connect to this peer. This property accepts boolean values.
Specifies the rating of this peer, in order to achiever peer priorities/sorting.
Parent element containing child elements which specify all realms that connect into the Diameter network.
Child element containing attributes and elements which describe different realms configured for the Core. It supports <ApplicationID> child elements, which define applications supported.
Realm supports following parameters:
Comma separated list of peers, each peer is represented by IP Address or FQDN.
Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer
Specifies if this realm is dynamic, ie, peers connecting to local peer with this realm name, will be added to the realm peer list if not present already.
The expire time for a peer belonging to this realm to be removed from it, if no connection is available.
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:
Add the following entries in Parameters
section of jdiameter-config.xml
:
<SessionDatasource>org.mobicents.diameter.impl. ha.data.ReplicatedData</SessionDatasource>
<TimerFacility>org.mobicents.diameter.impl.ha. timer.ReplicatedTimerFacilityImpl</TimerFacility>
Proper JBoss Cache
configuration file: jdiameter-jbc.xml
(located under config
directory). For instance following content is enough:
<?xml version="1.0" encoding="UTF-8"?>
<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:jboss:jbosscache-core:config:3.0">
<locking isolationLevel="REPEATABLE_READ"
lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000"
nodeLockingScheme="mvcc" writeSkewCheck="false" concurrencyLevel="500" />
<jmxStatistics enabled="false" />
<startup regionsInactiveOnStartup="false" />
<shutdown hookBehavior="DEFAULT" />
<listeners asyncPoolSize="1" asyncQueueSize="100000" />
<invocationBatching enabled="false" />
<serialization objectInputStreamPoolSize="12"
objectOutputStreamPoolSize="14" version="3.0.0"
marshallerClass="org.jboss.cache.marshall.CacheMarshaller300"
useLazyDeserialization="false" useRegionBasedMarshalling="false" />
<clustering mode="replication" clusterName="DiameterCluster">
<async useReplQueue="true" replQueueInterval="1000"
replQueueMaxElements="500" serializationExecutorPoolSize="20"
serializationExecutorQueueSize="5000000"/>
<jgroupsConfig>
<UDP
mcast_addr="${jgroups.udp.mcast_addr:228.10.10.10}"
mcast_port="${jgroups.udp.mcast_port:18811}"
discard_incompatible_packets="true"
max_bundle_size="60000"
max_bundle_timeout="30"
ip_ttl="${jgroups.udp.ip_ttl:2}"
enable_bundling="true"
thread_pool.enabled="true"
thread_pool.min_threads="1"
thread_pool.max_threads="25"
thread_pool.keep_alive_time="5000"
thread_pool.queue_enabled="false"
thread_pool.queue_max_size="100"
thread_pool.rejection_policy="Run"
oob_thread_pool.enabled="true"
oob_thread_pool.min_threads="1"
oob_thread_pool.max_threads="8"
oob_thread_pool.keep_alive_time="5000"
oob_thread_pool.queue_enabled="false"
oob_thread_pool.queue_max_size="100"
oob_thread_pool.rejection_policy="Run"/>
<PING timeout="2000"
num_initial_members="3"/>
<MERGE2 max_interval="30000"
min_interval="10000"/>
<FD_SOCK/>
<FD timeout="10000" max_tries="5" />
<VERIFY_SUSPECT timeout="1500" />
<BARRIER />
<pbcast.NAKACK
use_mcast_xmit="false" gc_lag="0"
retransmit_timeout="300,600,1200,2400,4800"
discard_delivered_msgs="true"/>
<UNICAST timeout="300,600,1200,2400,3600"/>
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
max_bytes="400000"/>
<VIEW_SYNC avg_send_interval="60000" />
<pbcast.GMS print_local_addr="true" join_timeout="3000"
view_bundling="true"/>
<FC max_credits="20000000"
min_threshold="0.10"/>
<FRAG2 frag_size="60000" />
<pbcast.STATE_TRANSFER />
</jgroupsConfig>
</clustering>
</jbosscache>
Mobicents Diameter stack is built with the following basic components:
Session Factory governs creation of sessions - raw and specific application sessions.
Sessions govern stateful message routing between peers. Specific application sessions consume different type of messages and act differently based on data present.
Stack governs all necessary components which allow to establish connection and communicate with remote peers.
For more detailed information please refer to Javadoc and simple examples which can be found at SVN Testsuite Trunk.
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;
<T extends AppSession> T getNewAppSession(ApplicationId applicationId,
Class<? extends AppSession> userSession) throws InternalException;
<T 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 {
<T 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
.
Example 2.1. SessionFactory use example
class Test implements EventListener<Request, Answer>
{
....
public void test(){
Stack stack = new StackImpl();
XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile));
SessionFactory sessionFactory = stack.init(config);
stack.start();
//perferctly legal, both factories are the same.
sessionFactor = stack.getSessionFactory();
Session session = sessionFactory.getNewSession();
session.setRequestListener(this);
Request r = session.createRequest(308,ApplicationId.createByAuth(100L,10101L),
"mobicents.org","aaa://uas.fancyapp.mobicents.org");
//add avps specific for app
session.send(r,this);
}
}
Example 2.2. SessionFactory use example
class Test implements EventListener<Request, Answer>
{
Stack stack = new StackImpl();
XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile));
ISessionFactory sessionFactory = (ISessionFactory)stack.init(config);
stack.start();
//perferctly legal, both factories are the same.
sessionFactor = (ISessionFactory)stack.getSessionFactory();
sessionFactory.registerAppFacory(ClientShSession.class, new ShClientSessionFactory(this));
//our implementation of factory does not require any parameters
ClientShSession session = (ClientShSession) sessionFactory.getNewAppSession(null, null
, ClientShSession.class, null);
...
session.sendUserDataRequest(udr);
}
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;
}
In table below you can find session factories provided by current implementatiotion, along with short description:
Table 2.1. Application Factories
Factory class | Application type & id | Application | Reference |
---|---|---|---|
org.jdiameter.common .impl.app.acc. AccSessionFactoryImpl | AccountingId[0:3] | Acc | RFC3588 |
org.jdiameter.common .impl.app.auth. AuthSessionFactoryImpl | Specific | Auth | RFC3588 |
org.jdiameter.common .impl.app.cca. CCASessionFactoryImpl | AuthId[0:4] | CCA | RFC4006 |
org.jdiameter.common .impl.app.sh. ShSessionFactoryImpl | AuthId[10415:16777217] | Sh | TS.29328, TS.29329 |
org.jdiameter.common .impl.app.cxdx. CxDxSessionFactoryImpl | AuthId[13019:16777216] | Cx | TS.29228, TS.29229 |
org.jdiameter.common .impl.app.cxdx. CxDxSessionFactoryImpl | AuthId[10415:16777216] | Dx | TS.29228, TS.29229 |
org.jdiameter.common .impl.app.acc. AccSessionFactoryImpl | AccountingId[10415:3] | Rf | TS.32240 |
org.jdiameter.common .impl.app.cca. CCASessionFactoryImpl | AuthId[10415:4] | Ro | TS.32240 |
There is no specific factory for Ro and Rf, those application reuse respective session and session factories.
Application id contains two numbers - [VendorId:ApplicationId].
Spaces where introduced in Factory class
column values, to correctly render the table. Please remove them when using copy/paste.
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:
URI, or Identifier types.
Enumerated types against defined values.
That is, it is capable of checking structural integrity, not content.
Validator performs the following checks:
Checks if AVPs are in correct place, eg, Session-Id
must always be encoded before any other AVP.
Checks if message AVPs occurs the correct number of times, eg, if Session-Id is present one and only one time.
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 contains more data than Validator use to build its data base. It is caused by the fact that Dictionary uses the same file to configure itself. It reuses AVP definitions, extended with some information like AVP type and flags.
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/>
The root element, which contains the child elements comprising the validator and dictionary components. This element does not support any attributes.
Specifies whether message validation is activated for sent and received stack messages. The element supports the following optional attributes:
Specifies whether the validator is activated or deactivated. If not specified, the validator is deactivated.
Determines the validation level for message sent by the stack instance. Values determine if sent messages are not validated at all (OFF
), only message level AVPs are checked (MESSAGE
) or all AVPs are in message are checked (ALL
).
Determines the validation level for message received by the stack instance. Values determine if sent messages are not validated at all (OFF
), only message level AVPs are checked (MESSAGE
) or all AVPs are in message are checked (ALL
).
Optional element, which specifies the mapping between the vendor name, vendor ID, and vendor code. The element supports the following required attributes:
Specifies the vendor name. For example "Hewlett Packard".
Specifies the unique ID associated with this vendor. For example, "HP".
Specifies the alpha-numeric code allocated to the vendor by IANA. For example "11". The value must be unique for each <vendor> declaration.
Example 2.3. <vendor> XML Attributes
...
<vendor vendor-id="None" code="0" name="None" />
<vendor vendor-id="HP" code="11" name="Hewlett Packard" />
<vendor vendor-id="Merit" code="61" name="Merit Networks" />
<vendor vendor-id="Sun" code="42" name="Sun Microsystems, Inc." />
<vendor vendor-id="USR" code="429" name="US Robotics Corp." />
<vendor vendor-id="3GPP2" code="5535" name="3GPP2" />
<vendor vendor-id="TGPP" code="10415" name="3GPP" />
<vendor vendor-id="TGPPCX" code="16777216" name="3GPP CX/DX" />
<vendor vendor-id="TGPPSH" code="16777217" name="3GPP SH" />
<vendor vendor-id="Ericsson" code="193" name="Ericsson" />
<vendor vendor-id="ETSI" code="13019" name="ETSI" />
<vendor vendor-id="Vodafone" code="12645" name="Vodafone" />
Defines the simple Attribute Value Pair (AVP) types. The element supports the following required attributes:
Specifies a type name in accordance with the acceptable base types defined in RFC 3588. For example; "Enumerated", "OctetString", "Integer32".
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".
Example 2.4. <typedefn> XML Attributes
<!-- Primitive types, see http://tools.ietf.org/html/rfc3588#section-4.2 -->
<typedefn type-name="OctetString" />
<typedefn type-name="Float64" />
<typedefn type-name="Float32" />
<typedefn type-name="Integer64" />
<typedefn type-name="Integer32" />
<typedefn type-name="Unsigned64" />
<typedefn type-name="Unsigned32" />
<!-- derived avp types, see http://tools.ietf.org/html/rfc3588#section-4.3 -->
<typedefn type-name="Address" type-parent="OctetString" />
<typedefn type-name="Time" type-parent="OctetString" />
<typedefn type-name="UTF8String" type-parent="OctetString" />
<typedefn type-name="DiameterIdentity" type-parent="OctetString" />
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:
Specifies the unique ID allocated to the application. The attribute is used in all messages and forms part of the message header.
Optional attribute, which specifies the logical name of the application.
Optional attribute, which specifies a link to additional application information.
Example 2.5. <application> XML Attributes
<application id="16777216" name="3GPP Cx/Dx" uri="http://www.ietf.org/rfc/rfc3588.txt?number=3588">
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>.
Different sets of elements are supported by <avp> depending on its position in the dictionary.xml file.
Example 2.6. <avp> Child Elements and Attributes
<avp name="Server-Assignment-Type" code="614" mandatory="must" vendor-bit="must"
vendor-id="TGPP" may-encrypt="no">
<type type-name="Unsigned32" />
<enum name="NO_ASSIGMENT" code="0" />
<enum name="REGISTRATION" code="1" />
<enum name="RE_REGISTRATION" code="2" />
<enum name="UNREGISTERED_USER" code="3" />
<grouped>
<gavp name="SIP-Item-Number" multiplicity="0-1"/>
<gavp name="SIP-Authentication-Scheme" multiplicity="0-1"/>
<gavp name="SIP-Authenticate" multiplicity="0-1"/>
<gavp name="Line-Identifier" multiplicity="0+"/>
</grouped>
</avp>
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:
Specifies the type name, which is used to match to the type-name value specified in the <typedefn> element.
<type> is ignored if the <avp> element contains the <grouped> element.
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:
Specifies the name of a constant value that applies to the AVP.
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.
<enum> is ignored if the <avp> element contains the <grouped> element.
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.
Child element of <grouped>, which specifies a reference to a grouped AVP. The element supports one mandatory attribute:
Specifies the name of the grouped AVP member. The value must match the defined AVP name.
Table 2.2. <avp> Attributes
Attribute Name (optional in brackets) | Explicit Values (default in brackets) | Description |
---|---|---|
name | Specifies the name of the AVP, which is used to match the AVP definition to any grouped AVP references. For further information about grouped AVPs, refer to the element description in this section. | |
code | Specifies the integer code of the AVP. | |
(vendor-id) | (none) | Used to match the vendor ID reference to the value defined in the <vendor> element. |
(multiplicity) | Specifies the number of acceptable AVPs in a message using an explicit value. | |
0 | An AVP must not be present in the message. | |
(0+) | Zero or more instances of the AVP must be present in the message. | |
0-1 | Zero, or one instance of the AVP may be present in the message. An error occurs if the message contains more than one instance of the AVP. | |
1 | One instance of the AVP must be present in the message. | |
1+ | At least one instance of the AVP must be present in the message. | |
may-encrypt | Yes | (No) | Specifies whether the AVP can be encrypted. |
protected | may | must | mustnot | Determines actaul state of AVP that is expected, if it MUST be encrypted , may or MUST NOT. |
vendor-bit | must | mustnot | Specifies whether the Vendor ID should be set. |
mandatory | may | must | mustnot | Determines if support for this AVP is madnatory in order to consume/process message. |
vendor | Specifies the defined vendor code, which is used by the <command> child element. |
Example 2.7. <avp> XML Attributes
<!-- MUST -->
<avp name="Session-Id" code="263" vendor="0" multiplicity="1" index="0" />
<avp name="Auth-Session-State" code="277" vendor="0" multiplicity="1" index="-1" />
<!-- MAY -->
<avp name="Destination-Host" code="293" vendor="0" multiplicity="0-1" index="-1" />
<avp name="Supported-Features" code="628" vendor="10415" multiplicity="0+" index="-1" />
<!-- FORBBIDEN -->
<avp name="Auth-Application-Id" code="258" vendor="0" multiplicity="0" index="-1" />
<avp name="Error-Reporting-Host" code="294" vendor="0" multiplicity="0" index="-1" />
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:
Optional parameter, which specifies the message name for descriptive purposes.
Mandatory parameter, which specifies the integer code of the message.
Mandatory parameter, which specifies whether the declared command is a request or answer. The available values are "true" (request) or "false" (answer).
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.
Example 2.8. <command> Elements and Attributes
<command name="User-Authorization" code="300" vendor-id="TGPP" request="true">
<avp name="Server-Assignment-Type" code="614" mandatory="must" vendor-bit="must" vendor-id="TGPP" may-encrypt="no"/>
</command>
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:
Simple method to determine if Validator
is enabled.
Returns validation level for outgoing messages. It can have one of following values: OFF
, MESSAGE
, ALL
Returns validation level for incoming messages. It can have one of following values: OFF
, MESSAGE
, ALL
Performs validation on message. Based on incoming
flag, the correct validation level is applied. If validation fails, an exception with details is thrown.
Performs validation on message with the specified level. It is a programatical way to allow different level of validation different than configured. If validation fails, a JAvpNotAllowedException
with details is thrown.
Current implementation provides more methods, however those are out of scope for this documentation.
Simple example of validator use case look as follows:
Example 2.9. Validator Message Check Example
The example below is pseudo-code.
...
boolean isRequest = true;
boolean isIncoming = false;
DiameterMessageValidator messageValidator = DiameterMessageValidator.getInstance();
Message message = createMessage(UserDataRequest.MESSAGE_CODE, isRequest,
applicationId);
//add AVPs
...
//perform check
try{
messageValidator.validate(message, isIncoming);
}
catch(JAvpNotAllowedException e) {
System.err.println("Failed to validate ..., avp code: " + e.getAvpCode() + " avp vendor:" + e.getVendorId() + ", message:" + e.getMessage());
}