Project

General

Profile

Actions

Bug #6399

closed

osmo-epdg: S6b ASR encoding fails

Added by pespin about 1 month ago. Updated about 1 month ago.

Status:
Resolved
Priority:
Normal
Assignee:
Target version:
-
Start date:
03/13/2024
Due date:
% Done:

100%


Description

I couldn't figure out yet why encoding the following message fails when running test EPDG_Tests.TC_hss_initiated_deregister_permanent_termination:

18:15:53.642 [debug] S6b Tx ASR: {'ASR',["aaa.localdomain",";","1771858795",";","30",";","nonode@nohost"],undefined,undefined,undefined,undefined,16777272,"262422638508077",1,[]}
18:15:53.642 [debug] S6b prepare_request: {'ASR',["aaa.localdomain",";","1771858795",";","30",";","nonode@nohost"],"aaa.localdomain","localdomain","localdomain","pgw.localdomain",16777272,"262422638508077",1,[]}
18:15:53.643 [error] Error: encode

The procedure is introduced here: https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36262
Grep for "handle_call({asr, Imsi}, _From, State)" in src/aaa_diameter_s6b.erl.

Actions #1

Updated by pespin about 1 month ago

  • Subject changed from S6b ASR encoding fails to osmo-epdg: S6b ASR encoding fails
Actions #2

Updated by pespin about 1 month ago

  • Status changed from Feedback to Resolved
  • % Done changed from 0 to 100

I added a test function reproducing the issue:

+foobar() ->
+    State = #s6b_state{tx_timeout = 10000},
+    Imsi = "262422638508077",
+    SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, dia_s6b_origin_host, ?ENV_DEFAULT_ORIG_HOST)),
+    ASR = #'ASR'{'Session-Id' = SessionId,
+                 'Auth-Application-Id' = ?DIAMETER_APP_ID_S6b,
+                 'User-Name' = Imsi,
+                 'Auth-Session-State' = ?'AUTH-SESSION-STATE_NO_STATE_MAINTAINED'
+                },
+    lager:debug("S6b Tx ASR: ~p~n", [ASR]),
+    Ret = diameter_call(ASR, State),
+    ok = Ret.

I traced the problem by using the following commands in the shell:

erlang:trace(all, true, [call]).
erlang:trace_pattern({aaa_diameter_s6b, 'foobar', '_'}, true, [local]).
erlang:trace_pattern({aaa_diameter_s6b, '_', '_'}, [{'_', [], [{return_trace}]}], [local]).
erlang:trace_pattern({diameter, '_', '_'}, true, [local]).
erlang:trace_pattern({diameter, '_', '_'}, [{'_', [], [{return_trace}]}], [local]).
erlang:trace_pattern({diameter_codec, '_', '_'}, true, [local]).
erlang:trace_pattern({diameter_codec, '_', '_'}, [{'_', [], [{return_trace}]}], [local]).
erlang:trace_pattern({diameter_traffic, '_', '_'}, true, [local]).
erlang:trace_pattern({diameter_traffic, '_', '_'}, [{'_', [], [{return_trace}]}], [local]).
erlang:trace_pattern({diameter_types, 'UTF8String', '_'}, true, [local]).
erlang:trace_pattern({diameter_types, 'UTF8String', '_'}, [{'_', [], [{return_trace}]}], [local]).
erlang:trace_pattern({diameter_gen, 'enc1', '_'}, true, [local]).
erlang:trace_pattern({diameter_gen, 'enc1', '_'}, [{'_', [], [{return_trace}]}], [local]).
spawn(fun() -> aaa_diameter_s6b:foobar() end).

Then I use "flush()." to see the output of the trace.
Interesting parts here:

Shell got {trace,<0.546.0>,call,
                 {diameter_gen,enc1,
                               ['User-Name',
                                {1,64,undefined},
                                50,
                                #{decode_format => record,
                                  incoming_maxlen => 16777215,
                                  module => diameter_3gpp_ts29_273_s6b,
                                  restrict_connections => nodes,
                                  sequence => {0,32},
                                  share_peers => false,spawn_opt => [],
                                  strict_mbit => true,string_decode => true,
                                  traffic_counters => true,
                                  use_shared_peers => false},
                                diameter_3gpp_ts29_273_s6b]}}
Shell got {trace,<0.546.0>,call,
                 {diameter_types,'UTF8String',
                                 [encode,50,
                                  #{decode_format => record,
                                    incoming_maxlen => 16777215,
                                    module => diameter_gen_base_rfc6733,
                                    restrict_connections => nodes,
                                    sequence => {0,32},
                                    share_peers => false,spawn_opt => [],
                                    strict_mbit => true,string_decode => true,
                                    traffic_counters => true,
                                    use_shared_peers => false}]}}
Shell got {trace,<0.546.0>,call,
              {diameter_traffic,incr_error,
                  [send,
                   {{encode_failure,badarg,'ASR',
                        [{unicode,characters_to_binary,"2",
                             [{file,"unicode.erl"},
                              {line,895},
                              {error_info,#{module => erl_stdlib_errors}}]},
                         {diameter_types,'UTF8String',3,
                             [{file,"base/diameter_types.erl"},{line,363}]},
                         {diameter_gen,enc1,5,
                             [{file,"base/diameter_gen.erl"},{line,189}]},
                         {diameter_gen,enc,9,
                             [{file,"base/diameter_gen.erl"},{line,167}]},
                         {diameter_gen,'-encode/5-lc$^3/1-3-',5,
                             [{file,"base/diameter_gen.erl"},{line,106}]},
                         {diameter_gen,'-encode/5-lc$^3/1-3-',5,
                             [{file,"base/diameter_gen.erl"},{line,106}]},
                         {diameter_gen,encode_avps,3,
                             [{file,"base/diameter_gen.erl"},{line,71}]},
                         {diameter_codec,enc,3,
                             [{file,"base/diameter_codec.erl"},{line,161}]}]},
                    [{diameter_gen,encode_avps,3,
                         [{file,"base/diameter_gen.erl"},{line,84}]},
                     {diameter_codec,enc,3,
                         [{file,"base/diameter_codec.erl"},{line,161}]},
                     {diameter_codec,encode,3,
                         [{file,"base/diameter_codec.erl"},{line,88}]},
                     {diameter_traffic,encode,4,
                         [{file,"base/diameter_traffic.erl"},{line,1823}]},
                     {diameter_traffic,send_request,6,
                         [{file,"base/diameter_traffic.erl"},{line,1459}]},
                     {diameter_traffic,'-send_request/4-fun-0-',6,
                         [{file,"base/diameter_traffic.erl"},{line,1342}]}],
                    {diameter_header,1,undefined,274,16777272,3213723902,
                        3213723902,true,true,false,false}},
                   <0.508.0>,diameter_3gpp_ts29_273_s6b]}}

Fixed with:

diff --git a/src/aaa_diameter_s6b.erl b/src/aaa_diameter_s6b.erl
index c9afc37..94b4aea 100644
--- a/src/aaa_diameter_s6b.erl
+++ b/src/aaa_diameter_s6b.erl
@@ -146,8 +148,8 @@ handle_call({asr, Imsi}, _From, State) ->
     SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, dia_s6b_origin_host, ?ENV_DEFAULT_ORIG_HOST)),
     ASR = #'ASR'{'Session-Id' = SessionId,
                  'Auth-Application-Id' = ?DIAMETER_APP_ID_S6b,
-                 'User-Name' = Imsi,
-                 'Auth-Session-State' = ?'AUTH-SESSION-STATE_NO_STATE_MAINTAINED'
+                 'User-Name' = [Imsi],
+                 'Auth-Session-State' = [?'AUTH-SESSION-STATE_NO_STATE_MAINTAINED']

So it seems if I don't pass Imsi inside the "optional" array, then since Imsi itself is an aray of characters, the string is discarded and the first character taken instead of the full string. Then "diameter_types:'UTF8String'()" fails to convert an integer/character to binary.

Actions

Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)