]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
cleanup debug and memory and add stupid code for using sep dtls session when rtcp...
authorAnthony Minessale <anthm@freeswitch.org>
Sun, 3 Feb 2013 05:57:27 +0000 (23:57 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 1 Apr 2013 02:27:23 +0000 (21:27 -0500)
src/include/switch_rtp.h
src/mod/endpoints/mod_sofia/sofia_reg.c
src/switch_core_cert.c
src/switch_core_media.c
src/switch_rtp.c

index 825aec1af7301b2584ac3835d0b3647ff13f915b..91e7251496bcee7e57b2af5f8070c6afd5044f08 100644 (file)
@@ -53,6 +53,8 @@ SWITCH_BEGIN_EXTERN_C
        typedef enum {
        SWITCH_RTP_CRYPTO_SEND,
        SWITCH_RTP_CRYPTO_RECV,
+       SWITCH_RTP_CRYPTO_SEND_RTCP,
+       SWITCH_RTP_CRYPTO_RECV_RTCP,
        SWITCH_RTP_CRYPTO_MAX
 } switch_rtp_crypto_direction_t;
 
@@ -99,7 +101,7 @@ typedef struct ice_s {
 
        icand_t cands[MAX_CAND][2];
        int cand_idx;
-       int chosen;
+       int chosen[2];
        char *ufrag;
        char *pwd;
        char *options;
index 5df024328307ae0e01928fbe08f7ec24a9bd4d38..de613a482fa370b4cbf0400e097aee132798dfea 100644 (file)
@@ -1706,8 +1706,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
                                        abort();
                                }
 
-                               printf("SOFIA nh[%p] pvt[%p] call_id %s key %s\n", (void*) nh, (void *) sofia_private, call_id, key);
-                       
                                memset(sofia_private, 0, sizeof(*sofia_private));
                                sofia_private->call_id = su_strdup(nh->nh_home, call_id);
                                sofia_private->network_ip = su_strdup(nh->nh_home, network_ip);
index 58c140d3e71437128246db944b6732778cd91428..bbcfb185053d6f35e147d9b8ec32822380879aa2 100644 (file)
@@ -133,6 +133,10 @@ SWITCH_DECLARE(int) switch_core_cert_gen_fingerprint(const char *prefix, dtls_fi
                BIO_free_all(bio);
        }
 
+       if (x509) {
+               X509_free(x509);
+       }
+
        free(rsa);
        
        return ret;
index 4b5c830ae3945869c455e63c6195ac9f959730fc..bc443c9a6d8c4ac2c50753ff3d3af0fa94a24692 100644 (file)
@@ -140,6 +140,13 @@ typedef struct switch_rtp_engine_s {
        dtls_fingerprint_t local_dtls_fingerprint;
        dtls_fingerprint_t remote_dtls_fingerprint;
 
+       char *remote_rtp_ice_addr;
+       switch_port_t remote_rtp_ice_port;
+
+       char *remote_rtcp_ice_addr;
+       switch_port_t remote_rtcp_ice_port;
+
+
 
 } switch_rtp_engine_t;
 
@@ -1793,15 +1800,11 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
        switch_rtp_engine_t *engine = &smh->engines[type];
        sdp_attribute_t *attr;
        int i = 0, got_rtcp_mux = 0;
-       char tmp[80] = "";
 
-       engine->ice_in.chosen = 0;
+       engine->ice_in.chosen[0] = 0;
+       engine->ice_in.chosen[1] = 0;
        engine->ice_in.cand_idx = 0;
 
-       for (attr = m->m_attributes; attr; attr = attr->a_next) {
-
-       }
-       
 
        for (attr = m->m_attributes; attr; attr = attr->a_next) {
                char *data;
@@ -1842,8 +1845,8 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
 
 #ifdef RTCP_MUX
                } else if (!strcasecmp(attr->a_name, "rtcp-mux")) {
-                       engine->remote_rtcp_port = engine->codec_params.remote_sdp_port;
                        engine->rtcp_mux = SWITCH_TRUE;
+                       engine->remote_rtcp_port = engine->codec_params.remote_sdp_port;
                        got_rtcp_mux++;
 #endif
                } else if (!strcasecmp(attr->a_name, "candidate")) {
@@ -1876,23 +1879,23 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
                        }
 
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, 
-                                                         "Checking Candidate cid: %d proto: %s type: %s addr: %s\n", cid+1, fields[2], fields[7], fields[4]);
+                                                         "Checking Candidate cid: %d proto: %s type: %s addr: %s:%s\n", cid+1, fields[2], fields[7], fields[4], fields[5]);
 
 
                        engine->ice_in.cand_idx++;
 
                        for (i = 0; i < engine->cand_acl_count; i++) {
-                               if (!engine->ice_in.chosen && switch_check_network_list_ip(fields[4], engine->cand_acl[i])) {
-                                       engine->ice_in.chosen = engine->ice_in.cand_idx;
+                               if (!engine->ice_in.chosen[cid] && switch_check_network_list_ip(fields[4], engine->cand_acl[i])) {
+                                       engine->ice_in.chosen[cid] = engine->ice_in.cand_idx;
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE, 
-                                                                         "Choose %s Candidate cid: %d proto: %s type: %s addr: %s\n", 
+                                                                         "Choose %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n", 
                                                                          type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
-                                                                         cid+1, fields[2], fields[7], fields[4]);
+                                                                         cid+1, fields[2], fields[7], fields[4], fields[5]);
                                } else {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE, 
-                                                                         "Save %s Candidate cid: %d proto: %s type: %s addr: %s\n", 
+                                                                         "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n", 
                                                                          type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
-                                                                         cid+1, fields[2], fields[7], fields[4]);
+                                                                         cid+1, fields[2], fields[7], fields[4], fields[5]);
                                }
 
                                engine->ice_in.cands[engine->ice_in.cand_idx][cid].foundation = switch_core_session_strdup(smh->session, fields[0]);
