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