diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 477aa3b877..4699cd238f 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -170,6 +170,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME "__cache_speech_handles_obj__"
#define SWITCH_BYPASS_MEDIA_VARIABLE "bypass_media"
#define SWITCH_PROXY_MEDIA_VARIABLE "proxy_media"
+#define SWITCH_ZRTP_PASSTHRU_VARIABLE "zrtp_passthru"
#define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition"
#define SWITCH_HOLD_MUSIC_VARIABLE "hold_music"
#define SWITCH_TEMP_HOLD_MUSIC_VARIABLE "temp_hold_music"
@@ -1213,8 +1214,9 @@ typedef enum {
CF_VIDEO_REFRESH_REQ,
CF_SERVICE_AUDIO,
CF_SERVICE_VIDEO,
+ CF_ZRTP_PASSTHRU_REQ,
+ CF_ZRTP_PASSTHRU,
CF_ZRTP_HASH,
- CF_ZRTP_PASS,
CF_CHANNEL_SWAP,
CF_PICKUP,
CF_CONFIRM_BLIND_TRANSFER,
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index ebd009a16d..92a27fd0f2 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -2997,6 +2997,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
stream->write_function(stream, "NOMEDIA \t%s\n", sofia_test_flag(profile, TFLAG_INB_NOMEDIA) ? "true" : "false");
stream->write_function(stream, "LATE-NEG \t%s\n", sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION) ? "true" : "false");
stream->write_function(stream, "PROXY-MEDIA \t%s\n", sofia_test_flag(profile, TFLAG_PROXY_MEDIA) ? "true" : "false");
+ stream->write_function(stream, "ZRTP-PASSTHRU \t%s\n", sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU) ? "true" : "false");
stream->write_function(stream, "AGGRESSIVENAT \t%s\n",
sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ? "true" : "false");
stream->write_function(stream, "STUN-ENABLED \t%s\n", sofia_test_pflag(profile, PFLAG_STUN_ENABLED) ? "true" : "false");
@@ -3275,6 +3276,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_INB_NOMEDIA) ? "true" : "false");
stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION) ? "true" : "false");
stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_PROXY_MEDIA) ? "true" : "false");
+ stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU) ? "true" : "false");
stream->write_function(stream, " %s\n",
sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ? "true" : "false");
stream->write_function(stream, " %s\n",
@@ -4785,6 +4787,17 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
sofia_clear_flag(ctech_pvt, TFLAG_ENABLE_SOA);
}
+ if (switch_channel_test_flag(o_channel, CF_ZRTP_PASSTHRU_REQ)) {
+ const char *x = NULL;
+ sofia_glue_pass_zrtp_hash2(session, nsession);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[zrtp_passthru] Setting a-leg inherit_codec=true\n");
+ switch_channel_set_variable(o_channel, "inherit_codec", "true");
+ if ((x = switch_channel_get_variable(o_channel, "ep_codec_string"))) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[zrtp_passthru] Setting b-leg absolute_codec_string='%s'\n", x);
+ switch_channel_set_variable(nchannel, "absolute_codec_string", x);
+ }
+ }
+
/* SNARK: lets copy this across so we can see if we're the other leg of 3PCC + bypass_media... */
if (sofia_test_flag(ctech_pvt, TFLAG_3PCC) && (switch_channel_test_flag(o_channel, CF_PROXY_MODE) || switch_channel_test_flag(o_channel, CF_PROXY_MEDIA))) {
sofia_set_flag(tech_pvt, TFLAG_3PCC_INVITE);
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index f6e4c1122e..67d513cf27 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -317,6 +317,7 @@ typedef enum {
TFLAG_TPORT_LOG,
TFLAG_SENT_UPDATE,
TFLAG_PROXY_MEDIA,
+ TFLAG_ZRTP_PASSTHRU,
TFLAG_HOLD_LOCK,
TFLAG_3PCC_HAS_ACK,
TFLAG_PASS_RFC2833,
@@ -825,6 +826,11 @@ struct private_object {
switch_payload_t ianacodes[SWITCH_MAX_CODECS];
uint32_t session_timeout;
enum nua_session_refresher session_refresher;
+ /** ZRTP **/
+ char *local_sdp_audio_zrtp_hash;
+ char *local_sdp_video_zrtp_hash;
+ char *remote_sdp_audio_zrtp_hash;
+ char *remote_sdp_video_zrtp_hash;
};
struct callback_t {
@@ -932,6 +938,8 @@ void launch_sofia_profile_thread(sofia_profile_t *profile);
switch_status_t sofia_presence_chat_send(switch_event_t *message_event);
void sofia_glue_tech_absorb_sdp(private_object_t *tech_pvt);
+void sofia_glue_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session);
+void sofia_glue_pass_zrtp_hash(switch_core_session_t *session);
/*
* \brief Sets the "ep_codec_string" channel variable, parsing r_sdp and taing codec_string in consideration
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index e5d026975d..0621b3b84d 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -3321,6 +3321,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_flag(profile, TFLAG_PROXY_MEDIA);
}
+ } else if (!strcasecmp(var, "inbound-zrtp-passthru")) {
+ if (switch_true(val)) {
+ sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU);
+ } else {
+ sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU);
+ }
} else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_CALLID_AS_UUID);
@@ -3695,6 +3701,10 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
}
}
+ if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)) {
+ sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
+ }
+
if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
parse_gateways(profile, gateways_tag);
}
@@ -4171,6 +4181,8 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
} else if (!strcasecmp(var, "inbound-proxy-media") && switch_true(val)) {
sofia_set_flag(profile, TFLAG_PROXY_MEDIA);
+ } else if (!strcasecmp(var, "inbound-zrtp-passthru") && switch_true(val)) {
+ sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU);
} else if (!strcasecmp(var, "force-subscription-expires")) {
int tmp = atoi(val);
if (tmp > 0) {
@@ -4801,6 +4813,10 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
}
+ if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)) {
+ sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
+ }
+
if ((!profile->cng_pt) && (!sofia_test_pflag(profile, PFLAG_SUPPRESS_CNG))) {
profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD;
}
@@ -8264,6 +8280,10 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
switch_channel_set_flag(channel, CF_PROXY_MEDIA);
}
+ if (sofia_test_flag(tech_pvt, TFLAG_ZRTP_PASSTHRU)) {
+ switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU_REQ);
+ }
+
if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {
tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 0adcce9606..6bb7d3ee5f 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -184,7 +184,6 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
int rate;
int already_did[128] = { 0 };
int ptime = 0, noptime = 0;
- const char *zrtp;
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP",
port, secure ? "S" : "");
@@ -344,8 +343,11 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ptime:%d\n", cur_ptime);
}
- if ((zrtp = switch_channel_get_variable(tech_pvt->channel, "sdp_zrtp_hash_string"))) {
- switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=zrtp-hash:%s\n", zrtp);
+ if (tech_pvt->local_sdp_audio_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Adding audio a=zrtp-hash:%s\n",
+ tech_pvt->local_sdp_audio_zrtp_hash);
+ switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=zrtp-hash:%s\n",
+ tech_pvt->local_sdp_audio_zrtp_hash);
}
if (sr) {
@@ -391,7 +393,6 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
switch_event_t *map = NULL, *ptmap = NULL;
const char *b_sdp = NULL;
int verbose_sdp = 0;
- const char *zrtp;
sofia_glue_check_dtmf_type(tech_pvt);
@@ -545,8 +546,12 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", ptime);
}
- if ((zrtp = switch_channel_get_variable(tech_pvt->channel, "sdp_zrtp_hash_string"))) {
- switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=zrtp-hash:%s\n", zrtp);
+
+ if (tech_pvt->local_sdp_audio_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Adding audio a=zrtp-hash:%s\n",
+ tech_pvt->local_sdp_audio_zrtp_hash);
+ switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=zrtp-hash:%s\n",
+ tech_pvt->local_sdp_audio_zrtp_hash);
}
if (sr) {
@@ -747,6 +752,13 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
}
}
+
+ if (tech_pvt->local_sdp_video_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n",
+ tech_pvt->local_sdp_video_zrtp_hash);
+ switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=zrtp-hash:%s\n",
+ tech_pvt->local_sdp_video_zrtp_hash);
+ }
}
}
@@ -3563,9 +3575,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
- if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASS)) {
+ if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASSTHRU)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Disable NOTIMER_DURING_BRIDGE\n");
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Activating audio UDPTL mode\n");
switch_rtp_udptl_mode(tech_pvt->rtp_session);
}
@@ -3752,7 +3766,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
}
}
}
-
+ if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASSTHRU)) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Activating video UDPTL mode\n");
+ switch_rtp_udptl_mode(tech_pvt->video_rtp_session);
+ }
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
@@ -3837,7 +3854,93 @@ static void add_audio_codec(sdp_rtpmap_t *map, int ptime, char *buf, switch_size
}
+void sofia_glue_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session)
+{
+ switch_channel_t *aleg_channel = switch_core_session_get_channel(aleg_session);
+ private_object_t *aleg_tech_pvt = switch_core_session_get_private(aleg_session);
+ switch_channel_t *bleg_channel = switch_core_session_get_channel(bleg_session);
+ private_object_t *bleg_tech_pvt = switch_core_session_get_private(bleg_session);
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Deciding whether to pass zrtp-hash between a-leg and b-leg\n");
+ if (!(switch_channel_test_flag(aleg_tech_pvt->channel, CF_ZRTP_PASSTHRU_REQ))) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n");
+ return;
+ }
+ if (aleg_tech_pvt->remote_sdp_audio_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Passing a-leg remote zrtp-hash (audio) to b-leg\n");
+ bleg_tech_pvt->local_sdp_audio_zrtp_hash = switch_core_session_strdup(bleg_tech_pvt->session, aleg_tech_pvt->remote_sdp_audio_zrtp_hash);
+ switch_channel_set_variable(bleg_channel, "l_sdp_audio_zrtp_hash", bleg_tech_pvt->local_sdp_audio_zrtp_hash);
+ }
+ if (aleg_tech_pvt->remote_sdp_video_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Passing a-leg remote zrtp-hash (video) to b-leg\n");
+ bleg_tech_pvt->local_sdp_video_zrtp_hash = switch_core_session_strdup(bleg_tech_pvt->session, aleg_tech_pvt->remote_sdp_video_zrtp_hash);
+ switch_channel_set_variable(bleg_channel, "l_sdp_video_zrtp_hash", bleg_tech_pvt->local_sdp_video_zrtp_hash);
+ }
+ if (bleg_tech_pvt->remote_sdp_audio_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Passing b-leg remote zrtp-hash (audio) to a-leg\n");
+ aleg_tech_pvt->local_sdp_audio_zrtp_hash = switch_core_session_strdup(aleg_tech_pvt->session, bleg_tech_pvt->remote_sdp_audio_zrtp_hash);
+ switch_channel_set_variable(aleg_channel, "l_sdp_audio_zrtp_hash", aleg_tech_pvt->local_sdp_audio_zrtp_hash);
+ }
+ if (bleg_tech_pvt->remote_sdp_video_zrtp_hash) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Passing b-leg remote zrtp-hash (video) to a-leg\n");
+ aleg_tech_pvt->local_sdp_video_zrtp_hash = switch_core_session_strdup(aleg_tech_pvt->session, bleg_tech_pvt->remote_sdp_video_zrtp_hash);
+ switch_channel_set_variable(aleg_channel, "l_sdp_video_zrtp_hash", aleg_tech_pvt->local_sdp_video_zrtp_hash);
+ }
+}
+void sofia_glue_pass_zrtp_hash(switch_core_session_t *session)
+{
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ private_object_t *tech_pvt = switch_core_session_get_private(session);
+ switch_core_session_t *other_session;
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Deciding whether to pass zrtp-hash between legs\n");
+ if (!(switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASSTHRU_REQ))) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "CF_ZRTP_PASSTHRU_REQ not set, so not propagating zrtp-hash\n");
+ return;
+ } else if (!(switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS)) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "No partner channel found, so not propagating zrtp-hash\n");
+ return;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Found peer channel; propagating zrtp-hash if set\n");
+ sofia_glue_pass_zrtp_hash2(session, other_session);
+ switch_core_session_rwunlock(other_session);
+ }
+}
+
+static void find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp)
+{
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ private_object_t *tech_pvt = switch_core_session_get_private(session);
+ sdp_media_t *m;
+ sdp_attribute_t *attr;
+ int got_audio = 0, got_video = 0;
+
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Looking for zrtp-hash\n");
+ for (m = sdp->sdp_media; m; m = m->m_next) {
+ if (got_audio && got_video) break;
+ if (m->m_port && ((m->m_type == sdp_media_audio && !got_audio)
+ || (m->m_type == sdp_media_video && !got_video))) {
+ for (attr = m->m_attributes; attr; attr = attr->a_next) {
+ if (zstr(attr->a_name)) continue;
+ if (strcasecmp(attr->a_name, "zrtp-hash") || !(attr->a_value)) continue;
+ if (m->m_type == sdp_media_audio) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG,
+ "Found audio zrtp-hash; setting r_sdp_audio_zrtp_hash=%s\n", attr->a_value);
+ switch_channel_set_variable(channel, "r_sdp_audio_zrtp_hash", attr->a_value);
+ tech_pvt->remote_sdp_audio_zrtp_hash = switch_core_session_strdup(tech_pvt->session, attr->a_value);
+ got_audio++;
+ } else if (m->m_type == sdp_media_video) {
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG,
+ "Found video zrtp-hash; setting r_sdp_video_zrtp_hash=%s\n", attr->a_value);
+ switch_channel_set_variable(channel, "r_sdp_video_zrtp_hash", attr->a_value);
+ tech_pvt->remote_sdp_video_zrtp_hash = switch_core_session_strdup(tech_pvt->session, attr->a_value);
+ got_video++;
+ }
+ switch_channel_set_flag(channel, CF_ZRTP_HASH);
+ break;
+ }
+ }
+ }
+}
void sofia_glue_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp)
{
@@ -3887,18 +3990,8 @@ void sofia_glue_set_r_sdp_codec_string(switch_core_session_t *session, const cha
}
}
- switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Looking for zrtp-hash to set sdp_zrtp_hash_string\n");
- for (m = sdp->sdp_media; m; m = m->m_next) {
- for (attr = m->m_attributes; attr; attr = attr->a_next) {
- if (zstr(attr->a_name)) continue;
- if (!strcasecmp(attr->a_name, "zrtp-hash") && attr->a_value) {
- switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Found zrtp-hash, setting sdp_zrtp_hash_string=%s\n", attr->a_value);
- switch_channel_set_variable(channel, "sdp_zrtp_hash_string", attr->a_value);
- switch_channel_set_flag(channel, CF_ZRTP_HASH);
- break;
- }
- }
- }
+ find_zrtp_hash(session, sdp);
+ sofia_glue_pass_zrtp_hash(session);
for (m = sdp->sdp_media; m; m = m->m_next) {
ptime = dptime;
@@ -4578,6 +4671,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
switch_channel_set_variable(tech_pvt->channel, "t38_broken_boolean", "true");
}
+ find_zrtp_hash(session, sdp);
+ sofia_glue_pass_zrtp_hash(session);
+
for (m = sdp->sdp_media; m; m = m->m_next) {
sdp_connection_t *connection;
switch_core_session_t *other_session;
@@ -4699,9 +4795,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
ptime = atoi(attr->a_value);
} else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
maxptime = atoi(attr->a_value);
- } else if (!strcasecmp(attr->a_name, "zrtp-hash") && attr->a_value) {
- switch_channel_set_variable(tech_pvt->channel, "sdp_zrtp_hash_string", attr->a_value);
- switch_channel_set_flag(tech_pvt->channel, CF_ZRTP_HASH);
} else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
int crypto_tag;
diff --git a/src/switch_channel.c b/src/switch_channel.c
index e06706cbc3..dc983c78cd 100644
--- a/src/switch_channel.c
+++ b/src/switch_channel.c
@@ -2955,7 +2955,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi
SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel)
{
- if (switch_channel_test_flag(channel, CF_ZRTP_HASH) && !switch_channel_test_flag(channel, CF_ZRTP_PASS)) {
+ if (!switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU)
+ && switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU_REQ)
+ && switch_channel_test_flag(channel, CF_ZRTP_HASH)) {
switch_core_session_t *other_session;
switch_channel_t *other_channel;
int doit = 1;
@@ -2963,14 +2965,16 @@ SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel)
if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
other_channel = switch_core_session_get_channel(other_session);
- if (switch_channel_test_flag(other_channel, CF_ZRTP_HASH) && !switch_channel_test_flag(other_channel, CF_ZRTP_PASS)) {
+ if (switch_channel_test_flag(other_channel, CF_ZRTP_HASH) && !switch_channel_test_flag(other_channel, CF_ZRTP_PASSTHRU)) {
- switch_channel_set_flag(channel, CF_ZRTP_PASS);
- switch_channel_set_flag(other_channel, CF_ZRTP_PASS);
+ switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU);
+ switch_channel_set_flag(other_channel, CF_ZRTP_PASSTHRU);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO,
"%s Activating ZRTP passthru mode.\n", switch_channel_get_name(channel));
+ switch_channel_set_variable(channel, "zrtp_passthru_active", "true");
+ switch_channel_set_variable(other_channel, "zrtp_passthru_active", "true");
switch_channel_set_variable(channel, "zrtp_secure_media", "false");
switch_channel_set_variable(other_channel, "zrtp_secure_media", "false");
doit = 0;
@@ -2980,18 +2984,20 @@ SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel)
}
if (doit) {
+ switch_channel_set_variable(channel, "zrtp_passthru_active", "false");
switch_channel_set_variable(channel, "zrtp_secure_media", "true");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO,
"%s ZRTP not negotiated on both sides; disabling ZRTP passthru mode.\n", switch_channel_get_name(channel));
- switch_channel_clear_flag(channel, CF_ZRTP_PASS);
+ switch_channel_clear_flag(channel, CF_ZRTP_PASSTHRU);
switch_channel_clear_flag(channel, CF_ZRTP_HASH);
if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
other_channel = switch_core_session_get_channel(other_session);
+ switch_channel_set_variable(other_channel, "zrtp_passthru_active", "false");
switch_channel_set_variable(other_channel, "zrtp_secure_media", "true");
- switch_channel_clear_flag(other_channel, CF_ZRTP_PASS);
+ switch_channel_clear_flag(other_channel, CF_ZRTP_PASSTHRU);
switch_channel_clear_flag(other_channel, CF_ZRTP_HASH);
switch_core_session_rwunlock(other_session);
diff --git a/src/switch_core_session.c b/src/switch_core_session.c
index 56c6e0b3a4..4e43987ecf 100644
--- a/src/switch_core_session.c
+++ b/src/switch_core_session.c
@@ -577,6 +577,10 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_
}
}
+ if (switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU_REQ)) {
+ switch_channel_set_flag(peer_channel, CF_ZRTP_PASSTHRU_REQ);
+ }
+
if (profile) {
if ((cloned_profile = switch_caller_profile_clone(*new_session, profile)) != 0) {
switch_channel_set_originator_caller_profile(peer_channel, cloned_profile);
diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c
index 87ff02ec8c..98fed62b34 100644
--- a/src/switch_ivr_originate.c
+++ b/src/switch_ivr_originate.c
@@ -1820,7 +1820,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
if (session) {
- const char *to_var, *bypass_media = NULL, *proxy_media = NULL;
+ const char *to_var, *bypass_media = NULL, *proxy_media = NULL, *zrtp_passthru = NULL;
caller_channel = switch_core_session_get_channel(session);
switch_channel_set_flag(caller_channel, CF_ORIGINATOR);
oglobals.session = session;
@@ -1833,6 +1833,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
proxy_media = switch_channel_get_variable(caller_channel, SWITCH_PROXY_MEDIA_VARIABLE);
bypass_media = switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE);
+ zrtp_passthru = switch_channel_get_variable(caller_channel, SWITCH_ZRTP_PASSTHRU_VARIABLE);
if (!zstr(proxy_media)) {
if (switch_true(proxy_media)) {
@@ -1842,6 +1843,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
}
+ if (!zstr(zrtp_passthru)) {
+ if (switch_true(zrtp_passthru)) {
+ switch_channel_set_flag(caller_channel, CF_ZRTP_PASSTHRU_REQ);
+ } else if (switch_channel_test_flag(caller_channel, CF_ZRTP_PASSTHRU_REQ)) {
+ switch_channel_clear_flag(caller_channel, CF_ZRTP_PASSTHRU_REQ);
+ }
+ }
+
if (bypass_media && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
switch_core_session_message_t msg = { 0 };