@@ -1918,8 +1921,8 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
                                        j += 2;
                                } 
 
-                               if (engine->ice_in.chosen) {
-                                       engine->ice_in.cands[engine->ice_in.chosen][cid].ready++;
+                               if (engine->ice_in.chosen[cid]) {
+                                       engine->ice_in.cands[engine->ice_in.chosen[cid]][cid].ready++;
                                }
                                
                                break;
@@ -1929,31 +1932,41 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
        }
 
        for (i = 0; i < 2; i++) {
-               if (engine->ice_in.cands[engine->ice_in.chosen][i].ready) {
+               if (engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready) {
                        if (zstr(engine->ice_in.ufrag) || zstr(engine->ice_in.pwd)) {
-                               engine->ice_in.cands[engine->ice_in.chosen][i].ready = 0;
+                               engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready = 0;
                        }
                }
        }
 
 
-       if (engine->ice_in.cands[engine->ice_in.chosen][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen][0].con_port) {
-               engine->codec_params.remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen][0].con_addr);
-               engine->codec_params.remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen][0].con_port;
+       if (engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
+               char tmp[80] = "";
+               engine->codec_params.remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE, 
-                                                 "setting remote %s addr to %s:%d based on candidate\n", type2str(type),
-                                                 engine->ice_in.cands[engine->ice_in.chosen][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen][0].con_port);
+                                                 "setting remote %s ice addr to %s:%d based on candidate\n", type2str(type),
+                                                 engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
 
+               engine->remote_rtp_ice_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
+               engine->remote_rtp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
+
+               engine->codec_params.remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
+               engine->codec_params.remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
+
+                                                                                                                                
                switch_snprintf(tmp, sizeof(tmp), "%d", engine->codec_params.remote_sdp_port);
                switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, engine->codec_params.remote_sdp_ip);
                switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);                                     
        }
 
-       if (engine->ice_in.cands[engine->ice_in.chosen][1].con_port) {
+       if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE,
                                                  "setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type),
-                                                 engine->ice_in.cands[engine->ice_in.chosen][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen][1].con_port);
-               engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen][1].con_port;
+                                                 engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
+               engine->remote_rtcp_ice_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
+               engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
+
+               engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
        }
 
 
@@ -3706,16 +3719,22 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
 
 
                if (!zstr(a_engine->local_dtls_fingerprint.str)) {
-                       dtls_type_t dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
+                       dtls_type_t xtype, dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
 
-                       dtype |= DTLS_TYPE_RTP;
-                       if (a_engine->rtcp_mux > 0) dtype |= DTLS_TYPE_RTCP;
+                       xtype = DTLS_TYPE_RTP;
+                       if (a_engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP;
                
-                       switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype);
+                       switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype);
+
+                       if (a_engine->rtcp_mux < 1) {
+                               xtype = DTLS_TYPE_RTCP;
+                               switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype);
+                       }
+
                }
 
 
-               if (a_engine->ice_in.cands[a_engine->ice_in.chosen][0].ready) {
+               if (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready) {
                        
                        gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, NULL, 0);
 
@@ -3766,7 +3785,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                        }
 
 
-                       if (a_engine->ice_in.cands[a_engine->ice_in.chosen][1].ready && a_engine->rtcp_mux < 1) {
+                       if (a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].ready) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP ICE\n");
                                
                                switch_rtp_activate_ice(a_engine->rtp_session, 
@@ -4096,16 +4115,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                                        switch_rtp_set_ssrc(v_engine->rtp_session, v_engine->ssrc);
                                }
 
