1diameter_app(3)            Erlang Module Definition            diameter_app(3)
2
3
4

NAME

6       diameter_app - Callback module of a Diameter application.
7

DESCRIPTION

9       A  diameter  service  as started by diameter:start_service/2 configures
10       one of more Diameter applications, each of whose  configuration  speci‐
11       fies  a callback that handles messages specific to the application. The
12       messages and AVPs of the application are defined in a  dictionary  file
13       whose  format is documented in diameter_dict(4) while the callback mod‐
14       ule is documented here. The callback  module  implements  the  Diameter
15       application-specific functionality of a service.
16
17       A  callback  module  must export all of the functions documented below.
18       The functions themselves are of three distinct flavours:
19
20         * peer_up/3 and peer_down/3 signal the attainment or loss of  connec‐
21           tivity with a Diameter peer.
22
23         * pick_peer/4,    prepare_request/3,    prepare_retransmit/3,    han‐
24           dle_answer/4 and handle_error/4 are (or may be) called as a  conse‐
25           quence  of  a  call to diameter:call/4 to send an outgoing Diameter
26           request message.
27
28         * handle_request/3 is called in  response  to  an  incoming  Diameter
29           request message.
30
31       The  arities  for the the callback functions here assume no extra argu‐
32       ments. All functions will also be passed any extra arguments configured
33       with  the  callback module itself when calling diameter:start_service/2
34       and, for the call-specific callbacks, any  extra  arguments  passed  to
35       diameter:call/4.
36

DATA TYPES

38         capabilities() = #diameter_caps{}:
39           A  record  containing the identities of the local Diameter node and
40           the remote Diameter peer having an  established  transport  connec‐
41           tion,  as  well  as  the capabilities as determined by capabilities
42           exchange. Each field of the record is a 2-tuple consisting of  val‐
43           ues  for  the  (local) host and (remote) peer. Optional or possibly
44           multiple values are encoded as lists of values, mandatory values as
45           the bare value.
46
47         message() = diameter_codec:message():
48           The  representation  of  a  Diameter  message  as  passed to diame‐
49           ter:call/4 or returned from a handle_request/3 callback.
50
51         packet() = diameter_codec:packet():
52           A container for incoming  and  outgoing  Diameter  messages  that's
53           passed  through  encode/decode  and transport. Fields should not be
54           set in return values except as documented.
55
56         peer_ref() = term():
57           A term identifying a transport connection with a Diameter peer.
58
59         peer() = {peer_ref(), capabilities()}:
60           A tuple representing a Diameter peer connection.
61
62         state() = term():
63           The  state  maintained  by  the  application   callback   functions
64           peer_up/3,  peer_down/3  and  (optionally) pick_peer/4. The initial
65           state is configured in the call  to  diameter:start_service/2  that
66           configures the application on a service. Callback functions return‐
67           ing a state are evaluated  in  a  common  service-specific  process
68           while those not returning state are evaluated in a request-specific
69           process.
70

EXPORTS

