summaryrefslogtreecommitdiff
path: root/res/res_pjsip_sdp_rtp.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-10-17 13:35:44 +0000
committerMatthew Jordan <mjordan@digium.com>2014-10-17 13:35:44 +0000
commit8f58592252e3089fe67f805c86b737ecdb592b1d (patch)
tree06fc676c1b2e888cb7f54fd03978dbe0a0aa8f66 /res/res_pjsip_sdp_rtp.c
parent0d0e38a0e11d6c2f8b3d678ec2c51ab686babf54 (diff)
res_pjsip_session/res_pjsip_sdp_rtp: Be more tolerant of offers
When an inbound SDP offer is received, Asterisk currently makes a few incorrection assumptions: (1) If the offer contains more than a single audio/video stream, Asterisk will reject the entire stream with a 488. This is an overly strict response; generally, Asterisk should accept the media streams that it can accept and decline the others. (2) If the offer contains a declined media stream, Asterisk will attempt to process it anyway. This can result in attempting to match format capabilities on a declined media stream, leading to a 488. Asterisk should simply ignore declined media streams. (3) Asterisk will currently attempt to handle offers with AVPF with use_avpf=No/AVP with use_avpf=Yes. This mismatch results in invalid SDP answers being sent in response. If there is a mismatch between the media type being offered and the configuration, Asterisk must reject the offer with a 488. This patch does the following: * Asterisk will accept SDP offers with at least one media stream that it can use. Some WARNING messages have been dropped to NOTICEs as a result. * Asterisk will not accept an offer with a media type that doesn't match its configuration. * Asterisk will ignore declined media streams properly. #SIPit31 Review: https://reviewboard.asterisk.org/r/4063/ ASTERISK-24122 #close Reported by: James Van Vleet ASTERISK-24381 #close Reported by: Matt Jordan ........ Merged revisions 425868 from http://svn.asterisk.org/svn/asterisk/branches/12 ........ Merged revisions 425879 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@425881 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_sdp_rtp.c')
-rw-r--r--res/res_pjsip_sdp_rtp.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 2aa8acc38..1f863008f 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -247,9 +247,10 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi
struct ast_str *thembuf = ast_str_alloca(64);
ast_rtp_codecs_payloads_destroy(&codecs);
- ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n",
- ast_format_cap_get_names(peer, &usbuf),
- ast_format_cap_get_names(caps, &thembuf));
+ ast_log(LOG_NOTICE, "No joint capabilities for '%s' media stream between our configuration(%s) and incoming SDP(%s)\n",
+ session_media->stream_type,
+ ast_format_cap_get_names(caps, &usbuf),
+ ast_format_cap_get_names(peer, &thembuf));
return -1;
}
@@ -521,12 +522,11 @@ static enum ast_sip_session_media_encryption check_endpoint_media_transport(
const struct pjmedia_sdp_media *stream)
{
enum ast_sip_session_media_encryption incoming_encryption;
+ char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
- if (endpoint->media.rtp.use_avpf) {
- char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1];
- if (transport_end != 'F') {
- return AST_SIP_MEDIA_TRANSPORT_INVALID;
- }
+ if ((transport_end == 'F' && !endpoint->media.rtp.use_avpf)
+ || (transport_end != 'F' && endpoint->media.rtp.use_avpf)) {
+ return AST_SIP_MEDIA_TRANSPORT_INVALID;
}
incoming_encryption = get_media_encryption_type(stream->desc.transport);
@@ -727,8 +727,15 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct
RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
enum ast_media_type media_type = stream_to_media_type(session_media->stream_type);
+ /* If port is 0, ignore this media stream */
+ if (!stream->desc.port) {
+ ast_debug(3, "Media stream '%s' is already declined\n", session_media->stream_type);
+ return 0;
+ }
+
/* If no type formats have been configured reject this stream */
if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) {
+ ast_debug(3, "Endpoint has no codecs for media type '%s', declining stream\n", session_media->stream_type);
return 0;
}
@@ -760,7 +767,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct
}
if (set_caps(session, session_media, stream)) {
- return -1;
+ return 0;
}
return 1;
}
@@ -1061,6 +1068,10 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
return 1;
}
+ if (!local_stream->desc.port || !remote_stream->desc.port) {
+ return 1;
+ }
+
/* Ensure incoming transport is compatible with the endpoint's configuration */
if (!session->endpoint->media.rtp.use_received_transport &&
check_endpoint_media_transport(session->endpoint, remote_stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
@@ -1088,7 +1099,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
ast_sockaddr_set_port(addrs, remote_stream->desc.port);
ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
if (set_caps(session, session_media, local_stream)) {
- return -1;
+ return 1;
}
if ((fdno = media_type_to_fdno(media_type)) < 0) {