-                               if (!zstr(v_engine->local_dtls_fingerprint.str)) {
-                                       dtls_type_t dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
-                                       
-                                       dtype |= DTLS_TYPE_RTP;
-                                       if (v_engine->rtcp_mux > 0) dtype |= DTLS_TYPE_RTCP;
-                                       
-                                       switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype);
-                               }
 
-                               if (v_engine->ice_in.cands[v_engine->ice_in.chosen][0].ready) {
+                               if (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready) {
                                        
                                        gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, NULL, 0);
                                        
@@ -4150,7 +4161,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                                        }
                                        
 
-                                       if (v_engine->ice_in.cands[v_engine->ice_in.chosen][1].ready && v_engine->rtcp_mux < 1) {
+                                       if (!zstr(v_engine->local_dtls_fingerprint.str)) {
+                                               dtls_type_t xtype, 
+                                                       dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
+                                               printf("FUCK FP XXXXX %d\n", v_engine->rtcp_mux);
+                                               xtype = DTLS_TYPE_RTP;
+                                               if (v_engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP;
+                                       
+                                               switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype);
+
+                                               if (v_engine->rtcp_mux < 1) {
+                                                       xtype = DTLS_TYPE_RTCP;
+                                                       printf("FUCKER\n");
+                                                       switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype);
+                                               }
+                                       }
+                                       
+
+                                       if (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].ready) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP ICE\n");
                                                switch_rtp_activate_ice(v_engine->rtp_session, 
                                                                                                v_engine->ice_in.ufrag,
index 5afb17d3a2de40348f18d13cba183364e1e61f34..ad521de3be7bae6bb1f1713bbf0812f2d1c940c1 100644 (file)
@@ -240,12 +240,18 @@ struct switch_rtp {
        uint32_t autoadj_window;
        uint32_t autoadj_tally;
 
-       srtp_ctx_t *send_ctx;
-       srtp_ctx_t *recv_ctx;
-       srtp_policy_t send_policy;
-       srtp_policy_t recv_policy;
-       uint32_t srtp_errs;
-       uint32_t srctp_errs;
+       srtp_ctx_t *send_ctx[2];
+       srtp_ctx_t *recv_ctx[2];
+
+       srtp_policy_t send_policy[2];
+       srtp_policy_t recv_policy[2];
+
+       uint32_t srtp_errs[2];
+       uint32_t srctp_errs[2];
+
+
+       int srtp_idx_rtp;
+       int srtp_idx_rtcp;
 
        switch_dtls_t *dtls;
        switch_dtls_t *rtcp_dtls;
@@ -720,7 +726,7 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice)
        if ((ice->type & ICE_VANILLA)) {
                char sw[128] = "";
 
-               switch_stun_packet_attribute_add_priority(packet, ice->ice_params->cands[ice->ice_params->chosen][ice->proto].priority);
+               switch_stun_packet_attribute_add_priority(packet, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].priority);
 
                switch_snprintf(sw, sizeof(sw), "FreeSWITCH (%s)", SWITCH_VERSION_REVISION_HUMAN);
                switch_stun_packet_attribute_add_software(packet, sw, strlen(sw));
@@ -792,7 +798,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
        memcpy(buf, data, cpylen);
        packet = switch_stun_packet_parse(buf, cpylen);
        if (!packet) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Invalid STUN/ICE packet received\n");
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Invalid STUN/ICE packet received %ld %d\n", cpylen, *(uint8_t *) data);
                goto end;
 
        }
@@ -829,7 +835,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
                case SWITCH_STUN_ATTR_PRIORITY:
                        {
                                pri = (uint32_t *) attr->value;
-                               ok = *pri == ice->ice_params->cands[ice->ice_params->chosen][ice->proto].priority;
+                               ok = *pri == ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].priority;
                        }
                        break;
                }
