summaryrefslogtreecommitdiff
path: root/res/res_pjsip_sdp_rtp.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-06-30 19:51:28 +0000
committerJoshua Colp <jcolp@digium.com>2014-06-30 19:51:28 +0000
commit6e60f5d317d2bccaa556c98fbcc01d2db5796c1e (patch)
tree9d2e1bd2d26e584aa31e3b6b019ffe145784a2b2 /res/res_pjsip_sdp_rtp.c
parent688bb204dc872aaec9f2b829fe85039c08091b55 (diff)
Recorded merge of revisions 417677 from http://svn.asterisk.org/svn/asterisk/branches/11
........ res_rtp_asterisk: Add SHA-256 support for DTLS and perform DTLS negotiation on RTCP. This change fixes up DTLS support in res_rtp_asterisk so it can accept and provide a SHA-256 fingerprint, so it occurs on RTCP, and so it occurs after ICE negotiation completes. Configuration options to chan_sip and chan_pjsip have also been added to allow behavior to be tweaked (such as forcing the AVP type media transports in SDP). ASTERISK-22961 #close Reported by: Jay Jideliov Review: https://reviewboard.asterisk.org/r/3679/ Review: https://reviewboard.asterisk.org/r/3686/ ........ Merged revisions 417678 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@417679 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_sdp_rtp.c')
-rw-r--r--res/res_pjsip_sdp_rtp.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 59fa647d9..b7e1eef3d 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -390,14 +390,26 @@ static void process_ice_attributes(struct ast_sip_session *session, struct ast_s
return;
}
- if ((attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL))) {
+ attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL);
+ if (!attr) {
+ attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL);
+ }
+ if (attr) {
ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
ice->set_authentication(session_media->rtp, attr_value, NULL);
+ } else {
+ return;
}
- if ((attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL))) {
+ attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL);
+ if (!attr) {
+ pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL);
+ }
+ if (attr) {
ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
ice->set_authentication(session_media->rtp, NULL, attr_value);
+ } else {
+ return;
}
if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
@@ -452,6 +464,8 @@ static void process_ice_attributes(struct ast_sip_session *session, struct ast_s
ice->add_remote_candidate(session_media->rtp, &candidate);
}
+ ice->set_role(session_media->rtp, pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_TRUE ?
+ AST_RTP_ICE_ROLE_CONTROLLING : AST_RTP_ICE_ROLE_CONTROLLED);
ice->start(session_media->rtp);
}
@@ -529,6 +543,10 @@ static enum ast_sip_session_media_encryption check_endpoint_media_transport(
return incoming_encryption;
}
+ if (endpoint->media.rtp.force_avp) {
+ return incoming_encryption;
+ }
+
return AST_SIP_MEDIA_TRANSPORT_INVALID;
}
@@ -615,13 +633,15 @@ static int parse_dtls_attrib(struct ast_sip_session_media *session_media,
ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
}
} else if (!pj_strcmp2(&attr->name, "fingerprint")) {
- char hash_value[256], hash[6];
+ char hash_value[256], hash[32];
char fingerprint_text[value->slen + 1];
ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));
- if (sscanf(fingerprint_text, "%5s %255s", hash, hash_value) == 2) {
+ if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
if (!strcasecmp(hash, "sha-1")) {
dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
+ } else if (!strcasecmp(hash, "sha-256")) {
+ dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
} else {
ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
hash);
@@ -710,7 +730,8 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct
}
/* Ensure incoming transport is compatible with the endpoint's configuration */
- if (check_endpoint_media_transport(session->endpoint, stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
+ if (!session->endpoint->media.rtp.use_received_transport &&
+ check_endpoint_media_transport(session->endpoint, stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
return -1;
}
@@ -727,6 +748,10 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct
return -1;
}
+ if (session->endpoint->media.rtp.use_received_transport) {
+ pj_strdup(session->inv_session->pool, &session_media->transport, &stream->desc.transport);
+ }
+
if (setup_media_encryption(session, session_media, stream)) {
return -1;
}
@@ -748,6 +773,7 @@ static int add_crypto_to_stream(struct ast_sip_session *session,
{
pj_str_t stmp;
pjmedia_sdp_attr *attr;
+ enum ast_rtp_dtls_hash hash;
const char *crypto_attribute;
struct ast_rtp_engine_dtls *dtls;
static const pj_str_t STR_NEW = { "new", 3 };
@@ -824,13 +850,19 @@ static int add_crypto_to_stream(struct ast_sip_session *session,
break;
}
- if ((crypto_attribute = dtls->get_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1))) {
+ hash = dtls->get_fingerprint_hash(session_media->rtp);
+ crypto_attribute = dtls->get_fingerprint(session_media->rtp);
+ if (crypto_attribute && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) {
RAII_VAR(struct ast_str *, fingerprint, ast_str_create(64), ast_free);
if (!fingerprint) {
return -1;
}
- ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
+ if (hash == AST_RTP_DTLS_HASH_SHA1) {
+ ast_str_set(&fingerprint, 0, "SHA-1 %s", crypto_attribute);
+ } else {
+ ast_str_set(&fingerprint, 0, "SHA-256 %s", crypto_attribute);
+ }
attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
media->attr[media->attr_count++] = attr;
@@ -889,9 +921,14 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
}
media->desc.media = pj_str(session_media->stream_type);
- media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
- session->endpoint->media.rtp.encryption == AST_SIP_MEDIA_ENCRYPT_SDES,
- session_media->rtp, session->endpoint->media.rtp.use_avpf));
+ if (session->endpoint->media.rtp.use_received_transport && pj_strlen(&session_media->transport)) {
+ media->desc.transport = session_media->transport;
+ } else {
+ media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
+ session->endpoint->media.rtp.encryption == AST_SIP_MEDIA_ENCRYPT_SDES,
+ session_media->rtp, session->endpoint->media.rtp.use_avpf,
+ session->endpoint->media.rtp.force_avp));
+ }
/* Add connection level details */
if (direct_media_enabled) {
@@ -1033,7 +1070,8 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
}
/* Ensure incoming transport is compatible with the endpoint's configuration */
- if (check_endpoint_media_transport(session->endpoint, remote_stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
+ if (!session->endpoint->media.rtp.use_received_transport &&
+ check_endpoint_media_transport(session->endpoint, remote_stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
return -1;
}