Go to main content

man pages section 3: Extended Library Functions, Volume 1

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

diameter_app (3erl)

Name

diameter_app - Callback module of a Diameter application.

Synopsis

Please see following description for synopsis

Description

diameter_app(3)            Erlang Module Definition            diameter_app(3)



NAME
       diameter_app - Callback module of a Diameter application.

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

       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  connec-
           tivity with a Diameter peer.

         * pick_peer/4,    prepare_request/3,    prepare_retransmit/3,    han-
           dle_answer/4 and handle_error/4 are (or may be) called as a  conse-
           quence  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.

       The  arities  for the the callback functions here assume no extra argu-
       ments. All functions will also be passed any extra arguments configured
       with  the  callback module itself when calling diameter:start_service/2
       and, for the call-specific callbacks, any  extra  arguments  passed  to
       diameter:call/4.

DATA TYPES
         capabilities() = #diameter_caps{}:
           A  record  containing the identities of the local Diameter node and
           the remote Diameter peer having an  established  transport  connec-
           tion,  as  well  as  the capabilities as determined by capabilities
           exchange. Each field of the record is a 2-tuple consisting of  val-
           ues  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() = diameter_codec:message():
           The  representation  of  a  Diameter  message  as  passed to diame-
           ter:call/4 or returned from a handle_request/3 callback.

         packet() = diameter_codec:packet():
           A container for incoming  and  outgoing  Diameter  messages  that's
           passed  through  encode/decode  and transport. Fields should not be
           set in return values except as documented.

         peer_ref() = term():
           A term identifying a transport connection with a Diameter peer.

         peer() = {peer_ref(), capabilities()}:
           A tuple representing a Diameter peer connection.

         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 return-
           ing a state are evaluated  in  a  common  service-specific  process
           while those not returning state are evaluated in a request-specific
           process.