@@ -846,7 +852,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
 
        if (ice->type == ICE_VANILLA) {
                if (!ok && ice == &rtp_session->ice && pri && 
-                       *pri == rtp_session->rtcp_ice.ice_params->cands[rtp_session->rtcp_ice.ice_params->chosen][1].priority) {
+                       *pri == rtp_session->rtcp_ice.ice_params->cands[rtp_session->rtcp_ice.ice_params->chosen[1]][1].priority) {
                        ice = &rtp_session->rtcp_ice;
                        ok = 1;
                }
@@ -874,7 +880,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
                                        for (i = 0; i < icep[j]->ice_params->cand_idx; i++) {
                                                if (icep[j]->ice_params->cands[i][icep[j]->proto].priority == *pri) {
                                                        if (j == IPR_RTP) {
-                                                               icep[j]->ice_params->chosen = i;
+                                                               icep[j]->ice_params->chosen[j] = i;
                                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Change candidate index to %d\n", i);
                                                        }
 
@@ -1320,7 +1326,7 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session)
 #ifdef ENABLE_SRTP
                if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND]) {
                        int sbytes = (int) rtcp_bytes;
-                       int stat = srtp_protect_rtcp(rtp_session->send_ctx, &rtp_session->rtcp_send_msg.header, &sbytes);
+                       int stat = srtp_protect_rtcp(rtp_session->send_ctx[rtp_session->srtp_idx_rtcp], &rtp_session->rtcp_send_msg.header, &sbytes);
                        
                        if (stat) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error: SRTP RTCP protection failed with code %d\n", stat);
@@ -1999,8 +2005,13 @@ static int dtls_state_setup(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
                memcpy(remote_key_buf, remote_key, cr_keylen);
                memcpy(remote_key_buf + cr_keylen, remote_salt, cr_saltlen);
                
-               switch_rtp_add_crypto_key(rtp_session, SWITCH_RTP_CRYPTO_SEND, 0, AES_CM_128_HMAC_SHA1_80, local_key_buf, cr_kslen);
-               switch_rtp_add_crypto_key(rtp_session, SWITCH_RTP_CRYPTO_RECV, 0, AES_CM_128_HMAC_SHA1_80, remote_key_buf, cr_kslen);
+               if (dtls == rtp_session->rtcp_dtls && rtp_session->rtcp_dtls != rtp_session->dtls) {
+                       switch_rtp_add_crypto_key(rtp_session, SWITCH_RTP_CRYPTO_SEND_RTCP, 0, AES_CM_128_HMAC_SHA1_80, local_key_buf, cr_kslen);
+                       switch_rtp_add_crypto_key(rtp_session, SWITCH_RTP_CRYPTO_RECV_RTCP, 0, AES_CM_128_HMAC_SHA1_80, remote_key_buf, cr_kslen);
+               } else {
+                       switch_rtp_add_crypto_key(rtp_session, SWITCH_RTP_CRYPTO_SEND, 0, AES_CM_128_HMAC_SHA1_80, local_key_buf, cr_kslen);
+                       switch_rtp_add_crypto_key(rtp_session, SWITCH_RTP_CRYPTO_RECV, 0, AES_CM_128_HMAC_SHA1_80, remote_key_buf, cr_kslen);
+               }
        }
 
        dtls_set_state(dtls, DS_READY);
@@ -2050,6 +2061,10 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
                        dtls_set_state(dtls, DS_FAIL);
                        return -1;
                }
+
+               if (dtls->state == DS_READY) {
+                       dtls_set_state(dtls, DS_HANDSHAKE);
+               }
        }
 
        if (SSL_read(dtls->ssl, dtls->data, dtls->bytes) == dtls->bytes) {
@@ -2117,102 +2132,105 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, 
                                          "Activate %s DTLS %s\n", rtp_type(rtp_session), (type & DTLS_TYPE_SERVER) ? "server" : "cleint");
 
-       if (!(dtls = rtp_session->dtls)) {
-               dtls = switch_core_alloc(rtp_session->pool, sizeof(*dtls));
+       if (((type & DTLS_TYPE_RTP) && rtp_session->dtls) || ((type & DTLS_TYPE_RTCP) && rtp_session->rtcp_dtls)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "DTLS ALREADY INIT\n");
+               return SWITCH_STATUS_FALSE;
+       }
+
+
+
+       dtls = switch_core_alloc(rtp_session->pool, sizeof(*dtls));
 
                
-               dtls->pvt = switch_core_sprintf(rtp_session->pool, "%s%s%s.key", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, DTLS_SRTP_FNAME);
-               dtls->rsa = switch_core_sprintf(rtp_session->pool, "%s%s%s.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, DTLS_SRTP_FNAME);
-               //dtls->ca = switch_core_sprintf(rtp_session->pool, "%s%sca-bundle.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR);
+       dtls->pvt = switch_core_sprintf(rtp_session->pool, "%s%s%s.key", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, DTLS_SRTP_FNAME);
+       dtls->rsa = switch_core_sprintf(rtp_session->pool, "%s%s%s.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, DTLS_SRTP_FNAME);
+       //dtls->ca = switch_core_sprintf(rtp_session->pool, "%s%sca-bundle.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR);
                
-               dtls->ssl_ctx = SSL_CTX_new(DTLSv1_method());
-               switch_assert(dtls->ssl_ctx);
+       dtls->ssl_ctx = SSL_CTX_new(DTLSv1_method());
+       switch_assert(dtls->ssl_ctx);
 
-               SSL_CTX_set_mode(dtls->ssl_ctx, SSL_MODE_AUTO_RETRY);
+       SSL_CTX_set_mode(dtls->ssl_ctx, SSL_MODE_AUTO_RETRY);
 
 
-               //SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
-               SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_NONE, NULL); 
+       //SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+       SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_NONE, NULL); 
 
-               SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL");
+       SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL");
                
 
-               //SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32");
-               SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80");
+       //SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32");
+       SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80");
 
        
-               dtls->type = type;
-               dtls->read_bio = BIO_new(BIO_s_mem());
-               switch_assert(dtls->read_bio);
+       dtls->type = type;
+       dtls->read_bio = BIO_new(BIO_s_mem());
+       switch_assert(dtls->read_bio);
 
-               dtls->write_bio = BIO_new(BIO_s_mem());
-               switch_assert(dtls->write_bio);
+       dtls->write_bio = BIO_new(BIO_s_mem());
+       switch_assert(dtls->write_bio);
                
-               BIO_set_mem_eof_return(dtls->read_bio, -1);
-               BIO_set_mem_eof_return(dtls->write_bio, -1);
+       BIO_set_mem_eof_return(dtls->read_bio, -1);
+       BIO_set_mem_eof_return(dtls->write_bio, -1);
 
-               if ((ret=SSL_CTX_use_certificate_file(dtls->ssl_ctx, dtls->rsa, SSL_FILETYPE_PEM)) != 1) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS cert err [%d]\n", rtp_type(rtp_session), SSL_get_error(dtls->ssl, ret));
-                       return SWITCH_STATUS_FALSE;
-               }
+       if ((ret=SSL_CTX_use_certificate_file(dtls->ssl_ctx, dtls->rsa, SSL_FILETYPE_PEM)) != 1) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS cert err [%d]\n", rtp_type(rtp_session), SSL_get_error(dtls->ssl, ret));
+               return SWITCH_STATUS_FALSE;
+       }
 
