From 16fa338b49bd2e74a8e010850d02f05b3eee4d2b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 2 Feb 2013 23:57:27 -0600 Subject: [PATCH] cleanup debug and memory and add stupid code for using sep dtls session when rtcp is not mux --- src/include/switch_rtp.h | 4 +- src/mod/endpoints/mod_sofia/sofia_reg.c | 2 - src/switch_core_cert.c | 4 + src/switch_core_media.c | 112 +++++--- src/switch_rtp.c | 351 ++++++++++++++---------- 5 files changed, 288 insertions(+), 185 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 825aec1af7..91e7251496 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -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; diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 5df0243283..de613a482f 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -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); diff --git a/src/switch_core_cert.c b/src/switch_core_cert.c index 58c140d3e7..bbcfb18505 100644 --- a/src/switch_core_cert.c +++ b/src/switch_core_cert.c @@ -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; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 4b5c830ae3..bc443c9a6d 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -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, diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 5afb17d3a2..ad521de3be 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -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)); - - - 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); - - 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_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"); - - - 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); - - 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_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 (!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); - - 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; - - 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_SERVER)) { - SSL_set_accept_state(dtls->ssl); - } else { - SSL_set_connect_state(dtls->ssl); - } - - - return SWITCH_STATUS_SUCCESS; + 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; } - 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->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_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_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->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); + + 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 (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; + } + + 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); + + 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); + + 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_SERVER)) { + SSL_set_accept_state(dtls->ssl); + } else { + SSL_set_connect_state(dtls->ssl); + } + + + 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); }