pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36308?usp=email )
Change subject: Propagate SWx PPR as S6b Re-Auth-Request ......................................................................
Propagate SWx PPR as S6b Re-Auth-Request
This commit implements the 3GPP TS 29.273 section 9.1.2.5 "Service Authorization Information Update Procedures".
Related: OS#6400 Change-Id: I0e263dae37d5b8b3cdce2014787eb82910ed686a --- M src/aaa_diameter_s6b.erl M src/aaa_diameter_s6b_cb.erl M src/aaa_ue_fsm.erl 3 files changed, 80 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/08/36308/1
diff --git a/src/aaa_diameter_s6b.erl b/src/aaa_diameter_s6b.erl index f8f9027..1639d02 100644 --- a/src/aaa_diameter_s6b.erl +++ b/src/aaa_diameter_s6b.erl @@ -49,7 +49,7 @@ %% gen_server Function Exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, peer_down/3]). -export([code_change/3]). --export([tx_as_request/1]). +-export([tx_reauth_request/1, tx_as_request/1]). -export([tx_aa_answer/2, tx_st_answer/2]).
%% Diameter Application Definitions @@ -138,9 +138,30 @@ % handle_request(STR) was spawned into its own process, and it's blocked waiting for STA: Pid ! {sta, DiaRC}.
+tx_reauth_request(NAI) -> + gen_server:call(?SERVER, {rar, NAI}). + tx_as_request(NAI) -> gen_server:call(?SERVER, {asr, NAI}).
+handle_call({rar, NAI}, _From, State) -> + lager:debug("S6b Tx RAR NAI=~p~n", [NAI]), + SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, dia_s6b_origin_host, ?ENV_DEFAULT_ORIG_HOST)), + RAR = #'RAR'{'Session-Id' = SessionId, + 'Auth-Application-Id' = ?DIAMETER_APP_ID_S6b, + 'Re-Auth-Request-Type' = ?'RE-AUTH-REQUEST-TYPE_AUTHORIZE_ONLY', + 'User-Name' = [NAI] + }, + lager:debug("S6b Tx RAR: ~p~n", [RAR]), + Ret = diameter_call(RAR, State), + case Ret of + ok -> + {reply, ok, State}; + {error, Err} -> + lager:error("Error: ~w~n", [Err]), + {reply, {error, Err}, State} + end; + handle_call({asr, NAI}, _From, State) -> lager:debug("S6b Tx ASR NAI=~p~n", [NAI]), SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, dia_s6b_origin_host, ?ENV_DEFAULT_ORIG_HOST)), diff --git a/src/aaa_diameter_s6b_cb.erl b/src/aaa_diameter_s6b_cb.erl index b3f8d5f..8e2bcca 100644 --- a/src/aaa_diameter_s6b_cb.erl +++ b/src/aaa_diameter_s6b_cb.erl @@ -41,6 +41,15 @@ | Avps]}; % TODO: is there a simple way to capture all the following requests? prepare_request(#diameter_packet{msg = Req}, _, {_, Caps}) + when is_record(Req, 'RAR') -> + #diameter_caps{origin_host = {OH, DH}, origin_realm = {OR, DR}} = Caps, + Msg = Req#'RAR'{'Origin-Host' = OH, + 'Origin-Realm' = OR, + 'Destination-Realm' = DR, + 'Destination-Host' = DH}, + lager:debug("S6b prepare_request: ~p~n", [Msg]), + {send, Msg}; +prepare_request(#diameter_packet{msg = Req}, _, {_, Caps}) when is_record(Req, 'ASR') -> #diameter_caps{origin_host = {OH, DH}, origin_realm = {OR, DR}} = Caps, Msg = Req#'ASR'{'Origin-Host' = OH, @@ -134,6 +143,22 @@ erlang:error({unexpected, ?MODULE, ?LINE}).
%% handle_answer/4 +handle_answer(#diameter_packet{msg = Msg, errors = Errors}, Request, _SvcName, Peer) when is_record(Msg, 'RAA') -> + lager:info("S6b Rx RAA ~p: ~p/ Errors ~p ~n", [Peer, Msg, Errors]), + % Obtain Imsi from originating Request: + #'RAR'{'User-Name' = [NAI]} = Request, + Imsi = conv:nai_to_imsi(NAI), + PidRes = aaa_ue_fsm:get_pid_by_imsi(Imsi), + #'RAA'{'Result-Code' = ResultCode} = Msg, + DiaRC = #epdg_dia_rc{result_code = ResultCode}, + case conv:dia_rc_success(DiaRC) of + ok -> + aaa_ue_fsm:ev_rx_s6b_raa(PidRes, ok); + _ -> + aaa_ue_fsm:ev_rx_s6b_raa(PidRes, {error, DiaRC}) + end, + {ok, Msg}; + handle_answer(#diameter_packet{msg = Msg, errors = Errors}, Request, _SvcName, Peer) when is_record(Msg, 'ASA') -> lager:info("S6b Rx ASA ~p: ~p/ Errors ~p ~n", [Peer, Msg, Errors]), % Obtain Imsi from originating Request: diff --git a/src/aaa_ue_fsm.erl b/src/aaa_ue_fsm.erl index b32d6c0..38538b5 100644 --- a/src/aaa_ue_fsm.erl +++ b/src/aaa_ue_fsm.erl @@ -44,7 +44,7 @@ -export([get_server_name_by_imsi/1, get_pid_by_imsi/1]). -export([ev_rx_swm_auth_req/2, ev_rx_swm_reauth_answer/2, ev_rx_swm_auth_compl/2, ev_rx_swm_str/1, ev_rx_swm_asa/1, ev_rx_swx_maa/2, ev_rx_swx_saa/2, ev_rx_swx_ppr/2, ev_rx_swx_rtr/1, - ev_rx_s6b_aar/2, ev_rx_s6b_str/1, ev_rx_s6b_asa/2]). + ev_rx_s6b_aar/2, ev_rx_s6b_str/1, ev_rx_s6b_raa/2, ev_rx_s6b_asa/2]). -export([state_new/3, state_wait_swx_maa/3, state_wait_swx_saa/3, @@ -175,6 +175,15 @@ {error, Err} end.
+ev_rx_s6b_raa(Pid, Result) -> + lager:info("ue_fsm ev_rx_s6b_raa: ~p~n", [Result]), + try + gen_statem:call(Pid, {rx_s6b_raa, Result}) + catch + exit:Err -> + {error, Err} + end. + ev_rx_s6b_asa(Pid, Result) -> lager:info("ue_fsm ev_rx_s6b_asa: ~p~n", [Result]), try @@ -340,16 +349,22 @@ %% After a successful user profile download, the 3GPP AAA Server shall %% initiate re-authentication procedure as described %% in clause 7.2.2.4 - case aaa_diameter_swm:tx_reauth_request(Data#ue_fsm_data.imsi) of - ok -> {keep_state, Data, [{reply,From,ok}]}; - {error, Err} -> {keep_state, Data, [{reply,From,{error, Err}}]} - end; + aaa_diameter_swm:tx_reauth_request(Data#ue_fsm_data.imsi), + aaa_diameter_s6b:tx_reauth_request(Data#ue_fsm_data.nai), + %% Following a successful download of subscription and equipment trace data, the 3GPP AAA Server shall forward the + %% trace data by initiating reauthorization towards all PDN GWs that have an active authorization session. + {keep_state, Data, [{reply,From,ok}]};
state_authenticated({call, From}, {rx_swm_reauth_answer, Result}, Data) -> lager:info("ue_fsm state_authenticated event=rx_swm_reauth_answer ~p, ~p~n", [Result, Data]), %% SWx PPA was already answered immediately when PPR was received, nothing to do here. {keep_state, Data, [{reply,From,ok}]};
+state_authenticated({call, From}, {rx_s6b_raa, Result}, Data) -> + lager:info("ue_fsm state_authenticated event=rx_s6b_raa ~p, ~p~n", [Result, Data]), + %% SWx PPA was already answered immediately when PPR was received, nothing to do here. + {keep_state, Data, [{reply,From,ok}]}; + state_authenticated({call, From}, rx_swx_rtr, Data) -> lager:info("ue_fsm state_authenticated event=rx_swx_rtr ~p~n", [Data]), case {Data#ue_fsm_data.pgw_sess_active, Data#ue_fsm_data.epdg_sess_active} of