Author: rmudgett Date: Tue Feb 17 09:34:10 2015 New Revision: 431899 URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=431899 Log: res_pjsip_refer: Fix crash from a REFER and BYE collision.
Analyzing a one-off crash on a busy system showed that processing a REFER request had a NULL session channel pointer. The only way I can think of that could cause this is if an outgoing BYE transaction overlapped the incoming REFER transaction in a collision. Asterisk sends a BYE while the phone sends a REFER to complete an attended transfer. * Made check the session channel pointer before processing an incoming REFER request in res_pjsip_refer. * Fixed similar crash potential for res_pjsip supplement incoming request processing for res_pjsip_sdp_rtp INFO, res_pjsip_caller_id INVITE/UPDATE, res_pjsip_messaging MESSAGE, and res_pjsip_send_to_voicemail REFER messages. * Made res_pjsip_messaging respond to a message body too large with a 413 instead of ignoring it. ASTERISK-24700 #close Reported by: Zane Conkle Review: https://reviewboard.asterisk.org/r/4417/ ........ Merged revisions 431898 from http://svn.asterisk.org/svn/asterisk/branches/13 Modified: trunk/ (props changed) trunk/res/res_pjsip_caller_id.c trunk/res/res_pjsip_messaging.c trunk/res/res_pjsip_refer.c trunk/res/res_pjsip_sdp_rtp.c trunk/res/res_pjsip_send_to_voicemail.c Propchange: trunk/ ------------------------------------------------------------------------------ Binary property 'branch-13-merged' - no diff available. Modified: trunk/res/res_pjsip_caller_id.c URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_caller_id.c?view=diff&rev=431899&r1=431898&r2=431899 ============================================================================== --- trunk/res/res_pjsip_caller_id.c (original) +++ trunk/res/res_pjsip_caller_id.c Tue Feb 17 09:34:10 2015 @@ -361,7 +361,7 @@ if (!session->endpoint->id.self.number.valid) { set_id_from_from(rdata, &session->id); } - } else { + } else if (session->channel) { /* Reinvite. Check for changes to the ID and queue a connected line * update if necessary */ Modified: trunk/res/res_pjsip_messaging.c URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_messaging.c?view=diff&rev=431899&r1=431898&r2=431899 ============================================================================== --- trunk/res/res_pjsip_messaging.c (original) +++ trunk/res/res_pjsip_messaging.c Tue Feb 17 09:34:10 2015 @@ -681,9 +681,13 @@ char buf[MAX_BODY_SIZE]; enum pjsip_status_code code; struct ast_frame f; - pjsip_dialog *dlg = session->inv_session->dlg; pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata); + + if (!session->channel) { + send_response(rdata, PJSIP_SC_NOT_FOUND, dlg, tsx); + return 0; + } if ((code = check_content_type(rdata)) != PJSIP_SC_OK) { send_response(rdata, code, dlg, tsx); @@ -692,6 +696,7 @@ if (print_body(rdata, buf, sizeof(buf)-1) < 1) { /* invalid body size */ + send_response(rdata, PJSIP_SC_REQUEST_ENTITY_TOO_LARGE, dlg, tsx); return 0; } Modified: trunk/res/res_pjsip_refer.c URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_refer.c?view=diff&rev=431899&r1=431898&r2=431899 ============================================================================== --- trunk/res/res_pjsip_refer.c (original) +++ trunk/res/res_pjsip_refer.c Tue Feb 17 09:34:10 2015 @@ -418,7 +418,7 @@ struct refer_attended *attended = obj; ao2_cleanup(attended->transferer); - ast_channel_unref(attended->transferer_chan); + ast_channel_cleanup(attended->transferer_chan); ao2_cleanup(attended->transferer_second); ao2_cleanup(attended->progress); } @@ -674,7 +674,7 @@ return 200; } else { - const char *context = (session->channel ? pbx_builtin_getvar_helper(session->channel, "TRANSFER_CONTEXT") : ""); + const char *context = pbx_builtin_getvar_helper(session->channel, "TRANSFER_CONTEXT"); struct refer_blind refer = { 0, }; if (ast_strlen_zero(context)) { @@ -718,10 +718,6 @@ char exten[AST_MAX_EXTENSION]; struct refer_blind refer = { 0, }; - if (!session->channel) { - return 404; - } - /* If no explicit transfer context has been provided use their configured context */ context = pbx_builtin_getvar_helper(session->channel, "TRANSFER_CONTEXT"); if (ast_strlen_zero(context)) { @@ -893,6 +889,14 @@ static const pj_str_t str_refer_to = { "Refer-To", 8 }; static const pj_str_t str_replaces = { "Replaces", 8 }; + if (!session->channel) { + /* No channel to refer. Likely because the call was just hung up. */ + pjsip_dlg_respond(session->inv_session->dlg, rdata, 404, NULL, NULL, NULL); + ast_debug(3, "Received a REFER on a session with no channel from endpoint '%s'.\n", + ast_sorcery_object_get_id(session->endpoint)); + return 0; + } + if (!session->endpoint->allowtransfer) { pjsip_dlg_respond(session->inv_session->dlg, rdata, 603, NULL, NULL, NULL); ast_log(LOG_WARNING, "Endpoint %s transfer attempt blocked due to configuration\n", Modified: trunk/res/res_pjsip_sdp_rtp.c URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_sdp_rtp.c?view=diff&rev=431899&r1=431898&r2=431899 ============================================================================== --- trunk/res/res_pjsip_sdp_rtp.c (original) +++ trunk/res/res_pjsip_sdp_rtp.c Tue Feb 17 09:34:10 2015 @@ -1269,14 +1269,17 @@ static int video_info_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata) { - struct pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata); + struct pjsip_transaction *tsx; pjsip_tx_data *tdata; - if (!ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type, - "application", - "media_control+xml")) { + if (!session->channel + || !ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type, + "application", + "media_control+xml")) { return 0; } + + tsx = pjsip_rdata_get_tsx(rdata); ast_queue_control(session->channel, AST_CONTROL_VIDUPDATE); Modified: trunk/res/res_pjsip_send_to_voicemail.c URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_send_to_voicemail.c?view=diff&rev=431899&r1=431898&r2=431899 ============================================================================== --- trunk/res/res_pjsip_send_to_voicemail.c (original) +++ trunk/res/res_pjsip_send_to_voicemail.c Tue Feb 17 09:34:10 2015 @@ -119,13 +119,17 @@ static int handle_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata) { - struct ast_datastore *sip_session_datastore; struct ast_channel *other_party; - - int has_feature = has_call_feature(rdata); - int has_reason = has_diversion_reason(rdata); - + int has_feature; + int has_reason; + + if (!session->channel) { + return 0; + } + + has_feature = has_call_feature(rdata); + has_reason = has_diversion_reason(rdata); if (!has_feature && !has_reason) { /* If we don't have a call feature or diversion reason or if it's not a feature this module is related to then there -- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- svn-commits mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/svn-commits