aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmsc/msc_mgcp.c
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2018-04-11 17:36:45 +0200
committerPhilipp Maier <pmaier@sysmocom.de>2018-04-11 17:36:45 +0200
commit79beccd93a27796a2ca9be201a5b9cf3695fbf5c (patch)
treeeb448f59b2aba0d372c70c04b046de76299f9771 /src/libmsc/msc_mgcp.c
parentd997fa176d8774863ef6db92b29ea06a1fb8b2d5 (diff)
msc_mgcp: do not send wildcarded DLCX messages
If an error on the MGW side occurs, the MSC may send out a DLCX command that contains a wildcarded endpoint name. Wildcarded DLCX commands are legal in principle but not in the context of an error on a single endpoint. Apart from that osmo-mgw is (not yet) capable to handle wildcarded DLCX command. The problem is caused by a wrong error handling. When the first (RAN) CRCX fails the error handling logic tries to perform a DLCX, but since we did not receive a specific endpoint name yet, the buffer containing the endpoint name is still initalized with the wildcarded enpoint name, but the error handler and the code that generates the DLCX is not aware of that. - Perform a check in the error handler function that checks if a DLCX can be made (a specific endpoint name is set - Correct the flags in the code that handles the first CRCX so that no DLCX is requested in the case of error Related OS#2882 Change-Id: I64c2a82016d854ad446fd49a5d76a28324e8bd4b
Diffstat (limited to 'src/libmsc/msc_mgcp.c')
-rw-r--r--src/libmsc/msc_mgcp.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/libmsc/msc_mgcp.c b/src/libmsc/msc_mgcp.c
index b0c68a564..7c49c6ebc 100644
--- a/src/libmsc/msc_mgcp.c
+++ b/src/libmsc/msc_mgcp.c
@@ -156,6 +156,7 @@ static const struct value_string msc_mgcp_fsm_evt_names[] = {
static void _handle_error(struct mgcp_ctx *mgcp_ctx, enum msc_mgcp_cause_code cause, bool dlcx, const char *file,
int line)
{
+ bool dlcx_possible = true;
struct osmo_fsm_inst *fi;
struct gsm_mncc mncc = {
.msg_type = MNCC_REL_REQ,
@@ -171,6 +172,14 @@ static void _handle_error(struct mgcp_ctx *mgcp_ctx, enum msc_mgcp_cause_code ca
fi = mgcp_ctx->fsm;
OSMO_ASSERT(fi);
+ /* Check if the endpoint identifier is a specific endpoint identifier,
+ * since in order to perform a DLCX we must know the specific
+ * identifier of the endpoint we want to release. If we do not have
+ * this information because of errornous communication we can not
+ * perform a DLCX. */
+ if (strstr(mgcp_ctx->rtp_endpoint, "*"))
+ dlcx_possible = false;
+
LOGPFSMLSRC(mgcp_ctx->fsm, LOGL_ERROR, file, line, "%s -- graceful shutdown...\n",
get_value_string(msc_mgcp_cause_codes_names, cause));
@@ -180,7 +189,7 @@ static void _handle_error(struct mgcp_ctx *mgcp_ctx, enum msc_mgcp_cause_code ca
* where a DLCX does not make sense (e.g. the MGW times out), halting
* directly is the better options. In those cases, the dlcx flag
* should not be set */
- if (dlcx) {
+ if (dlcx && dlcx_possible) {
/* Fast-forward the FSM into call state. In this state the FSM
* expects either an EV_TEARDOWN or an EV_TEARDOWN_ERROR. When
* one of the two events is received a DLCX will be send to
@@ -273,6 +282,10 @@ static void fsm_crcx_ran_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data
mgcp = mgcp_ctx->mgcp;
OSMO_ASSERT(mgcp);
+ /* NOTE: In case of error, we will not be able to perform any DLCX
+ * operation because until this point we do not have requested any
+ * endpoint yet. */
+
LOGPFSML(fi, LOGL_DEBUG,
"CRCX/RAN: creating connection for the RAN side on MGW endpoint:%s...\n", mgcp_ctx->rtp_endpoint);
@@ -285,7 +298,7 @@ static void fsm_crcx_ran_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data
};
if (osmo_strlcpy(mgcp_msg.endpoint, mgcp_ctx->rtp_endpoint, sizeof(mgcp_msg.endpoint)) >=
MGCP_ENDPOINT_MAXLEN) {
- handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, true);
+ handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, false);
return;
}
@@ -296,7 +309,7 @@ static void fsm_crcx_ran_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data
mgcp_ctx->mgw_pending_trans = mgcp_msg_trans_id(msg);
rc = mgcp_client_tx(mgcp, msg, mgw_crcx_ran_resp_cb, mgcp_ctx);
if (rc < 0) {
- handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, true);
+ handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, false);
return;
}
@@ -311,6 +324,13 @@ static void mgw_crcx_ran_resp_cb(struct mgcp_response *r, void *priv)
struct gsm_trans *trans;
struct gsm_subscriber_connection *conn;
+ /* NOTE: In case of error, we will not be able to perform any DLCX
+ * operation because until we either get a parseable message that
+ * contains an error code (no endpoint is seized in those cases)
+ * or we get an unparseable message. In this case we can not be
+ * sure, but we also can not draw any assumptions from unparseable
+ * messages. */
+
OSMO_ASSERT(mgcp_ctx);
trans = mgcp_ctx->trans;
OSMO_ASSERT(trans);
@@ -320,7 +340,7 @@ static void mgw_crcx_ran_resp_cb(struct mgcp_response *r, void *priv)
if (r->head.response_code != 200) {
LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR,
"CRCX/RAN: response yields error: %d %s\n", r->head.response_code, r->head.comment);
- handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, true);
+ handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, false);
return;
}
@@ -333,7 +353,7 @@ static void mgw_crcx_ran_resp_cb(struct mgcp_response *r, void *priv)
rc = mgcp_response_parse_params(r);
if (rc) {
LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR, "CRCX/RAN: Cannot parse response\n");
- handle_error(mgcp_ctx, MGCP_ERR_MGW_INVAL_RESP, true);
+ handle_error(mgcp_ctx, MGCP_ERR_MGW_INVAL_RESP, false);
return;
}