From 3c15ff32e89e401b4dde2b8acc9699be2614b996 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Wed, 18 May 2011 18:29:12 +0200 Subject: Initial commit of the diameter application. The application provides an implementation of the Diameter protocol as defined in RFC 3588. --- lib/diameter/doc/src/diameter_app.xml | 582 ++++++++++++++++++++++++++++++++++ 1 file changed, 582 insertions(+) create mode 100644 lib/diameter/doc/src/diameter_app.xml (limited to 'lib/diameter/doc/src/diameter_app.xml') diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml new file mode 100644 index 0000000000..c2fecce768 --- /dev/null +++ b/lib/diameter/doc/src/diameter_app.xml @@ -0,0 +1,582 @@ + + + + +
+ + +2011 +Ericsson AB. All Rights Reserved. + + +The contents of this file are subject to the Erlang Public License, +Version 1.1, (the "License"); you may not use this file except in +compliance with the License. You should have received a copy of the +Erlang Public License along with this software. If not, it can be +retrieved online at http://www.erlang.org/. + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +the License for the specific language governing rights and limitations +under the License. + + + +diameter_app(3) +Anders Svensson + + + + + +%REV% +diameter_app.xml + +
+ +diameter_app + +Callback module of a Diameter application. + + + +

+A diameter service as started by diameter:start_service/2 +configures one of more Diameter applications, each of whose +configuration specifies a callback that handles messages specific to +its application. +The messages and AVPs of the Diameter application are defined in a +specification file whose format is documented in +diameter_dict(4) +while the callback module is documented here. +The callback module implements the Diameter application-specific +functionality of a service.

+ + +

+The arities of the callback functions below assume no extra arguments. +All functions will also be passed any extra arguments configured with +the callback module itself when calling diameter:start_service/2 +and, except for peer_up, peer_down and handle_request, any extra +arguments passed to diameter:call/4.

+
+ +

+A callback module must export all of the functions documented below. +The functions themselves are of three distinct flavours:

+ + + +

+peer_up/3 and +peer_down/3 signal the attainment +or loss of communicativity with a Diameter peer.

+
+ + +

+pick_peer/4, +prepare_request/3, +prepare_retransmit/3, +handle_answer/4 +and handle_error/4 are (or may +be) called as a consequence of a call to diameter:call/4 to send an outgoing +Diameter request message.

+
+ + +

+handle_request/3 +is called in response to an incoming Diameter request message.

+
+ +
+ +
+ + + + +
+DATA TYPES + + + +capabilities() = #diameter_caps{} + +

+A record containing the identities of +the local and remote Diameter peers having an established transport +connection, as well as the capabilities as +determined by capabilities exchange. +Each field of the record is a 2-tuple consisting of +values for the (local) host and (remote) peer. +Optional or possibly multiple values are encoded as lists of values, +mandatory values as the bare value.

+
+ +message() = record() | list() + +

+The representation of a Diameter message as passed to +diameter:call/4. +The record representation is as outlined in +diameter_dict(4): +a message as defined in a dictionary file is encoded as a record with +one field for each component AVP. +Equivalently, a message can also be encoded as a list whose head is +the atom-valued message name (the record name minus any +prefix in the dictionary file) and whose tail is a list of +{FieldName, FieldValue} pairs.

+ +

+A third representation allows a message to be specified as a list +whose head is a diameter_header record and whose tail is a list +of diameter_avp records. +This representation is used by diameter itself when relaying requests +as directed by the return value of a +handle_request/3 +callback. +It differs from the other other two in that it bypasses the checks for +messages that do not agree with their definitions in the dictionary in +question: messages are sent exactly as specified.

+ +
+ +packet() = #diameter_packet{} + +

+A container for incoming and outgoing Diameters message that's passed +through encode/decode and transport. +Defined in diameter.hrl. +Fields should not be altered except as documented.

+
+ +peer_ref() = term() + +

+A term identifying a transport connection with a Diameter peer. +Should be treated opaquely.

+
+ +peer() = {peer_ref(), capabilities()} + +

+A tuple representing a Diameter peer connection.

+
+ +service_name() = term() + +

+The service supporting the Diameter application. +Specified to diameter:start_service/2 +when starting the service.

+
+ +state() = term() + +

