laforge submitted this change.
rua: validate correct RUA ctx state per RUA message type
It helps in a pretty complex situation seen in the field.
A third-party MSC releases SCCP in one fell swoop, not waiting for the
Iu Release Complete to come back from RAN as the specs would suggest.
The result is this odd sequence, where late rx of RUA Disconnect
actually causes a new SCCP connection to be established and torn down
again:
RAN HNBGW MSC
|--active-RUA-ctx----|--active-sccp------|
| |<--IU-Release-Cmd--|
|<--IU-Release-Cmd---| |
| |<--SCCP-RLSD-------| (too soon)
|...<-RUA-Disconnect-| x (the consequence)
| x
|--RUA-Disconnect--->| (IU Release Complete)
x <create-new-ctx>
|-SCCP-CR---------->|
|-IU-Release-Compl->|
|<--CREF------------|
x x
This patch is a relatively simple practical improvement of above
situation that is logically obvious:
Validate the correct message type for creating a new RUA-to-SCCP
context: RUA Connect.
That means the IU Release Complete is ignored:
RAN HNBGW MSC
|--active-RUA-ctx----|--active-sccp------|
| |<--IU-Release-Cmd--|
|<--IU-Release-Cmd---| |
| |<--SCCP-RLSD-------| (too soon)
|...<-RUA-Disconnect-| x (the consequence)
| x
|--RUA-Disconnect--->| (IU Release Complete)
x <error>
x
Related: SYS#6602
Change-Id: Ie359fcada98fb19f56015cf462e6d8c039f5fce5
---
M src/osmo-hnbgw/hnbgw_rua.c
1 file changed, 82 insertions(+), 14 deletions(-)
diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c
index 073f3ce..84bd817 100644
--- a/src/osmo-hnbgw/hnbgw_rua.c
+++ b/src/osmo-hnbgw/hnbgw_rua.c
@@ -179,18 +179,12 @@
return get_value_string(rua_procedure_code_names, val);
}
-static struct hnbgw_context_map *find_or_create_context_map(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps,
- struct msgb *ranap_msg)
+static struct hnbgw_context_map *create_context_map(struct hnb_context *hnb, uint32_t rua_ctx_id, bool is_ps,
+ struct msgb *ranap_msg)
{
struct hnbgw_context_map *map;
struct hnbgw_cnlink *cnlink;
- map = context_map_find_by_rua_ctx_id(hnb, rua_ctx_id, is_ps);
- if (map) {
- /* Already established SCCP link. Continue to use that. */
- return map;
- }
-
/* Establish a new context map. From the RUA Connect, extract a mobile identity, if any, and select a CN link
* based on an NRI found in the mobile identity, if any. */
@@ -255,12 +249,35 @@
memcpy(ranap_msg->l2h, data, len);
}
- map = find_or_create_context_map(hnb, context_id, is_ps, ranap_msg);
- if (!map) {
- LOGHNB(hnb, DRUA, LOGL_ERROR,
- "Failed to create context map for %s: rx RUA %s with %u bytes RANAP data\n",
- is_ps ? "IuPS" : "IuCS", rua_procedure_code_name(rua_procedure), data ? len : 0);
- return -1;
+ map = context_map_find_by_rua_ctx_id(hnb, context_id, is_ps);
+
+ switch (rua_procedure) {
+ case RUA_ProcedureCode_id_Connect:
+ /* A Connect message can only be the first message for an unused RUA context */
+ if (map) {
+ /* Already established this RUA context. But then how can it be a Connect message. */
+ LOGHNB(hnb, DRUA, LOGL_ERROR, "rx RUA %s for already active RUA context %u\n",
+ rua_procedure_code_name(rua_procedure), context_id);
+ return -EINVAL;
+ }
+ /* ok, this RUA context does not exist yet, so create one. */
+ map = create_context_map(hnb, context_id, is_ps, ranap_msg);
+ if (!map) {
+ LOGHNB(hnb, DRUA, LOGL_ERROR,
+ "Failed to create context map for %s: rx RUA %s with %u bytes RANAP data\n",
+ is_ps ? "IuPS" : "IuCS", rua_procedure_code_name(rua_procedure), data ? len : 0);
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ /* Any message other than Connect must have a valid RUA context */
+ if (!map) {
+ LOGHNB(hnb, DRUA, LOGL_ERROR, "rx RUA %s for unknown RUA context %u\n",
+ rua_procedure_code_name(rua_procedure), context_id);
+ return -EINVAL;
+ }
+ break;
}
LOG_MAP(map, DRUA, LOGL_DEBUG, "rx RUA %s with %u bytes RANAP data\n",
To view, visit change 35329. To unsubscribe, or for help writing mail filters, visit settings.