72       Mod:peer_up(SvcName, Peer, State) -> NewState
73
74              Types:
75
76                 SvcName = diameter:service_name()
77                 Peer = peer()
78                 State = NewState = state()
79
80              Invoked to signal the availability of a peer connection  on  the
81              local Erlang node. In particular, capabilities exchange with the
82              peer has indicated support for the application in question,  the
83              RFC  3539  watchdog state machine for the connection has reached
84              state OKAY and Diameter messages can be both sent and received.
85
86          Note:
87              A watchdog state machine can reach state OKAY from state SUSPECT
88              without  a  new capabilities exchange taking place. A new trans‐
89              port connection (and capabilities exchange)  results  in  a  new
90              peer_ref().
91
92
93          Note:
94              There  is  no requirement that a callback return before incoming
95              requests are received: handle_request/3 callbacks must  be  han‐
96              dled independently of peer_up/3 and peer_down/3.
97
98
99       Mod:peer_down(SvcName, Peer, State) -> NewState
100
101              Types:
102
103                 SvcName = diameter:service_name()
104                 Peer = peer()
105                 State = NewState = state()
106
107              Invoked  to  signal  that  a peer connection on the local Erlang
108              node is  no  longer  available  following  a  previous  call  to
109              peer_up/3.  In  particular,  that  the  RFC  3539 watchdog state
110              machine for the connection has left state OKAY and the peer will
111              no longer be a candidate in pick_peer/4 callbacks.
112
113       Mod:pick_peer(LocalCandidates,  RemoteCandidates,  SvcName,  State)  ->
114       Selection | false
115
116              Types:
117
118                 LocalCandidates = RemoteCandidates = [peer()]
119                 SvcName = diameter:service_name()
120                 State = NewState = state()
121                 Selection = {ok, Peer} | {Peer, NewState}
122                 Peer = peer() | false
123
124              Invoked as a consequence of a call to diameter:call/4 to  select
125              a  destination  peer  for  an outgoing request. The return value
126              indicates the selected peer.
127
128              The candidate lists contain only those peers  that  have  adver‐
129              tised  support  for  the Diameter application in question during
130              capabilities exchange, that have not be  excluded  by  a  filter
131              option  in  the call to diameter:call/4 and whose watchdog state
132              machine is in the OKAY state.  The  order  of  the  elements  is
133              unspecified  except that any peers whose Origin-Host and Origin-
134              Realm matches that of the outgoing request (in the  sense  of  a
135              {filter,  {all,  [host, realm]}} option to diameter:call/4) will
136              be placed at the head  of  the  list.  LocalCandidates  contains
137              peers  whose  transport process resides on the local Erlang node
138              while RemoteCandidates contains peers that  have  been  communi‐
139              cated from other nodes by services of the same name.
140
141              A  callback  that  returns  a  peer() will be followed by a pre‐
142              pare_request/3 callback and, if the latter  indicates  that  the
143              request  should  be  sent,  by  either  handle_answer/4  or han‐
144              dle_error/4 depending on whether or not  an  answer  message  is
145              received  from  the  peer.  If the transport becomes unavailable
146              after prepare_request/3 then a new pick_peer/4 callback may take
147              place  to  failover  to  an  alternate  peer,  after  which pre‐
148              pare_retransmit/3  takes  the  place  of  prepare_request/3   in
149              resending  the request. There is no guarantee that a pick_peer/4
150              callback to select an alternate peer will  be  followed  by  any
151              additional callbacks since a retransmission to an alternate peer
152              is abandoned if an answer is received from a previously selected
153              peer.
154
155              The  return values false and {false, State} (that is, NewState =
156              State) are equivalent, as are {ok, Peer} and {Peer, State}.
157
158          Note:
159              The diameter:service_opt() use_shared_peers  determines  whether
160              or not a service uses peers shared from other nodes. If not then
161              RemoteCandidates is the empty list.
162
163
164          Warning:
165              The return value {Peer, NewState} is only allowed if the  Diame‐
166              ter  application  in  question  was  configured  with the diame‐
167              ter:application_opt() {call_mutates_state, true}. Otherwise, the
168              State  argument is always the initial value as configured on the
169              application, not any subsequent value returned by a peer_up/3 or
170              peer_down/3 callback.
171
172
173       Mod:prepare_request(Packet, SvcName, Peer) -> Action
174
175              Types:
176
177                 Packet = packet()
178                 SvcName = diameter:service_name()
179                 Peer = peer()
180                 Action = Send | Discard | {eval_packet, Action, PostF}
181                 Send = {send, packet() | message()}
182                 Discard = {discard, Reason} | discard
183                 PostF = diameter:eval()}
184
185              Invoked  to  return a request for encoding and transport. Allows
186              the sender to use the selected peer's capabilities to modify the
187              outgoing request. Many implementations may simply want to return
188              {send, Packet}
189
190              A returned packet() should set the request to be encoded in  its
191              msg  field and can set the transport_data field in order to pass
192              information to the transport process. Extra arguments passed  to
193              diameter:call/4  can  be  used  to communicate transport (or any
194              other) data to the callback.
195
196              A returned packet() can  set  the  header  field  to  a  #diame‐
197              ter_header{}  to  specify values that should be preserved in the
198              outgoing request, values otherwise being  those  in  the  header
199              record  contained  in  Packet.  A  returned  length, cmd_code or
200              application_id is ignored.
201
202              A returned PostF  will  be  evaluated  on  any  encoded  #diame‐
203              ter_packet{} prior to transmission, the bin field containing the
204              encoded binary. The return value is ignored.
205
206              Returning {discard, Reason} causes the request to be aborted and
207              the  diameter:call/4  for  which the callback has taken place to
208              return {error,  Reason}.  Returning  discard  is  equivalent  to
209              returning {discard, discarded}.
210
211       Mod:prepare_retransmit(Packet, SvcName, Peer) -> Action
212
213              Types:
214
215                 Packet = packet()
216                 SvcName = diameter:service_name()
217                 Peer = peer()
218                 Action = Send | Discard | {eval_packet, Action, PostF}
219                 Send = {send, packet() | message()}
220                 Discard = {discard, Reason} | discard
221                 PostF = diameter:eval()}
222
223              Invoked to return a request for encoding and retransmission. Has
224              the same role as prepare_request/3 in the case that a peer  con‐
225              nection  is  lost an an alternate peer selected but the argument
226              packet() is as returned by the initial prepare_request/3.
227
228              Returning {discard, Reason} causes the request to be aborted and
229              a  handle_error/4  callback to take place with Reason as initial
230              argument. Returning discard is equivalent to returning {discard,
231              discarded}.
232
233       Mod:handle_answer(Packet, Request, SvcName, Peer) -> Result
234
235              Types:
236
237                 Packet = packet()
238                 Request = message()
239                 SvcName = diameter:service_name()
240                 Peer = peer()
241                 Result = term()
242
243              Invoked  when  an  answer  message  is received from a peer. The
244              return value is returned from diameter:call/4 unless the  detach
245              option was specified.
246
247              The  decoded  answer  record and undecoded binary are in the msg
248              and bin fields of the argument packet() respectively. Request is
249              the   outgoing   request  message  as  was  returned  from  pre‐
250              pare_request/3 or prepare_retransmit/3.
251
252              For any given call to diameter:call/4 there is at most one  han‐
253              dle_answer/4  callback: any duplicate answer (due to retransmis‐
254              sion or otherwise) is discarded. Similarly,  only  one  of  han‐
255              dle_answer/4 or handle_error/4 is called.
256
257              By  default,  an incoming answer message that cannot be success‐
258              fully decoded causes the request process to fail, causing diame‐
259              ter:call/4  to  return {error, failure} unless the detach option
260              was specified. In particular, there is no  handle_error/4  call‐
261              back  in this case. The diameter:application_opt() answer_errors
262              can be set to change this behaviour.
263
264       Mod:handle_error(Reason, Request, SvcName, Peer) -> Result
265
266              Types:
267
268                 Reason = timeout | failover | term()
269                 Request = message()
270                 SvcName = diameter:service_name()
271                 Peer = peer()
272                 Result = term()
273
274              Invoked when  an  error  occurs  before  an  answer  message  is
275              received in response to an outgoing request. The return value is
276              returned from diameter:call/4 unless the detach option was spec‐
277              ified.
278
279              Reason  timeout  indicates  that  an answer message has not been
280              received within the time specified with the corresponding diame‐
281              ter:call_opt().  Reason  failover  indicates  that the transport
282              connection to the peer to which the request has  been  sent  has
283              become unavailable and that not alternate peer was not selected.
284
285       Mod:handle_request(Packet, SvcName, Peer) -> Action
286
287              Types:
288
289                 Packet = packet()
290                 SvcName = term()
291                 Peer = peer()
292                 Action    =    Reply   |   {relay,   [Opt]}   |   discard   |
293                 {eval|eval_packet, Action, PostF}
294                 Reply = {reply,  packet()  |  message()}  |  {answer_message,
295                 3000..3999|5000..5999} | {protocol_error, 3000..3999}
296                 Opt = diameter:call_opt()
297                 PostF = diameter:eval()
298
299              Invoked  when  a  request  message  is received from a peer. The
300              application in which the callback  takes  place  (that  is,  the
301              callback  module as configured with diameter:start_service/2) is
302              determined by the Application Identifier in the  header  of  the
303              incoming  request  message,  the  selected  module being the one
304              whose  corresponding  dictionary  declares  itself  as  defining
305              either the application in question or the Relay application.
306
307              The argument packet() has the following signature.
308
309              #diameter_packet{header = #diameter_header{},
310                               avps   = [#diameter_avp{}],
311                               msg    = record() | undefined,
312                               errors = [Unsigned32() | {Unsigned32(), #diameter_avp{}}],
313                               bin    = binary(),
314                               transport_data = term()}
315
316
317              The  msg  field  will  be undefined in case the request has been
318              received in the relay application.  Otherwise  it  contains  the
319              record representing the request as outlined in diameter_dict(4).
320
321              The  errors field specifies any results codes identifying errors
322              found while decoding the request. This is used  to  set  Result-
323              Code  and/or Failed-AVP in a returned answer unless the callback
324              returns a #diameter_packet{} whose errors field is set to either
325              a  non-empty  list  of  its own, in which case this list is used
326              instead, or the atom false to disable any setting of Result-Code
327              and Failed-AVP. Note that the errors detected by diameter are of
328              the 3xxx and 5xxx series, Protocol Errors and Permanent Failures
329              respectively.  The  errors list is empty if the request has been
330              received in the relay application.
331
332              The transport_data field contains an arbitrary term passed  into
333              diameter  from  the  transport  module  in question, or the atom
334              undefined if the transport specified no data. The term  is  pre‐
335              served  if a message() is returned but must be set explicitly in
336              a returned packet().
337
338              The semantics of each of the possible return values are as  fol‐
339              lows.
340
341                {reply, packet() | message()}:
342                  Send  the  specified answer message to the peer. In the case
343                  of a packet(), the message to be sent must be set in the msg
344                  field  and  the  header  field  can  be  set  to  a  #diame‐
345                  ter_header{} to specify values that should be  preserved  in
346                  the  outgoing answer, appropriate values otherwise being set
347                  by diameter.
348
349                {answer_message, 3000..3999|5000..5999}:
350                  Send an answer message to the peer containing the  specified
351                  Result-Code. Equivalent to
352
353                {reply, ['answer-message' | Avps]
354
355
356                  where Avps sets the Origin-Host, Origin-Realm, the specified
357                  Result-Code and (if the request  contained  one)  Session-Id
358                  AVPs, and possibly Failed-AVP as described below.
359
360                  Returning  a  value  other  than 3xxx or 5xxx will cause the
361                  request process in question to fail,  as  will  returning  a
362                  5xxx  value if the peer connection in question has been con‐
363                  figured  with  the  RFC  3588   common   dictionary   diame‐
364                  ter_gen_base_rfc3588.  (Since RFC 3588 only allows 3xxx val‐
365                  ues in an answer-message.)
366
367                  When returning 5xxx, Failed-AVP will be populated  with  the
368                  AVP of the first matching Result-Code/AVP pair in the errors
369                  field of the argument packet(), if found.  If  this  is  not
370                  appropriate  then  an  answer-message  should be constructed
371                  explicitly and returned in a reply tuple instead.
372
373                {relay, Opts}:
374                  Relay a request to another peer in the role  of  a  Diameter
375                  relay  agent. If a routing loop is detected then the request
376                  is answered with 3005 (DIAMETER_LOOP_DETECTED). Otherwise  a
377                  Route-Record AVP (containing the sending peer's Origin-Host)
378                  is added to the request and pick_peer/4 and subsequent call‐
379                  backs  take place just as if diameter:call/4 had been called
380                  explicitly.  The  End-to-End  Identifier  of  the   incoming
381                  request is preserved in the header of the relayed request.
382
383                  The  returned  Opts  should not specify detach. A subsequent
384                  handle_answer/4 callback for the relayed request must return
385                  its  first argument, the packet() containing the answer mes‐
386                  sage. Note that the extra option can be specified to  supply
387                  arguments that can distinguish the relay case from others if
388                  so desired. Any other return value (for example, from a han‐
389                  dle_error/4 callback) causes the request to be answered with
390                  3002 (DIAMETER_UNABLE_TO_DELIVER).
391
392                discard:
393                  Discard the request. No answer message is sent to the peer.
394
395                {eval, Action, PostF}:
396                  Handle the request as if Action has been returned  and  then
397                  evaluate  PostF  in the request process. The return value is
398                  ignored.
399
400                {eval_packet, Action, PostF}:
401                  Like  eval  but  evaluate  PostF  on  any  encoded   #diame‐
402                  ter_packet{} prior to transmission, the bin field containing
403                  the encoded binary. The return value is ignored.
404
405                {protocol_error, 3000..3999}:
406                  Equivalent to {answer_message, 3000..3999}.
407
408          Note:
409              Requests containing errors may be answered by diameter,  without
410              a  callback  taking  place, depending on the value of the diame‐
411              ter:application_opt() request_errors.
412
413
414
415
416Ericsson AB                     diameter 2.2.3                 diameter_app(3)
Impressum