+The state maintained by the application callback functions +peer_up/3, +peer_down/3 and (optionally) +pick_peer/4. +The initial state is configured in the call to +diameter:start_service/2 +that configures the application on a service. +Callback functions returning a state are evaluated in a common +service-specific process while +those not returning state are evaluated in a request-specific +process.

+
+ +
+ + +
+ + + + + + + +Mod:peer_up(SvcName, Peer, State) -> NewState +Invoked when a transport connection has been established + +SvcName = service_name() +Peer = peer() +State = NewState = state() + + +

+Invoked when a transport connection has been established +and a successful capabilities exchange has indicated that the peer +supports the Diameter application of the application on which +the callback module in question has been configured.

+ + +
+
+ + +Mod:peer_down(SvcName, Peer, State) -> NewState +Invoked when a transport connection has been lost. + +SvcName = service_name() +Peer = peer() +State = NewState = state() + + +

+Invoked when a transport connection has been lost following a previous +call to peer_up/3.

+ + +
+
+ + +Mod:pick_peer(Cands, Reserved, SvcName, State) + -> {ok, Peer} | {Peer, NewState} | false +Select a target peer for an outgoing request. + +Cands = [Peer] +Peer = peer() | false +SvcName = service_name() +State = NewState = state() + + +

+Invoked as a consequence of a call to diameter:call/4 to select a destination +peer for an outgoing request, the return value indicating the selected peer. +A new application state can also be returned but only if the Diameter +application in question was +configured with the option call_mutates_state set to +true, as documented for diameter:start_service/2.

+ +

+The candidate peers list will only include those +which are selected by any filter option specified in the call to +diameter:call/4.

+ + +

+The return values false and {false, State} are +equivalent when callback state is mutable, as are +{ok, Peer} and {Peer, State}. +Returning a peer as false causes {error, no_connection} +to be returned from diameter:call/4. +Returning a peer() from an initial pick_peer/4 callback will result in a +prepare_request/3 callback +followed by either handle_answer/4 +or handle_error/4 depending +on whether or not an answer message is received from the peer. +If transport with the peer is lost before this then a new pick_peer/4 callback takes place to +select an alternate peer.

+ +

+Note that there is no guarantee that a pick_peer/4 callback to select +an alternate peer will be followed by any additional callbacks, only +that the initial pick_peer/4 will be, since a +retransmission to an alternate peer is abandoned if an answer is +received from a previously selected peer.

+ + +
+ +
+ + +Mod:prepare_request(Packet, SvcName, Peer) -> Action +Return a request for encoding and transport. + +Packet = packet() +SvcName = service_name() +Peer = peer() +Action = {send, packet() | message()} | {discard, Reason} | discard + + +

+Invoked to return a request for encoding and transport. +Allows the sender to access the selected peer's capabilities +in order to set (for example) Destination-Host and/or +Destination-Realm in the outgoing request, although the +callback need not be limited to this usage. +Many implementations may simply want to return {send, Packet}

+ +

+A returned packet() should set the request to be encoded in its +msg field and can set the transport_data field in order +to pass information to the transport module. +Extra arguments passed to diameter:call/4 can be used to +communicate transport data to the callback.

+ +

+Any returned packet() can set the header field to a +diameter_header record in order to specify values that should +be preserved in the outgoing request. +A specified message_length is ignored.

+ +

+Returning {discard, Reason} causes the request to be aborted +and the diameter:call/4 for which the +callback has taken place to return {error, Reason}. +Returning discard is equivalent to returning {discard, +discarded}.

+ + +
+
+ + +Mod:prepare_retransmit(Packet, SvcName, Peer) -> Result +Return a request for encoding and retransmission. + +Packet = packet() +SvcName = service_name() +Peer = peer() +Result = {send, packet() | message()} | {discard, Reason} | discard + + +

+Invoked to return a request for encoding and retransmission. +Has the same role as prepare_request/3 in the case that +a peer connection is lost an an alternate peer selected but the +Packet passed to prepare_retransmit/3 is as returned by +prepare_request/3.

+ +

+Returning {discard, Reason} causes the request to be aborted +and a handle_error/4 callback to +take place with Reason as initial argument. +Returning discard is equivalent to returning {discard, +discarded}.

+ + +
+
+ + +Mod:handle_answer(Packet, Request, SvcName, Peer) -> Result +Receive an answer message from a peer. + +Packet = packet() +Request = message() +SvcName = service_name() +Peer = peer() +Result = term() + + +

