]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_session.c: End call on initial invalid SDP negotiation. 29/3129/1
authorRichard Mudgett <rmudgett@digium.com>
Mon, 27 Jun 2016 22:19:08 +0000 (17:19 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 30 Jun 2016 17:27:20 +0000 (12:27 -0500)
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

res/res_pjsip_session.c

index 32bdeb8851f9d6af414ada7cf284a3283aefa47b..c64ea4dc3192da435a959d6776e53ae6ebb77afb 100644 (file)
@@ -2490,6 +2490,36 @@ static int session_end_completion(void *vsession)
        return 0;
 }
 
+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];
@@ -2511,8 +2541,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));
@@ -2522,8 +2551,7 @@ static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
                        handle_outgoing(session, e->body.tsx_state.src.tdata);
                        break;
                case PJSIP_EVENT_RX_MSG:
-                       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:
                case PJSIP_EVENT_TIMER: