]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
huge sonus infection FSRTP-8
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 3 Dec 2009 22:51:50 +0000 (22:51 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 3 Dec 2009 22:51:50 +0000 (22:51 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15781 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_rtp.c

index 60c7a56338afc386d909a0efd77821e2d44c9397..b7a4bca92cbbfb27105048aaaa65389ed6f8f216 100644 (file)
@@ -789,7 +789,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                        if (tech_pvt->read_frame.datalen > 0) {
                                uint32_t bytes = 0;
                                int frames = 1;
-                               
+
                                if (!switch_test_flag((&tech_pvt->read_frame), SFF_CNG)) {
                                        if (!tech_pvt->read_codec.implementation || !switch_core_codec_ready(&tech_pvt->read_codec)) {
                                                *frame = NULL;
@@ -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) {
                                                        uint32_t codec_ms = (int)(tech_pvt->read_frame.timestamp - 
                                                                                                                   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;
                                                        }
                                                        
+
                                                        if (tech_pvt->last_codec_ms && tech_pvt->last_codec_ms == codec_ms) {
                                                                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" 
                                                                                                          "Linksys/Sipura aka Cisco\n"
                                                                                                          "ShoreTel\n"
-                                                                                                         "Sonus/L3 (If you're really lucky, you may even get this message twice once they "
-                                                                                                         "answer and change it back again!! Go Sonus!)\n"
+                                                                                                         "Sonus/L3\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);
-                                                                       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_core_codec_destroy(&tech_pvt->write_codec);
+                                                                       switch_channel_set_variable_printf(channel, "sip_h_X-Broken-PTIME", "Adv=%d;Sent=%d", 
+                                                                                                                                          (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) {
                                                                                *frame = NULL;
-                                                                               switch_core_session_unlock_codec_write(session);
-                                                                               switch_core_session_unlock_codec_read(session);
                                                                                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;
                                                                        }
                                                                        
-                                                                       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 = MAX_CODEC_CHECK_FRAMES;
+                                                                       
+                                                                       tech_pvt->check_frames = 0;
+                                                                       tech_pvt->last_ts = 0;
                                                                        /* inform them of the codec they are actually sending */
                                                                        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)) {
                                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;
        default:
index 41203ffc54ddaef6531ad4f956128e9912beb355..4304b43b68de01f9c0a4ebb94b3c3ef450c04b45 100644 (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)) {
                                tech_pvt->check_frames = 0;
+                               tech_pvt->last_ts = 0;
                        }
 
                }
index 0ae8ca6a6528e891d8c41b7e23432b24485fed6b..79b66ff8f989c40fdda3ac91f5242058f34b4cac 100644 (file)
@@ -2057,21 +2057,24 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
        int ms;
        switch_status_t status = SWITCH_STATUS_SUCCESS;
        int resetting = 0;
-       
+
        if (!tech_pvt->iananame) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "No audio codec available\n");
                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) {
                        switch_goto_status(SWITCH_STATUS_SUCCESS, end);
                }
-               if (strcasecmp(tech_pvt->read_codec.implementation->iananame, tech_pvt->iananame) ||
-                       tech_pvt->read_codec.implementation->samples_per_second != tech_pvt->rm_rate) {
+               if (strcasecmp(tech_pvt->read_impl.iananame, tech_pvt->iananame) ||
+                       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_read(tech_pvt->session);
                        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_session_reset(tech_pvt->session, SWITCH_TRUE, SWITCH_TRUE);
                } 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);
                }
        }
@@ -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)) {
                switch_assert(tech_pvt->read_codec.implementation);
-               switch_rtp_set_interval(tech_pvt->rtp_session,
-                                                                  tech_pvt->write_codec.implementation->microseconds_per_packet,
-                                                                  tech_pvt->read_impl.samples_per_packet);
+
+               if (switch_rtp_change_interval(tech_pvt->rtp_session, 
+                                                                          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;
index 88ef81335102eddd5e3ae2d7eef6589ec1c90994..730edcb0195a02495d3b21ae0874689fdd3647f6 100644 (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_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);
        
-       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) {
                        switch_core_timer_destroy(&rtp_session->timer);
                }
-               if (switch_core_timer_init(&rtp_session->timer, 
-                                                                  rtp_session->timer_name, ms_per_packet / 1000, samples_per_interval, rtp_session->pool) == SWITCH_STATUS_SUCCESS) {
+               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) {
                        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);
                } else {
                        memset(&rtp_session->timer, 0, sizeof(rtp_session->timer));
                        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);
-                       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,