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/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index b042baf..81bda76 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -1764,12 +1764,22 @@
 }
 
 /* VLR informs us that the subscriber has been associated with a conn */
-static void msc_vlr_subscr_assoc(void *msc_conn_ref,
+static int msc_vlr_subscr_assoc(void *msc_conn_ref,
 				 struct vlr_subscr *vsub)
 {
 	struct ran_conn *conn = msc_conn_ref;
 	OSMO_ASSERT(vsub);
-	OSMO_ASSERT(!conn->vsub);
+	if (conn->vsub) {
+		if (conn->vsub == vsub)
+			LOGPCONN(conn, LOGL_NOTICE, "msc_vlr_subscr_assoc(): conn already associated with %s\n",
+				 vlr_subscr_name(vsub));
+		else {
+			LOGPCONN(conn, LOGL_ERROR, "msc_vlr_subscr_assoc(): conn already associated with a subscriber,"
+				 " cannot associate with %s\n", vlr_subscr_name(vsub));
+			return -EINVAL;
+		}
+	}
+
 	conn->vsub = vlr_subscr_get(vsub);
 	OSMO_ASSERT(conn->vsub);
 	conn->vsub->cs.attached_via_ran = conn->via_ran;
@@ -1778,6 +1788,7 @@
 	 * 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);
+	return 0;
 }
 
 static int msc_vlr_route_gsup_msg(struct vlr_subscr *vsub,