aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_peer_fsm.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/diameter/src/base/diameter_peer_fsm.erl')
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl51
1 files changed, 38 insertions, 13 deletions
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index f76bd96c3c..32e1b91966 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -292,7 +292,8 @@ handle_info(T, #state{} = State) ->
?LOG(stop, T),
{stop, {shutdown, T}, State}
catch
- exit: {diameter_codec, encode, _} = Reason ->
+ exit: {diameter_codec, encode, T} = Reason ->
+ incr_error(send, T),
?LOG(stop, Reason),
%% diameter_codec:encode/2 emits an error report. Only
%% indicate the probable reason here.
@@ -609,9 +610,13 @@ rcv('DPR' = N, Pkt, S) ->
%% DPA in response to DPR and with the expected identifiers.
rcv('DPA' = N,
#diameter_packet{header = #diameter_header{end_to_end_id = Eid,
- hop_by_hop_id = Hid}},
- #state{transport = TPid,
+ hop_by_hop_id = Hid}}
+ = Pkt,
+ #state{dictionary = Dict0,
+ transport = TPid,
dpr = {Hid, Eid}}) ->
+
+ incr_rc(recv, diameter_codec:decode(Dict0, Pkt), Dict0),
diameter_peer:close(TPid),
{stop, N};
@@ -619,6 +624,16 @@ rcv('DPA' = N,
rcv(_, _, _) ->
ok.
+%% incr_rc/3
+
+incr_rc(Dir, Pkt, Dict0) ->
+ diameter_traffic:incr_rc(Dir, Pkt, self(), Dict0).
+
+%% incr_error/2
+
+incr_error(Dir, Pkt) ->
+ diameter_traffic:incr_error(Dir, Pkt, self()).
+
%% send/2
%% Msg here could be a #diameter_packet or a binary depending on who's
@@ -637,6 +652,8 @@ handle_request(Type, #diameter_packet{} = Pkt, #state{dictionary = D} = S) ->
%% send_answer/3
send_answer(Type, ReqPkt, #state{transport = TPid, dictionary = Dict} = S) ->
+ incr_error(recv, ReqPkt),
+
#diameter_packet{header = H,
transport_data = TD}
= ReqPkt,
@@ -653,13 +670,14 @@ send_answer(Type, ReqPkt, #state{transport = TPid, dictionary = Dict} = S) ->
msg = Msg,
transport_data = TD},
- send(TPid, diameter_codec:encode(Dict, Pkt)),
+ AnsPkt = diameter_codec:encode(Dict, Pkt),
+
+ incr_rc(send, AnsPkt, Dict),
+ send(TPid, AnsPkt),
eval(PostF, S).
eval([F|A], S) ->
apply(F, A ++ [S]);
-eval(ok, S) ->
- S;
eval(T, _) ->
close(T).
@@ -723,8 +741,8 @@ cea(CEA, RC, Dict0) ->
post('CER' = T, RC, Pkt, S) ->
{T, caps(S), {RC, Pkt}};
-post('DPR', _, _, _) ->
- ok.
+post('DPR' = T, _, _, #state{parent = Pid}) ->
+ [fun(S) -> Pid ! {T, self()}, S end].
rejected({capabilities_cb, _F, Reason}, T, S) ->
rejected(Reason, T, S);
@@ -734,7 +752,7 @@ rejected(discard, T, _) ->
rejected({N, Es}, T, S) ->
{answer('CER', N, failed_avp(N, Es), S), T};
rejected(N, T, S) ->
- rejected({N, []}, T, S).
+ {answer('CER', N, [], S), T}.
failed_avp(RC, [{RC, Avp} | _]) ->
[{'Failed-AVP', [[{'AVP', [Avp]}]]}];
@@ -848,7 +866,7 @@ recv_CER(CER, #state{service = Svc, dictionary = Dict}) ->
close({'CER', CER, Svc, Dict, Reason})
end.
-%% handle_CEA/1
+%% handle_CEA/2
handle_CEA(#diameter_packet{bin = Bin}
= Pkt,
@@ -858,18 +876,18 @@ handle_CEA(#diameter_packet{bin = Bin}
when is_binary(Bin) ->
?LOG(recv, 'CEA'),
- #diameter_packet{msg = CEA}
+ #diameter_packet{}
= DPkt
= diameter_codec:decode(Dict0, Pkt),
+ RC = result_code(incr_rc(recv, DPkt, Dict0)),
+
{SApps, IS, RCaps} = recv_CEA(DPkt, S),
#diameter_caps{origin_host = {OH, DH}}
= Caps
= capz(LCaps, RCaps),
- RC = Dict0:'#get-'('Result-Code', CEA),
-
%% Ensure that we don't already have a connection to the peer in
%% question. This isn't the peer election of 3588 except in the
%% sense that, since we don't know who we're talking to until we
@@ -877,6 +895,8 @@ handle_CEA(#diameter_packet{bin = Bin}
%% connection with the peer.
try
+ is_integer(RC)
+ orelse ?THROW(no_result_code),
?IS_SUCCESS(RC)
orelse ?THROW(RC),
[] == SApps
@@ -897,6 +917,11 @@ handle_CEA(#diameter_packet{bin = Bin}
%% capabilities exchange could send DIAMETER_LIMITED_SUCCESS = 2002,
%% even if this isn't required by RFC 3588.
+result_code({{'Result-Code', N}, _}) ->
+ N;
+result_code(_) ->
+ undefined.
+
%% recv_CEA/2
recv_CEA(#diameter_packet{header = #diameter_header{version