res_rtp_asterisk: trigger source change control frame when dtls is established
authorKevin Harwell <kharwell@digium.com>
Thu, 29 Jun 2017 19:56:10 +0000 (14:56 -0500)
committerKevin Harwell <kharwell@digium.com>
Fri, 30 Jun 2017 15:57:33 +0000 (10:57 -0500)
There needed to be a way to notify handlers upstream that DTLS had been
established. This patch makes it so once DTLS has been estalished a source
change control frame is put into the read queue. Any handlers can then watch
for that frame and trigger off of it.

ASTERISK-27096 #close

Change-Id: I27ff344f5a8c691a1890dfe3254a4b1a49e7f4a0

res/res_rtp_asterisk.c

index 600846c..dc09166 100644 (file)
 #define SRTP_MASTER_SALT_LEN 14
 #define SRTP_MASTER_LEN (SRTP_MASTER_KEY_LEN + SRTP_MASTER_SALT_LEN)
 
+#define RTP_DTLS_ESTABLISHED -37
+
 enum strict_rtp_state {
        STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
        STRICT_RTP_LEARN,    /*! Accept next packet as source */
@@ -2477,7 +2479,11 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
                        /* Any further connections will be existing since this is now established */
                        dtls->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
                        /* Use the keying material to set up key/salt information */
-                       res = dtls_srtp_setup(rtp, srtp, instance, rtcp);
+                       if ((res = dtls_srtp_setup(rtp, srtp, instance, rtcp))) {
+                               return res;
+                       }
+                       /* Notify that dtls has been established */
+                       res = RTP_DTLS_ESTABLISHED;
                } else {
                        /* Since we've sent additional traffic start the timeout timer for retransmission */
                        dtls_srtp_start_timeout_timer(instance, rtp, rtcp);
@@ -4750,6 +4756,12 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
        /* Read in RTCP data from the socket */
        if ((res = rtcp_recvfrom(instance, read_area, read_area_size,
                                0, &addr)) < 0) {
+               if (res == RTP_DTLS_ESTABLISHED) {
+                       rtp->f.frametype = AST_FRAME_CONTROL;
+                       rtp->f.subclass.integer = AST_CONTROL_SRCCHANGE;
+                       return &rtp->f;
+               }
+
                ast_assert(errno != EBADF);
                if (errno != EAGAIN) {
                        ast_log(LOG_WARNING, "RTCP Read error: %s.  Hanging up.\n",
@@ -4947,6 +4959,12 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
        /* Actually read in the data from the socket */
        if ((res = rtp_recvfrom(instance, read_area, read_area_size, 0,
                                &addr)) < 0) {
+               if (res == RTP_DTLS_ESTABLISHED) {
+                       rtp->f.frametype = AST_FRAME_CONTROL;
+                       rtp->f.subclass.integer = AST_CONTROL_SRCCHANGE;
+                       return &rtp->f;
+               }
+
                ast_assert(errno != EBADF);
                if (errno != EAGAIN) {
                        ast_log(LOG_WARNING, "RTP Read error: %s.  Hanging up.\n",