diff options
author | Joshua Colp <jcolp@digium.com> | 2014-06-30 19:51:28 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2014-06-30 19:51:28 +0000 |
commit | 6e60f5d317d2bccaa556c98fbcc01d2db5796c1e (patch) | |
tree | 9d2e1bd2d26e584aa31e3b6b019ffe145784a2b2 /res/res_pjsip_sdp_rtp.c | |
parent | 688bb204dc872aaec9f2b829fe85039c08091b55 (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.c | 60 |
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; } |