]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-4408 fix crash caused by missing or invalid call-id in sip invite
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 7 Sep 2012 20:08:10 +0000 (15:08 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 7 Sep 2012 20:08:10 +0000 (15:08 -0500)
src/mod/endpoints/mod_sofia/sofia.c

index 21ff55d480af9e262983853a427be0c33ae5bedf..79a925f4f844e92a9bcd3a18ad1d7c2aacfb579d 100644 (file)
@@ -1690,6 +1690,14 @@ static void sofia_queue_message(sofia_dispatch_event_t *de)
        switch_queue_push(mod_sofia_globals.msg_queue, de);
 }
 
+static void set_call_id(private_object_t *tech_pvt, sip_t const *sip)
+{
+       if (!tech_pvt->call_id && tech_pvt->session && tech_pvt->channel && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
+               tech_pvt->call_id = switch_core_session_strdup(tech_pvt->session, sip->sip_call_id->i_id);
+               switch_channel_set_variable(tech_pvt->channel, "sip_call_id", tech_pvt->call_id);
+       }
+}
+
 
 void sofia_event_callback(nua_event_t event,
                                                  int status,
@@ -1709,16 +1717,22 @@ void sofia_event_callback(nua_event_t event,
 
                        if ((session = switch_core_session_locate(sofia_private->uuid))) {
                                private_object_t *tech_pvt = switch_core_session_get_private(session);
+                               switch_channel_t *channel = switch_core_session_get_channel(session);
 
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);                         
-
-                               tech_pvt->sofia_private = NULL;
-                               tech_pvt->nh = NULL;
-                               sofia_set_flag(tech_pvt, TFLAG_BYE);
-                               switch_mutex_lock(profile->flag_mutex);
-                               switch_core_hash_insert(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
-                               switch_mutex_unlock(profile->flag_mutex);
-                               switch_core_session_rwunlock(session);
+                               set_call_id(tech_pvt, sip);
+                               
+                               if (!zstr(tech_pvt->call_id)) {
+                                       tech_pvt->sofia_private = NULL;
+                                       tech_pvt->nh = NULL;
+                                       sofia_set_flag(tech_pvt, TFLAG_BYE);
+                                       switch_mutex_lock(profile->flag_mutex);
+                                       switch_core_hash_insert(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
+                                       switch_mutex_unlock(profile->flag_mutex);
+                                       switch_core_session_rwunlock(session);
+                               } else {
+                                       switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+                               }
                        }
                }
                goto end;
@@ -1804,9 +1818,25 @@ void sofia_event_callback(nua_event_t event,
                                } else {
                                        free(uuid);
                                        uuid = NULL;
+                                       sip = NULL;
                                }
                        }
                }
+               
+               if (!sip || !sip->sip_call_id || zstr(sip->sip_call_id->i_id)) {
+                       nua_respond(nh, 503, "INVALID INVITE", TAG_END());
+                       nua_destroy_event(de->event);   
+                       su_free(nh->nh_home, de);
+                       
+                       switch_mutex_lock(profile->flag_mutex);
+                       profile->queued_events--;
+                       switch_mutex_unlock(profile->flag_mutex);
+                       
+                       nua_handle_unref(nh);
+                       nua_stack_unref(nua);
+                       
+                       goto end;
+               }
 
                if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)) {
                        session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL, sip->sip_call_id->i_id);
@@ -1829,13 +1859,8 @@ void sofia_event_callback(nua_event_t event,
                        }
                        
                        sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
-                       
-                       if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {
-                               switch_channel_t *channel = switch_core_session_get_channel(session);
-                               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);
-                       }
 
+                       set_call_id(tech_pvt, sip);
                } else {
                        nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
                        nua_destroy_event(de->event);