[asterisk-commits] mjordan: branch 12 r413009 - in /branches/12: ./ res/res_rtp_asterisk.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Apr 25 12:48:27 CDT 2014
Author: mjordan
Date: Fri Apr 25 12:48:19 2014
New Revision: 413009
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=413009
Log:
res_rtp_asterisk: Add support for DTLS handshake retransmissions
On congested networks, it is possible for the DTLS handshake messages to get
lost. This patch adds a timer to res_rtp_asterisk that will periodically
check to see if the handshake has succeeded. If not, it will retransmit the
DTLS handshake.
Review: https://reviewboard.asterisk.org/r/3337
ASTERISK-23649 #close
Reported by: Nitesh Bansal
patches:
dtls_retransmission.patch uploaded by Nitesh Bansal (License 6418)
........
Merged revisions 413008 from http://svn.asterisk.org/svn/asterisk/branches/11
Modified:
branches/12/ (props changed)
branches/12/res/res_rtp_asterisk.c
Propchange: branches/12/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.
Modified: branches/12/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_rtp_asterisk.c?view=diff&rev=413009&r1=413008&r2=413009
==============================================================================
--- branches/12/res/res_rtp_asterisk.c (original)
+++ branches/12/res/res_rtp_asterisk.c Fri Apr 25 12:48:19 2014
@@ -283,6 +283,7 @@
SSL *ssl; /*!< SSL session */
BIO *read_bio; /*!< Memory buffer for reading */
BIO *write_bio; /*!< Memory buffer for writing */
+ ast_mutex_t dtls_timer_lock; /*!< Lock for synchronization purposes */
enum ast_rtp_dtls_setup dtls_setup; /*!< Current setup state */
enum ast_srtp_suite suite; /*!< SRTP crypto suite */
char local_fingerprint[160]; /*!< Fingerprint of our certificate */
@@ -291,6 +292,7 @@
unsigned int dtls_failure:1; /*!< Failure occurred during DTLS negotiation */
unsigned int rekey; /*!< Interval at which to renegotiate and rekey */
int rekeyid; /*!< Scheduled item id for rekeying */
+ int dtlstimerid; /*!< Scheduled item id for DTLS retransmission for RTP */
#endif
};
@@ -402,6 +404,7 @@
#ifdef HAVE_OPENSSL_SRTP
static int ast_rtp_activate(struct ast_rtp_instance *instance);
+static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp);
#endif
static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *ice, int use_srtp);
@@ -1320,9 +1323,43 @@
}
#ifdef HAVE_OPENSSL_SRTP
+
+static int dtls_srtp_handle_timeout(const void *data)
+{
+ struct ast_rtp_instance *instance = (struct ast_rtp_instance *)data;
+ struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+
+ if (!rtp)
+ {
+ return 0;
+ }
+
+ ast_mutex_lock(&rtp->dtls_timer_lock);
+ if (rtp->dtlstimerid == -1)
+ {
+ ast_mutex_unlock(&rtp->dtls_timer_lock);
+ ao2_ref(instance, -1);
+ return 0;
+ }
+
+ rtp->dtlstimerid = -1;
+ ast_mutex_unlock(&rtp->dtls_timer_lock);
+
+ if (rtp->ssl) {
+ DTLSv1_handle_timeout(rtp->ssl);
+ }
+
+ dtls_srtp_check_pending(instance, rtp);
+
+ ao2_ref(instance, -1);
+
+ return 0;
+}
+
static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp)
{
size_t pending = BIO_ctrl_pending(rtp->write_bio);
+ struct timeval dtls_timeout; /* timeout on DTLS */
if (pending > 0) {
char outgoing[pending];
@@ -1338,6 +1375,23 @@
}
out = BIO_read(rtp->write_bio, outgoing, sizeof(outgoing));
+
+ /* Stop existing DTLS timer if running */
+ ast_mutex_lock(&rtp->dtls_timer_lock);
+ if (rtp->dtlstimerid > -1) {
+ AST_SCHED_DEL_UNREF(rtp->sched, rtp->dtlstimerid, ao2_ref(instance, -1));
+ rtp->dtlstimerid = -1;
+ }
+
+ if (DTLSv1_get_timeout(rtp->ssl, &dtls_timeout)) {
+ int timeout = dtls_timeout.tv_sec * 1000 + dtls_timeout.tv_usec / 1000;
+ ao2_ref(instance, +1);
+ if ((rtp->dtlstimerid = ast_sched_add(rtp->sched, timeout, dtls_srtp_handle_timeout, instance)) < 0) {
+ ao2_ref(instance, -1);
+ ast_log(LOG_WARNING, "scheduling DTLS retransmission for RTP instance [%p] failed.\n", instance);
+ }
+ }
+ ast_mutex_unlock(&rtp->dtls_timer_lock);
__rtp_sendto(instance, outgoing, out, 0, &remote_address, 0, &ice, 0);
}
@@ -1972,6 +2026,7 @@
#ifdef HAVE_OPENSSL_SRTP
rtp->rekeyid = -1;
+ rtp->dtlstimerid = -1;
#endif
return 0;
@@ -4319,6 +4374,9 @@
#ifdef HAVE_OPENSSL_SRTP
AST_SCHED_DEL_UNREF(rtp->sched, rtp->rekeyid, ao2_ref(instance, -1));
+ ast_mutex_lock(&rtp->dtls_timer_lock);
+ AST_SCHED_DEL_UNREF(rtp->sched, rtp->dtlstimerid, ao2_ref(instance, -1));
+ ast_mutex_unlock(&rtp->dtls_timer_lock);
#endif
if (rtp->rtcp && rtp->rtcp->schedid > 0) {
More information about the asterisk-commits
mailing list