diff options
Diffstat (limited to 'lib/diameter/src/base/diameter_service.erl')
-rw-r--r-- | lib/diameter/src/base/diameter_service.erl | 121 |
1 files changed, 37 insertions, 84 deletions
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl index a4a0b80348..d2a416166f 100644 --- a/lib/diameter/src/base/diameter_service.erl +++ b/lib/diameter/src/base/diameter_service.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -361,9 +361,6 @@ find_state(SvcName) -> fs([#state{} = S]) -> S; -fs([S]) -> %% inserted from old code - upgrade(S); - fs([]) -> false. @@ -462,10 +459,6 @@ i(_, false) -> %%% # handle_call(Req, From, State) %%% --------------------------------------------------------------------------- -handle_call(T, From, S) - when not is_record(S, state) -> - handle_call(T, From, upgrade(S)); - handle_call(state, _, S) -> {reply, S, S}; @@ -489,10 +482,6 @@ handle_call({pick_peer, Local, Remote, App}, _From, S) -> handle_call({call_module, AppMod, Req}, From, S) -> call_module(AppMod, Req, From, S); -%% Call from old code. -handle_call({info, Item}, _From, S) -> - {reply, service_info(Item, S), S}; - handle_call(stop, _From, S) -> shutdown(service, S), {stop, normal, ok, S}; @@ -500,14 +489,6 @@ handle_call(stop, _From, S) -> %% gets the reply. We deal with this in the call to the server, %% stating a monitor that waits for DOWN before returning. -%% Watchdog is asking for the sequence mask. -handle_call(sequence, _From, #state{options = [{_, Mask} | _]} = S) -> - {reply, Mask, S}; - -%% Watchdog is asking for the nodes restriction. -handle_call(restriction, _From, #state{options = [_,_,_,{_,R} | _]} = S) -> - {reply, R, S}; - handle_call(Req, From, S) -> unexpected(handle_call, [Req, From], S), {reply, nok, S}. @@ -530,10 +511,7 @@ handle_info(T, #state{} = S) -> {noreply, S}; {stop, Reason} -> {stop, {shutdown, Reason}, S} - end; - -handle_info(T, S) -> - handle_info(T, upgrade(S)). + end. %% transition/2 @@ -576,9 +554,9 @@ transition({reconnect, Pid}, S) -> ok; %% Watchdog is sending notification of a state transition. Note that -%% the connection_up/down messages are pre-date this message and are -%% still used. A watchdog message will follow these and communicate -%% the same state as was set in handling connection_up/down. +%% the connection_up/down messages pre-date this message and are still +%% used. A watchdog message will follow these and communicate the same +%% state as was set in handling connection_up/down. transition({watchdog, Pid, {TPid, From, To}}, #state{service_name = SvcName, peerT = PeerT}) -> #peer{ref = Ref, type = T, options = Opts, op_state = {OS,_}} @@ -643,39 +621,10 @@ transition({failover, TRef, Seqs}, S) -> failover(TRef, Seqs, S), ok; -%% Ensure upgraded state is stored in state table. -transition(upgrade, _) -> - ok; - transition(Req, S) -> unexpected(handle_info, [Req], S), ok. -%% upgrade/1 - -upgrade({state, Id, Svc, Name, Svc, PT, CT, SB, UB, SD, LD, MPid}) -> - S = #state{id = Id, - service_name = Name, - service = Svc, - peerT = PT, - connT = CT, - shared_peers = SD, - local_peers = LD, - monitor = MPid, - options = [{sequence, ?NOMASK}, - {share_peers, SB}, - {use_shared_peers, UB}, - {restrict_connections, ?RESTRICT}]}, - upgrade_insert(S), - S. - -upgrade_insert(#state{service = #diameter_service{pid = Pid}} = S) -> - if Pid == self() -> - ets:insert(?STATE_TABLE, S); - true -> - Pid ! upgrade - end. - %%% --------------------------------------------------------------------------- %%% # terminate(Reason, State) %%% --------------------------------------------------------------------------- @@ -859,10 +808,10 @@ i(SvcName) -> true = ets:insert_new(?STATE_TABLE, S), %% Start fsms for each transport. + send_event(SvcName, start), lists:foreach(fun(T) -> start_fsm(T,S) end, CL), init_shared(S), - send_event(SvcName, start), S. cfg_acc({SvcName, #diameter_service{applications = Apps} = Rec, Opts}, @@ -944,6 +893,7 @@ type(connect = T) -> T. start(Ref, Type, Opts, #state{peerT = PeerT, connT = ConnT, + options = SvcOpts, service_name = SvcName, service = Svc}) when Type == connect; @@ -951,6 +901,7 @@ start(Ref, Type, Opts, #state{peerT = PeerT, Pid = s(Type, Ref, {ConnT, Opts, SvcName, + SvcOpts, merge_service(Opts, Svc)}), insert(PeerT, #peer{pid = Pid, type = Type, @@ -963,13 +914,8 @@ start(Ref, Type, Opts, #state{peerT = PeerT, %% record is what is passed back into application callbacks. s(Type, Ref, T) -> - case diameter_watchdog:start({Type, Ref}, T) of - {_MRef, Pid} -> - Pid; - Pid when is_pid(Pid) -> %% from old code - erlang:monitor(process, Pid), - Pid - end. + {_MRef, Pid} = diameter_watchdog:start({Type, Ref}, T), + Pid. %% merge_service/2 @@ -1116,12 +1062,7 @@ init_conn(Id, Alias, {TPid, _} = TC, {SvcName, Apps}) -> %% find_app/2 find_app(Alias, Apps) -> - case lists:keyfind(Alias, #diameter_app.alias, Apps) of - #diameter_app{options = E} = A when is_atom(E) -> %% upgrade - A#diameter_app{options = [{answer_errors, E}]}; - A -> - A - end. + lists:keyfind(Alias, #diameter_app.alias, Apps). %% Don't bring down the service (and all associated connections) %% regardless of what happens. @@ -1457,7 +1398,7 @@ make_prepare_packet(Mask, #diameter_packet{header = Hdr} = Pkt) -> make_prepare_packet(Mask, Msg) -> make_prepare_packet(Mask, #diameter_packet{msg = Msg}). -%% make_prepare_header/1 +%% make_prepare_header/2 make_prepare_header(Mask, undefined) -> Seq = diameter_session:sequence(Mask), @@ -1465,10 +1406,11 @@ make_prepare_header(Mask, undefined) -> hop_by_hop_id = Seq}); make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined, - hop_by_hop_id = undefined}) -> + hop_by_hop_id = undefined} + = H) -> Seq = diameter_session:sequence(Mask), - make_prepare_header(#diameter_header{end_to_end_id = Seq, - hop_by_hop_id = Seq}); + make_prepare_header(H#diameter_header{end_to_end_id = Seq, + hop_by_hop_id = Seq}); make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined} = H) -> Seq = diameter_session:sequence(Mask), @@ -1703,16 +1645,20 @@ send(Pid, Pkt) -> %% retransmit/4 retransmit({TPid, Caps, #diameter_app{alias = Alias} = App} = T, - #request{app = Alias, packet = Pkt} + #request{app = Alias, packet = Pkt0} = Req, SvcName, Timeout) -> - have_request(Pkt, TPid) %% Don't failover to a peer we've + have_request(Pkt0, TPid) %% Don't failover to a peer we've andalso ?THROW(timeout), %% already sent to. + #diameter_packet{header = Hdr0} = Pkt0, + Hdr = Hdr0#diameter_header{is_retransmitted = true}, + Pkt = Pkt0#diameter_packet{header = Hdr}, + resend_req(cb(App, prepare_retransmit, [Pkt, SvcName, {TPid, Caps}]), T, - Req, + Req#request{packet = Pkt}, Timeout, []). @@ -1814,9 +1760,6 @@ request_peer_down(TPid, S) -> %%% recv_request/3 %%% --------------------------------------------------------------------------- -recv_request(TPid, Pkt, {ConnT, SvcName, Apps}) -> %% upgrade - recv_request(TPid, Pkt, {ConnT, SvcName, Apps, ?NOMASK}); - recv_request(TPid, Pkt, {ConnT, SvcName, Apps, Mask}) -> try ets:lookup(ConnT, TPid) of [C] -> @@ -2049,15 +1992,21 @@ request_cb({eval_packet, RC, F}, App, Mask, T, TC, Fs, Pkt) -> request_cb(RC, App, Mask, T, TC, [F|Fs], Pkt); request_cb({eval, RC, F}, App, Mask, T, TC, Fs, Pkt) -> - request_cb(RC, App, Mask, T, TC, Pkt, Fs), + request_cb(RC, App, Mask, T, TC, Fs, Pkt), diameter_lib:eval(F). %% protocol_error/5 protocol_error(RC, {_, OH, OR}, TPid, Fs, Pkt) -> - #diameter_packet{avps = Avps} = Pkt, + #diameter_packet{avps = Avps, errors = Es} = Pkt, ?LOG({error, RC}, Pkt), - reply(answer_message({OH, OR, RC}, Avps), ?BASE, TPid, Fs, Pkt). + reply(answer_message({OH, OR, RC}, Avps), + ?BASE, + TPid, + Fs, + Pkt#diameter_packet{errors = [RC | Es]}). +%% Note that reply/5 may set the result code once more. It's set in +%% answer_message/2 in case reply/5 doesn't. %% protocol_error/4 @@ -2170,7 +2119,8 @@ is_loop(Code, Vid, OH, Avps) -> %% %% Send a locally originating reply. -%% Skip the setting of Result-Code and Failed-AVP's below. +%% Skip the setting of Result-Code and Failed-AVP's below. This is +%% currently undocumented. reply([Msg], Dict, TPid, Fs, Pkt) when is_list(Msg); is_tuple(Msg) -> @@ -2238,6 +2188,9 @@ rc(RC) -> %% rc/4 +rc(#diameter_packet{msg = Rec} = Pkt, RC, Failed, Dict) -> + Pkt#diameter_packet{msg = rc(Rec, RC, Failed, Dict)}; + rc(Rec, RC, Failed, Dict) when is_integer(RC) -> set(Rec, |