From 09bd8e6f373f8427c2128a621fb63c73fd967186 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Thu, 25 Feb 2021 11:58:08 +0100 Subject: [PATCH] return proper sender TEID when rejecting new sessions Make sure to return a proper TEID when rejecting new sessions due to an internal block (accept_new == false). Fixes #322 --- src/gtp_context.erl | 14 ++++++++------ src/gtp_v1_c.erl | 4 ++++ test/ergw_ggsn_test_lib.erl | 10 +++++++++- test/ergw_pgw_test_lib.erl | 31 ++++++++++++++++++++++++++++--- test/ergw_saegw_test_lib.erl | 9 +++++++++ test/ggsn_SUITE.erl | 2 +- test/ggsn_proxy_SUITE.erl | 2 +- test/pgw_SUITE.erl | 12 +++++++++++- test/pgw_proxy_SUITE.erl | 2 +- test/saegw_s11_SUITE.erl | 2 +- 10 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/gtp_context.erl b/src/gtp_context.erl index 3adaa342..ccba2ebe 100644 --- a/src/gtp_context.erl +++ b/src/gtp_context.erl @@ -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) diff --git a/src/gtp_v1_c.erl b/src/gtp_v1_c.erl index 242cd12f..7ad5f65f 100644 --- a/src/gtp_v1_c.erl +++ b/src/gtp_v1_c.erl @@ -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. diff --git a/test/ergw_ggsn_test_lib.erl b/test/ergw_ggsn_test_lib.erl index cef62061..c7ba41f1 100644 --- a/test/ergw_ggsn_test_lib.erl +++ b/test/ergw_ggsn_test_lib.erl @@ -469,7 +469,6 @@ 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, @@ -477,6 +476,15 @@ validate_response(create_pdp_context_request, overload, Response, GtpC) -> 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), diff --git a/test/ergw_pgw_test_lib.erl b/test/ergw_pgw_test_lib.erl index 514b1593..cf314007 100644 --- a/test/ergw_pgw_test_lib.erl +++ b/test/ergw_pgw_test_lib.erl @@ -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, @@ -814,7 +823,7 @@ 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, @@ -822,6 +831,14 @@ validate_response(create_session_request, missing_ie, Response, GtpC) -> 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), @@ -840,7 +857,6 @@ 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, @@ -848,6 +864,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, no_resources_available, Response, GtpC) -> validate_seq_no(Response, GtpC), validate_teid(Response, GtpC), diff --git a/test/ergw_saegw_test_lib.erl b/test/ergw_saegw_test_lib.erl index 6d130096..e3aa15a7 100644 --- a/test/ergw_saegw_test_lib.erl +++ b/test/ergw_saegw_test_lib.erl @@ -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), diff --git a/test/ggsn_SUITE.erl b/test/ggsn_SUITE.erl index d54f12f8..fe295e87 100644 --- a/test/ggsn_SUITE.erl +++ b/test/ggsn_SUITE.erl @@ -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()), diff --git a/test/ggsn_proxy_SUITE.erl b/test/ggsn_proxy_SUITE.erl index 606362b2..b4d04603 100644 --- a/test/ggsn_proxy_SUITE.erl +++ b/test/ggsn_proxy_SUITE.erl @@ -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()), diff --git a/test/pgw_SUITE.erl b/test/pgw_SUITE.erl index 02fdcfb8..5939e150 100644 --- a/test/pgw_SUITE.erl +++ b/test/pgw_SUITE.erl @@ -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, @@ -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"}]. @@ -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), diff --git a/test/pgw_proxy_SUITE.erl b/test/pgw_proxy_SUITE.erl index 6d631e58..3aeee313 100644 --- a/test/pgw_proxy_SUITE.erl +++ b/test/pgw_proxy_SUITE.erl @@ -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()), diff --git a/test/saegw_s11_SUITE.erl b/test/saegw_s11_SUITE.erl index 5e66147e..88afa73c 100644 --- a/test/saegw_s11_SUITE.erl +++ b/test/saegw_s11_SUITE.erl @@ -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),