MSC_Tests: Test what happens when the DLCX is dropped
Test the reaction of osmo-msc when the DLCX at the end of a call is not answered. Normally osmo-msc should time out and clear the connection. Change-ID osmo-msc:I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 fixes a regression that causes osmo-msc to segfault due to a use after free. This testcase provokes the situation that leads to the crash. Change-Id: Ic124ea116496209f9a1d8e74ae3e3a36cf866db0 Related OS#2881 Related OS#2882
This commit is contained in:
parent
cd66857671
commit
2a98a73be4
|
@ -373,6 +373,8 @@ type record CallParameters {
|
||||||
PortNumber mgw_rtp_port_mss, /* MSS-facing MGW RTP Port */
|
PortNumber mgw_rtp_port_mss, /* MSS-facing MGW RTP Port */
|
||||||
uint7_t rtp_payload_type, /* dynamic RTP payload type */
|
uint7_t rtp_payload_type, /* dynamic RTP payload type */
|
||||||
charstring rtp_sdp_format, /* AMR/8000 or the like */
|
charstring rtp_sdp_format, /* AMR/8000 or the like */
|
||||||
|
boolean mgw_drop_dlcx optional, /* Provoke errors by not responding to DLCX
|
||||||
|
(f_mt_call and f_mt_call) */
|
||||||
|
|
||||||
MgcpCallId mgcp_call_id optional, /* MGCP Call ID; CallAgent allocated */
|
MgcpCallId mgcp_call_id optional, /* MGCP Call ID; CallAgent allocated */
|
||||||
MgcpEndpoint mgcp_ep optional /* MGCP Endpoint, CallAgent or MGW allocated */,
|
MgcpEndpoint mgcp_ep optional /* MGCP Endpoint, CallAgent or MGW allocated */,
|
||||||
|
@ -410,6 +412,7 @@ runs on BSC_ConnHdlr {
|
||||||
var MobileIdentityLV mi;
|
var MobileIdentityLV mi;
|
||||||
var MNCC_PDU mncc;
|
var MNCC_PDU mncc;
|
||||||
var MgcpCommand mgcp_cmd;
|
var MgcpCommand mgcp_cmd;
|
||||||
|
var boolean respond_to_dlcx;
|
||||||
|
|
||||||
f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);
|
f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);
|
||||||
|
|
||||||
|
@ -510,6 +513,8 @@ runs on BSC_ConnHdlr {
|
||||||
BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_REL_COMPL(cpars.transaction_id)));
|
BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_REL_COMPL(cpars.transaction_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
respond_to_dlcx := not (isbound(cpars.mgw_drop_dlcx) and valueof(cpars.mgw_drop_dlcx));
|
||||||
|
|
||||||
/* clearing of radio channel */
|
/* clearing of radio channel */
|
||||||
interleave {
|
interleave {
|
||||||
[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
|
[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
|
||||||
|
@ -517,9 +522,11 @@ runs on BSC_ConnHdlr {
|
||||||
BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
|
BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
|
||||||
}
|
}
|
||||||
[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
|
[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
|
||||||
/* TODO: For one or all connections on EP? */
|
if (respond_to_dlcx) {
|
||||||
MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
|
/* TODO: For one or all connections on EP? */
|
||||||
f_create_mgcp_delete_ep(cpars.mgcp_ep);
|
MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
|
||||||
|
f_create_mgcp_delete_ep(cpars.mgcp_ep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setverdict(pass);
|
setverdict(pass);
|
||||||
|
@ -531,6 +538,7 @@ runs on BSC_ConnHdlr {
|
||||||
var MobileIdentityLV mi;
|
var MobileIdentityLV mi;
|
||||||
var MNCC_PDU mncc;
|
var MNCC_PDU mncc;
|
||||||
var MgcpCommand mgcp_cmd;
|
var MgcpCommand mgcp_cmd;
|
||||||
|
var boolean respond_to_dlcx;
|
||||||
|
|
||||||
/* If we have a TMSI, use TMSI instead of IMSI */
|
/* If we have a TMSI, use TMSI instead of IMSI */
|
||||||
if (ispresent(g_pars.tmsi)) {
|
if (ispresent(g_pars.tmsi)) {
|
||||||
|
@ -628,6 +636,8 @@ runs on BSC_ConnHdlr {
|
||||||
BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
|
BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
|
||||||
BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
|
BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
|
||||||
|
|
||||||
|
respond_to_dlcx := not (isbound(cpars.mgw_drop_dlcx) and valueof(cpars.mgw_drop_dlcx));
|
||||||
|
|
||||||
/* clearing of radio channel */
|
/* clearing of radio channel */
|
||||||
interleave {
|
interleave {
|
||||||
[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
|
[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
|
||||||
|
@ -635,9 +645,11 @@ runs on BSC_ConnHdlr {
|
||||||
BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
|
BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
|
||||||
}
|
}
|
||||||
[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
|
[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
|
||||||
/* TODO: For one or all connections on EP? */
|
if (respond_to_dlcx) {
|
||||||
MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
|
/* TODO: For one or all connections on EP? */
|
||||||
f_create_mgcp_delete_ep(cpars.mgcp_ep);
|
MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
|
||||||
|
f_create_mgcp_delete_ep(cpars.mgcp_ep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setverdict(pass);
|
setverdict(pass);
|
||||||
|
|
|
@ -1734,6 +1734,45 @@ testcase TC_mo_release_timeout() runs on MTC_CT {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* LU followed by MT call (including paging) */
|
||||||
|
private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
|
||||||
|
f_init_handler(pars);
|
||||||
|
//FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
|
||||||
|
var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
|
||||||
|
cpars.bss_rtp_port := 1110;
|
||||||
|
cpars.mgcp_connection_id_bss := '10004'H;
|
||||||
|
cpars.mgcp_connection_id_mss := '10005'H;
|
||||||
|
|
||||||
|
/* Note: This is an optional parameter. When the call-agent (MSC) does
|
||||||
|
* supply a full endpoint name this setting will be overwritten. */
|
||||||
|
cpars.mgcp_ep := "rtpbridge/1@mgw";
|
||||||
|
|
||||||
|
/* Intentionally disable the CRCX response */
|
||||||
|
cpars.mgw_drop_dlcx := true;
|
||||||
|
|
||||||
|
/* Perform location update and call */
|
||||||
|
f_perform_lu();
|
||||||
|
f_mt_call(cpars);
|
||||||
|
}
|
||||||
|
testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
|
||||||
|
var BSC_ConnHdlr vc_conn;
|
||||||
|
f_init();
|
||||||
|
|
||||||
|
/* Perform an almost normal looking locationupdate + mt-call, but do
|
||||||
|
* not respond to the DLCX at the end of the call */
|
||||||
|
vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
|
||||||
|
vc_conn.done;
|
||||||
|
|
||||||
|
/* Wait a guard period until the MGCP layer in the MSC times out,
|
||||||
|
* if the MSC is vulnerable to the use-after-free situation that is
|
||||||
|
* fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
|
||||||
|
* segfault now */
|
||||||
|
f_sleep(6.0);
|
||||||
|
|
||||||
|
/* Run the init procedures once more. If the MSC has crashed, this
|
||||||
|
* this will fail */
|
||||||
|
f_init();
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
|
* continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
|
||||||
|
@ -1791,6 +1830,7 @@ control {
|
||||||
execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
|
execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
|
||||||
execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
|
execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
|
||||||
execute( TC_mo_release_timeout() );
|
execute( TC_mo_release_timeout() );
|
||||||
|
execute( TC_lu_and_mt_call_no_dlcx_resp() );
|
||||||
|
|
||||||
execute( TC_lu_and_mt_call() );
|
execute( TC_lu_and_mt_call() );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue