[asterisk-commits] kmoore: branch kmoore/pjsip_dtls r394606 - /team/kmoore/pjsip_dtls/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jul 17 15:07:53 CDT 2013
Author: kmoore
Date: Wed Jul 17 15:07:52 2013
New Revision: 394606
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394606
Log:
Finish DTLS support and fix bugs
Add support in SDES SRTP and DTLS SRTP for varying tag lengths.
Fix a segfault where certain SDP lines were handled improperly.
Fix up and refactor remainder of DTLS support.
Modified:
team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c
Modified: team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c?view=diff&rev=394606&r1=394605&r2=394606
==============================================================================
--- team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c (original)
+++ team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c Wed Jul 17 15:07:52 2013
@@ -555,6 +555,7 @@
return -1;
}
+ session->dtls_cfg.suite = ((session->endpoint->srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80);
if (dtls->set_configuration(session_media->rtp, &session->dtls_cfg)) {
ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
session_media->rtp);
@@ -575,7 +576,13 @@
for (i = 0; i < stream->attr_count; i++) {
pjmedia_sdp_attr *attr = stream->attr[i];
- pj_str_t *value = pj_strtrim(&attr->value);
+ pj_str_t *value;
+
+ if (!attr->value.ptr) {
+ continue;
+ }
+
+ value = pj_strtrim(&attr->value);
if (!pj_strcmp2(&attr->name, "setup")) {
RAII_VAR(char *, setup_type, ast_strndup(value->ptr, value->slen), ast_free);
@@ -666,40 +673,11 @@
return -1;
}
-/*! \brief Function which negotiates an incoming media stream */
-static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
- const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
-{
- char host[NI_MAXHOST];
- RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
- enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
- enum ast_sip_session_media_encryption incoming_encryption;
-
- /* If no type formats have been configured reject this stream */
- if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) {
- return 0;
- }
-
- /* Ensure incoming transport is compatible with the endpoint's configuration */
- incoming_encryption = check_endpoint_media_transport(session->endpoint, stream);
- if (incoming_encryption == AST_SIP_MEDIA_TRANSPORT_INVALID) {
- return -1;
- }
-
- ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
-
- /* Ensure that the address provided is valid */
- if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
- /* The provided host was actually invalid so we error out this negotiation */
- return -1;
- }
-
- /* Using the connection information create an appropriate RTP instance */
- if (!session_media->rtp && create_rtp(session, session_media, ast_sockaddr_is_ipv6(addrs))) {
- return -1;
- }
-
- switch (incoming_encryption) {
+static int setup_media_encryption(struct ast_sip_session *session,
+ struct ast_sip_session_media *session_media,
+ const struct pjmedia_sdp_media *stream)
+{
+ switch (session->endpoint->media_encryption) {
case AST_SIP_MEDIA_ENCRYPT_SDES:
if (setup_sdes_srtp(session_media, stream)) {
return -1;
@@ -714,9 +692,46 @@
}
break;
case AST_SIP_MEDIA_TRANSPORT_INVALID:
- /* Already handled above, fallthrough */
case AST_SIP_MEDIA_ENCRYPT_NONE:
break;
+ }
+
+ return 0;
+}
+
+/*! \brief Function which negotiates an incoming media stream */
+static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
+{
+ char host[NI_MAXHOST];
+ RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
+ enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+
+ /* If no type formats have been configured reject this stream */
+ if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) {
+ return 0;
+ }
+
+ /* Ensure incoming transport is compatible with the endpoint's configuration */
+ if (check_endpoint_media_transport(session->endpoint, stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
+ return -1;
+ }
+
+ ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
+
+ /* Ensure that the address provided is valid */
+ if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
+ /* The provided host was actually invalid so we error out this negotiation */
+ return -1;
+ }
+
+ /* Using the connection information create an appropriate RTP instance */
+ if (!session_media->rtp && create_rtp(session, session_media, ast_sockaddr_is_ipv6(addrs))) {
+ return -1;
+ }
+
+ if (setup_media_encryption(session, session_media, stream)) {
+ return -1;
}
return set_caps(session, session_media, stream);
@@ -729,31 +744,89 @@
pj_str_t stmp;
pjmedia_sdp_attr *attr;
const char *crypto_attribute;
-
- if (session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_DTLS) {
+ struct ast_rtp_engine_dtls *dtls;
+
+ switch (session->endpoint->media_encryption) {
+ case AST_SIP_MEDIA_ENCRYPT_NONE:
+ case AST_SIP_MEDIA_TRANSPORT_INVALID:
+ break;
+ case AST_SIP_MEDIA_ENCRYPT_SDES:
+ if (!session_media->srtp) {
+ session_media->srtp = ast_sdp_srtp_alloc();
+ if (!session_media->srtp) {
+ return -1;
+ }
+ }
+
+ crypto_attribute = ast_sdp_srtp_get_attrib(session_media->srtp,
+ 0 /* DTLS running? No */,
+ session->endpoint->srtp_tag_32 /* 32 byte tag length? */);
+ if (!crypto_attribute) {
+ /* No crypto attribute to add, bad news */
+ return -1;
+ }
+
+ attr = pjmedia_sdp_attr_create(pool, "crypto", pj_cstr(&stmp, crypto_attribute));
+ media->attr[media->attr_count++] = attr;
+ break;
+ case AST_SIP_MEDIA_ENCRYPT_DTLS:
if (setup_dtls_srtp(session, session_media)) {
return -1;
}
- return 0;
- }
-
- if (!session_media->srtp && session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_SDES) {
- session_media->srtp = ast_sdp_srtp_alloc();
- if (!session_media->srtp) {
+
+ dtls = ast_rtp_instance_get_dtls(session_media->rtp);
+ if (!dtls) {
return -1;
}
- }
-
- crypto_attribute = ast_sdp_srtp_get_attrib(session_media->srtp,
- session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_DTLS /* DTLS running? */,
- 0 /* don't prefer 32byte tag length */);
- if (!crypto_attribute) {
- /* No crypto attribute to add */
- return -1;
- }
-
- attr = pjmedia_sdp_attr_create(pool, "crypto", pj_cstr(&stmp, crypto_attribute));
- media->attr[media->attr_count++] = attr;
+
+ switch (dtls->get_connection(session_media->rtp)) {
+ case AST_RTP_DTLS_CONNECTION_NEW:
+ attr = pjmedia_sdp_attr_create(pool, "connection", pj_cstr(&stmp, "new"));
+ media->attr[media->attr_count++] = attr;
+ break;
+ case AST_RTP_DTLS_CONNECTION_EXISTING:
+ attr = pjmedia_sdp_attr_create(pool, "connection", pj_cstr(&stmp, "existing"));
+ media->attr[media->attr_count++] = attr;
+ break;
+ default:
+ break;
+ }
+
+ switch (dtls->get_setup(session_media->rtp)) {
+ case AST_RTP_DTLS_SETUP_ACTIVE:
+ attr = pjmedia_sdp_attr_create(pool, "setup", pj_cstr(&stmp, "active"));
+ media->attr[media->attr_count++] = attr;
+ break;
+ case AST_RTP_DTLS_SETUP_PASSIVE:
+ attr = pjmedia_sdp_attr_create(pool, "setup", pj_cstr(&stmp, "passive"));
+ media->attr[media->attr_count++] = attr;
+ break;
+ case AST_RTP_DTLS_SETUP_ACTPASS:
+ attr = pjmedia_sdp_attr_create(pool, "setup", pj_cstr(&stmp, "actpass"));
+ media->attr[media->attr_count++] = attr;
+ break;
+ case AST_RTP_DTLS_SETUP_HOLDCONN:
+ attr = pjmedia_sdp_attr_create(pool, "setup", pj_cstr(&stmp, "holdconn"));
+ media->attr[media->attr_count++] = attr;
+ break;
+ default:
+ break;
+ }
+
+ if ((crypto_attribute = dtls->get_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1))) {
+ 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);
+
+ attr = pjmedia_sdp_attr_create(pool, "fingerprint", pj_cstr(&stmp, ast_str_buffer(fingerprint)));
+ media->attr[media->attr_count++] = attr;
+ }
+ break;
+ }
+
return 0;
}
@@ -777,7 +850,6 @@
struct ast_format format;
RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
- int crypto_res;
int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
!ast_format_cap_is_empty(session->direct_media_cap);
@@ -799,11 +871,14 @@
return -1;
}
- crypto_res = add_crypto_to_stream(session, session_media, pool, media);
+ if (add_crypto_to_stream(session, session_media, pool, media)) {
+ return -1;
+ }
media->desc.media = pj_str(session_media->stream_type);
media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
- !crypto_res, session_media->rtp, session->endpoint->use_avpf));
+ session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_SDES,
+ session_media->rtp, session->endpoint->use_avpf));
/* Add connection level details */
if (direct_media_enabled) {
@@ -928,8 +1003,17 @@
return 1;
}
+ /* Ensure incoming transport is compatible with the endpoint's configuration */
+ if (check_endpoint_media_transport(session->endpoint, remote_stream) == AST_SIP_MEDIA_TRANSPORT_INVALID) {
+ return -1;
+ }
+
/* Create an RTP instance if need be */
if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
+ return -1;
+ }
+
+ if (setup_media_encryption(session, session_media, remote_stream)) {
return -1;
}
More information about the asterisk-commits
mailing list