summaryrefslogtreecommitdiff
path: root/main/rtp_engine.c
diff options
context:
space:
mode:
authorJacek Konieczny <jkonieczny@eggsoft.pl>2016-03-25 16:59:05 +0100
committerJoshua Colp <jcolp@digium.com>2016-03-29 10:57:55 -0500
commit970803efcb291d73bfdb0ffb91934b5a4faa1dc5 (patch)
treeabd54dd529a64b517a92243113c8e8db79e92ac3 /main/rtp_engine.c
parent6ce25bd62a0f31aa616272585e4f1ea1f2b86fd9 (diff)
res_rtp_asterisk: Use separate SRTP session for RTCP with DTLS
Asterisk uses separate UDP ports for RTP and RTCP traffic and RFC 5764 explicitly states: There MUST be a separate DTLS-SRTP session for each distinct pair of source and destination ports used by a media session This means RTP keying material cannot be used for DTLS RTCP, which was the reason why RTCP encryption would fail. ASTERISK-25642 Change-Id: I7e8779d8b63e371088081bb113131361b2847e3a
Diffstat (limited to 'main/rtp_engine.c')
-rw-r--r--main/rtp_engine.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index fd472ba72..11e94c699 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -188,6 +188,8 @@ struct ast_rtp_instance {
struct ast_rtp_glue *glue;
/*! SRTP info associated with the instance */
struct ast_srtp *srtp;
+ /*! SRTP info dedicated for RTCP associated with the instance */
+ struct ast_srtp *rtcp_srtp;
/*! Channel unique ID */
char channel_uniqueid[AST_MAX_UNIQUEID];
/*! Time of last packet sent */
@@ -364,6 +366,10 @@ static void instance_destructor(void *obj)
res_srtp->destroy(instance->srtp);
}
+ if (instance->rtcp_srtp) {
+ res_srtp->destroy(instance->rtcp_srtp);
+ }
+
ast_rtp_codecs_payloads_destroy(&instance->codecs);
/* Drop our engine reference */
@@ -2052,29 +2058,38 @@ int ast_rtp_engine_srtp_is_registered(void)
return res_srtp && res_srtp_policy;
}
-int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *remote_policy, struct ast_srtp_policy *local_policy)
+int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *remote_policy, struct ast_srtp_policy *local_policy, int rtcp)
{
int res = 0;
+ struct ast_srtp **srtp;
if (!res_srtp) {
return -1;
}
- if (!instance->srtp) {
- res = res_srtp->create(&instance->srtp, instance, remote_policy);
+
+ srtp = rtcp ? &instance->rtcp_srtp : &instance->srtp;
+
+ if (!*srtp) {
+ res = res_srtp->create(srtp, instance, remote_policy);
} else {
- res = res_srtp->replace(&instance->srtp, instance, remote_policy);
+ res = res_srtp->replace(srtp, instance, remote_policy);
}
if (!res) {
- res = res_srtp->add_stream(instance->srtp, local_policy);
+ res = res_srtp->add_stream(*srtp, local_policy);
}
return res;
}
-struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance)
+struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
{
- return instance->srtp;
+ if (rtcp && instance->rtcp_srtp) {
+ return instance->rtcp_srtp;
+ }
+ else {
+ return instance->srtp;
+ }
}
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)