From 58a070c491e7f2f87a3c6bb09a5c05208a9aa333 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Thu, 22 May 2014 02:09:23 +0200 Subject: Count encode errors in outgoing messages Only decode errors were counted previously. Keys are of the form {Id, send, error}, where Id is: {ApplicationId, CommandCode, Rbit} | unknown The latter will be the case if not even a #diameter_header{} can be constructed. --- lib/diameter/src/base/diameter_traffic.erl | 89 ++++++++++++++++++------------ 1 file changed, 53 insertions(+), 36 deletions(-) (limited to 'lib/diameter/src/base/diameter_traffic.erl') diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl index 29d21fa7dc..f113d95b2e 100644 --- a/lib/diameter/src/base/diameter_traffic.erl +++ b/lib/diameter/src/base/diameter_traffic.erl @@ -32,8 +32,8 @@ -export([receive_message/4]). %% towards diameter_peer_fsm and diameter_watchdog --export([incr_A/4, - incr_R/3]). +-export([incr_error/3, + incr_rc/4]). %% towards diameter_service -export([make_recvdata/1, @@ -116,10 +116,35 @@ peer_down(TPid) -> failover(TPid). %% --------------------------------------------------------------------------- -%% incr_A/4 +%% incr_error/3 %% --------------------------------------------------------------------------- --spec incr_A(send|recv, #diameter_packet{}, TPid, Dict0) +%% A decoded message with errors. +incr_error(Dir, #diameter_packet{header = H, errors = [_|_]}, TPid) -> + incr_error(Dir, H, TPid); + +%% An encoded message with errors and an identifiable header ... +incr_error(Dir, {_, _, #diameter_header{} = H}, TPid) -> + incr_error(Dir, H, TPid); + +%% ... or not. +incr_error(Dir, {_,_}, TPid) -> + incr(TPid, {unknown, Dir, error}); + +incr_error(Dir, #diameter_header{} = H, TPid) -> + incr_error(Dir, diameter_codec:msg_id(H), TPid); + +incr_error(Dir, {_,_,_} = Id, TPid) -> + incr(TPid, {Id, Dir, error}); + +incr_error(_, _, _) -> + false. + +%% --------------------------------------------------------------------------- +%% incr_rc/4 +%% --------------------------------------------------------------------------- + +-spec incr_rc(send|recv, #diameter_packet{}, TPid, Dict0) -> {Counter, non_neg_integer()} | Reason when TPid :: pid(), @@ -128,9 +153,9 @@ peer_down(TPid) -> | {'Experimental-Result', integer(), integer()}, Reason :: atom(). -incr_A(Dir, Pkt, TPid, Dict0) -> +incr_rc(Dir, Pkt, TPid, Dict0) -> try - incr_A(Dir, Pkt, Dict0, TPid, Dict0) + incr_rc(Dir, Pkt, Dict0, TPid, Dict0) catch exit: {invalid_error_bit = E, _} -> E; @@ -138,18 +163,6 @@ incr_A(Dir, Pkt, TPid, Dict0) -> E end. -%% --------------------------------------------------------------------------- -%% incr_R/3 -%% --------------------------------------------------------------------------- - -%% incr_R/3 - -incr_R(recv = D, #diameter_packet{header = H, errors = [_|_]}, TPid) -> - incr_error(diameter_codec:msg_id(H), D, TPid); - -incr_R(_, _, _) -> - ok. - %% --------------------------------------------------------------------------- %% pending/1 %% --------------------------------------------------------------------------- @@ -254,7 +267,7 @@ recv_R({#diameter_app{id = Id, dictionary = Dict} = App, Caps}, Dict0, RecvData) -> Pkt = errors(Id, diameter_codec:decode(Id, Dict, Pkt0)), - incr_R(recv, Pkt, TPid), + incr_error(recv, Pkt, TPid), {Caps, Pkt, App, recv_R(App, TPid, Dict0, Caps, RecvData, Pkt)}; %% Note that the decode is different depending on whether or not Id is %% ?APP_ID_RELAY. @@ -647,9 +660,10 @@ reply([Msg], Dict, TPid, Dict0, Fs, ReqPkt) reply(Msg, Dict, TPid, Dict0, Fs, ReqPkt) -> Pkt = encode(Dict, + TPid, reset(make_answer_packet(Msg, ReqPkt), Dict, Dict0), Fs), - incr_A(send, Pkt, Dict, TPid, Dict0), %% count outgoing + incr_rc(send, Pkt, Dict, TPid, Dict0), %% count outgoing send(TPid, Pkt). %% reset/3 @@ -1014,19 +1028,19 @@ find(Pred, [H|T]) -> %% code, the missing vendor id, and a zero filled payload of the minimum %% required length for the omitted AVP will be added. -%% incr_A/5 +%% incr_rc/5 %% %% Increment a stats counter for result codes in incoming and outgoing %% answers. %% Outgoing message as binary: don't count. (Sending binaries is only %% partially supported.) -incr_A(_, #diameter_packet{msg = undefined = No}, _, _, _) -> +incr_rc(_, #diameter_packet{msg = undefined = No}, _, _, _) -> No; %% Incoming or outgoing. Outgoing with encode errors never gets here %% since encode fails. -incr_A(Dir, Pkt, Dict, TPid, Dict0) -> +incr_rc(Dir, Pkt, Dict, TPid, Dict0) -> #diameter_packet{header = #diameter_header{is_error = E} = Hdr, msg = Msg, @@ -1036,7 +1050,7 @@ incr_A(Dir, Pkt, Dict, TPid, Dict0) -> Id = diameter_codec:msg_id(Hdr), %% Count incoming decode errors. - recv /= Dir orelse [] == Es orelse incr_error(Id, Dir, TPid), + recv /= Dir orelse [] == Es orelse incr_error(Dir, Id, TPid), %% Exit on a missing result code. T = rc_counter(Dict, Msg), @@ -1120,9 +1134,6 @@ x(Reason, F, A) -> x(T) -> exit(T). -incr_error(Id, Dir, TPid) -> - incr(TPid, {Id, Dir, error}). - %% --------------------------------------------------------------------------- %% # send_request/4 %% @@ -1361,7 +1372,7 @@ send_R(Pkt0, {Pid, Ref}, SvcName, Fs) -> - Pkt = encode(Dict, Pkt0, Fs), + Pkt = encode(Dict, TPid, Pkt0, Fs), #options{timeout = Timeout} = Opts, @@ -1427,7 +1438,7 @@ handle_answer(SvcName, handle_A(Pkt, SvcName, Dict, Dict0, App, #request{transport = TPid} = Req) -> try - incr_A(recv, Pkt, Dict, TPid, Dict0) %% count incoming + incr_rc(recv, Pkt, Dict, TPid, Dict0) %% count incoming of _ -> answer(Pkt, SvcName, App, Req) catch @@ -1525,10 +1536,10 @@ msg(#diameter_packet{msg = undefined, bin = Bin}) -> msg(#diameter_packet{msg = Msg}) -> Msg. -%% encode/3 +%% encode/4 -encode(Dict, Pkt, Fs) -> - P = encode(Dict, Pkt), +encode(Dict, TPid, Pkt, Fs) -> + P = encode(Dict, TPid, Pkt), eval_packet(P, Fs), P. @@ -1540,11 +1551,17 @@ encode(Dict, Pkt, Fs) -> %% support retransmission but is useful for test. %% A message to be encoded. -encode(Dict, #diameter_packet{bin = undefined} = Pkt) -> - diameter_codec:encode(Dict, Pkt); +encode(Dict, TPid, #diameter_packet{bin = undefined} = Pkt) -> + try + diameter_codec:encode(Dict, Pkt) + catch + exit: {diameter_codec, encode, T} = Reason -> + incr_error(send, T, TPid), + exit(Reason) + end; %% An encoded binary: just send. -encode(_, #diameter_packet{} = Pkt) -> +encode(_, _, #diameter_packet{} = Pkt) -> Pkt. %% send_request/5 @@ -1641,7 +1658,7 @@ resend_request(Pkt0, SvcName, Tmo, Fs) -> - Pkt = encode(Dict, Pkt0, Fs), + Pkt = encode(Dict, TPid, Pkt0, Fs), Req = Req0#request{transport = TPid, packet = Pkt0, -- cgit v1.2.3