Skip to content
This repository has been archived by the owner on Jan 14, 2020. It is now read-only.

Commit

Permalink
res_rtp_asterisk: Add support for DTLS handshake retransmissions
Browse files Browse the repository at this point in the history
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
........

Merged revisions 413009 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: http://svn.asterisk.org/svn/asterisk/trunk@413012 f38db490-d61c-443f-a65b-d21fe96a405b
  • Loading branch information
matt-jordan committed Apr 25, 2014
1 parent b274a46 commit 9fd9783
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions res/res_rtp_asterisk.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ struct ast_rtp {
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 */
Expand All @@ -291,6 +292,7 @@ struct ast_rtp {
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
};

Expand Down Expand Up @@ -402,6 +404,7 @@ static int ast_rtp_sendcng(struct ast_rtp_instance *instance, int level);

#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);
Expand Down Expand Up @@ -1320,9 +1323,43 @@ static inline int rtcp_debug_test_addr(struct ast_sockaddr *addr)
}

#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];
Expand All @@ -1339,6 +1376,23 @@ static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct as

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);
}
}
Expand Down Expand Up @@ -1972,6 +2026,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,

#ifdef HAVE_OPENSSL_SRTP
rtp->rekeyid = -1;
rtp->dtlstimerid = -1;
#endif

return 0;
Expand Down Expand Up @@ -4319,6 +4374,9 @@ static void ast_rtp_stop(struct ast_rtp_instance *instance)

#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) {
Expand Down

0 comments on commit 9fd9783

Please sign in to comment.