-               if ((ret=SSL_CTX_use_PrivateKey_file(dtls->ssl_ctx, dtls->pvt, SSL_FILETYPE_PEM)) != 1) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS key err [%d]\n", rtp_type(rtp_session), SSL_get_error(dtls->ssl, ret));
-                       return SWITCH_STATUS_FALSE;
-               }
+       if ((ret=SSL_CTX_use_PrivateKey_file(dtls->ssl_ctx, dtls->pvt, SSL_FILETYPE_PEM)) != 1) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS key err [%d]\n", rtp_type(rtp_session), SSL_get_error(dtls->ssl, ret));
+               return SWITCH_STATUS_FALSE;
+       }
 
-               if (SSL_CTX_check_private_key(dtls->ssl_ctx) == 0) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check key failed\n", rtp_type(rtp_session));
-                       return SWITCH_STATUS_FALSE;
-               }
+       if (SSL_CTX_check_private_key(dtls->ssl_ctx) == 0) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check key failed\n", rtp_type(rtp_session));
+               return SWITCH_STATUS_FALSE;
+       }
 
-               if (!zstr(dtls->ca) && (ret=SSL_CTX_load_verify_locations(dtls->ssl_ctx, dtls->ca, NULL)) != 1) {
-                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check chain cert failed [%d]\n",
-                                                         rtp_type(rtp_session) ,
-                                                         SSL_get_error(dtls->ssl, ret));
-                       return SWITCH_STATUS_FALSE;
-               }
+       if (!zstr(dtls->ca) && (ret=SSL_CTX_load_verify_locations(dtls->ssl_ctx, dtls->ca, NULL)) != 1) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check chain cert failed [%d]\n",
+                                                 rtp_type(rtp_session) ,
+                                                 SSL_get_error(dtls->ssl, ret));
+               return SWITCH_STATUS_FALSE;
+       }
 
-               dtls->ssl = SSL_new(dtls->ssl_ctx);
+       dtls->ssl = SSL_new(dtls->ssl_ctx);
 
-               SSL_set_bio(dtls->ssl, dtls->read_bio, dtls->write_bio);
-               SSL_set_mode(dtls->ssl, SSL_MODE_AUTO_RETRY);
-               SSL_set_read_ahead(dtls->ssl, 1);
-               //SSL_set_verify(dtls->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), cb_verify_peer);
-               SSL_set_verify(dtls->ssl, SSL_VERIFY_NONE, NULL);
-               SSL_set_app_data(dtls->ssl, dtls);
+       SSL_set_bio(dtls->ssl, dtls->read_bio, dtls->write_bio);
+       SSL_set_mode(dtls->ssl, SSL_MODE_AUTO_RETRY);
+       SSL_set_read_ahead(dtls->ssl, 1);
+       //SSL_set_verify(dtls->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), cb_verify_peer);
+       SSL_set_verify(dtls->ssl, SSL_VERIFY_NONE, NULL);
+       SSL_set_app_data(dtls->ssl, dtls);
 
-               dtls->local_fp = local_fp;
-               dtls->remote_fp = remote_fp;
-               dtls->rtp_session = rtp_session;
+       dtls->local_fp = local_fp;
+       dtls->remote_fp = remote_fp;
+       dtls->rtp_session = rtp_session;
                
-               switch_core_cert_expand_fingerprint(remote_fp, remote_fp->str);
+       switch_core_cert_expand_fingerprint(remote_fp, remote_fp->str);
 
