huge sonus infection FSRTP-8

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15781 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-12-03 22:51:50 +00:00
parent b69c844817
commit 6158aac6ab
4 changed files with 55 additions and 39 deletions

View File

@ -808,11 +808,13 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
if (tech_pvt->last_ts && tech_pvt->read_frame.datalen != tech_pvt->read_impl.encoded_bytes_per_packet) { if (tech_pvt->last_ts && tech_pvt->read_frame.datalen != tech_pvt->read_impl.encoded_bytes_per_packet) {
uint32_t codec_ms = (int)(tech_pvt->read_frame.timestamp - uint32_t codec_ms = (int)(tech_pvt->read_frame.timestamp -
tech_pvt->last_ts) / (tech_pvt->read_impl.samples_per_second / 1000); tech_pvt->last_ts) / (tech_pvt->read_impl.samples_per_second / 1000);
if ((codec_ms % 10) != 0) {
tech_pvt->check_frames = MAX_CODEC_CHECK_FRAMES; if ((codec_ms % 10) != 0 || codec_ms > tech_pvt->read_impl.samples_per_packet * 10) {
tech_pvt->last_ts = 0;
goto skip; goto skip;
} }
if (tech_pvt->last_codec_ms && tech_pvt->last_codec_ms == codec_ms) { if (tech_pvt->last_codec_ms && tech_pvt->last_codec_ms == codec_ms) {
tech_pvt->mismatch_count++; tech_pvt->mismatch_count++;
} }
@ -839,22 +841,18 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
"This issue has so far been identified to happen on the following broken platforms/devices:\n" "This issue has so far been identified to happen on the following broken platforms/devices:\n"
"Linksys/Sipura aka Cisco\n" "Linksys/Sipura aka Cisco\n"
"ShoreTel\n" "ShoreTel\n"
"Sonus/L3 (If you're really lucky, you may even get this message twice once they " "Sonus/L3\n"
"answer and change it back again!! Go Sonus!)\n"
"We will try to fix it but some of the devices on this list are so broken who knows what will happen..\n" "We will try to fix it but some of the devices on this list are so broken who knows what will happen..\n"
, ,
(int)tech_pvt->codec_ms, (int)codec_ms); (int)tech_pvt->codec_ms, (int)codec_ms);
tech_pvt->codec_ms = codec_ms;
switch_core_session_lock_codec_write(session);
switch_core_session_lock_codec_read(session);
switch_core_codec_destroy(&tech_pvt->read_codec); switch_channel_set_variable_printf(channel, "sip_h_X-Broken-PTIME", "Adv=%d;Sent=%d",
switch_core_codec_destroy(&tech_pvt->write_codec); (int)tech_pvt->codec_ms, (int)codec_ms);
tech_pvt->codec_ms = codec_ms;
if (sofia_glue_tech_set_codec(tech_pvt, 2) != SWITCH_STATUS_SUCCESS) { if (sofia_glue_tech_set_codec(tech_pvt, 2) != SWITCH_STATUS_SUCCESS) {
*frame = NULL; *frame = NULL;
switch_core_session_unlock_codec_write(session);
switch_core_session_unlock_codec_read(session);
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
@ -887,19 +885,11 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
tech_pvt->read_impl.samples_per_packet; tech_pvt->read_impl.samples_per_packet;
} }
if (switch_rtp_change_interval(tech_pvt->rtp_session,
tech_pvt->codec_ms * 1000,
tech_pvt->read_impl.samples_per_packet
) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
} tech_pvt->check_frames = 0;
tech_pvt->last_ts = 0;
tech_pvt->check_frames = MAX_CODEC_CHECK_FRAMES;
/* inform them of the codec they are actually sending */ /* inform them of the codec they are actually sending */
sofia_glue_do_invite(session); sofia_glue_do_invite(session);
switch_core_session_unlock_codec_write(session);
switch_core_session_unlock_codec_read(session);
} }
@ -1182,10 +1172,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
} }
if ((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) && switch_true(var)) { if ((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) && switch_true(var)) {
sofia_set_flag_locked(tech_pvt, TFLAG_SECURE); sofia_set_flag_locked(tech_pvt, TFLAG_SECURE);
} }
if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTOFIX_TIMING)) {
tech_pvt->check_frames = 0;
tech_pvt->last_ts = 0;
}
} }
break; break;
default: default:

View File

@ -3337,6 +3337,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTOFIX_TIMING)) { if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTOFIX_TIMING)) {
tech_pvt->check_frames = 0; tech_pvt->check_frames = 0;
tech_pvt->last_ts = 0;
} }
} }

View File

