In hold/retrieve/reinvite, add check that other_leg exists
We should always check that the other leg did not somehow dissapear before accessing it. Change-Id: I947aab6c0cc5019929bde1c7012e1a8c3d3472a5
This commit is contained in:
parent
b43c296f19
commit
eb0a93e037
14
src/mncc.c
14
src/mncc.c
|
@ -703,6 +703,12 @@ static void check_hold_ind(struct mncc_connection *conn, const char *buf, int rc
|
||||||
LOGP(DMNCC, LOGL_DEBUG,
|
LOGP(DMNCC, LOGL_DEBUG,
|
||||||
"leg(%u) is requesting hold.\n", leg->callref);
|
"leg(%u) is requesting hold.\n", leg->callref);
|
||||||
other_leg = call_leg_other(&leg->base);
|
other_leg = call_leg_other(&leg->base);
|
||||||
|
if (!other_leg) {
|
||||||
|
LOGP(DMNCC, LOGL_ERROR, "leg(%u) other leg gone!\n",
|
||||||
|
leg->callref);
|
||||||
|
mncc_send(leg->conn, MNCC_HOLD_REJ, leg->callref);
|
||||||
|
return;
|
||||||
|
}
|
||||||
other_leg->hold_call(other_leg);
|
other_leg->hold_call(other_leg);
|
||||||
mncc_send(leg->conn, MNCC_HOLD_CNF, leg->callref);
|
mncc_send(leg->conn, MNCC_HOLD_CNF, leg->callref);
|
||||||
leg->state = MNCC_CC_HOLD;
|
leg->state = MNCC_CC_HOLD;
|
||||||
|
@ -721,6 +727,14 @@ static void check_retrieve_ind(struct mncc_connection *conn, const char *buf, in
|
||||||
LOGP(DMNCC, LOGL_DEBUG,
|
LOGP(DMNCC, LOGL_DEBUG,
|
||||||
"leg(%u) is requesting unhold.\n", leg->callref);
|
"leg(%u) is requesting unhold.\n", leg->callref);
|
||||||
other_leg = call_leg_other(&leg->base);
|
other_leg = call_leg_other(&leg->base);
|
||||||
|
if (!other_leg) {
|
||||||
|
/* The SIP leg went away while we were holding! */
|
||||||
|
LOGP(DMNCC, LOGL_ERROR, "leg(%u) other leg gone!\n",
|
||||||
|
leg->callref);
|
||||||
|
mncc_send(leg->conn, MNCC_RETRIEVE_CNF, leg->callref);
|
||||||
|
mncc_call_leg_release(&leg->base);
|
||||||
|
return;
|
||||||
|
}
|
||||||
other_leg->retrieve_call(other_leg);
|
other_leg->retrieve_call(other_leg);
|
||||||
mncc_send(leg->conn, MNCC_RETRIEVE_CNF, leg->callref);
|
mncc_send(leg->conn, MNCC_RETRIEVE_CNF, leg->callref);
|
||||||
/* In case of call waiting/swap, At this point we need to tell the MSC to send
|
/* In case of call waiting/swap, At this point we need to tell the MSC to send
|
||||||
|
|
17
src/sip.c
17
src/sip.c
|
@ -193,6 +193,13 @@ static void sip_handle_reinvite(struct sip_call_leg *leg, nua_handle_t *nh, cons
|
||||||
LOGP(DSIP, LOGL_INFO, "re-INVITE for call %s\n", sip->sip_call_id->i_id);
|
LOGP(DSIP, LOGL_INFO, "re-INVITE for call %s\n", sip->sip_call_id->i_id);
|
||||||
|
|
||||||
struct call_leg *other = call_leg_other(&leg->base);
|
struct call_leg *other = call_leg_other(&leg->base);
|
||||||
|
|
||||||
|
if (!other) {
|
||||||
|
LOGP(DMNCC, LOGL_ERROR, "leg(%p) other leg gone!\n", leg);
|
||||||
|
sip_release_call(&leg->base);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sdp_get_sdp_mode(sip, &mode)) {
|
if (!sdp_get_sdp_mode(sip, &mode)) {
|
||||||
/* re-INVITE with no SDP.
|
/* re-INVITE with no SDP.
|
||||||
* We should respond with SDP reflecting current session
|
* We should respond with SDP reflecting current session
|
||||||
|
@ -540,6 +547,11 @@ static void sip_hold_call(struct call_leg *_leg)
|
||||||
OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
|
OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
|
||||||
leg = (struct sip_call_leg *) _leg;
|
leg = (struct sip_call_leg *) _leg;
|
||||||
other_leg = call_leg_other(&leg->base);
|
other_leg = call_leg_other(&leg->base);
|
||||||
|
if (!other_leg) {
|
||||||
|
LOGP(DMNCC, LOGL_ERROR, "leg(%p) other leg gone!\n", leg);
|
||||||
|
sip_release_call(&leg->base);
|
||||||
|
return;
|
||||||
|
}
|
||||||
char *sdp = sdp_create_file(leg, other_leg, sdp_sendonly);
|
char *sdp = sdp_create_file(leg, other_leg, sdp_sendonly);
|
||||||
nua_invite(leg->nua_handle,
|
nua_invite(leg->nua_handle,
|
||||||
NUTAG_MEDIA_ENABLE(0),
|
NUTAG_MEDIA_ENABLE(0),
|
||||||
|
@ -557,6 +569,11 @@ static void sip_retrieve_call(struct call_leg *_leg)
|
||||||
OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
|
OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
|
||||||
leg = (struct sip_call_leg *) _leg;
|
leg = (struct sip_call_leg *) _leg;
|
||||||
other_leg = call_leg_other(&leg->base);
|
other_leg = call_leg_other(&leg->base);
|
||||||
|
if (!other_leg) {
|
||||||
|
LOGP(DMNCC, LOGL_ERROR, "leg(%p) other leg gone!\n", leg);
|
||||||
|
sip_release_call(&leg->base);
|
||||||
|
return;
|
||||||
|
}
|
||||||
char *sdp = sdp_create_file(leg, other_leg, sdp_sendrecv);
|
char *sdp = sdp_create_file(leg, other_leg, sdp_sendrecv);
|
||||||
nua_invite(leg->nua_handle,
|
nua_invite(leg->nua_handle,
|
||||||
NUTAG_MEDIA_ENABLE(0),
|
NUTAG_MEDIA_ENABLE(0),
|
||||||
|
|
Loading…
Reference in New Issue