Skip to content

Commit

Permalink
return proper sender TEID when rejecting new sessions
Browse files Browse the repository at this point in the history
Make sure to return a proper TEID when rejecting new sessions due to an internal block
(accept_new == false).

Fixes #322
  • Loading branch information
RoadRunnr committed Feb 25, 2021
1 parent d71b404 commit 09bd8e6
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 15 deletions.
14 changes: 8 additions & 6 deletions src/gtp_context.erl
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,15 @@ port_message(#request{socket = Socket, info = Info} = Request,
case get_handler_if(Socket, Msg) of
{ok, Interface, InterfaceOpts} ->
case ergw:get_accept_new() of
true -> ok;
true ->
validate_teid(Msg),
Server = context_new(Socket, Info, Version, Interface, InterfaceOpts),
port_message(Server, Request, Msg, false);

_ ->
throw({error, no_resources_available})
end,
validate_teid(Msg),
Server = context_new(Socket, Info, Version, Interface, InterfaceOpts),
port_message(Server, Request, Msg, false);
gtp_context:generic_error(Request, Msg, no_resources_available),
ok
end;

{error, _} = Error ->
throw(Error)
Expand Down
4 changes: 4 additions & 0 deletions src/gtp_v1_c.erl
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ load_class(#gtp{type = g_pdu}) ->
load_class(_) ->
other.

find_sender_teid(#gtp{
ie = #{{tunnel_endpoint_identifier_control_plane,0} :=
#tunnel_endpoint_identifier_control_plane{tei = TEID}}}) ->
TEID;
find_sender_teid(_) ->
undefined.

Expand Down
10 changes: 9 additions & 1 deletion test/ergw_ggsn_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -469,14 +469,22 @@ validate_response(create_pdp_context_request, overload, Response, GtpC) ->
validate_seq_no(Response, GtpC),

%% this is debatable, but decoding the request would require even more resources.
%% validate_teid(Response, GtpC),
validate_teid(Response, 0),

?match(#gtp{type = create_pdp_context_response,
ie = #{{cause,0} := #cause{value = no_resources_available}}},
Response),
GtpC;

validate_response(create_pdp_context_request, reject_new, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),

?match(#gtp{type = create_pdp_context_response,
ie = #{{cause,0} := #cause{value = no_resources_available}}},
Response),
GtpC;

validate_response(create_pdp_context_request, no_resources_available, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),
Expand Down
31 changes: 28 additions & 3 deletions test/ergw_pgw_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,21 @@ make_request(echo_request, _SubType,
#gtp{version = v2, type = echo_request, tei = undefined,
seq_no = SeqNo, ie = IEs};

make_request(create_session_request, missing_ie,
make_request(create_session_request, missing_sender_teid,
#gtpc{restart_counter = RCnt, seq_no = SeqNo}) ->
IEs = [#v2_recovery{restart_counter = RCnt}],
#gtp{version = v2, type = create_session_request, tei = 0,
seq_no = SeqNo, ie = IEs};

make_request(create_session_request, missing_ie,
#gtpc{restart_counter = RCnt, seq_no = SeqNo,
local_ip = LocalIP,
local_control_tei = LocalCntlTEI}) ->
IEs = [#v2_recovery{restart_counter = RCnt},
fq_teid(0, ?'S5/S8-C SGW', LocalCntlTEI, LocalIP)],
#gtp{version = v2, type = create_session_request, tei = 0,
seq_no = SeqNo, ie = IEs};

make_request(create_session_request, SubType,
#gtpc{restart_counter = RCnt, seq_no = SeqNo,
local_ip = LocalIP,
Expand Down Expand Up @@ -814,14 +823,22 @@ validate_response(_Type, invalid_teid, Response, GtpC) ->
}, Response),
GtpC;

validate_response(create_session_request, missing_ie, Response, GtpC) ->
validate_response(create_session_request, missing_sender_teid, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, 0),
?match(#gtp{type = create_session_response,
ie = #{{v2_cause,0} := #v2_cause{v2_cause = mandatory_ie_missing}}},
Response),
GtpC;

validate_response(create_session_request, missing_ie, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),
?match(#gtp{type = create_session_response,
ie = #{{v2_cause,0} := #v2_cause{v2_cause = mandatory_ie_missing}}},
Response),
GtpC;

validate_response(create_session_request, aaa_reject, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),
Expand All @@ -840,14 +857,22 @@ validate_response(create_session_request, overload, Response, GtpC) ->
validate_seq_no(Response, GtpC),

%% this is debatable, but decoding the request would require even more resources.
%% validate_teid(Response, GtpC),
validate_teid(Response, 0),

?match(#gtp{type = create_session_response,
ie = #{{v2_cause,0} := #v2_cause{v2_cause = no_resources_available}}},
Response),
GtpC;

validate_response(create_session_request, reject_new, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),

?match(#gtp{type = create_session_response,
ie = #{{v2_cause,0} := #v2_cause{v2_cause = no_resources_available}}},
Response),
GtpC;

validate_response(create_session_request, no_resources_available, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),
Expand Down
9 changes: 9 additions & 0 deletions test/ergw_saegw_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,15 @@ validate_response(create_session_request, overload, Response, GtpC) ->
Response),
GtpC;

validate_response(create_session_request, reject_new, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),

?match(#gtp{type = create_session_response,
ie = #{{v2_cause,0} := #v2_cause{v2_cause = no_resources_available}}},
Response),
GtpC;

validate_response(create_session_request, invalid_apn, Response, GtpC) ->
validate_seq_no(Response, GtpC),
validate_teid(Response, GtpC),
Expand Down
2 changes: 1 addition & 1 deletion test/ggsn_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ create_pdp_context_request_accept_new() ->
[{doc, "Check the accept_new = false can block new contexts"}].
create_pdp_context_request_accept_new(Config) ->
?equal(ergw:system_info(accept_new, false), true),
create_pdp_context(overload, Config),
create_pdp_context(reject_new, Config),
?equal(ergw:system_info(accept_new, true), false),

?equal([], outstanding_requests()),
Expand Down
2 changes: 1 addition & 1 deletion test/ggsn_proxy_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ create_pdp_context_request_accept_new() ->
[{doc, "Check the accept_new = false can block new connections"}].
create_pdp_context_request_accept_new(Config) ->
?equal(ergw:system_info(accept_new, false), true),
create_pdp_context(overload, Config),
create_pdp_context(reject_new, Config),
?equal(ergw:system_info(accept_new, true), false),

?equal([], outstanding_requests()),
Expand Down
12 changes: 11 additions & 1 deletion test/pgw_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ common() ->
[invalid_gtp_pdu,
invalid_gtp_version,
apn_lookup,
create_session_request_missing_sender_teid,
create_session_request_missing_ie,
create_session_request_aaa_reject,
create_session_request_gx_fail,
Expand Down Expand Up @@ -1032,6 +1033,15 @@ invalid_gtp_version(Config) ->
meck_validate(Config),
ok.

%%--------------------------------------------------------------------
create_session_request_missing_sender_teid() ->
[{doc, "Check that Create Session Request IE validation works"}].
create_session_request_missing_sender_teid(Config) ->
create_session(missing_sender_teid, Config),

meck_validate(Config),
ok.

%%--------------------------------------------------------------------
create_session_request_missing_ie() ->
[{doc, "Check that Create Session Request IE validation works"}].
Expand Down Expand Up @@ -1170,7 +1180,7 @@ create_session_request_accept_new() ->
[{doc, "Check the accept_new = false can block new session"}].
create_session_request_accept_new(Config) ->
?equal(ergw:system_info(accept_new, false), true),
create_session(overload, Config),
create_session(reject_new, Config),
?equal(ergw:system_info(accept_new, true), false),

meck_validate(Config),
Expand Down
2 changes: 1 addition & 1 deletion test/pgw_proxy_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ create_session_request_accept_new() ->
[{doc, "Check the accept_new = false can block new session"}].
create_session_request_accept_new(Config) ->
?equal(ergw:system_info(accept_new, false), true),
create_session(overload, Config),
create_session(reject_new, Config),
?equal(ergw:system_info(accept_new, true), false),

?equal([], outstanding_requests()),
Expand Down
2 changes: 1 addition & 1 deletion test/saegw_s11_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ create_session_request_accept_new() ->
[{doc, "Check the accept_new = false can block new session"}].
create_session_request_accept_new(Config) ->
?equal(ergw:system_info(accept_new, false), true),
create_session(overload, Config),
create_session(reject_new, Config),
?equal(ergw:system_info(accept_new, true), false),

meck_validate(Config),
Expand Down

0 comments on commit 09bd8e6

Please sign in to comment.