fix vlr ops.subscr_assoc re-association
In rare cases, a conn is already associated with a subscriber. So far, we
abort()ed on that, bringing the entire osmo-msc down. Rather log an error and
keep the service running.
In vlr.ops.subscr_assoc, add success/failure return value, and abort the
LU/PARQ on error.
I haven't figured out in detail yet why/how a subscriber would re-launch a
LU/PARQ on a conn that is already associated, so far it is merely clear that we
do not want to crash the MSC if that happens. A log is in OS#3742.
Related: OS#3742, OS#3743
Change-Id: Ic0d54644bc735700220b1ef3a4384c217d57d20f
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
index 3a0760d..3b40285 100644
--- a/src/libvlr/vlr_access_req_fsm.c
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -72,7 +72,7 @@
bool implicitly_accepted_parq_by_ciphering_cmd;
};
-static void assoc_par_with_subscr(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub)
+static int assoc_par_with_subscr(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub)
{
struct proc_arq_priv *par = fi->priv;
struct vlr_instance *vlr = par->vlr;
@@ -81,7 +81,7 @@
par->vsub = vsub;
/* Tell MSC to associate this subscriber with the given
* connection */
- vlr->ops.subscr_assoc(par->msc_conn_ref, par->vsub);
+ return vlr->ops.subscr_assoc(par->msc_conn_ref, par->vsub);
}
static const char *vlr_proc_arq_result_name(const struct osmo_fsm_inst *fi)
@@ -371,8 +371,10 @@
GSM48_REJECT_NETWORK_FAILURE);
}
vsub->proc_arq_fsm = fi;
- assoc_par_with_subscr(fi, vsub);
- proc_arq_vlr_fn_post_imsi(fi);
+ if (assoc_par_with_subscr(fi, vsub) != 0)
+ proc_arq_fsm_done(fi, GSM48_REJECT_NETWORK_FAILURE);
+ else
+ proc_arq_vlr_fn_post_imsi(fi);
vlr_subscr_put(vsub);
return;
}
@@ -414,8 +416,10 @@
proc_arq_fsm_done(fi, GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
return;
}
- assoc_par_with_subscr(fi, vsub);
- proc_arq_vlr_fn_post_imsi(fi);
+ if (assoc_par_with_subscr(fi, vsub))
+ proc_arq_fsm_done(fi, GSM48_REJECT_NETWORK_FAILURE);
+ else
+ proc_arq_vlr_fn_post_imsi(fi);
vlr_subscr_put(vsub);
}