-               if ((type & DTLS_TYPE_RTP)) {
-                       rtp_session->dtls = dtls;
-                       dtls->sock_output = rtp_session->sock_output;
-                       dtls->remote_addr = rtp_session->remote_addr;
-               }
-
-               if ((type & DTLS_TYPE_RTCP)) {
-                       rtp_session->rtcp_dtls = dtls;
-                       if (!(type & DTLS_TYPE_RTP)) {
-                               dtls->sock_output = rtp_session->rtcp_sock_output;
-                               dtls->remote_addr = rtp_session->rtcp_remote_addr;
-                       }
-               }
+       if ((type & DTLS_TYPE_RTP)) {
+               rtp_session->dtls = dtls;
+               dtls->sock_output = rtp_session->sock_output;
+               dtls->remote_addr = rtp_session->remote_addr;
+       }
 
-               if ((type & DTLS_TYPE_SERVER)) {
-                       SSL_set_accept_state(dtls->ssl);
-               } else {
-                       SSL_set_connect_state(dtls->ssl);
+       if ((type & DTLS_TYPE_RTCP)) {
+               rtp_session->rtcp_dtls = dtls;
+               if (!(type & DTLS_TYPE_RTP)) {
+                       dtls->sock_output = rtp_session->rtcp_sock_output;
+                       dtls->remote_addr = rtp_session->rtcp_remote_addr;
                }
+       }
 
-               
-               return SWITCH_STATUS_SUCCESS;
+       if ((type & DTLS_TYPE_SERVER)) {
+               SSL_set_accept_state(dtls->ssl);
+       } else {
+               SSL_set_connect_state(dtls->ssl);
        }
 
-       return SWITCH_STATUS_FALSE;
+               
+       return SWITCH_STATUS_SUCCESS;
        
 }
 
@@ -2232,6 +2250,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
        
        switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session);
        switch_event_t *fsevent = NULL;
