]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_pjsip: Ignore RTP that we haven't negotiated
authorSean Bright <sean.bright@gmail.com>
Thu, 23 Jan 2020 15:06:35 +0000 (10:06 -0500)
committerSean Bright <sean.bright@gmail.com>
Thu, 23 Jan 2020 15:53:07 +0000 (10:53 -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 check that the received frame is in a format we have negotiated
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

index 8ce563055ed98ef1a76353cc66d15bc458139d4b..72075b7e02b99f7a8d0de589f8ab5ffba480d2c1 100644 (file)
@@ -807,6 +807,16 @@ static struct ast_frame *chan_pjsip_cng_tone_detected(struct ast_channel *ast, s
        return f;
 }
 
+/*! \brief Determine if the given frame is in a format we've negotiated */
+static int is_compatible_format(struct ast_sip_session *session, struct ast_frame *f)
+{
+       struct ast_stream_topology *topology = session->active_media_state->topology;
+       struct ast_stream *stream = ast_stream_topology_get_stream(topology, f->stream_num);
+       struct ast_format_cap *cap = ast_stream_get_formats(stream);
+
+       return ast_format_cap_iscompatible_format(cap, f->subclass.format) != AST_FORMAT_CMP_NOT_EQUAL;
+}
+
 /*!
  * \brief Function called by core to read any waiting frames
  *
@@ -844,7 +854,8 @@ static struct ast_frame *chan_pjsip_read_stream(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 &&
+               is_compatible_format(session, f)) {
                struct ast_format_cap *caps;
 
                /* For maximum compatibility we ensure that the formats match that of the received media */