diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2018-09-18 15:52:58 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2018-09-18 16:13:58 +0200 |
commit | 68cf957bfd8ccee8c82f5328eb7a15aca28cf332 (patch) | |
tree | f5cb8455f8c1739f1d8b941d97028e6df92ca77f /src/libmsc/gsm_04_08.c | |
parent | 3117b701c8d4645215896c459d6c608358a0a51b (diff) |
fix Classmark Update without VLR subscriber
This recent patch moves Classmark storage to the VLR subscriber, and introduced
a segfault when a Classmark Update is received during IMSI detach:
commit 986fe7ed18580775bed91399a1f02eae60bda251
change-id I27081bf6e9e017923b2d02607f7ea06beddad82a
Mon Sep 17 01:12:13 2018 +0200
"store classmark in vlr_subscr, not conn"
It assumed that we would never accept any Classmark Update messages unless we
also have a valid subscriber for it. Well, that is proven wrong by the
ttcn3-msc-test TC_imsi_detach_by_imsi(), which brings osmo-msc to its knees.
Fix: in case of no valid vlr_subscr being present, store Classmark in the conn
temporarily, and copy any received Classmark to VLR subscriber as soon as it
gets associated with the conn (if at all).
Change-Id: Ib2a2ae6bf86e8f29fc6751a8b5cdb7187cd70290
Diffstat (limited to 'src/libmsc/gsm_04_08.c')
-rw-r--r-- | src/libmsc/gsm_04_08.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index 564e90bff..0f52d0939 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -1739,6 +1739,22 @@ static void msc_vlr_subscr_update(struct vlr_subscr *subscr) subscr->imsi, subscr->msisdn, subscr->use_count); } +static void update_classmark(const struct gsm_classmark *src, struct gsm_classmark *dst) +{ + if (src->classmark1_set) { + dst->classmark1 = src->classmark1; + dst->classmark1_set = true; + } + if (src->classmark2_len) { + dst->classmark2_len = src->classmark2_len; + memcpy(dst->classmark2, src->classmark2, sizeof(dst->classmark2)); + } + if (src->classmark3_len) { + dst->classmark3_len = src->classmark3_len; + memcpy(dst->classmark3, src->classmark3, sizeof(dst->classmark3)); + } +} + /* VLR informs us that the subscriber has been associated with a conn */ static void msc_vlr_subscr_assoc(void *msc_conn_ref, struct vlr_subscr *vsub) @@ -1749,6 +1765,11 @@ static void msc_vlr_subscr_assoc(void *msc_conn_ref, conn->vsub = vlr_subscr_get(vsub); OSMO_ASSERT(conn->vsub); conn->vsub->cs.attached_via_ran = conn->via_ran; + + /* In case we have already received Classmark Information before the VLR Subscriber was + * associated with the conn: merge the new Classmark into vsub->classmark. Don't overwrite valid + * vsub->classmark with unset classmark, though. */ + update_classmark(&conn->temporary_classmark, &conn->vsub->classmark); } static int msc_vlr_route_gsup_msg(struct vlr_subscr *vsub, |