+       int idx = 0;
 
        if (direction >= SWITCH_RTP_CRYPTO_MAX || keylen > SWITCH_RTP_MAX_CRYPTO_LEN) {
                return SWITCH_STATUS_FALSE;
@@ -2239,10 +2258,18 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
 
        crypto_key = switch_core_alloc(rtp_session->pool, sizeof(*crypto_key));
 
+       if (direction == SWITCH_RTP_CRYPTO_RECV_RTCP) {
+               direction = SWITCH_RTP_CRYPTO_RECV;
+               rtp_session->srtp_idx_rtcp = idx = 1;
+       } else if (direction == SWITCH_RTP_CRYPTO_SEND_RTCP) {
+               direction = SWITCH_RTP_CRYPTO_SEND;
+               rtp_session->srtp_idx_rtcp = idx = 1;
+       }
+
        if (direction == SWITCH_RTP_CRYPTO_RECV) {
-               policy = &rtp_session->recv_policy;
+               policy = &rtp_session->recv_policy[idx];
        } else {
-               policy = &rtp_session->send_policy;
+               policy = &rtp_session->send_policy[idx];
        }
 
        crypto_key->type = type;
@@ -2305,10 +2332,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
        case SWITCH_RTP_CRYPTO_RECV:
                policy->ssrc.type = ssrc_any_inbound;
 
-               if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV]) {
+               if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && idx == 0) {
                        rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV_RESET] = 1;
                } else {
-                       if ((stat = srtp_create(&rtp_session->recv_ctx, policy))) {
+                       if ((stat = srtp_create(&rtp_session->recv_ctx[idx], policy))) {
                                status = SWITCH_STATUS_FALSE;
                        }
 
@@ -2327,10 +2354,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
                //policy->ssrc.type = ssrc_specific;
                //policy->ssrc.value = rtp_session->ssrc;
 
-               if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND]) {
+               if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] && idx == 0) {
                        rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_RESET] = 1;
                } else {
-                       if ((stat = srtp_create(&rtp_session->send_ctx, policy))) {
+                       if ((stat = srtp_create(&rtp_session->send_ctx[idx], policy))) {
                                status = SWITCH_STATUS_FALSE;
                        }
 
@@ -3027,10 +3054,32 @@ SWITCH_DECLARE(uint8_t) switch_rtp_ready(switch_rtp_t *rtp_session)
        return ret;
 }
 
+static void free_dtls(switch_dtls_t **dtlsp)
+{
+       switch_dtls_t *dtls;
+
+       if (!dtlsp) {
+               return;
+       }
+
+       dtls = *dtlsp;
+       *dtlsp = NULL;
+
+       if (dtls->ssl) {
+               SSL_free(dtls->ssl);
+       }
+
+       if (dtls->ssl_ctx) {
+               SSL_CTX_free(dtls->ssl_ctx);
+       }
+}
+
+
 SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
 {
        void *pop;
        switch_socket_t *sock;
+       int x;
 
        if (!rtp_session || !*rtp_session || !(*rtp_session)->ready) {
                return;
@@ -3062,6 +3111,19 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
                stfu_n_destroy(&(*rtp_session)->jb);
        }
 
+       if ((*rtp_session)->dtls && (*rtp_session)->dtls == (*rtp_session)->rtcp_dtls) {
+               (*rtp_session)->rtcp_dtls = NULL;
+       }
+
+       if ((*rtp_session)->dtls) {
+               free_dtls(&(*rtp_session)->dtls);
+       }
+
+       if ((*rtp_session)->rtcp_dtls) {
+               free_dtls(&(*rtp_session)->rtcp_dtls);
+       }
+
+
        sock = (*rtp_session)->sock_input;
        (*rtp_session)->sock_input = NULL;
        switch_socket_close(sock);
@@ -3090,14 +3152,22 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
 
 #ifdef ENABLE_SRTP
        if ((*rtp_session)->flags[SWITCH_RTP_FLAG_SECURE_SEND]) {
-               srtp_dealloc((*rtp_session)->send_ctx);
-               (*rtp_session)->send_ctx = NULL;
+               for(x = 0; x < 2; x++) {
+                       if ((*rtp_session)->send_ctx[x]) {
+                               srtp_dealloc((*rtp_session)->send_ctx[x]);
+                               (*rtp_session)->send_ctx[x] = NULL;
+                       }
+               }
                (*rtp_session)->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 0;
        }
 
        if ((*rtp_session)->flags[SWITCH_RTP_FLAG_SECURE_RECV]) {
-               srtp_dealloc((*rtp_session)->recv_ctx);
-               (*rtp_session)->recv_ctx = NULL;
+               for (x = 0; x < 2; x++) {
+                       if ((*rtp_session)->recv_ctx[x]) {
+                               srtp_dealloc((*rtp_session)->recv_ctx[x]);
+                               (*rtp_session)->recv_ctx[x] = NULL;
+                       }
+               }
                (*rtp_session)->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 0;
        }
 #endif
@@ -3525,6 +3595,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                char *b = (char *) &rtp_session->recv_msg;
                
                //printf("RECV %d %ld\n", *b, *bytes);
+
                
                if ((*b >= 20) && (*b <= 64)) {
                        rtp_session->dtls->bytes = *bytes;
@@ -3533,7 +3604,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                        rtp_session->dtls->bytes = 0;
                        rtp_session->dtls->data = NULL;
                        
-                       if (*b != 0 && *b != 1 && rtp_session->dtls->state != DS_READY) {
+                       if (0 && *b != 0 && *b != 1 && rtp_session->dtls->state != DS_READY) {
                                *bytes = 0;
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Drop %s packet %ld bytes (dtls not ready!)\n", rtp_type(rtp_session), *bytes);
                        }
@@ -3681,25 +3752,25 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 
                                if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV_RESET]) {
                                        switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV_RESET);
-                                       srtp_dealloc(rtp_session->recv_ctx);
-                                       rtp_session->recv_ctx = NULL;
-                                       if ((stat = srtp_create(&rtp_session->recv_ctx, &rtp_session->recv_policy))) {
+                                       srtp_dealloc(rtp_session->recv_ctx[rtp_session->srtp_idx_rtp]);
+                                       rtp_session->recv_ctx[rtp_session->srtp_idx_rtp] = NULL;
+                                       if ((stat = srtp_create(&rtp_session->recv_ctx[rtp_session->srtp_idx_rtp], &rtp_session->recv_policy[rtp_session->srtp_idx_rtp]))) {
                                                
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error! RE-Activating Secure RTP RECV\n");
                                                return SWITCH_STATUS_FALSE;
                                        } else {
                                                
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "RE-Activating Secure RTP RECV\n");
-                                               rtp_session->srtp_errs = 0;
+                                               rtp_session->srtp_errs[rtp_session->srtp_idx_rtp] = 0;
                                        }
                                }
 
                                if (!(*flags & SFF_PLC)) {
-                                       stat = srtp_unprotect(rtp_session->recv_ctx, &rtp_session->recv_msg.header, &sbytes);
+                                       stat = srtp_unprotect(rtp_session->recv_ctx[rtp_session->srtp_idx_rtp], &rtp_session->recv_msg.header, &sbytes);
                                }
 
                                if (stat && rtp_session->recv_msg.header.pt != rtp_session->recv_te && rtp_session->recv_msg.header.pt != rtp_session->cng_pt) {
-                                       if (++rtp_session->srtp_errs >= MAX_SRTP_ERRS) {
+                                       if (++rtp_session->srtp_errs[rtp_session->srtp_idx_rtp] >= MAX_SRTP_ERRS) {
                                                
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR,
                                                                                  "Error: SRTP %s unprotect failed with code %d%s %ld\n", rtp_type(rtp_session), stat,
@@ -3710,7 +3781,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                                                sbytes = 0;
                                        }
                                } else {
-                                       rtp_session->srtp_errs = 0;
+                                       rtp_session->srtp_errs[rtp_session->srtp_idx_rtp] = 0;
                                }
 
                                *bytes = sbytes;
@@ -3855,7 +3926,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
        if (rtp_session->rtcp_dtls) {
                char *b = (char *) &rtp_session->rtcp_recv_msg;
                
-               //printf("RECV %d %ld\n", *b, *bytes);
+               //printf("RECV2 %d %ld\n", *b, *bytes);
                
                if ((*b >= 20) && (*b <= 64)) {
                        rtp_session->rtcp_dtls->bytes = *bytes;
@@ -3881,11 +3952,11 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
                err_status_t stat = 0;
                
 
-               if ((stat = srtp_unprotect_rtcp(rtp_session->recv_ctx, &rtp_session->rtcp_recv_msg_p->header, &sbytes))) {
-                       //++rtp_session->srtp_errs++;
+               if ((stat = srtp_unprotect_rtcp(rtp_session->recv_ctx[rtp_session->srtp_idx_rtcp], &rtp_session->rtcp_recv_msg_p->header, &sbytes))) {
+                       //++rtp_session->srtp_errs[rtp_session->srtp_idx_rtp]++;
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "RTCP UNPROTECT ERR\n");
                } else {
-                       //rtp_session->srtp_errs = 0;
+                       //rtp_session->srtp_errs[rtp_session->srtp_idx_rtp] = 0;
                }
                
                *bytes = sbytes;
@@ -4202,7 +4273,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 #ifdef ENABLE_SRTP
                                                                        if (switch_rtp_test_flag(other_rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) {
                                                                                int sbytes = (int) rtcp_bytes;
-                                                                               int stat = srtp_protect_rtcp(other_rtp_session->send_ctx, &other_rtp_session->rtcp_send_msg.header, &sbytes);
+                                                                               int stat = srtp_protect_rtcp(other_rtp_session->send_ctx[rtp_session->srtp_idx_rtcp], &other_rtp_session->rtcp_send_msg.header, &sbytes);
                                                                                if (stat) {
                                                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error: SRTP RTCP protection failed with code %d\n", stat);
                                                                                }
@@ -5080,7 +5151,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
 
        if (rtp_session->ice.ice_user && !(rtp_session->ice.rready)) {
                send = 0;
-               //printf("XXX skip no stun love %d/%d\n", rtp_session->ice.ready, rtp_session->ice.rready);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Skip sending %s packet %ld bytes (ice not ready!)\n", rtp_type(rtp_session), bytes);
        }
 
        if (rtp_session->dtls && rtp_session->dtls->state != DS_READY) {
@@ -5104,9 +5175,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
                        if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_RESET]) {
                                
                                switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND_RESET);
-                               srtp_dealloc(rtp_session->send_ctx);
-                               rtp_session->send_ctx = NULL;
-                               if ((stat = srtp_create(&rtp_session->send_ctx, &rtp_session->send_policy))) {
+                               srtp_dealloc(rtp_session->send_ctx[rtp_session->srtp_idx_rtp]);
+                               rtp_session->send_ctx[rtp_session->srtp_idx_rtp] = NULL;
+                               if ((stat = srtp_create(&rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->send_policy[rtp_session->srtp_idx_rtp]))) {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error! RE-Activating Secure RTP SEND\n");
                                        ret = -1;
                                        goto end;
@@ -5116,7 +5187,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
                        }
 
 
-                       stat = srtp_protect(rtp_session->send_ctx, &send_msg->header, &sbytes);
+                       stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &send_msg->header, &sbytes);
                        if (stat) {
                                
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error: SRTP protection failed with code %d\n", stat);
@@ -5506,9 +5577,9 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
 
                if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_RESET]) {
                        switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND_RESET);
-                       srtp_dealloc(rtp_session->send_ctx);
-                       rtp_session->send_ctx = NULL;
-                       if ((stat = srtp_create(&rtp_session->send_ctx, &rtp_session->send_policy))) {
+                       srtp_dealloc(rtp_session->send_ctx[rtp_session->srtp_idx_rtp]);
+                       rtp_session->send_ctx[rtp_session->srtp_idx_rtp] = NULL;
+                       if ((stat = srtp_create(&rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->send_policy[rtp_session->srtp_idx_rtp]))) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error! RE-Activating Secure RTP SEND\n");
                                ret = -1;
                                goto end;
@@ -5517,7 +5588,7 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
                        }
                }
 
-               stat = srtp_protect(rtp_session->send_ctx, &rtp_session->write_msg.header, &sbytes);
+               stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg.header, &sbytes);
                if (stat) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error: SRTP protection failed with code %d\n", stat);
                }