diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2018-04-11 17:36:45 +0200 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2018-04-11 17:36:45 +0200 |
commit | 79beccd93a27796a2ca9be201a5b9cf3695fbf5c (patch) | |
tree | eb448f59b2aba0d372c70c04b046de76299f9771 | |
parent | d997fa176d8774863ef6db92b29ea06a1fb8b2d5 (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
-rw-r--r-- | src/libmsc/msc_mgcp.c | 30 |
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; } |