]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_pjsip: Ignore RTP that we haven't negotiated
authorSean Bright <sean.bright@gmail.com>
Fri, 27 Dec 2019 13:04:42 +0000 (08:04 -0500)
committerSean Bright <sean.bright@gmail.com>
Fri, 17 Jan 2020 13:59:22 +0000 (08:59 -0500)
If chan_pjsip receives an RTP packet whose payload differs from the
channel's native format, and asymmetric_rtp_codec is disabled (the
default), Asterisk will switch the channel's native format to match
that of the incoming packet without regard to the negotiated payloads.

We now keep track of the formats that have been negotiated and check
before switching payloads which results in these packets being dropped
instead of causing the session to terminate.

ASTERISK-28139 #close
Reported by: Paul Brooks

Change-Id: Icc3b85cee1772026cee5dc1b68459bf9431c14a3

channels/chan_pjsip.c
include/asterisk/res_pjsip_session.h
res/res_pjsip_sdp_rtp.c
res/res_pjsip_session.c

index 33abe032091ff51fe350b85be18da09eb2a1461d..c4281c32da6052bfede0141f4936989262d96bb7 100644 (file)
@@ -771,7 +771,8 @@ static struct ast_frame *chan_pjsip_read(struct ast_channel *ast)
         * raw read format BEFORE the native format check
         */
        if (!session->endpoint->asymmetric_rtp_codec &&
-               ast_format_cmp(ast_channel_rawwriteformat(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+               ast_format_cmp(ast_channel_rawwriteformat(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL &&
+               ast_format_cap_iscompatible_format(session->joint_caps, f->subclass.format) == AST_FORMAT_CMP_EQUAL) {
                struct ast_format_cap *caps;
 
                /* For maximum compatibility we ensure that the formats match that of the received media */
index 9ae1883d0410a6ba0aa9918d579393f06ea0d23b..38df3fd1658f1cf3d84fc9d44d225374ef56f51d 100644 (file)
@@ -167,6 +167,8 @@ struct ast_sip_session {
        enum ast_sip_dtmf_mode dtmf;
        /*! Initial incoming INVITE Request-URI.  NULL otherwise. */
        pjsip_uri *request_uri;
+       /*! Joint capabilities */
+       struct ast_format_cap *joint_caps;
 };
 
 typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
index 98e981965f697bace44372be4fa7ac0956770bad..36b60444d355d025e77c5695010f5fe192a160e0 100644 (file)
@@ -408,6 +408,9 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi
 
        if (session->channel) {
                ast_channel_lock(session->channel);
+               ast_format_cap_remove_by_type(session->joint_caps, media_type);
+               ast_format_cap_append_from_cap(session->joint_caps, joint, media_type);
+
                ast_format_cap_remove_by_type(caps, AST_MEDIA_TYPE_UNKNOWN);
                ast_format_cap_append_from_cap(caps, ast_channel_nativeformats(session->channel),
                        AST_MEDIA_TYPE_UNKNOWN);
index bbdb8d148abbc987092d4f83090cd86bb6d38d0b..b61b0fd91773c922e13733a30710b95877b5121f 100644 (file)
@@ -1351,6 +1351,7 @@ static void session_destructor(void *obj)
        ao2_cleanup(session->aor);
        ao2_cleanup(session->contact);
        ao2_cleanup(session->req_caps);
+       ao2_cleanup(session->joint_caps);
        ao2_cleanup(session->direct_media_cap);
 
        ast_dsp_free(session->dsp);
@@ -1433,6 +1434,10 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
        if (!session->req_caps) {
                return NULL;
        }
+       session->joint_caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+       if (!session->joint_caps) {
+               return NULL;
+       }
        session->datastores = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
                DATASTORE_BUCKETS, datastore_hash, NULL, datastore_cmp);
        if (!session->datastores) {