diff options
author | Richard Mudgett <rmudgett@digium.com> | 2016-06-27 17:19:08 -0500 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2016-06-30 15:40:39 -0500 |
commit | 08d3b9a89ef521e84e61ea1d6110b000454076cd (patch) | |
tree | 16eadc19a81f6f112d3e98e8003113c0b62ebcaf /res/res_pjsip_session.c | |
parent | e6e12c752cfb6ef1a0164c290ebc27b093f1041f (diff) |
res_pjsip_session.c: End call on initial invalid SDP negotiation.
When an incoming call defers SDP negotiation and then sends us an invalid
SDP in the ACK, we need to send a BYE to disconnect the call. In this
case SDP negotiation has failed and we don't have valid media streams
negotiated.
ASTERISK-25772
Change-Id: Ia358516b0fc1e6c4c139b78246f10b9da7a2dfb8
Diffstat (limited to 'res/res_pjsip_session.c')
-rw-r--r-- | res/res_pjsip_session.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 56e3ce112..405fdf839 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2513,6 +2513,36 @@ static int check_request_status(pjsip_inv_session *inv, pjsip_event *e) return 1; } +static void handle_incoming_before_media(pjsip_inv_session *inv, + struct ast_sip_session *session, pjsip_rx_data *rdata) +{ + pjsip_msg *msg; + + handle_incoming(session, rdata, AST_SIP_SESSION_BEFORE_MEDIA); + msg = rdata->msg_info.msg; + if (msg->type == PJSIP_REQUEST_MSG + && msg->line.req.method.id == PJSIP_ACK_METHOD + && pjmedia_sdp_neg_get_state(inv->neg) != PJMEDIA_SDP_NEG_STATE_DONE) { + pjsip_tx_data *tdata; + + /* + * SDP negotiation failed on an incoming call that delayed + * negotiation and then gave us an invalid SDP answer. We + * need to send a BYE to end the call because of the invalid + * SDP answer. + */ + ast_debug(1, + "Endpoint '%s(%s)': Ending session due to incomplete SDP negotiation. %s\n", + ast_sorcery_object_get_id(session->endpoint), + session->channel ? ast_channel_name(session->channel) : "", + pjsip_rx_data_get_info(rdata)); + if (pjsip_inv_end_session(inv, 400, NULL, &tdata) == PJ_SUCCESS + && tdata) { + ast_sip_session_send_request(session, tdata); + } + } +} + static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) { struct ast_sip_session *session = inv->mod_data[session_module.id]; @@ -2534,8 +2564,7 @@ static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) handle_outgoing(session, e->body.tx_msg.tdata); break; case PJSIP_EVENT_RX_MSG: - handle_incoming(session, e->body.rx_msg.rdata, - AST_SIP_SESSION_BEFORE_MEDIA); + handle_incoming_before_media(inv, session, e->body.rx_msg.rdata); break; case PJSIP_EVENT_TSX_STATE: ast_debug(3, "Source of transaction state change is %s\n", pjsip_event_str(e->body.tsx_state.type)); @@ -2546,8 +2575,7 @@ static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) break; case PJSIP_EVENT_RX_MSG: if (!check_request_status(inv, e)) { - handle_incoming(session, e->body.tsx_state.src.rdata, - AST_SIP_SESSION_BEFORE_MEDIA); + handle_incoming_before_media(inv, session, e->body.tsx_state.src.rdata); } break; case PJSIP_EVENT_TRANSPORT_ERROR: |