@ -2063,15 +2063,18 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
switch_goto_status(SWITCH_STATUS_FALSE, end); switch_goto_status(SWITCH_STATUS_FALSE, end);
} }
if (tech_pvt->read_codec.implementation && switch_core_codec_ready(&tech_pvt->read_codec)) { if (switch_core_codec_ready(&tech_pvt->read_codec)) {
if (!force) { if (!force) {
switch_goto_status(SWITCH_STATUS_SUCCESS, end); switch_goto_status(SWITCH_STATUS_SUCCESS, end);
} }
if (strcasecmp(tech_pvt->read_codec.implementation->iananame, tech_pvt->iananame) || if (strcasecmp(tech_pvt->read_impl.iananame, tech_pvt->iananame) ||
tech_pvt->read_codec.implementation->samples_per_second != tech_pvt->rm_rate) { tech_pvt->read_impl.samples_per_second != tech_pvt->rm_rate ||
tech_pvt->codec_ms != tech_pvt->read_impl.microseconds_per_packet) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Changing Codec from %s@%dms to %s@%dms\n",
tech_pvt->read_impl.iananame, tech_pvt->read_impl.microseconds_per_packet / 1000,
tech_pvt->rm_encoding, tech_pvt->codec_ms);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Changing Codec from %s to %s\n",
tech_pvt->read_codec.implementation->iananame, tech_pvt->rm_encoding);
switch_core_session_lock_codec_write(tech_pvt->session); switch_core_session_lock_codec_write(tech_pvt->session);
switch_core_session_lock_codec_read(tech_pvt->session); switch_core_session_lock_codec_read(tech_pvt->session);
resetting = 1; resetting = 1;
@ -2079,7 +2082,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
switch_core_codec_destroy(&tech_pvt->write_codec); switch_core_codec_destroy(&tech_pvt->write_codec);
switch_core_session_reset(tech_pvt->session, SWITCH_TRUE, SWITCH_TRUE); switch_core_session_reset(tech_pvt->session, SWITCH_TRUE, SWITCH_TRUE);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Already using %s\n", tech_pvt->read_codec.implementation->iananame); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Already using %s\n", tech_pvt->read_impl.iananame);
switch_goto_status(SWITCH_STATUS_SUCCESS, end); switch_goto_status(SWITCH_STATUS_SUCCESS, end);
} }
} }
@ -2119,9 +2122,14 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
if (switch_rtp_ready(tech_pvt->rtp_session)) { if (switch_rtp_ready(tech_pvt->rtp_session)) {
switch_assert(tech_pvt->read_codec.implementation); switch_assert(tech_pvt->read_codec.implementation);
switch_rtp_set_interval(tech_pvt->rtp_session,
tech_pvt->write_codec.implementation->microseconds_per_packet, if (switch_rtp_change_interval(tech_pvt->rtp_session,
tech_pvt->read_impl.samples_per_packet); tech_pvt->read_impl.microseconds_per_packet,
tech_pvt->read_impl.samples_per_packet
) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
} }
tech_pvt->read_frame.rate = tech_pvt->rm_rate; tech_pvt->read_frame.rate = tech_pvt->rm_rate;

View File

@ -1052,26 +1052,38 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_interval(switch_rtp_t *rtp_sessio
SWITCH_DECLARE(switch_status_t) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval) SWITCH_DECLARE(switch_status_t) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval)
{ {
switch_status_t status = SWITCH_STATUS_SUCCESS;
int change_timer = 0;
if (rtp_session->ms_per_packet && rtp_session->ms_per_packet != ms_per_packet) {
change_timer = 1;
}
switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval); switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval);
if (rtp_session->timer_name) { if (change_timer && rtp_session->timer_name) {
READ_INC(rtp_session);
WRITE_INC(rtp_session);
if (rtp_session->timer.timer_interface) { if (rtp_session->timer.timer_interface) {
switch_core_timer_destroy(&rtp_session->timer); switch_core_timer_destroy(&rtp_session->timer);
} }
if (switch_core_timer_init(&rtp_session->timer, if ((status = switch_core_timer_init(&rtp_session->timer,
rtp_session->timer_name, ms_per_packet / 1000, samples_per_interval, rtp_session->pool) == SWITCH_STATUS_SUCCESS) { rtp_session->timer_name, ms_per_packet / 1000,
samples_per_interval, rtp_session->pool)) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"RE-Starting timer [%s] %d bytes per %dms\n", rtp_session->timer_name, samples_per_interval, ms_per_packet); "RE-Starting timer [%s] %d bytes per %dms\n", rtp_session->timer_name, samples_per_interval, ms_per_packet);
} else { } else {
memset(&rtp_session->timer, 0, sizeof(rtp_session->timer)); memset(&rtp_session->timer, 0, sizeof(rtp_session->timer));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Problem RE-Starting timer [%s] %d bytes per %dms\n", rtp_session->timer_name, samples_per_interval, ms_per_packet / 1000); "Problem RE-Starting timer [%s] %d bytes per %dms\n", rtp_session->timer_name, samples_per_interval, ms_per_packet / 1000);
return SWITCH_STATUS_FALSE;
} }
WRITE_DEC(rtp_session);
READ_DEC(rtp_session);
} }
return SWITCH_STATUS_SUCCESS; return status;
} }
SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session, SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session,