chan_pjsip: Ignore RTP that we haven't negotiated

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
13.32
Sean Bright 5 years ago
parent 9ba3bddd37
commit bfc93cc954

@ -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 */

@ -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);

@ -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);

@ -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) {

Loading…
Cancel
Save