From b1dfc9c8058e5570e83602e34210a2ee77f85bb5 Mon Sep 17 00:00:00 2001 From: George Joseph <gjoseph@digium.com> Date: Mon, 10 Jan 2022 06:44:12 -0700 Subject: [PATCH] res_pjsip: Make message_filter and session multipart aware Neither pjsip_message_filter's filter_on_tx_message() nor res_pjsip_session's session_outgoing_nat_hook() were multipart aware and just assumed that an SDP would be the only thing in a message body. Both were changed to use the new pjsip_get_sdp_info() function which searches for an sdp in both single- and multi- part message bodies. ASTERISK-29813 Change-Id: I8f5b8cfdc27f1d4bd3e7491ea9090951a4525c56 --- res/res_pjsip/pjsip_message_filter.c | 23 +++++++++++++++++++---- res/res_pjsip_session.c | 18 ++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/res/res_pjsip/pjsip_message_filter.c b/res/res_pjsip/pjsip_message_filter.c index 23369dc8e7..edac55fca3 100644 --- a/res/res_pjsip/pjsip_message_filter.c +++ b/res/res_pjsip/pjsip_message_filter.c @@ -231,6 +231,8 @@ static pj_status_t filter_on_tx_message(pjsip_tx_data *tdata) pjsip_via_hdr *via; pjsip_fromto_hdr *from; pjsip_tpselector sel; + pjsip_sdp_info *sdp_info; + pjmedia_sdp_session *sdp; sanitize_tdata(tdata); @@ -326,10 +328,23 @@ static pj_status_t filter_on_tx_message(pjsip_tx_data *tdata) } } - /* Update the SDP if it is present */ - if (tdata->msg->body && ast_sip_is_content_type(&tdata->msg->body->content_type, "application", "sdp") && - multihomed_rewrite_sdp(tdata->msg->body->data)) { - struct pjmedia_sdp_session *sdp = tdata->msg->body->data; + /* If there's no body in the tdata we can just return here. */ + if (!tdata->msg->body) { + return PJ_SUCCESS; + } + + /* + * pjsip_get_sdp_info will search for an SDP even if it's in + * a multipart message body. + */ + sdp_info = pjsip_get_sdp_info(tdata->pool, tdata->msg->body, NULL, &pjsip_media_type_application_sdp); + if (sdp_info->sdp_err != PJ_SUCCESS || !sdp_info->sdp) { + return PJ_SUCCESS; + } + + sdp = sdp_info->sdp; + + if (multihomed_rewrite_sdp(sdp)) { static const pj_str_t STR_IP4 = { "IP4", 3 }; static const pj_str_t STR_IP6 = { "IP6", 3 }; pj_str_t STR_IP; diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index cfd71fb576..d4a857f63c 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -5480,19 +5480,25 @@ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_trans RAII_VAR(struct ast_sip_transport_state *, transport_state, ast_sip_get_transport_state(ast_sorcery_object_get_id(transport)), ao2_cleanup); struct ast_sip_nat_hook *hook = ast_sip_mod_data_get( tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK); - struct pjmedia_sdp_session *sdp; + pjsip_sdp_info *sdp_info; + pjmedia_sdp_session *sdp; pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata); RAII_VAR(struct ast_sip_session *, session, dlg ? ast_sip_dialog_get_session(dlg) : NULL, ao2_cleanup); int stream; - /* SDP produced by us directly will never be multipart */ - if (!transport_state || hook || !tdata->msg->body || - !ast_sip_are_media_types_equal(&tdata->msg->body->content_type, &pjsip_media_type_application_sdp) || - ast_strlen_zero(transport->external_media_address)) { + /* + * If there's no transport_state or body, or the hook + * has already been run, just return. + */ + if (ast_strlen_zero(transport->external_media_address) || !transport_state || hook || !tdata->msg->body) { return; } - sdp = tdata->msg->body->data; + sdp_info = pjsip_get_sdp_info(tdata->pool, tdata->msg->body, NULL, &pjsip_media_type_application_sdp); + if (sdp_info->sdp_err != PJ_SUCCESS || !sdp_info->sdp) { + return; + } + sdp = sdp_info->sdp; if (sdp->conn) { char host[NI_MAXHOST]; -- GitLab