+Invoked when an answer message is received from a peer. +The return value is returned from the call to diameter:call/4 for which the +callback takes place.

+ +

+The decoded answer record is in the msg field of Packet, +the undecoded binary in the packet field. +Request is the outgoing request message as was returned from +prepare_request/3 or +prepare_retransmit/3 +before the request was passed to the transport.

+ +

+For any given call to diameter:call/4 there is at most one +call to the handle_answer callback of the application in question: any +duplicate answer (due to retransmission or otherwise) is discarded. +Similarly, only one of handle_answer/4 or handle_error/4 is +called for any given request.

+ +

+By default, an incoming answer message that cannot be successfully +decoded causes the request process in question to fail, causing the +relevant call to diameter:call/4 +to return {error, failure}. +There is no handle_error/4 callback in this case. +Application configuration may change this behaviour as described for +diameter:start_service/2.

+ + +
+
+ + +Mod:handle_error(Reason, Request, SvcName, Peer) -> Result +Return an error from a outgoing request. + +Reason = timeout | failover | term() +Request = message() +SvcName = service_name() +Peer = peer() +Result = term() + + +

+Invoked when an error occurs before an answer message is received from +a peer in response to an outgoing request. +The return value is returned from the call to diameter:call/4 for which the +callback takes place.

+ +

+Reason timeout indicates that an answer message has not been +received within the required time. +Reason failover indicates +that the transport connection to the peer to which the request has +been sent has been lost but that not alternate node was available, +possibly because a pick_peer/4 +callback returned false. +

+ + +
+
+ + +Mod:handle_request(Packet, SvcName, Peer) -> Action +Receive an incoming request. + +Packet = packet() +SvcName = term() +Peer = peer() +Action = Reply | NoReply | Relay | {eval, Action, ContF} +Reply = {reply, message()} + | {protocol_error, ResultCode} +NoReply = discard +Relay = {relay, Opts} +Opts = list() +ContF = diameter:evaluable() +ResultCode = 3000..3999 + + +

+Invoked when a request message is received from a peer.

+ +

+The application in which the callback takes place (that is, the +callback module as configured with diameter:start_service/2) +is determined by the Application Identifier in the header of the +incoming Diameter request message, the selected module being the one +whose corresponding dictionary declares +itself as defining the application in question, or the RFC 3588 relay +application if the specific application is unsupported but the relay +application has been advertised.

+ +

+The packet() in which the incoming request is communicated has the +following signature.

+ + +#diameter_packet{header = #diameter_header{}, + avps = [#diameter_avp{}], + msg = record() | undefined, + errors = [integer() | {integer(), #diameter_avp{}}], + bin = binary(), + transport_data = term()} + + +

+The msg field will be undefined only in case the request has +been received in the relay application. +Otherwise it contains the record representing the request as outlined +in diameter_dict(4).

+ +

+The errors field specifies any non-protocol errors that were +encountered in decoding the request and can be returned in a +reply tuple to have diameter set the Result-Code and Failed-AVP +AVP's appropriately. +The list is empty if the request has been received in the relay +application.

+ +

+The transport_data field contains an arbitrary term passed into +diameter from the transport module in question, or the atom +undefined if the transport specified no data. +The term is preserved in the packet() containing any answer message +sent back to the transport process unless another value is explicitly +specified.

+ +

+The semantics of each of the possible return values are as follows. +(TODO: more.)

+ + + +{reply, Answer} + +

+Send the specified answer message to the peer.

+
+ +{relay, Opts} + +

+Relay a request to another peer.

+
+ +{protocol_error, ResultCode} + +

+Send an answer message to the peer containing the specified 3xxx +protocol error.

+ +

+RFC 3588 mandates that only answers with a 3xxx series +Result-Code (protocol errors) may set the E bit. +Returning a non-3xxx value in a {protocol_error, ResultCode} +tuple will cause the request process in question to fail.

+
+ +discard + +

+Discard the request.

+
+ +{eval, Action, ContF} + +

+Handle the request as if Action has been returned and then +evaluate the evaluable() ContF in the request process.

+
+ +
+ +

+Note that diameter will respond to protocol errors in an incoming +request without invoking the a handle_request/3 callback.

+ +
+
+ +
+ +
-- cgit v1.2.3