From f24adb28f51ea35d13dcc501920ef727dfb2d61b Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Fri, 21 Sep 2012 10:29:00 +0200
Subject: Add eval_packet for examining outgoing messages after encode
Both prepare_request/prepare_retransmit and handle_request can
return {eval_packet, RC, PostF} where PostF will be evaluated on any
encoded packet before transmission.
---
lib/diameter/src/base/diameter_service.erl | 194 ++++++++++++++++++-----------
1 file changed, 122 insertions(+), 72 deletions(-)
(limited to 'lib')
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 725cccda1e..01c50a8e30 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -1301,28 +1301,34 @@ cm([_,_|_], _, _, _) ->
%% The mod field of the #diameter_app{} here includes any extra
%% arguments passed to diameter:call/2.
-send_request({TPid, Caps, App}, Msg, Opts, Caller, SvcName) ->
+send_request({TPid, Caps, App} = T, Msg, Opts, Caller, SvcName) ->
#diameter_app{module = ModX}
= App,
Pkt = make_request_packet(Msg),
- case cb(ModX, prepare_request, [Pkt, SvcName, {TPid, Caps}]) of
- {send, P} ->
- send_request(make_request_packet(P, Pkt),
- TPid,
- Caps,
- App,
- Opts,
- Caller,
- SvcName);
- {discard, Reason} ->
- {error, Reason};
- discard ->
- {error, discarded};
- T ->
- ?ERROR({invalid_return, prepare_request, App, T})
- end.
+ send_req(cb(ModX, prepare_request, [Pkt, SvcName, {TPid, Caps}]),
+ Pkt,
+ T,
+ Opts,
+ Caller,
+ SvcName,
+ []).
+
+send_req({send, P}, Pkt, T, Opts, Caller, SvcName, Fs) ->
+ send_request(make_request_packet(P, Pkt), T, Opts, Caller, SvcName, Fs);
+
+send_req({discard, Reason} , _, _, _, _, _, _) ->
+ {error, Reason};
+
+send_req(discard, _, _, _, _, _, _) ->
+ {error, discarded};
+
+send_req({eval_packet, RC, F}, Pkt, T, Opts, Caller, SvcName, Fs) ->
+ send_req(RC, Pkt, T, Opts, Caller, SvcName, [F|Fs]);
+
+send_req(E, _, {_, _, App}, _, _, _, _) ->
+ ?ERROR({invalid_return, prepare_request, App, E}).
%% make_request_packet/1
%%
@@ -1400,16 +1406,16 @@ fold_record(undefined, R) ->
fold_record(Rec, R) ->
diameter_lib:fold_tuple(2, Rec, R).
-%% send_request/7
+%% send_request/6
-send_request(Pkt, TPid, Caps, App, Opts, Caller, SvcName) ->
+send_request(Pkt, {TPid, Caps, App}, Opts, Caller, SvcName, Fs) ->
#diameter_app{alias = Alias,
dictionary = Dict,
module = ModX,
options = [{answer_errors, AE} | _]}
= App,
- EPkt = encode(Dict, Pkt),
+ EPkt = encode(Dict, Pkt, Fs),
#options{filter = Filter,
timeout = Timeout}
@@ -1490,6 +1496,13 @@ msg(#diameter_packet{msg = undefined, bin = Bin}) ->
msg(#diameter_packet{msg = Msg}) ->
Msg.
+%% encode/3
+
+encode(Dict, Pkt, Fs) ->
+ P = encode(Dict, Pkt),
+ eval_packet(P, Fs),
+ P.
+
%% encode/2
%% Note that prepare_request can return a diameter_packet containing
@@ -1571,38 +1584,47 @@ send(Pid, Pkt) ->
%% retransmit/4
-retransmit({TPid, Caps, #diameter_app{alias = Alias} = App},
- #request{app = Alias,
- packet = Pkt}
+retransmit({TPid, Caps, #diameter_app{alias = Alias} = App} = T,
+ #request{app = Alias, packet = Pkt}
= Req,
SvcName,
Timeout) ->
have_request(Pkt, TPid) %% Don't failover to a peer we've
andalso ?THROW(timeout), %% already sent to.
- case cb(App, prepare_retransmit, [Pkt, SvcName, {TPid, Caps}]) of
- {send, P} ->
- retransmit(make_request_packet(P, Pkt), TPid, Caps, Req, Timeout);
- {discard, Reason} ->
- ?THROW(Reason);
- discard ->
- ?THROW(discarded);
- T ->
- ?ERROR({invalid_return, prepare_retransmit, App, T})
- end.
+ resend_req(cb(App, prepare_retransmit, [Pkt, SvcName, {TPid, Caps}]),
+ T,
+ Req,
+ Timeout,
+ []).
-%% retransmit/5
+resend_req({send, P}, T, #request{packet = Pkt} = Req, Timeout, Fs) ->
+ retransmit(make_request_packet(P, Pkt), T, Req, Timeout, Fs);
-retransmit(Pkt, TPid, Caps, #request{dictionary = Dict} = Req, Timeout) ->
- EPkt = encode(Dict, Pkt),
+resend_req({discard, Reason}, _, _, _, _) ->
+ ?THROW(Reason);
- NewReq = Req#request{transport = TPid,
- packet = Pkt,
- caps = Caps},
+resend_req(discard, _, _, _, _) ->
+ ?THROW(discarded);
- ?LOG(retransmission, NewReq),
- TRef = send_request(TPid, EPkt, NewReq, Timeout),
- {TRef, NewReq}.
+resend_req({eval_packet, RC, F}, T, Req, Timeout, Fs) ->
+ resend_req(RC, T, Req, Timeout, [F|Fs]);
+
+resend_req(T, {_, _, App}, _, _, _) ->
+ ?ERROR({invalid_return, prepare_retransmit, App, T}).
+
+%% retransmit/6
+
+retransmit(Pkt, {TPid, Caps, _}, #request{dictionary = D} = Req0, Tmo, Fs) ->
+ EPkt = encode(D, Pkt, Fs),
+
+ Req = Req0#request{transport = TPid,
+ packet = Pkt,
+ caps = Caps},
+
+ ?LOG(retransmission, Req),
+ TRef = send_request(TPid, EPkt, Req, Tmo),
+ {TRef, Req}.
%% store_request/4
@@ -1805,7 +1827,12 @@ recv_request(T, TC, App, Pkt) ->
%% (3xxx) errors that lead to an answer-message.
request_cb({SvcName, _OH, _OR} = T, TC, App, Pkt) ->
- request_cb(cb(App, handle_request, [Pkt, SvcName, TC]), App, T, TC, Pkt).
+ request_cb(cb(App, handle_request, [Pkt, SvcName, TC]),
+ App,
+ T,
+ TC,
+ [],
+ Pkt).
%% examine/1
%%
@@ -1825,7 +1852,7 @@ examine(#diameter_packet{errors = Es} = Pkt) ->
Pkt#diameter_packet{errors = [5011 | Es]}.
%% It's odd/unfortunate that this isn't a protocol error.
-%% request_cb/5
+%% request_cb/6
%% A reply may be an answer-message, constructed either here or by
%% the handle_request callback. The header from the incoming request
@@ -1836,20 +1863,21 @@ request_cb({reply, Ans},
#diameter_app{dictionary = Dict},
_,
{TPid, _},
+ Fs,
Pkt) ->
- reply(Ans, Dict, TPid, Pkt);
+ reply(Ans, Dict, TPid, Fs, Pkt);
%% An 3xxx result code, for which the E-bit is set in the header.
-request_cb({protocol_error, RC}, _, T, {TPid, _}, Pkt)
+request_cb({protocol_error, RC}, _, T, {TPid, _}, Fs, Pkt)
when 3000 =< RC, RC < 4000 ->
- protocol_error(RC, T, TPid, Pkt);
+ protocol_error(RC, T, TPid, Fs, Pkt);
%% RFC 3588 says we must reply 3001 to anything unrecognized or
%% unsupported. 'noreply' is undocumented (and inappropriately named)
%% backwards compatibility for this, protocol_error the documented
%% alternative.
-request_cb(noreply, _, T, {TPid, _}, Pkt) ->
- protocol_error(3001, T, TPid, Pkt);
+request_cb(noreply, _, T, {TPid, _}, Fs, Pkt) ->
+ protocol_error(3001, T, TPid, Fs, Pkt);
%% Relay a request to another peer. This is equivalent to doing an
%% explicit call/4 with the message in question except that (1) a loop
@@ -1871,26 +1899,36 @@ request_cb({A, Opts},
= App,
T,
TC,
+ Fs,
Pkt)
when A == relay, Id == ?APP_ID_RELAY;
A == proxy, Id /= ?APP_ID_RELAY;
A == resend ->
- resend(Opts, App, T, TC, Pkt);
+ resend(Opts, App, T, TC, Fs, Pkt);
-request_cb(discard, _, _, _, _) ->
+request_cb(discard, _, _, _, _, _) ->
ok;
-request_cb({eval, RC, F}, App, T, TC, Pkt) ->
- request_cb(RC, App, T, TC, Pkt),
+request_cb({eval_packet, RC, F}, App, T, TC, Fs, Pkt) ->
+ request_cb(RC, App, T, TC, [F|Fs], Pkt);
+
+request_cb({eval, RC, F}, App, T, TC, Fs, Pkt) ->
+ request_cb(RC, App, T, TC, Pkt, Fs),
diameter_lib:eval(F).
-%% protocol_error/4
+%% protocol_error/5
-protocol_error(RC, {_, OH, OR}, TPid, #diameter_packet{avps = Avps} = Pkt) ->
+protocol_error(RC, {_, OH, OR}, TPid, Fs, Pkt) ->
+ #diameter_packet{avps = Avps} = Pkt,
?LOG({error, RC}, Pkt),
- reply(answer_message({OH, OR, RC}, Avps), ?BASE, TPid, Pkt).
+ reply(answer_message({OH, OR, RC}, Avps), ?BASE, TPid, Fs, Pkt).
+
+%% protocol_error/4
-%% resend/5
+protocol_error(RC, T, TPid, Pkt) ->
+ protocol_error(RC, T, TPid, [], Pkt).
+
+%% resend/6
%%
%% Resend a message as a relay or proxy agent.
@@ -1898,9 +1936,12 @@ resend(Opts,
#diameter_app{} = App,
{_SvcName, OH, _OR} = T,
{_TPid, _Caps} = TC,
+ Fs,
#diameter_packet{avps = Avps} = Pkt) ->
{Code, _Flags, Vid} = ?BASE:avp_header('Route-Record'),
- resend(is_loop(Code, Vid, OH, Avps), Opts, App, T, TC, Pkt).
+ resend(is_loop(Code, Vid, OH, Avps), Opts, App, T, TC, Fs, Pkt).
+
+%% resend/7
%% DIAMETER_LOOP_DETECTED 3005
%% An agent detected a loop while trying to get the message to the
@@ -1908,8 +1949,8 @@ resend(Opts,
%% if one is available, but the peer reporting the error has
%% identified a configuration problem.
-resend(true, _, _, T, {TPid, _}, Pkt) -> %% Route-Record loop
- protocol_error(3005, T, TPid, Pkt);
+resend(true, _, _, T, {TPid, _}, Fs, Pkt) -> %% Route-Record loop
+ protocol_error(3005, T, TPid, Fs, Pkt);
%% 6.1.8. Relaying and Proxying Requests
%%
@@ -1922,6 +1963,7 @@ resend(false,
App,
{SvcName, _, _} = T,
{TPid, #diameter_caps{origin_host = {_, OH}}},
+ Fs,
#diameter_packet{header = Hdr0,
avps = Avps}
= Pkt) ->
@@ -1929,7 +1971,7 @@ resend(false,
Seq = diameter_session:sequence(),
Hdr = Hdr0#diameter_header{hop_by_hop_id = Seq},
Msg = [Hdr, Route | Avps],
- resend(call(SvcName, App, Msg, Opts), T, TPid, Pkt).
+ resend(call(SvcName, App, Msg, Opts), T, TPid, Fs, Pkt).
%% The incoming request is relayed with the addition of a
%% Route-Record. Note the requirement on the return from call/4 below,
%% which places a requirement on the value returned by the
@@ -1955,15 +1997,18 @@ resend(#diameter_packet{bin = B}
= Pkt,
_,
TPid,
+ Fs,
#diameter_packet{header = #diameter_header{hop_by_hop_id = Id},
transport_data = TD}) ->
- send(TPid, Pkt#diameter_packet{bin = diameter_codec:hop_by_hop_id(Id, B),
- transport_data = TD});
+ P = Pkt#diameter_packet{bin = diameter_codec:hop_by_hop_id(Id, B),
+ transport_data = TD},
+ eval_packet(P, Fs),
+ send(TPid, P);
%% TODO: counters
%% Or not: DIAMETER_UNABLE_TO_DELIVER.
-resend(_, T, TPid, Pkt) ->
- protocol_error(3002, T, TPid, Pkt).
+resend(_, T, TPid, Fs, Pkt) ->
+ protocol_error(3002, T, TPid, Fs, Pkt).
%% is_loop/4
%%
@@ -1985,33 +2030,38 @@ is_loop(Code, Vid, OH, [_ | Avps])
is_loop(Code, Vid, OH, Avps) ->
is_loop(Code, Vid, ?BASE:avp(encode, OH, 'Route-Record'), Avps).
-%% reply/4
+%% reply/5
%%
%% Send a locally originating reply.
%% Skip the setting of Result-Code and Failed-AVP's below.
-reply([Msg], Dict, TPid, Pkt)
+reply([Msg], Dict, TPid, Fs, Pkt)
when is_list(Msg);
is_tuple(Msg) ->
- reply(Msg, Dict, TPid, Pkt#diameter_packet{errors = []});
+ reply(Msg, Dict, TPid, Fs, Pkt#diameter_packet{errors = []});
%% No errors or a diameter_header/avp list.
-reply(Msg, Dict, TPid, #diameter_packet{errors = Es,
- transport_data = TD}
- = ReqPkt)
+reply(Msg, Dict, TPid, Fs, #diameter_packet{errors = Es,
+ transport_data = TD}
+ = ReqPkt)
when [] == Es;
is_record(hd(Msg), diameter_header) ->
Pkt = diameter_codec:encode(Dict, make_answer_packet(Msg, ReqPkt)),
+ eval_packet(Pkt, Fs),
incr(send, Pkt, Dict, TPid), %% count result codes in sent answers
send(TPid, Pkt#diameter_packet{transport_data = TD});
%% Or not: set Result-Code and Failed-AVP AVP's.
-reply(Msg, Dict, TPid, #diameter_packet{errors = [H|_] = Es} = Pkt) ->
+reply(Msg, Dict, TPid, Fs, #diameter_packet{errors = [H|_] = Es} = Pkt) ->
reply(rc(Msg, rc(H), [A || {_,A} <- Es], Dict),
Dict,
TPid,
+ Fs,
Pkt#diameter_packet{errors = []}).
+eval_packet(Pkt, Fs) ->
+ lists:foreach(fun(F) -> diameter_lib:eval([F,Pkt]) end, Fs).
+
%% make_answer_packet/2
%% Binaries and header/avp lists are sent as-is.
--
cgit v1.2.3
From 98836f68bd01ef82df5b9816a3ff065f02e50156 Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Thu, 4 Oct 2012 19:12:05 +0200
Subject: Document eval_packet
---
lib/diameter/doc/src/diameter_app.xml | 67 +++++++++++++++++++++++++----------
1 file changed, 49 insertions(+), 18 deletions(-)
(limited to 'lib')
diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml
index 4a4b212787..98c8b8c807 100644
--- a/lib/diameter/doc/src/diameter_app.xml
+++ b/lib/diameter/doc/src/diameter_app.xml
@@ -325,32 +325,44 @@ or peer_down/3 callback.
Packet = packet()
SvcName = diameter:service_name()
Peer = peer()
-Action = {send, packet() | message()} | {discard, Reason} | discard
+Action = Send | Discard | {eval_packet, Action, PostF}
+Send = {send, packet()
+ | message()}
+Discard = {discard, Reason} | discard
+PostF =
+ diameter:evaluable()}
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.
+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
+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.
+to pass information to the transport process.
Extra arguments passed to diameter:call/4 can be used to
-communicate transport data to the callback.
-A returned packet() can also set the header field to a
-#diameter_header{} record in order to specify values that should
-be preserved in the outgoing request, although this should typically
-not be necessary and allows the callback to set header values
-inappropriately.
+communicate transport (or any other) data to the callback.
+
+
+A returned packet() can set
+the header field to a
+#diameter_header{} in order 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
+#diameter_packet{} prior to transmission, the bin field
+of this record containing the encoded binary.
+The return value is ignored.
+
Returning {discard, Reason} causes the request to be aborted
and the .
-Mod:prepare_retransmit(Packet, SvcName, Peer) -> Result
+Mod:prepare_retransmit(Packet, SvcName, Peer) -> Action
Return a request for encoding and retransmission.
Packet = packet()
SvcName = diameter:service_name()
-Peer = peer()
-Result = {send, packet() | message()} | {discard, Reason} | discard
+Peer = peer()
+Action = Send | Discard | {eval_packet, Action, PostF}
+Send = {send, packet()
+ | message()}
+Discard = {discard, Reason} | discard
+PostF =
+ diameter:evaluable()}
@@ -484,7 +501,11 @@ callback returned false.
Packet = packet()
SvcName = term()
Peer = peer()
-Action = Reply | {relay, [Opt]} | discard | {eval, Action, PostF}
+Action = Reply
+ | {relay, [Opt]}
+ | discard
+ | {eval, Action, PostF}
+ | {eval_packet, Action, PostF}
Reply = {reply, message()}
| {protocol_error, 3000..3999}
Opt = diameter:call_opt()
@@ -610,7 +631,17 @@ Discard the request.
-
Handle the request as if Action has been returned and then
-evaluate PostF in the request process.
+evaluate PostF in the request process.
+The return value is ignored.
+
+
+{eval_packet, Action, PostF}
+-
+
+Like eval but evaluate PostF on any encoded
+#diameter_packet{} prior to transmission, the bin field
+of this record containing the encoded binary.
+The return value is ignored.
--
cgit v1.2.3
From e28ced7b0be4282063ca111782f13f4ba4f6c3ac Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Fri, 5 Oct 2012 01:47:30 +0200
Subject: Improve other diameter_app doc
---
lib/diameter/doc/src/diameter_app.xml | 192 ++++++++++++++++++++--------------
1 file changed, 112 insertions(+), 80 deletions(-)
(limited to 'lib')
diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml
index 98c8b8c807..9d8a6568eb 100644
--- a/lib/diameter/doc/src/diameter_app.xml
+++ b/lib/diameter/doc/src/diameter_app.xml
@@ -112,7 +112,8 @@ and, for the call-specific callbacks, any extra arguments passed to
-
A record containing the identities of
-the local Diameter node and the remote Diameter peer having an established transport
+the local Diameter node and the remote Diameter peer 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
@@ -168,13 +169,14 @@ Fields should not be set in return values except as documented.
peer_ref() = term()
-
-A term identifying a transport connection with a Diameter peer.
-Should be treated opaquely.
+A term identifying a transport connection with a Diameter peer.
-peer() = {peer_ref(), capabilities()}
+peer() =
+ {peer_ref(),
+ capabilities()}
-
A tuple representing a Diameter peer connection.
@@ -219,10 +221,29 @@ process.
-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.
+Invoked to signal the availability of a peer connection.
+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.
+
+
+
+A watchdog state machine can reach state OKAY from state
+SUSPECT without a new capabilities exchange taking place.
+A new transport connection (and capabilities exchange) results in a
+new peer_ref().
+
+
+
+
+There is no requirement that a callback return before incoming
+requests are received: handle_request/3 callbacks must be
+handled independently of peer_up/3 and peer_down/3.
+
@@ -238,36 +259,42 @@ the callback module in question has been configured.
-Invoked when a transport connection has been lost following a previous
-call to peer_up/3.
+Invoked to signal that a peer connection 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()
+callbacks.
-Mod:pick_peer(Candidates, Reserved, SvcName, State)
- -> {ok, Peer} | {Peer, NewState} | false
+Mod:pick_peer(Candidates, _Reserved, SvcName, State)
+ -> Selection | false
Select a target peer for an outgoing request.
Candidates = [peer()]
-Peer = peer() | false
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 indicating the selected
-peer.
+peer for an outgoing request.
+The return value indicates the selected peer.
-The candidate peers list will only include those
-which are selected by any filter option specified in the call to
-diameter:call/4, and only
-those which have indicated support for the Diameter application in
-question.
+The candidate list contains only those peers that have advertised
+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]}}
@@ -275,36 +302,40 @@ option to diameter:call/4)
will be placed at the head of the list.
-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
+A callback that returns a peer() will be followed by a
+prepare_request/3
+callback and, if the latter indicates that the request should be sent,
+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 prepare_request/3 then a new pick_peer/4 callback may take place to
+failover to an alternate peer, after which prepare_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, only
-that the initial pick_peer/4 will be, since a
+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.
+
+Returning false or {false, NewState} causes {error,
+no_connection} to be returned from diameter:call/4.
+
+
+The return values false and {false, State} (that is,
+NewState = State) are equivalent, as are {ok, Peer} and
+{Peer, State}.
+
-{Peer, NewState} and its equivalents can only be returned if
-the Diameter application in question was
-configured with the {Peer, NewState} is only allowed if
+the Diameter application in question was configured with the diameter:application_opt()
{call_mutates_state, true}.
Otherwise, the State argument is always
@@ -360,7 +391,7 @@ ignored.
A returned PostF will be evaluated on any encoded
#diameter_packet{} prior to transmission, the bin field
-of this record containing the encoded binary.
+containing the encoded binary.
The return value is ignored.
@@ -395,8 +426,9 @@ 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
-argument packet() is as returned by the initial
-prepare_request/3.
+argument packet() is as returned
+by the initial prepare_request/3.
Returning {discard, Reason} causes the request to be aborted
@@ -423,40 +455,41 @@ discarded}.
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 unless the detach option was
-specified.
+The return value is returned from diameter:call/4 unless the
+detach option was specified.
-The decoded answer record is in the msg field of the argument
-packet(),
-the undecoded binary in the packet field.
+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
prepare_request/3 or
-prepare_retransmit/3
-before the request was passed to the transport.
+prepare_retransmit/3.
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
+handle_answer/4 callback: 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.
+Similarly, only one of handle_answer/4 or
+handle_error/4 is
+called.
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} (unless the detach option was
-specified).
-In particular, there is no handle_error/4 callback in this
+decoded causes the request process to fail, causing
+diameter:call/4
+to return {error, failure} unless the detach option was
+specified.
+In particular, there is no handle_error/4 callback in this
case.
-Application configuration may change this behaviour as described for
-diameter:start_service/2.
+The diameter:application_opt()
+answer_errors can be set to change this behaviour.
@@ -474,21 +507,20 @@ marker="diameter#start_service">diameter:start_service/2.
-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 (unless the detach option was
-specified).
+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 specified.
Reason timeout indicates that an answer message has not been
-received within the required time.
+received within the time specified with the corresponding diameter:call_opt().
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.
+been sent has become unavailable and that not alternate peer was
+not selected.
@@ -504,8 +536,7 @@ callback returned false.
Action = Reply
| {relay, [Opt]}
| discard
- | {eval, Action, PostF}
- | {eval_packet, Action, PostF}
+ | {eval|eval_packet, Action, PostF}
Reply = {reply, message()}
| {protocol_error, 3000..3999}
Opt = diameter:call_opt()
@@ -624,7 +655,8 @@ causes the request to be answered with 3002 (DIAMETER_UNABLE_TO_DELIVER).
discard
-
-Discard the request.
+Discard the request.
+No answer message is sent to the peer.
{eval, Action, PostF}
@@ -640,7 +672,7 @@ The return value is ignored.
Like eval but evaluate PostF on any encoded
#diameter_packet{} prior to transmission, the bin field
-of this record containing the encoded binary.
+containing the encoded binary.
The return value is ignored.
--
cgit v1.2.3
From 3e936e07da7f0c949d2ba08ee7a8d3d533dc27db Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Tue, 9 Oct 2012 02:07:42 +0200
Subject: Use packet callbacks in traffic suite
---
lib/diameter/test/diameter_traffic_SUITE.erl | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index 669918f757..dd07679764 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -624,7 +624,10 @@ prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, Name) ->
{send, prepare(Pkt, Caps, Name)}.
prepare_request(Pkt, ?CLIENT, {_Ref, Caps}, send_detach, _) ->
- {send, prepare(Pkt, Caps)}.
+ {eval_packet, {send, prepare(Pkt, Caps)}, [fun log/2, detach]}.
+
+log(#diameter_packet{} = P, T) ->
+ io:format("~p: ~p~n", [T,P]).
prepare(Pkt, Caps, send_unsupported) ->
Req = prepare(Pkt, Caps),
@@ -738,7 +741,7 @@ handle_request(#diameter_packet{msg = M}, ?SERVER, {_Ref, Caps}) ->
request(#diameter_base_accounting_ACR{'Accounting-Record-Number' = 0},
_) ->
- {protocol_error, ?INVALID_AVP_BITS};
+ {eval_packet, {protocol_error, ?INVALID_AVP_BITS}, [fun log/2, invalid]};
request(#diameter_base_accounting_ACR{'Session-Id' = SId,
'Accounting-Record-Type' = RT,
--
cgit v1.2.3