EXPORTS
       Mod:peer_up(SvcName, Peer, State) -> NewState

              Types:

                 SvcName = diameter:service_name()
                 Peer = peer()
                 State = NewState = state()

              Invoked to signal the availability of a peer connection  on  the
              local Erlang node. In particular, capabilities exchange with the
              peer has indicated support for the application in question,  the
              RFC  3539  watchdog state machine for the connection has reached
              state OKAY and Diameter messages can be both sent and received.

          Note:
              A watchdog state machine can reach state OKAY from state SUSPECT
              without  a  new capabilities exchange taking place. A new trans-
              port connection (and capabilities exchange)  results  in  a  new
              peer_ref().


          Note:
              There  is  no requirement that a callback return before incoming
              requests are received: handle_request/3 callbacks must  be  han-
              dled independently of peer_up/3 and peer_down/3.


       Mod:peer_down(SvcName, Peer, State) -> NewState

              Types:

                 SvcName = diameter:service_name()
                 Peer = peer()
                 State = NewState = state()

              Invoked  to  signal  that  a peer connection on the local Erlang
              node is  no  longer  available  following  a  previous  call  to
              peer_up/3.  In  particular,  that  the  RFC  3539 watchdog state
              machine for the connection has left state OKAY and the peer will
              no longer be a candidate in pick_peer/4 callbacks.

       Mod:pick_peer(LocalCandidates,  RemoteCandidates,  SvcName,  State)  ->
       Selection | false

              Types:

                 LocalCandidates = RemoteCandidates = [peer()]
                 SvcName = diameter:service_name()
                 State = NewState = state()
                 Selection = {ok, Peer} | {Peer, NewState}
                 Peer = peer() | false

              Invoked as a consequence of a call to diameter:call/4 to  select
              a  destination  peer  for  an outgoing request. The return value
              indicates the selected peer.

              The candidate lists contain only those peers  that  have  adver-
              tised  support  for  the Diameter application in question during
              capabilities exchange, that have not be  excluded  by  a  filter
              option  in  the call to diameter:call/4 and whose watchdog state
              machine is in the OKAY state.  The  order  of  the  elements  is
              unspecified  except that any peers whose Origin-Host and Origin-
              Realm matches that of the outgoing request (in the  sense  of  a
              {filter,  {all,  [host, realm]}} option to diameter:call/4) will
              be placed at the head  of  the  list.  LocalCandidates  contains
              peers  whose  transport process resides on the local Erlang node
              while RemoteCandidates contains peers that  have  been  communi-
              cated from other nodes by services of the same name.

              A  callback  that  returns  a  peer() will be followed by a pre-
              pare_request/3 callback and, if the latter  indicates  that  the
              request  should  be  sent,  by  either  handle_answer/4  or han-
              dle_error/4 depending on whether or not  an  answer  message  is
              received  from  the  peer.  If the transport becomes unavailable
              after prepare_request/3 then a new pick_peer/4 callback may take
              place  to  failover  to  an  alternate  peer,  after  which pre-
              pare_retransmit/3  takes  the  place  of  prepare_request/3   in
              resending  the request. There is no guarantee that a pick_peer/4
              callback to select an alternate peer will  be  followed  by  any
              additional callbacks since a retransmission to an alternate peer
              is abandoned if an answer is received from a previously selected
              peer.

              The  return values false and {false, State} (that is, NewState =
              State) are equivalent, as are {ok, Peer} and {Peer, State}.

          Note:
              The diameter:service_opt() use_shared_peers  determines  whether
              or not a service uses peers shared from other nodes. If not then
              RemoteCandidates is the empty list.


          Warning:
              The return value {Peer, NewState} is only allowed if the  Diame-
              ter  application  in  question  was  configured  with the diame-
              ter:application_opt() {call_mutates_state, true}. Otherwise, the
              State  argument is always the initial value as configured on the
              application, not any subsequent value returned by a peer_up/3 or
              peer_down/3 callback.


       Mod:prepare_request(Packet, SvcName, Peer) -> Action

              Types:

                 Packet = packet()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Action = Send | Discard | {eval_packet, Action, PostF}
                 Send = {send, packet() | message()}
                 Discard = {discard, Reason} | discard
                 PostF = diameter:eval()}

              Invoked  to  return a request for encoding and transport. Allows
              the sender to use the selected peer's capabilities to modify the
              outgoing request. 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 process. Extra arguments passed  to
              diameter:call/4  can  be  used  to communicate transport (or any
              other) data to the callback.

              A returned packet() can  set  the  header  field  to  a  #diame-
              ter_header{}  to  specify values that should be preserved in the
              outgoing request, values otherwise being  those  in  the  header
              record  contained  in  Packet.  A  returned  length, cmd_code or
              application_id is ignored.

              A returned PostF  will  be  evaluated  on  any  encoded  #diame-
              ter_packet{} prior to transmission, the bin field containing the
              encoded binary. The return value 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) -> Action

              Types:

                 Packet = packet()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Action = Send | Discard | {eval_packet, Action, PostF}
                 Send = {send, packet() | message()}
                 Discard = {discard, Reason} | discard
                 PostF = diameter:eval()}

              Invoked to return a request for encoding and retransmission. Has
              the same role as prepare_request/3 in the case that a peer  con-
              nection  is  lost an an alternate peer selected but the argument
              packet() is as returned by the initial 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

              Types:

                 Packet = packet()
                 Request = message()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Result = term()

              Invoked  when  an  answer  message  is received from a peer. The
              return value is returned from diameter:call/4 unless the  detach
              option was specified.

              The  decoded  answer  record and undecoded binary are in the msg
              and bin fields of the argument packet() respectively. Request is
              the   outgoing   request  message  as  was  returned  from  pre-
              pare_request/3 or prepare_retransmit/3.

              For any given call to diameter:call/4 there is at most one  han-
              dle_answer/4  callback: any duplicate answer (due to retransmis-
              sion or otherwise) is discarded. Similarly,  only  one  of  han-
              dle_answer/4 or handle_error/4 is called.

              By  default,  an incoming answer message that cannot be success-
              fully decoded causes the request process to fail, causing diame-
              ter:call/4  to  return {error, failure} unless the detach option
              was specified. In particular, there is no  handle_error/4  call-
              back  in this case. The diameter:application_opt() answer_errors
              can be set to change this behaviour.

       Mod:handle_error(Reason, Request, SvcName, Peer) -> Result

              Types:

                 Reason = timeout | failover | term()
                 Request = message()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Result = term()

              Invoked when  an  error  occurs  before  an  answer  message  is
              received in response to an outgoing request. The return value is
              returned from diameter:call/4 unless the detach option was spec-
              ified.

              Reason  timeout  indicates  that  an answer message has not been
              received within the time specified with the corresponding diame-
              ter:call_opt().  Reason  failover  indicates  that the transport
              connection to the peer to which the request has  been  sent  has
              become unavailable and that not alternate peer was not selected.

       Mod:handle_request(Packet, SvcName, Peer) -> Action

              Types:

                 Packet = packet()
                 SvcName = term()
                 Peer = peer()
                 Action    =    Reply   |   {relay,   [Opt]}   |   discard   |
                 {eval|eval_packet, Action, PostF}
                 Reply = {reply,  packet()  |  message()}  |  {answer_message,
                 3000..3999|5000..5999} | {protocol_error, 3000..3999}
                 Opt = diameter:call_opt()
                 PostF = diameter:eval()

              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  request  message,  the  selected  module being the one
              whose  corresponding  dictionary  declares  itself  as  defining
              either the application in question or the Relay application.

              The argument packet() has the following signature.

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


              The  msg  field  will  be undefined 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 results codes identifying errors
              found while decoding the request. This is used  to  set  Result-
              Code  and/or Failed-AVP in a returned answer unless the callback
              returns a #diameter_packet{} whose errors field is set to either
              a  non-empty  list  of  its own, in which case this list is used
              instead, or the atom false to disable any setting of Result-Code
              and Failed-AVP. Note that the errors detected by diameter are of
              the 3xxx and 5xxx series, Protocol Errors and Permanent Failures
              respectively.  The  errors 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  pre-
              served  if a message() is returned but must be set explicitly in
              a returned packet().

              The semantics of each of the possible return values are as  fol-
              lows.

                {reply, packet() | message()}:
                  Send  the  specified answer message to the peer. In the case
                  of a packet(), the message to be sent must be set in the msg
                  field  and  the  header  field  can  be  set  to  a  #diame-
                  ter_header{} to specify values that should be  preserved  in
                  the  outgoing answer, appropriate values otherwise being set
                  by diameter.

                {answer_message, 3000..3999|5000..5999}:
                  Send an answer message to the peer containing the  specified
                  Result-Code. Equivalent to

                {reply, ['answer-message' | Avps]


                  where Avps sets the Origin-Host, Origin-Realm, the specified
                  Result-Code and (if the request  contained  one)  Session-Id
                  AVPs, and possibly Failed-AVP as described below.

                  Returning  a  value  other  than 3xxx or 5xxx will cause the
                  request process in question to fail,  as  will  returning  a
                  5xxx  value if the peer connection in question has been con-
                  figured  with  the  RFC  3588   common   dictionary   diame-
                  ter_gen_base_rfc3588.  (Since RFC 3588 only allows 3xxx val-
                  ues in an answer-message.)

                  When returning 5xxx, Failed-AVP will be populated  with  the
                  AVP of the first matching Result-Code/AVP pair in the errors
                  field of the argument packet(), if found.  If  this  is  not
                  appropriate  then  an  answer-message  should be constructed
                  explicitly and returned in a reply tuple instead.

                {relay, Opts}:
                  Relay a request to another peer in the role  of  a  Diameter
                  relay  agent. If a routing loop is detected then the request
                  is answered with 3005 (DIAMETER_LOOP_DETECTED). Otherwise  a
                  Route-Record AVP (containing the sending peer's Origin-Host)
                  is added to the request and pick_peer/4 and subsequent call-
                  backs  take place just as if diameter:call/4 had been called
                  explicitly.  The  End-to-End  Identifier  of  the   incoming
                  request is preserved in the header of the relayed request.

                  The  returned  Opts  should not specify detach. A subsequent
                  handle_answer/4 callback for the relayed request must return
                  its  first argument, the packet() containing the answer mes-
                  sage. Note that the extra option can be specified to  supply
                  arguments that can distinguish the relay case from others if
                  so desired. Any other return value (for example, from a han-
                  dle_error/4 callback) causes the request to be answered with
                  3002 (DIAMETER_UNABLE_TO_DELIVER).

                discard:
                  Discard the request. No answer message is sent to the peer.

                {eval, Action, PostF}:
                  Handle the request as if Action has been returned  and  then
                  evaluate  PostF  in the request process. The return value is
                  ignored.

                {eval_packet, Action, PostF}:
                  Like  eval  but  evaluate  PostF  on  any  encoded   #diame-
                  ter_packet{} prior to transmission, the bin field containing
                  the encoded binary. The return value is ignored.

                {protocol_error, 3000..3999}:
                  Equivalent to {answer_message, 3000..3999}.

          Note:
              Requests containing errors may be answered by diameter,  without
              a  callback  taking  place, depending on the value of the diame-
              ter:application_opt() request_errors.




Ericsson AB                     diameter 2.2.4                 diameter_app(3)