2005-11-19 20:07:43 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2011-01-05 10:08:55 -06:00
* Copyright ( C ) 2005 - 2011 , Anthony Minessale II < anthm @ freeswitch . org >
2005-11-19 20:07:43 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2005-11-19 20:07:43 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2006-09-18 05:08:55 +00:00
* Michael Jerris < mike @ jerris . com >
* Paul D . Tinsley < pdt at jackhammer . org >
2007-04-07 03:07:43 +00:00
* Marcel Barbulescu < marcelbarbulescu @ gmail . com >
2005-11-19 20:07:43 +00:00
*
*
* switch_core . c - - Main Core Library
*
*/
2006-04-12 15:25:26 +00:00
2009-05-15 17:50:37 +00:00
2005-11-19 20:07:43 +00:00
# include <switch.h>
2011-05-25 14:45:55 -05:00
# include <switch_ssl.h>
2009-05-20 23:04:05 +00:00
# include <switch_stun.h>
2009-05-30 00:14:57 +00:00
# include <switch_nat.h>
2006-08-19 18:51:22 +00:00
# include <switch_version.h>
2007-05-14 17:10:46 +00:00
# include "private/switch_core_pvt.h"
2007-12-18 17:00:42 +00:00
# ifndef WIN32
2007-12-18 16:55:39 +00:00
# include <switch_private.h>
2008-09-26 16:16:52 +00:00
# ifdef HAVE_SETRLIMIT
2008-09-26 15:50:12 +00:00
# include <sys/resource.h>
2008-09-26 16:16:52 +00:00
# endif
# endif
2009-03-11 15:58:11 +00:00
# include <errno.h>
2008-09-26 15:50:12 +00:00
2009-05-15 17:50:37 +00:00
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 } ;
2007-03-28 23:37:12 +00:00
2007-03-29 22:31:56 +00:00
/* The main runtime obj we keep this hidden for ourselves */
2010-01-04 19:03:43 +00:00
struct switch_runtime runtime = { 0 } ;
2008-07-22 13:38:42 +00:00
static void switch_load_core_config ( const char * file ) ;
2005-12-21 22:25:22 +00:00
2007-03-28 23:37:12 +00:00
static void send_heartbeat ( void )
{
switch_event_t * event ;
switch_core_time_duration_t duration ;
switch_core_measure_time ( switch_core_uptime ( ) , & duration ) ;
2007-03-29 22:31:56 +00:00
2007-03-28 23:37:12 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_HEARTBEAT ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Event-Info " , " System Ready " ) ;
2007-03-29 22:31:56 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Up-Time " ,
2007-03-28 23:37:12 +00:00
" %u year%s, "
" %u day%s, "
" %u hour%s, "
" %u minute%s, "
" %u second%s, "
" %u millisecond%s, "
2007-06-12 01:24:29 +00:00
" %u microsecond%s " ,
2007-03-28 23:37:12 +00:00
duration . yr , duration . yr = = 1 ? " " : " s " ,
duration . day , duration . day = = 1 ? " " : " s " ,
2007-03-29 22:31:56 +00:00
duration . hr , duration . hr = = 1 ? " " : " s " ,
duration . min , duration . min = = 1 ? " " : " s " ,
duration . sec , duration . sec = = 1 ? " " : " s " ,
duration . ms , duration . ms = = 1 ? " " : " s " , duration . mms , duration . mms = = 1 ? " " : " s " ) ;
2005-11-19 20:07:43 +00:00
2007-03-29 22:31:56 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Session-Count " , " %u " , switch_core_session_count ( ) ) ;
2011-08-10 07:58:02 -05:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Max-Sessions " , " %u " , switch_core_session_limit ( 0 ) ) ;
2008-01-07 17:10:48 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Session-Per-Sec " , " %u " , runtime . sps ) ;
2009-03-05 21:34:13 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Session-Since-Startup " , " % " SWITCH_SIZE_T_FMT , switch_core_session_id ( ) - 1 ) ;
2010-03-10 20:21:34 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Idle-CPU " , " %f " , switch_core_idle_cpu ( ) ) ;
2007-03-29 22:31:56 +00:00
switch_event_fire ( & event ) ;
2005-11-19 20:07:43 +00:00
}
}
2008-07-22 22:23:50 +00:00
static char main_ip4 [ 256 ] = " " ;
static char main_ip6 [ 256 ] = " " ;
2010-02-06 03:38:24 +00:00
static void check_ip ( void )
{
2008-07-22 22:23:50 +00:00
char guess_ip4 [ 256 ] = " " ;
char guess_ip6 [ 256 ] = " " ;
2009-01-22 23:07:31 +00:00
char old_ip4 [ 256 ] = " " ;
char old_ip6 [ 256 ] = " " ;
2008-07-22 22:23:50 +00:00
int ok4 = 1 , ok6 = 1 ;
2009-06-02 16:55:10 +00:00
int mask = 0 ;
2009-09-01 18:04:01 +00:00
2011-02-25 16:34:17 -06:00
gethostname ( runtime . hostname , sizeof ( runtime . hostname ) ) ;
switch_core_set_variable ( " hostname " , runtime . hostname ) ;
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( guess_ip4 , sizeof ( guess_ip4 ) , & mask , AF_INET ) ;
switch_find_local_ip ( guess_ip6 , sizeof ( guess_ip6 ) , NULL , AF_INET6 ) ;
2008-07-22 22:23:50 +00:00
if ( ! * main_ip4 ) {
switch_set_string ( main_ip4 , guess_ip4 ) ;
} else {
if ( ! ( ok4 = ! strcmp ( main_ip4 , guess_ip4 ) ) ) {
2009-06-05 21:36:52 +00:00
struct in_addr in ;
in . s_addr = mask ;
2009-01-22 23:07:31 +00:00
switch_set_string ( old_ip4 , main_ip4 ) ;
2008-07-22 22:23:50 +00:00
switch_set_string ( main_ip4 , guess_ip4 ) ;
switch_core_set_variable ( " local_ip_v4 " , guess_ip4 ) ;
2009-06-05 21:04:37 +00:00
switch_core_set_variable ( " local_mask_v4 " , inet_ntoa ( in ) ) ;
2008-07-22 22:23:50 +00:00
}
}
if ( ! * main_ip6 ) {
switch_set_string ( main_ip6 , guess_ip6 ) ;
} else {
if ( ! ( ok6 = ! strcmp ( main_ip6 , guess_ip6 ) ) ) {
2009-01-22 23:07:31 +00:00
switch_set_string ( old_ip6 , main_ip6 ) ;
2008-07-22 22:23:50 +00:00
switch_set_string ( main_ip6 , guess_ip6 ) ;
2008-11-13 22:36:24 +00:00
switch_core_set_variable ( " local_ip_v6 " , guess_ip6 ) ;
2008-07-22 22:23:50 +00:00
}
}
2010-02-06 03:38:24 +00:00
2008-07-22 22:23:50 +00:00
if ( ! ok4 | | ! ok6 ) {
switch_event_t * event ;
if ( switch_event_create ( & event , SWITCH_EVENT_TRAP ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " condition " , " network-address-change " ) ;
if ( ! ok4 ) {
2009-01-22 23:07:31 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " network-address-previous-v4 " , old_ip4 ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " network-address-change-v4 " , main_ip4 ) ;
2008-07-22 22:23:50 +00:00
}
if ( ! ok6 ) {
2009-01-22 23:07:31 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " network-address-previous-v6 " , old_ip6 ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " network-address-change-v6 " , main_ip6 ) ;
2008-07-22 22:23:50 +00:00
}
switch_event_fire ( & event ) ;
}
}
}
2007-05-12 21:43:41 +00:00
SWITCH_STANDARD_SCHED_FUNC ( heartbeat_callback )
2005-11-19 20:07:43 +00:00
{
2007-03-29 22:31:56 +00:00
send_heartbeat ( ) ;
2005-11-19 20:07:43 +00:00
2007-03-29 22:31:56 +00:00
/* reschedule this task */
2009-01-25 21:23:07 +00:00
task - > runtime = switch_epoch_time_now ( NULL ) + 20 ;
2005-11-19 20:07:43 +00:00
}
2011-01-21 14:27:51 -06:00
SWITCH_STANDARD_SCHED_FUNC ( check_ip_callback )
{
check_ip ( ) ;
/* reschedule this task */
task - > runtime = switch_epoch_time_now ( NULL ) + 60 ;
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_set_console ( const char * console )
2005-11-19 20:07:43 +00:00
{
2007-03-29 22:31:56 +00:00
if ( ( runtime . console = fopen ( console , " a " ) ) = = 0 ) {
fprintf ( stderr , " Cannot open output file %s. \n " , console ) ;
return SWITCH_STATUS_FALSE ;
}
2006-03-27 17:42:59 +00:00
2007-03-29 22:31:56 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2005-11-19 20:07:43 +00:00
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( FILE * ) switch_core_get_console ( void )
{
return runtime . console ;
2005-11-19 20:07:43 +00:00
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( FILE * ) switch_core_data_channel ( switch_text_channel_t channel )
2005-11-19 20:07:43 +00:00
{
2007-03-29 22:31:56 +00:00
FILE * handle = stdout ;
2005-11-19 20:07:43 +00:00
2007-03-29 22:31:56 +00:00
switch ( channel ) {
case SWITCH_CHANNEL_ID_LOG :
case SWITCH_CHANNEL_ID_LOG_CLEAN :
handle = runtime . console ;
break ;
default :
handle = runtime . console ;
break ;
}
2005-11-19 20:07:43 +00:00
2007-03-29 22:31:56 +00:00
return handle ;
}
2006-07-07 18:59:14 +00:00
2011-05-13 13:17:54 -05:00
2008-09-16 17:12:14 +00:00
SWITCH_DECLARE ( void ) switch_core_remove_state_handler ( const switch_state_handler_table_t * state_handler )
{
2008-12-29 22:41:03 +00:00
int index , tmp_index = 0 ;
2010-02-06 03:38:24 +00:00
const switch_state_handler_table_t * tmp [ SWITCH_MAX_STATE_HANDLERS + 1 ] = { 0 } ;
2008-09-16 17:12:14 +00:00
switch_mutex_lock ( runtime . global_mutex ) ;
for ( index = 0 ; index < runtime . state_handler_index ; index + + ) {
const switch_state_handler_table_t * cur = runtime . state_handlers [ index ] ;
runtime . state_handlers [ index ] = NULL ;
if ( cur = = state_handler ) {
continue ;
}
2008-12-29 22:41:03 +00:00
tmp [ tmp_index + + ] = cur ;
2008-09-16 17:12:14 +00:00
}
runtime . state_handler_index = 0 ;
2008-12-29 22:41:03 +00:00
for ( index = 0 ; index < tmp_index ; index + + ) {
2008-09-16 17:12:14 +00:00
runtime . state_handlers [ runtime . state_handler_index + + ] = tmp [ index ] ;
}
switch_mutex_unlock ( runtime . global_mutex ) ;
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( int ) switch_core_add_state_handler ( const switch_state_handler_table_t * state_handler )
{
2008-09-16 17:12:14 +00:00
int index ;
switch_mutex_lock ( runtime . global_mutex ) ;
index = runtime . state_handler_index + + ;
2006-07-07 18:59:14 +00:00
2007-03-29 22:31:56 +00:00
if ( runtime . state_handler_index > = SWITCH_MAX_STATE_HANDLERS ) {
2008-09-16 17:12:14 +00:00
index = - 1 ;
} else {
runtime . state_handlers [ index ] = state_handler ;
2006-09-20 20:25:26 +00:00
}
2008-09-16 17:12:14 +00:00
switch_mutex_unlock ( runtime . global_mutex ) ;
2007-03-29 22:31:56 +00:00
return index ;
}
2005-11-19 20:07:43 +00:00
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( const switch_state_handler_table_t * ) switch_core_get_state_handler ( int index )
{
2005-11-19 20:07:43 +00:00
2007-12-17 20:44:48 +00:00
if ( index > = SWITCH_MAX_STATE_HANDLERS | | index > runtime . state_handler_index ) {
2005-11-19 20:07:43 +00:00
return NULL ;
}
2007-03-29 22:31:56 +00:00
return runtime . state_handlers [ index ] ;
2005-11-19 20:07:43 +00:00
}
2008-07-22 17:19:26 +00:00
SWITCH_DECLARE ( void ) switch_core_dump_variables ( switch_stream_handle_t * stream )
{
2010-05-25 16:54:13 -05:00
switch_event_header_t * hi ;
2008-07-22 17:19:26 +00:00
switch_mutex_lock ( runtime . global_mutex ) ;
2010-05-25 16:54:13 -05:00
for ( hi = runtime . global_vars - > headers ; hi ; hi = hi - > next ) {
stream - > write_function ( stream , " %s=%s \n " , hi - > name , hi - > value ) ;
2008-07-22 17:19:26 +00:00
}
switch_mutex_unlock ( runtime . global_mutex ) ;
}
2011-02-02 15:43:26 -06:00
SWITCH_DECLARE ( const char * ) switch_core_get_hostname ( void )
{
return runtime . hostname ;
}
2011-04-29 10:24:50 -05:00
SWITCH_DECLARE ( const char * ) switch_core_get_switchname ( void )
{
if ( ! zstr ( runtime . switchname ) ) return runtime . switchname ;
return runtime . hostname ;
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( char * ) switch_core_get_variable ( const char * varname )
2006-09-18 22:22:25 +00:00
{
2007-11-09 15:55:40 +00:00
char * val ;
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_rdlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
val = ( char * ) switch_event_get_header ( runtime . global_vars , varname ) ;
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2007-11-09 15:55:40 +00:00
return val ;
2006-09-18 22:22:25 +00:00
}
2011-02-02 15:43:26 -06:00
SWITCH_DECLARE ( char * ) switch_core_get_variable_dup ( const char * varname )
{
char * val = NULL , * v ;
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_rdlock ( runtime . global_var_rwlock ) ;
2011-02-02 15:43:26 -06:00
if ( ( v = ( char * ) switch_event_get_header ( runtime . global_vars , varname ) ) ) {
val = strdup ( v ) ;
}
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2011-02-02 15:43:26 -06:00
return val ;
}
SWITCH_DECLARE ( char * ) switch_core_get_variable_pdup ( const char * varname , switch_memory_pool_t * pool )
{
char * val = NULL , * v ;
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_rdlock ( runtime . global_var_rwlock ) ;
2011-02-02 15:43:26 -06:00
if ( ( v = ( char * ) switch_event_get_header ( runtime . global_vars , varname ) ) ) {
val = switch_core_strdup ( pool , v ) ;
}
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2011-02-02 15:43:26 -06:00
return val ;
}
2009-03-03 20:16:05 +00:00
static void switch_core_unset_variables ( void )
{
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_wrlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
switch_event_destroy ( & runtime . global_vars ) ;
switch_event_create_plain ( & runtime . global_vars , SWITCH_EVENT_CHANNEL_DATA ) ;
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2009-03-03 20:16:05 +00:00
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( void ) switch_core_set_variable ( const char * varname , const char * value )
2005-11-19 20:07:43 +00:00
{
2007-11-09 15:55:40 +00:00
char * val ;
2007-11-09 16:12:11 +00:00
if ( varname ) {
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_wrlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
val = ( char * ) switch_event_get_header ( runtime . global_vars , varname ) ;
if ( val ) {
switch_event_del_header ( runtime . global_vars , varname ) ;
}
if ( value ) {
char * v = strdup ( value ) ;
switch_string_var_check ( v , SWITCH_TRUE ) ;
switch_event_add_header_string ( runtime . global_vars , SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP , varname , v ) ;
} else {
switch_event_del_header ( runtime . global_vars , varname ) ;
}
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
}
}
SWITCH_DECLARE ( switch_bool_t ) switch_core_set_var_conditional ( const char * varname , const char * value , const char * val2 )
{
char * val ;
if ( varname ) {
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_wrlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
val = ( char * ) switch_event_get_header ( runtime . global_vars , varname ) ;
2007-11-09 16:12:11 +00:00
if ( val ) {
2010-05-25 16:54:13 -05:00
if ( ! val2 | | strcmp ( val , val2 ) ! = 0 ) {
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
return SWITCH_FALSE ;
}
switch_event_del_header ( runtime . global_vars , varname ) ;
} else if ( ! zstr ( val2 ) ) {
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2010-05-25 16:54:13 -05:00
return SWITCH_FALSE ;
2007-11-09 16:12:11 +00:00
}
2010-05-25 16:54:13 -05:00
2007-11-09 16:12:11 +00:00
if ( value ) {
2009-01-21 21:34:31 +00:00
char * v = strdup ( value ) ;
switch_string_var_check ( v , SWITCH_TRUE ) ;
2010-05-25 16:54:13 -05:00
switch_event_add_header_string ( runtime . global_vars , SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP , varname , v ) ;
2007-11-09 16:12:11 +00:00
} else {
2010-05-25 16:54:13 -05:00
switch_event_del_header ( runtime . global_vars , varname ) ;
2007-11-09 16:12:11 +00:00
}
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_unlock ( runtime . global_var_rwlock ) ;
2007-11-09 15:55:40 +00:00
}
2010-05-25 16:54:13 -05:00
return SWITCH_TRUE ;
2005-11-19 20:07:43 +00:00
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( char * ) switch_core_get_uuid ( void )
2007-02-23 16:42:40 +00:00
{
2007-03-29 22:31:56 +00:00
return runtime . uuid_str ;
}
2007-02-23 16:42:40 +00:00
2010-03-22 16:22:19 +00:00
static void * SWITCH_THREAD_FUNC switch_core_service_thread ( switch_thread_t * thread , void * obj )
2007-03-29 22:31:56 +00:00
{
2008-10-23 23:48:11 +00:00
switch_core_session_t * session = obj ;
2007-03-29 22:31:56 +00:00
switch_channel_t * channel ;
switch_frame_t * read_frame ;
2007-02-23 16:42:40 +00:00
2010-02-06 03:38:24 +00:00
// switch_assert(thread != NULL);
// switch_assert(session != NULL);
2008-10-23 23:48:11 +00:00
2009-01-09 20:34:01 +00:00
if ( switch_core_session_read_lock ( session ) ! = SWITCH_STATUS_SUCCESS ) {
return NULL ;
}
2010-03-22 16:22:19 +00:00
switch_mutex_lock ( session - > frame_read_mutex ) ;
2007-03-29 22:31:56 +00:00
channel = switch_core_session_get_channel ( session ) ;
2007-02-23 16:42:40 +00:00
2007-03-29 22:31:56 +00:00
switch_channel_set_flag ( channel , CF_SERVICE ) ;
2008-10-23 23:48:11 +00:00
while ( switch_channel_test_flag ( channel , CF_SERVICE ) ) {
switch ( switch_core_session_read_frame ( session , & read_frame , SWITCH_IO_FLAG_NONE , 0 ) ) {
2007-03-29 22:31:56 +00:00
case SWITCH_STATUS_SUCCESS :
case SWITCH_STATUS_TIMEOUT :
case SWITCH_STATUS_BREAK :
2007-02-23 16:42:40 +00:00
break ;
2007-03-29 22:31:56 +00:00
default :
2008-10-23 23:48:11 +00:00
switch_channel_clear_flag ( channel , CF_SERVICE ) ;
2007-03-29 22:31:56 +00:00
continue ;
2007-02-23 16:42:40 +00:00
}
}
2010-03-22 16:22:19 +00:00
switch_mutex_unlock ( session - > frame_read_mutex ) ;
2008-10-23 23:48:11 +00:00
switch_core_session_rwunlock ( session ) ;
2010-03-22 16:22:19 +00:00
2007-03-29 22:31:56 +00:00
return NULL ;
2007-02-23 16:42:40 +00:00
}
2007-03-29 22:31:56 +00:00
/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
2008-10-23 23:48:11 +00:00
SWITCH_DECLARE ( void ) switch_core_thread_session_end ( switch_core_session_t * session )
2005-12-21 22:25:22 +00:00
{
2008-10-23 23:48:11 +00:00
switch_channel_t * channel ;
switch_assert ( session ) ;
2006-04-26 17:18:33 +00:00
2008-10-23 23:48:11 +00:00
channel = switch_core_session_get_channel ( session ) ;
switch_assert ( channel ) ;
2010-02-06 03:38:24 +00:00
2008-10-23 23:48:11 +00:00
switch_channel_clear_flag ( channel , CF_SERVICE ) ;
2006-04-26 17:18:33 +00:00
}
2006-04-04 21:26:21 +00:00
2008-10-23 23:48:11 +00:00
SWITCH_DECLARE ( void ) switch_core_service_session ( switch_core_session_t * session )
2006-04-26 17:18:33 +00:00
{
2008-10-23 23:48:11 +00:00
switch_channel_t * channel ;
switch_assert ( session ) ;
channel = switch_core_session_get_channel ( session ) ;
switch_assert ( channel ) ;
2010-02-06 03:38:24 +00:00
2010-03-22 16:22:19 +00:00
switch_core_session_launch_thread ( session , ( void * ( * ) ( switch_thread_t * , void * ) ) switch_core_service_thread , session ) ;
2007-03-29 22:31:56 +00:00
}
2006-09-18 22:22:25 +00:00
2007-03-29 22:31:56 +00:00
/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
a void object and trust that that the function will be run in a thread with arg This lets
you request and activate a thread without giving up any knowledge about what is in the thread
neither the core nor the calling module know anything about each other .
2006-09-18 22:22:25 +00:00
2007-03-29 22:31:56 +00:00
This thread is expected to never exit until the application exits so the func is responsible
to make sure that is the case .
2006-09-18 22:22:25 +00:00
2007-03-29 22:31:56 +00:00
The typical use for this is so switch_loadable_module . c can start up a thread for each module
passing the table of module methods as a session obj into the core without actually allowing
the core to have any clue and keeping switch_loadable_module . c from needing any thread code .
2006-04-26 17:18:33 +00:00
2007-03-29 22:31:56 +00:00
*/
2006-04-26 17:18:33 +00:00
2009-02-20 01:10:59 +00:00
SWITCH_DECLARE ( switch_thread_t * ) switch_core_launch_thread ( switch_thread_start_t func , void * obj , switch_memory_pool_t * pool )
2006-04-26 17:18:33 +00:00
{
2009-02-20 01:10:59 +00:00
switch_thread_t * thread = NULL ;
2007-03-29 22:31:56 +00:00
switch_threadattr_t * thd_attr = NULL ;
switch_core_thread_session_t * ts ;
int mypool ;
2006-04-26 17:18:33 +00:00
2007-03-29 22:31:56 +00:00
mypool = pool ? 0 : 1 ;
2006-04-26 17:18:33 +00:00
2007-03-29 22:31:56 +00:00
if ( ! pool & & switch_core_new_memory_pool ( & pool ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not allocate memory pool \n " ) ;
2009-02-20 01:10:59 +00:00
return NULL ;
2007-03-29 22:31:56 +00:00
}
2006-04-26 17:18:33 +00:00
2007-03-29 22:31:56 +00:00
switch_threadattr_create ( & thd_attr , pool ) ;
2006-04-04 21:26:21 +00:00
2007-03-29 22:31:56 +00:00
if ( ( ts = switch_core_alloc ( pool , sizeof ( * ts ) ) ) = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not allocate memory \n " ) ;
} else {
if ( mypool ) {
ts - > pool = pool ;
2007-02-23 20:13:15 +00:00
}
2007-03-29 22:31:56 +00:00
ts - > objs [ 0 ] = obj ;
2009-02-20 01:10:59 +00:00
ts - > objs [ 1 ] = thread ;
2007-03-29 22:31:56 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2008-11-14 23:31:21 +00:00
switch_threadattr_priority_increase ( thd_attr ) ;
2007-03-29 22:31:56 +00:00
switch_thread_create ( & thread , thd_attr , func , ts , pool ) ;
2005-12-21 22:25:22 +00:00
}
2009-02-20 01:10:59 +00:00
return thread ;
2005-12-21 22:25:22 +00:00
}
2007-03-11 01:07:47 +00:00
2006-03-01 17:06:10 +00:00
SWITCH_DECLARE ( void ) switch_core_set_globals ( void )
2005-11-19 20:07:43 +00:00
{
2006-08-20 03:04:55 +00:00
# define BUFSIZE 1024
2007-03-11 01:07:47 +00:00
# ifdef WIN32
2007-03-29 22:31:56 +00:00
char lpPathBuffer [ BUFSIZE ] ;
DWORD dwBufSize = BUFSIZE ;
2007-03-11 01:07:47 +00:00
char base_dir [ 1024 ] ;
2006-08-20 03:04:55 +00:00
char * lastbacklash ;
2011-04-07 15:47:30 -05:00
2007-03-29 22:31:56 +00:00
GetModuleFileName ( NULL , base_dir , BUFSIZE ) ;
lastbacklash = strrchr ( base_dir , ' \\ ' ) ;
2007-03-11 01:07:47 +00:00
base_dir [ ( lastbacklash - base_dir ) ] = ' \0 ' ;
2011-04-07 15:47:30 -05:00
/* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */
SetCurrentDirectory ( base_dir ) ;
2007-03-11 01:07:47 +00:00
# else
char base_dir [ 1024 ] = SWITCH_PREFIX_DIR ;
# endif
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . base_dir & & ( SWITCH_GLOBAL_dirs . base_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
switch_snprintf ( SWITCH_GLOBAL_dirs . base_dir , BUFSIZE , " %s " , base_dir ) ;
2006-08-20 03:04:55 +00:00
}
2007-03-11 01:07:47 +00:00
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . mod_dir & & ( SWITCH_GLOBAL_dirs . mod_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
# ifdef SWITCH_MOD_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . mod_dir , BUFSIZE , " %s " , SWITCH_MOD_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . mod_dir , BUFSIZE , " %s%smod " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
2006-08-20 03:04:55 +00:00
}
2007-03-11 01:07:47 +00:00
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . conf_dir & & ( SWITCH_GLOBAL_dirs . conf_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
# ifdef SWITCH_CONF_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . conf_dir , BUFSIZE , " %s " , SWITCH_CONF_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . conf_dir , BUFSIZE , " %s%sconf " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
2006-08-20 03:04:55 +00:00
}
2007-03-11 01:07:47 +00:00
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . log_dir & & ( SWITCH_GLOBAL_dirs . log_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
# ifdef SWITCH_LOG_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . log_dir , BUFSIZE , " %s " , SWITCH_LOG_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . log_dir , BUFSIZE , " %s%slog " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
2006-08-20 03:04:55 +00:00
}
2007-03-11 01:07:47 +00:00
2009-09-04 18:26:15 +00:00
if ( ! SWITCH_GLOBAL_dirs . run_dir & & ( SWITCH_GLOBAL_dirs . run_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
# ifdef SWITCH_RUN_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . run_dir , BUFSIZE , " %s " , SWITCH_RUN_DIR ) ;
# else
2010-01-11 14:36:29 +00:00
switch_snprintf ( SWITCH_GLOBAL_dirs . run_dir , BUFSIZE , " %s%srun " , base_dir , SWITCH_PATH_SEPARATOR ) ;
2009-09-04 18:26:15 +00:00
# endif
}
2010-01-11 03:20:42 +00:00
if ( ! SWITCH_GLOBAL_dirs . recordings_dir & & ( SWITCH_GLOBAL_dirs . recordings_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
# ifdef SWITCH_RECORDINGS_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . recordings_dir , BUFSIZE , " %s " , SWITCH_RECORDINGS_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . recordings_dir , BUFSIZE , " %s%srecordings " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
}
2010-01-11 16:32:35 +00:00
if ( ! SWITCH_GLOBAL_dirs . sounds_dir & & ( SWITCH_GLOBAL_dirs . sounds_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
# ifdef SWITCH_SOUNDS_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . sounds_dir , BUFSIZE , " %s " , SWITCH_SOUNDS_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . sounds_dir , BUFSIZE , " %s%ssounds " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
}
2007-10-12 03:28:59 +00:00
if ( ! SWITCH_GLOBAL_dirs . storage_dir & & ( SWITCH_GLOBAL_dirs . storage_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
# ifdef SWITCH_STORAGE_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . storage_dir , BUFSIZE , " %s " , SWITCH_STORAGE_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . storage_dir , BUFSIZE , " %s%sstorage " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
}
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . db_dir & & ( SWITCH_GLOBAL_dirs . db_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
# ifdef SWITCH_DB_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . db_dir , BUFSIZE , " %s " , SWITCH_DB_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . db_dir , BUFSIZE , " %s%sdb " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
2006-08-20 03:04:55 +00:00
}
2007-03-11 01:07:47 +00:00
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . script_dir & & ( SWITCH_GLOBAL_dirs . script_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
# ifdef SWITCH_SCRIPT_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . script_dir , BUFSIZE , " %s " , SWITCH_SCRIPT_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . script_dir , BUFSIZE , " %s%sscripts " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
2006-08-20 03:04:55 +00:00
}
2007-03-11 01:07:47 +00:00
2006-08-20 03:36:14 +00:00
if ( ! SWITCH_GLOBAL_dirs . htdocs_dir & & ( SWITCH_GLOBAL_dirs . htdocs_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2007-03-11 01:07:47 +00:00
# ifdef SWITCH_HTDOCS_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . htdocs_dir , BUFSIZE , " %s " , SWITCH_HTDOCS_DIR ) ;
# else
switch_snprintf ( SWITCH_GLOBAL_dirs . htdocs_dir , BUFSIZE , " %s%shtdocs " , base_dir , SWITCH_PATH_SEPARATOR ) ;
# endif
2006-11-09 05:39:04 +00:00
}
2007-03-11 01:07:47 +00:00
if ( ! SWITCH_GLOBAL_dirs . grammar_dir & & ( SWITCH_GLOBAL_dirs . grammar_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
# ifdef SWITCH_GRAMMAR_DIR
switch_snprintf ( SWITCH_GLOBAL_dirs . grammar_dir , BUFSIZE , " %s " , SWITCH_GRAMMAR_DIR ) ;
2006-08-20 03:04:55 +00:00
# else
2007-03-11 01:07:47 +00:00
switch_snprintf ( SWITCH_GLOBAL_dirs . grammar_dir , BUFSIZE , " %s%sgrammar " , base_dir , SWITCH_PATH_SEPARATOR ) ;
2006-08-20 03:04:55 +00:00
# endif
2007-03-11 01:07:47 +00:00
}
if ( ! SWITCH_GLOBAL_dirs . temp_dir & & ( SWITCH_GLOBAL_dirs . temp_dir = ( char * ) malloc ( BUFSIZE ) ) ) {
2006-03-01 06:25:56 +00:00
# ifdef SWITCH_TEMP_DIR
2007-03-11 01:07:47 +00:00
switch_snprintf ( SWITCH_GLOBAL_dirs . temp_dir , BUFSIZE , " %s " , SWITCH_TEMP_DIR ) ;
2006-03-01 06:25:56 +00:00
# else
# ifdef WIN32
2007-03-11 01:07:47 +00:00
GetTempPath ( dwBufSize , lpPathBuffer ) ;
switch_snprintf ( SWITCH_GLOBAL_dirs . temp_dir , BUFSIZE , " %s " , lpPathBuffer ) ;
2006-03-01 06:25:56 +00:00
# else
2007-03-11 01:07:47 +00:00
switch_snprintf ( SWITCH_GLOBAL_dirs . temp_dir , BUFSIZE , " %s " , " /tmp/ " ) ;
2006-03-01 06:25:56 +00:00
# endif
# endif
2007-03-11 01:07:47 +00:00
}
2008-05-27 04:30:03 +00:00
2008-05-16 14:32:35 +00:00
switch_assert ( SWITCH_GLOBAL_dirs . base_dir ) ;
switch_assert ( SWITCH_GLOBAL_dirs . mod_dir ) ;
switch_assert ( SWITCH_GLOBAL_dirs . conf_dir ) ;
switch_assert ( SWITCH_GLOBAL_dirs . log_dir ) ;
2009-09-04 18:26:15 +00:00
switch_assert ( SWITCH_GLOBAL_dirs . run_dir ) ;
2008-05-16 14:32:35 +00:00
switch_assert ( SWITCH_GLOBAL_dirs . db_dir ) ;
switch_assert ( SWITCH_GLOBAL_dirs . script_dir ) ;
switch_assert ( SWITCH_GLOBAL_dirs . htdocs_dir ) ;
switch_assert ( SWITCH_GLOBAL_dirs . grammar_dir ) ;
2010-01-11 03:20:42 +00:00
switch_assert ( SWITCH_GLOBAL_dirs . recordings_dir ) ;
2010-01-11 16:32:35 +00:00
switch_assert ( SWITCH_GLOBAL_dirs . sounds_dir ) ;
2008-05-16 14:32:35 +00:00
switch_assert ( SWITCH_GLOBAL_dirs . temp_dir ) ;
2006-03-01 17:06:10 +00:00
}
2011-09-12 14:24:58 -05:00
2011-09-12 16:13:19 -05:00
SWITCH_DECLARE ( int32_t ) set_low_priority ( void )
2011-09-12 14:24:58 -05:00
{
2011-09-12 16:13:19 -05:00
2011-09-12 14:24:58 -05:00
# ifdef WIN32
SetPriorityClass ( GetCurrentProcess ( ) , BELOW_NORMAL_PRIORITY_CLASS ) ;
# else
# ifdef USE_SCHED_SETSCHEDULER
/*
* Try to use a normal scheduler
*/
struct sched_param sched = { 0 } ;
sched . sched_priority = 0 ;
if ( sched_setscheduler ( 0 , SCHED_OTHER , & sched ) ) {
return - 1 ;
}
# endif
# ifdef HAVE_SETPRIORITY
/*
* setpriority ( ) works on FreeBSD ( 6.2 ) , nice ( ) doesn ' t
*/
if ( setpriority ( PRIO_PROCESS , getpid ( ) , 19 ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not set nice level \n " ) ;
return - 1 ;
}
# else
if ( nice ( 19 ) ! = 19 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not set nice level \n " ) ;
return - 1 ;
}
# endif
# endif
2011-09-12 16:13:19 -05:00
2011-09-12 14:24:58 -05:00
return 0 ;
}
2011-09-12 16:13:19 -05:00
SWITCH_DECLARE ( int32_t ) set_realtime_priority ( void )
2006-09-20 20:25:26 +00:00
{
2011-03-22 13:48:19 -05:00
# ifdef WIN32
2011-09-12 16:13:19 -05:00
SetPriorityClass ( GetCurrentProcess ( ) , HIGH_PRIORITY_CLASS ) ;
2011-03-22 13:48:19 -05:00
# else
2007-10-23 15:56:23 +00:00
# ifdef USE_SCHED_SETSCHEDULER
/*
* Try to use a round - robin scheduler
* with a fallback if that does not work
*/
2007-03-29 22:31:56 +00:00
struct sched_param sched = { 0 } ;
2006-09-20 20:25:26 +00:00
sched . sched_priority = 1 ;
if ( sched_setscheduler ( 0 , SCHED_RR , & sched ) ) {
2007-03-29 22:31:56 +00:00
sched . sched_priority = 0 ;
if ( sched_setscheduler ( 0 , SCHED_OTHER , & sched ) ) {
2006-09-20 20:25:26 +00:00
return - 1 ;
}
}
# endif
2007-10-23 15:56:23 +00:00
# ifdef HAVE_SETPRIORITY
/*
* setpriority ( ) works on FreeBSD ( 6.2 ) , nice ( ) doesn ' t
*/
if ( setpriority ( PRIO_PROCESS , getpid ( ) , - 10 ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not set nice level \n " ) ;
2011-03-22 13:27:37 -05:00
return - 1 ;
2007-10-23 15:56:23 +00:00
}
2006-09-20 20:25:26 +00:00
# else
2007-10-23 15:56:23 +00:00
if ( nice ( - 10 ) ! = - 10 ) {
2007-09-21 18:49:14 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not set nice level \n " ) ;
2011-03-22 13:27:37 -05:00
return - 1 ;
2007-09-21 18:49:14 +00:00
}
2006-09-20 20:25:26 +00:00
# endif
2011-03-22 13:48:19 -05:00
# endif
2011-03-22 13:27:37 -05:00
return 0 ;
}
SWITCH_DECLARE ( int32_t ) set_normal_priority ( void )
{
2011-09-12 16:13:19 -05:00
return 0 ;
2011-03-22 13:27:37 -05:00
}
2011-09-12 16:13:19 -05:00
SWITCH_DECLARE ( int32_t ) set_auto_priority ( void )
2011-03-22 13:27:37 -05:00
{
2011-09-12 21:05:15 -05:00
# ifndef WIN32
2011-09-12 16:13:19 -05:00
runtime . cpu_count = sysconf ( _SC_NPROCESSORS_ONLN ) ;
2011-03-22 13:27:37 -05:00
2011-09-12 16:13:19 -05:00
/* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */
if ( runtime . cpu_count > 1 ) {
return set_realtime_priority ( ) ;
2007-10-23 15:56:23 +00:00
}
2011-09-12 21:05:15 -05:00
# endif
2007-10-23 15:56:23 +00:00
return 0 ;
}
SWITCH_DECLARE ( int32_t ) change_user_group ( const char * user , const char * group )
{
# ifndef WIN32
uid_t runas_uid = 0 ;
gid_t runas_gid = 0 ;
struct passwd * runas_pw = NULL ;
if ( user ) {
/*
* Lookup user information in the system ' s db
*/
2008-05-27 04:30:03 +00:00
runas_pw = getpwnam ( user ) ;
2007-10-23 15:56:23 +00:00
if ( ! runas_pw ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Unknown user \" %s \" \n " , user ) ;
return - 1 ;
}
runas_uid = runas_pw - > pw_uid ;
}
if ( group ) {
struct group * gr = NULL ;
/*
* Lookup group information in the system ' s db
*/
2008-05-27 04:30:03 +00:00
gr = getgrnam ( group ) ;
2007-10-23 15:56:23 +00:00
if ( ! gr ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Unknown group \" %s \" \n " , group ) ;
return - 1 ;
}
runas_gid = gr - > gr_gid ;
}
2008-10-08 14:53:31 +00:00
if ( runas_uid & & getuid ( ) = = runas_uid & & ( ! runas_gid | | runas_gid = = getgid ( ) ) ) {
/* already running as the right user and group, nothing to do! */
return 0 ;
}
2007-10-23 15:56:23 +00:00
if ( runas_uid ) {
# ifdef HAVE_SETGROUPS
/*
* Drop all group memberships prior to changing anything
* or else we ' re going to inherit the parent ' s list of groups
* ( which is not what we want . . . )
*/
if ( setgroups ( 0 , NULL ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failed to drop group access list \n " ) ;
return - 1 ;
}
# endif
if ( runas_gid ) {
/*
* A group has been passed , switch to it
* ( without loading the user ' s other groups )
*/
if ( setgid ( runas_gid ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failed to change gid! \n " ) ;
return - 1 ;
}
} else {
/*
* No group has been passed , use the user ' s primary group in this case
*/
if ( setgid ( runas_pw - > pw_gid ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failed to change gid! \n " ) ;
return - 1 ;
}
# ifdef HAVE_INITGROUPS
/*
* Set all the other groups the user is a member of
* ( This can be really useful for fine - grained access control )
*/
if ( initgroups ( runas_pw - > pw_name , runas_pw - > pw_gid ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failed to set group access list for user \n " ) ;
return - 1 ;
}
# endif
}
/*
* Finally drop all privileges by switching to the new userid
*/
if ( setuid ( runas_uid ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failed to change uid! \n " ) ;
return - 1 ;
}
}
2006-09-20 20:25:26 +00:00
# endif
return 0 ;
}
SWITCH_DECLARE ( void ) switch_core_runtime_loop ( int bg )
{
2006-09-20 20:47:28 +00:00
# ifdef WIN32
HANDLE shutdown_event ;
char path [ 256 ] = " " ;
# endif
2006-09-20 20:25:26 +00:00
if ( bg ) {
bg = 0 ;
# ifdef WIN32
2007-12-12 21:53:32 +00:00
switch_snprintf ( path , sizeof ( path ) , " Global \\ Freeswitch.%d " , getpid ( ) ) ;
2007-03-29 22:31:56 +00:00
shutdown_event = CreateEvent ( NULL , FALSE , FALSE , path ) ;
2007-12-11 21:31:57 +00:00
if ( shutdown_event ) {
WaitForSingleObject ( shutdown_event , INFINITE ) ;
}
2006-09-20 20:25:26 +00:00
# else
runtime . running = 1 ;
2007-03-29 22:31:56 +00:00
while ( runtime . running ) {
2006-09-20 20:25:26 +00:00
switch_yield ( 1000000 ) ;
}
# endif
2007-03-29 22:31:56 +00:00
} else {
2006-09-20 20:25:26 +00:00
/* wait for console input */
switch_console_loop ( ) ;
}
}
2007-11-26 23:41:00 +00:00
SWITCH_DECLARE ( const char * ) switch_core_mime_ext2type ( const char * ext )
{
2007-11-28 19:56:25 +00:00
if ( ! ext ) {
return NULL ;
}
2007-11-26 23:41:00 +00:00
return ( const char * ) switch_core_hash_find ( runtime . mime_types , ext ) ;
}
2008-05-27 04:30:03 +00:00
2007-11-28 20:44:18 +00:00
SWITCH_DECLARE ( switch_hash_index_t * ) switch_core_mime_index ( void )
{
return switch_hash_first ( NULL , runtime . mime_types ) ;
}
2007-11-26 23:41:00 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_mime_add_type ( const char * type , const char * ext )
{
2008-05-16 14:35:41 +00:00
const char * check ;
2007-11-26 23:41:00 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-12-11 19:23:57 +00:00
switch_assert ( type ) ;
switch_assert ( ext ) ;
2007-11-26 23:41:00 +00:00
2008-05-16 14:35:41 +00:00
check = ( const char * ) switch_core_hash_find ( runtime . mime_types , ext ) ;
2007-11-26 23:41:00 +00:00
if ( ! check ) {
char * ptype = switch_core_permanent_strdup ( type ) ;
char * ext_list = strdup ( ext ) ;
int argc = 0 ;
char * argv [ 20 ] = { 0 } ;
int x ;
2007-12-11 19:23:57 +00:00
switch_assert ( ext_list ) ;
2007-11-26 23:41:00 +00:00
if ( ( argc = switch_separate_string ( ext_list , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
for ( x = 0 ; x < argc ; x + + ) {
2008-01-28 08:47:55 +00:00
if ( argv [ x ] & & ptype ) {
switch_core_hash_insert ( runtime . mime_types , argv [ x ] , ptype ) ;
}
2007-11-26 23:41:00 +00:00
}
2008-05-27 04:30:03 +00:00
2007-11-26 23:41:00 +00:00
status = SWITCH_STATUS_SUCCESS ;
}
2008-05-27 04:30:03 +00:00
2007-11-26 23:41:00 +00:00
free ( ext_list ) ;
}
return status ;
}
2008-05-27 04:30:03 +00:00
static void load_mime_types ( void )
2007-11-26 23:41:00 +00:00
{
char * cf = " mime.types " ;
int fd = - 1 ;
char line_buf [ 1024 ] = " " ;
char * mime_path = NULL ;
mime_path = switch_mprintf ( " %s/%s " , SWITCH_GLOBAL_dirs . conf_dir , cf ) ;
2007-12-11 19:23:57 +00:00
switch_assert ( mime_path ) ;
2007-11-26 23:41:00 +00:00
2008-07-12 18:44:05 +00:00
fd = open ( mime_path , O_RDONLY | O_BINARY ) ;
2007-12-03 16:17:28 +00:00
if ( fd < = 0 ) {
2008-06-23 20:41:45 +00:00
goto end ;
2007-11-26 23:41:00 +00:00
}
2010-02-06 03:38:24 +00:00
2008-05-27 04:30:03 +00:00
while ( ( switch_fd_read_line ( fd , line_buf , sizeof ( line_buf ) ) ) ) {
2007-11-26 23:41:00 +00:00
char * p ;
char * type = line_buf ;
if ( * line_buf = = ' # ' ) {
continue ;
}
if ( ( p = strchr ( line_buf , ' \r ' ) ) | | ( p = strchr ( line_buf , ' \n ' ) ) ) {
* p = ' \0 ' ;
}
if ( ( p = strchr ( type , ' \t ' ) ) | | ( p = strchr ( type , ' ' ) ) ) {
* p + + = ' \0 ' ;
2008-05-27 04:30:03 +00:00
while ( * p = = ' ' | | * p = = ' \t ' ) {
2007-11-26 23:41:00 +00:00
p + + ;
}
switch_core_mime_add_type ( type , p ) ;
}
2008-05-27 04:30:03 +00:00
2007-11-26 23:41:00 +00:00
}
if ( fd > - 1 ) {
close ( fd ) ;
fd = - 1 ;
}
2008-06-23 20:41:45 +00:00
2010-02-06 03:38:24 +00:00
end :
2008-06-23 20:41:45 +00:00
2009-03-03 17:03:48 +00:00
switch_safe_free ( mime_path ) ;
2008-06-23 20:41:45 +00:00
2008-05-27 04:30:03 +00:00
}
2006-09-20 20:25:26 +00:00
2008-01-07 20:40:59 +00:00
SWITCH_DECLARE ( void ) switch_core_setrlimits ( void )
{
# ifdef HAVE_SETRLIMIT
struct rlimit rlp ;
/*
Setting the stack size on FreeBSD results in an instant crash .
2008-05-27 04:30:03 +00:00
2008-01-07 20:40:59 +00:00
If anyone knows how to fix this ,
feel free to submit a patch to http : //jira.freeswitch.org
2008-05-27 04:30:03 +00:00
*/
2008-01-07 20:40:59 +00:00
# ifndef __FreeBSD__
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
rlp . rlim_cur = SWITCH_THREAD_STACKSIZE ;
2009-03-11 15:57:42 +00:00
rlp . rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE ;
2008-01-07 20:40:59 +00:00
setrlimit ( RLIMIT_STACK , & rlp ) ;
# endif
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
rlp . rlim_cur = 999999 ;
rlp . rlim_max = 999999 ;
setrlimit ( RLIMIT_NOFILE , & rlp ) ;
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
rlp . rlim_cur = RLIM_INFINITY ;
rlp . rlim_max = RLIM_INFINITY ;
setrlimit ( RLIMIT_CPU , & rlp ) ;
setrlimit ( RLIMIT_DATA , & rlp ) ;
setrlimit ( RLIMIT_FSIZE , & rlp ) ;
2009-03-09 16:17:01 +00:00
# ifdef RLIMIT_NPROC
2009-03-07 02:20:29 +00:00
setrlimit ( RLIMIT_NPROC , & rlp ) ;
2009-03-09 16:17:01 +00:00
# endif
2009-03-08 05:43:51 +00:00
# ifdef RLIMIT_RTPRIO
2009-03-07 02:20:29 +00:00
setrlimit ( RLIMIT_RTPRIO , & rlp ) ;
2009-03-08 05:43:51 +00:00
# endif
2008-12-14 16:41:33 +00:00
# if !defined(__OpenBSD__) && !defined(__NetBSD__)
2008-01-07 20:40:59 +00:00
setrlimit ( RLIMIT_AS , & rlp ) ;
2008-02-22 23:18:28 +00:00
# endif
2008-01-07 20:40:59 +00:00
# endif
return ;
}
2008-03-26 22:14:09 +00:00
typedef struct {
switch_memory_pool_t * pool ;
switch_hash_t * hash ;
} switch_ip_list_t ;
static switch_ip_list_t IP_LIST = { 0 } ;
2008-07-16 17:44:54 +00:00
SWITCH_DECLARE ( switch_bool_t ) switch_check_network_list_ip_token ( const char * ip_str , const char * list_name , const char * * token )
2008-03-26 22:14:09 +00:00
{
switch_network_list_t * list ;
2010-11-15 11:37:07 -06:00
ip_t ip , mask , net ;
uint32_t bits ;
char * ipv6 = strchr ( ip_str , ' : ' ) ;
2008-03-26 22:14:09 +00:00
switch_bool_t ok = SWITCH_FALSE ;
2008-05-27 04:30:03 +00:00
2008-03-26 22:14:09 +00:00
switch_mutex_lock ( runtime . global_mutex ) ;
2010-11-15 11:37:07 -06:00
if ( ipv6 ) {
switch_inet_pton ( AF_INET6 , ip_str , & ip ) ;
} else {
switch_inet_pton ( AF_INET , ip_str , & ip ) ;
ip . v4 = htonl ( ip . v4 ) ;
}
2008-07-14 16:32:56 +00:00
2008-03-26 22:14:09 +00:00
if ( ( list = switch_core_hash_find ( IP_LIST . hash , list_name ) ) ) {
2010-11-15 11:37:07 -06:00
if ( ipv6 ) {
ok = switch_network_list_validate_ip6_token ( list , ip , token ) ;
} else {
ok = switch_network_list_validate_ip_token ( list , ip . v4 , token ) ;
}
2008-03-26 22:14:09 +00:00
} else if ( strchr ( list_name , ' / ' ) ) {
2010-02-06 03:38:24 +00:00
if ( strchr ( list_name , ' , ' ) ) {
2009-12-02 18:51:28 +00:00
char * list_name_dup = strdup ( list_name ) ;
char * argv [ 32 ] ;
int argc ;
switch_assert ( list_name_dup ) ;
if ( ( argc = switch_separate_string ( list_name_dup , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
int i ;
for ( i = 0 ; i < argc ; i + + ) {
switch_parse_cidr ( argv [ i ] , & net , & mask , & bits ) ;
2010-11-15 11:37:07 -06:00
if ( ipv6 ) {
if ( ( ok = switch_testv6_subnet ( ip , net , mask ) ) ) {
break ;
}
} else {
if ( ( ok = switch_test_subnet ( ip . v4 , net . v4 , mask . v4 ) ) ) {
break ;
}
2010-02-06 03:38:24 +00:00
}
2009-12-02 18:51:28 +00:00
}
}
free ( list_name_dup ) ;
} else {
switch_parse_cidr ( list_name , & net , & mask , & bits ) ;
2010-11-15 11:37:07 -06:00
ok = switch_test_subnet ( ip . v4 , net . v4 , mask . v4 ) ;
2009-12-02 18:51:28 +00:00
}
2008-03-26 22:14:09 +00:00
}
switch_mutex_unlock ( runtime . global_mutex ) ;
2008-05-27 04:30:03 +00:00
2008-03-26 22:14:09 +00:00
return ok ;
}
SWITCH_DECLARE ( void ) switch_load_network_lists ( switch_bool_t reload )
{
switch_xml_t xml = NULL , x_lists = NULL , x_list = NULL , x_node = NULL , cfg = NULL ;
2009-06-02 16:55:10 +00:00
switch_network_list_t * rfc_list , * list ;
char guess_ip [ 16 ] = " " ;
int mask = 0 ;
char guess_mask [ 16 ] = " " ;
char * tmp_name ;
2009-06-05 21:23:37 +00:00
struct in_addr in ;
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( guess_ip , sizeof ( guess_ip ) , & mask , AF_INET ) ;
2009-06-05 21:23:37 +00:00
in . s_addr = mask ;
switch_set_string ( guess_mask , inet_ntoa ( in ) ) ;
2010-02-06 03:38:24 +00:00
2008-03-26 22:14:09 +00:00
switch_mutex_lock ( runtime . global_mutex ) ;
if ( IP_LIST . hash ) {
switch_core_hash_destroy ( & IP_LIST . hash ) ;
}
if ( IP_LIST . pool ) {
switch_core_destroy_memory_pool ( & IP_LIST . pool ) ;
}
2008-05-27 04:30:03 +00:00
2008-03-26 22:14:09 +00:00
memset ( & IP_LIST , 0 , sizeof ( IP_LIST ) ) ;
switch_core_new_memory_pool ( & IP_LIST . pool ) ;
switch_core_hash_init ( & IP_LIST . hash , IP_LIST . pool ) ;
2008-05-27 04:30:03 +00:00
2009-06-02 16:55:10 +00:00
tmp_name = " rfc1918.auto " ;
switch_network_list_create ( & rfc_list , tmp_name , SWITCH_FALSE , IP_LIST . pool ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Created ip list %s default (deny) \n " , tmp_name ) ;
switch_network_list_add_cidr ( rfc_list , " 10.0.0.0/8 " , SWITCH_TRUE ) ;
switch_network_list_add_cidr ( rfc_list , " 172.16.0.0/12 " , SWITCH_TRUE ) ;
switch_network_list_add_cidr ( rfc_list , " 192.168.0.0/16 " , SWITCH_TRUE ) ;
2010-02-06 03:38:24 +00:00
switch_core_hash_insert ( IP_LIST . hash , tmp_name , rfc_list ) ;
2009-06-02 16:55:10 +00:00
2009-06-23 13:40:29 +00:00
tmp_name = " wan.auto " ;
switch_network_list_create ( & rfc_list , tmp_name , SWITCH_TRUE , IP_LIST . pool ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Created ip list %s default (allow) \n " , tmp_name ) ;
switch_network_list_add_cidr ( rfc_list , " 10.0.0.0/8 " , SWITCH_FALSE ) ;
switch_network_list_add_cidr ( rfc_list , " 172.16.0.0/12 " , SWITCH_FALSE ) ;
switch_network_list_add_cidr ( rfc_list , " 192.168.0.0/16 " , SWITCH_FALSE ) ;
2010-02-06 03:38:24 +00:00
switch_core_hash_insert ( IP_LIST . hash , tmp_name , rfc_list ) ;
2009-06-23 13:40:29 +00:00
2009-06-02 16:55:10 +00:00
tmp_name = " nat.auto " ;
switch_network_list_create ( & rfc_list , tmp_name , SWITCH_FALSE , IP_LIST . pool ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Created ip list %s default (deny) \n " , tmp_name ) ;
2009-06-23 21:41:22 +00:00
if ( switch_network_list_add_host_mask ( rfc_list , guess_ip , guess_mask , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Adding %s/%s (deny) to list %s \n " , guess_ip , guess_mask , tmp_name ) ;
}
2009-06-02 16:55:10 +00:00
switch_network_list_add_cidr ( rfc_list , " 10.0.0.0/8 " , SWITCH_TRUE ) ;
switch_network_list_add_cidr ( rfc_list , " 172.16.0.0/12 " , SWITCH_TRUE ) ;
switch_network_list_add_cidr ( rfc_list , " 192.168.0.0/16 " , SWITCH_TRUE ) ;
2010-02-06 03:38:24 +00:00
switch_core_hash_insert ( IP_LIST . hash , tmp_name , rfc_list ) ;
2009-06-02 16:55:10 +00:00
2009-06-03 19:25:42 +00:00
tmp_name = " loopback.auto " ;
switch_network_list_create ( & rfc_list , tmp_name , SWITCH_FALSE , IP_LIST . pool ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Created ip list %s default (deny) \n " , tmp_name ) ;
switch_network_list_add_cidr ( rfc_list , " 127.0.0.0/8 " , SWITCH_TRUE ) ;
switch_core_hash_insert ( IP_LIST . hash , tmp_name , rfc_list ) ;
2009-06-02 16:55:10 +00:00
tmp_name = " localnet.auto " ;
switch_network_list_create ( & list , tmp_name , SWITCH_FALSE , IP_LIST . pool ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Created ip list %s default (deny) \n " , tmp_name ) ;
2010-02-06 03:38:24 +00:00
2009-06-02 16:55:10 +00:00
if ( switch_network_list_add_host_mask ( list , guess_ip , guess_mask , SWITCH_TRUE ) = = SWITCH_STATUS_SUCCESS ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Adding %s/%s (allow) to list %s \n " , guess_ip , guess_mask , tmp_name ) ;
2009-06-02 16:55:10 +00:00
}
2010-02-06 03:38:24 +00:00
switch_core_hash_insert ( IP_LIST . hash , tmp_name , list ) ;
2009-06-02 16:55:10 +00:00
2008-03-26 22:14:09 +00:00
if ( ( xml = switch_xml_open_cfg ( " acl.conf " , & cfg , NULL ) ) ) {
if ( ( x_lists = switch_xml_child ( cfg , " network-lists " ) ) ) {
for ( x_list = switch_xml_child ( x_lists , " list " ) ; x_list ; x_list = x_list - > next ) {
const char * name = switch_xml_attr ( x_list , " name " ) ;
const char * dft = switch_xml_attr ( x_list , " default " ) ;
switch_bool_t default_type = SWITCH_TRUE ;
2009-10-23 16:03:42 +00:00
if ( zstr ( name ) ) {
2008-03-26 22:14:09 +00:00
continue ;
}
if ( dft ) {
default_type = switch_true ( dft ) ;
}
2008-05-27 04:30:03 +00:00
2009-06-02 16:55:10 +00:00
if ( switch_network_list_create ( & list , name , default_type , IP_LIST . pool ) ! = SWITCH_STATUS_SUCCESS ) {
2008-03-26 22:14:09 +00:00
abort ( ) ;
}
if ( reload ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Created ip list %s default (%s) \n " , name , default_type ? " allow " : " deny " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Created ip list %s default (%s) \n " , name , default_type ? " allow " : " deny " ) ;
}
for ( x_node = switch_xml_child ( x_list , " node " ) ; x_node ; x_node = x_node - > next ) {
2008-07-16 17:44:54 +00:00
const char * cidr = NULL , * host = NULL , * mask = NULL , * domain = NULL ;
2008-03-26 22:14:09 +00:00
switch_bool_t ok = default_type ;
const char * type = switch_xml_attr ( x_node , " type " ) ;
if ( type ) {
ok = switch_true ( type ) ;
2008-05-27 04:30:03 +00:00
}
2008-03-26 22:14:09 +00:00
cidr = switch_xml_attr ( x_node , " cidr " ) ;
host = switch_xml_attr ( x_node , " host " ) ;
mask = switch_xml_attr ( x_node , " mask " ) ;
2008-07-16 17:44:54 +00:00
domain = switch_xml_attr ( x_node , " domain " ) ;
if ( domain ) {
switch_event_t * my_params = NULL ;
switch_xml_t x_domain , xml_root ;
2008-12-28 23:17:29 +00:00
switch_xml_t gt , gts , ut , uts ;
2008-07-16 17:44:54 +00:00
2008-10-02 17:10:05 +00:00
switch_event_create ( & my_params , SWITCH_EVENT_GENERAL ) ;
2008-07-16 17:44:54 +00:00
switch_assert ( my_params ) ;
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " domain " , domain ) ;
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " purpose " , " network-list " ) ;
2010-02-06 03:38:24 +00:00
2008-07-16 17:44:54 +00:00
if ( switch_xml_locate_domain ( domain , my_params , & xml_root , & x_domain ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Cannot locate domain %s \n " , domain ) ;
2008-07-17 19:46:25 +00:00
switch_event_destroy ( & my_params ) ;
2008-07-16 17:44:54 +00:00
continue ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
switch_event_destroy ( & my_params ) ;
2008-07-16 17:44:54 +00:00
for ( ut = switch_xml_child ( x_domain , " user " ) ; ut ; ut = ut - > next ) {
const char * user_cidr = switch_xml_attr ( ut , " cidr " ) ;
const char * id = switch_xml_attr ( ut , " id " ) ;
if ( id & & user_cidr ) {
char * token = switch_mprintf ( " %s@%s " , id , domain ) ;
2009-06-06 01:37:26 +00:00
switch_assert ( token ) ;
2009-12-02 18:51:28 +00:00
switch_network_list_add_cidr_token ( list , user_cidr , ok , token ) ;
2008-07-16 17:44:54 +00:00
free ( token ) ;
2008-03-26 22:14:09 +00:00
}
2008-07-16 17:44:54 +00:00
}
2008-12-28 23:17:29 +00:00
for ( gts = switch_xml_child ( x_domain , " groups " ) ; gts ; gts = gts - > next ) {
for ( gt = switch_xml_child ( gts , " group " ) ; gt ; gt = gt - > next ) {
for ( uts = switch_xml_child ( gt , " users " ) ; uts ; uts = uts - > next ) {
for ( ut = switch_xml_child ( uts , " user " ) ; ut ; ut = ut - > next ) {
const char * user_cidr = switch_xml_attr ( ut , " cidr " ) ;
const char * id = switch_xml_attr ( ut , " id " ) ;
2010-02-06 03:38:24 +00:00
2008-12-28 23:17:29 +00:00
if ( id & & user_cidr ) {
char * token = switch_mprintf ( " %s@%s " , id , domain ) ;
2010-02-06 03:38:24 +00:00
switch_assert ( token ) ;
2009-12-02 18:51:28 +00:00
switch_network_list_add_cidr_token ( list , user_cidr , ok , token ) ;
2008-12-28 23:17:29 +00:00
free ( token ) ;
}
}
}
}
}
2010-02-06 03:38:24 +00:00
2008-07-16 17:44:54 +00:00
switch_xml_free ( xml_root ) ;
} else if ( cidr ) {
if ( switch_network_list_add_cidr ( list , cidr , ok ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Adding %s (%s) to list %s \n " , cidr , ok ? " allow " : " deny " , name ) ;
2008-03-26 22:14:09 +00:00
} else {
2008-07-16 17:44:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
" Error Adding %s (%s) to list %s \n " , cidr , ok ? " allow " : " deny " , name ) ;
2008-03-26 22:14:09 +00:00
}
} else if ( host & & mask ) {
if ( switch_network_list_add_host_mask ( list , host , mask , ok ) = = SWITCH_STATUS_SUCCESS ) {
2008-07-16 17:44:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE ,
" Adding %s/%s (%s) to list %s \n " , host , mask , ok ? " allow " : " deny " , name ) ;
2008-03-26 22:14:09 +00:00
}
2010-02-06 03:38:24 +00:00
}
2008-03-26 22:14:09 +00:00
switch_core_hash_insert ( IP_LIST . hash , name , list ) ;
}
}
}
switch_xml_free ( xml ) ;
}
switch_mutex_unlock ( runtime . global_mutex ) ;
}
2008-04-18 17:03:34 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_max_dtmf_duration ( uint32_t duration )
{
if ( duration ) {
if ( duration > SWITCH_MAX_DTMF_DURATION ) {
duration = SWITCH_MAX_DTMF_DURATION ;
}
2009-09-16 21:24:22 +00:00
if ( duration < SWITCH_MIN_DTMF_DURATION ) {
duration = SWITCH_MIN_DTMF_DURATION ;
}
2008-04-18 17:03:34 +00:00
runtime . max_dtmf_duration = duration ;
2011-09-16 11:39:41 -05:00
if ( duration < runtime . min_dtmf_duration ) {
runtime . min_dtmf_duration = duration ;
}
2008-04-18 17:03:34 +00:00
}
return runtime . max_dtmf_duration ;
}
SWITCH_DECLARE ( uint32_t ) switch_core_default_dtmf_duration ( uint32_t duration )
{
if ( duration ) {
2009-09-16 21:24:22 +00:00
if ( duration < SWITCH_MIN_DTMF_DURATION ) {
duration = SWITCH_MIN_DTMF_DURATION ;
}
if ( duration > SWITCH_MAX_DTMF_DURATION ) {
duration = SWITCH_MAX_DTMF_DURATION ;
2008-04-18 17:03:34 +00:00
}
runtime . default_dtmf_duration = duration ;
2011-09-16 11:39:41 -05:00
if ( duration < runtime . min_dtmf_duration ) {
runtime . min_dtmf_duration = duration ;
}
if ( duration > runtime . max_dtmf_duration ) {
runtime . max_dtmf_duration = duration ;
}
2008-04-18 17:03:34 +00:00
}
return runtime . default_dtmf_duration ;
}
2009-09-16 21:24:22 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_min_dtmf_duration ( uint32_t duration )
{
if ( duration ) {
if ( duration < SWITCH_MIN_DTMF_DURATION ) {
duration = SWITCH_MIN_DTMF_DURATION ;
}
if ( duration > SWITCH_MAX_DTMF_DURATION ) {
duration = SWITCH_MAX_DTMF_DURATION ;
}
2011-09-16 11:39:41 -05:00
runtime . min_dtmf_duration = duration ;
if ( duration > runtime . max_dtmf_duration ) {
runtime . max_dtmf_duration = duration ;
}
2009-09-16 21:24:22 +00:00
}
return runtime . min_dtmf_duration ;
}
2009-05-20 23:04:05 +00:00
static void switch_core_set_serial ( void )
{
char buf [ 13 ] = " " ;
char path [ 256 ] ;
2010-02-06 03:38:24 +00:00
2009-05-20 23:04:05 +00:00
int fd = - 1 , write_fd = - 1 ;
2009-05-21 14:55:58 +00:00
switch_ssize_t bytes = 0 ;
2009-05-20 23:04:05 +00:00
switch_snprintf ( path , sizeof ( path ) , " %s%sfreeswitch.serial " , SWITCH_GLOBAL_dirs . conf_dir , SWITCH_PATH_SEPARATOR ) ;
if ( ( fd = open ( path , O_RDONLY , 0 ) ) < 0 ) {
2011-02-02 15:43:26 -06:00
char * ip = switch_core_get_variable_dup ( " local_ip_v4 " ) ;
2009-05-20 23:04:05 +00:00
uint32_t ipi = 0 ;
switch_byte_t * byte ;
int i = 0 ;
2011-02-02 15:43:26 -06:00
if ( ip ) {
switch_inet_pton ( AF_INET , ip , & ipi ) ;
free ( ip ) ;
ip = NULL ;
}
2010-02-06 03:38:24 +00:00
byte = ( switch_byte_t * ) & ipi ;
2009-05-20 23:04:05 +00:00
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < 8 ; i + = 2 ) {
2009-05-20 23:04:05 +00:00
switch_snprintf ( buf + i , sizeof ( buf ) - i , " %0.2x " , * byte ) ;
byte + + ;
}
switch_stun_random_string ( buf + 8 , 4 , " 0123456789abcdef " ) ;
if ( ( write_fd = open ( path , O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR ) ) > = 0 ) {
bytes = write ( write_fd , buf , sizeof ( buf ) ) ;
2011-04-22 16:43:29 -05:00
bytes + + ;
2009-05-20 23:04:05 +00:00
close ( write_fd ) ;
write_fd = - 1 ;
}
} else {
bytes = read ( fd , buf , sizeof ( buf ) ) ;
close ( fd ) ;
fd = - 1 ;
}
2010-02-06 03:38:24 +00:00
2009-05-20 23:04:05 +00:00
switch_core_set_variable ( " switch_serial " , buf ) ;
}
2011-05-11 10:07:00 -05:00
2007-12-06 13:40:00 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_init ( switch_core_flag_t flags , switch_bool_t console , const char * * err )
2006-03-01 17:06:10 +00:00
{
2007-02-22 23:12:58 +00:00
switch_uuid_t uuid ;
2007-10-17 15:38:57 +00:00
char guess_ip [ 256 ] ;
2009-06-02 16:55:10 +00:00
int mask = 0 ;
2009-06-05 21:23:37 +00:00
struct in_addr in ;
2011-02-02 15:43:26 -06:00
2006-03-01 17:06:10 +00:00
2010-01-04 19:03:43 +00:00
if ( runtime . runlevel > 0 ) {
/* one per customer */
return SWITCH_STATUS_SUCCESS ;
}
2011-02-25 16:34:17 -06:00
memset ( & runtime , 0 , sizeof ( runtime ) ) ;
gethostname ( runtime . hostname , sizeof ( runtime . hostname ) ) ;
2011-03-04 13:52:30 -06:00
runtime . max_db_handles = 50 ;
runtime . db_handle_timeout = 5000000 ; ;
2010-01-04 19:03:43 +00:00
runtime . runlevel + + ;
2010-09-14 16:19:03 -05:00
runtime . sql_buffer_len = 1024 * 32 ;
runtime . max_sql_buffer_len = 1024 * 1024 ;
2008-05-06 21:05:38 +00:00
runtime . dummy_cng_frame . data = runtime . dummy_data ;
2008-05-27 04:30:03 +00:00
runtime . dummy_cng_frame . datalen = sizeof ( runtime . dummy_data ) ;
runtime . dummy_cng_frame . buflen = sizeof ( runtime . dummy_data ) ;
2008-11-26 18:56:37 +00:00
switch_set_flag ( ( & runtime . dummy_cng_frame ) , SFF_CNG ) ;
2010-08-04 09:56:53 -05:00
switch_set_flag ( ( & runtime ) , SCF_AUTO_SCHEMAS ) ;
2011-08-24 13:36:13 -05:00
switch_set_flag ( ( & runtime ) , SCF_CLEAR_SQL ) ;
2011-09-12 14:24:58 -05:00
switch_set_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ;
2008-05-06 21:05:38 +00:00
2007-09-29 01:06:08 +00:00
switch_set_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
2007-10-04 17:25:06 +00:00
runtime . hard_log_level = SWITCH_LOG_DEBUG ;
2007-11-05 18:45:26 +00:00
runtime . mailer_app = " sendmail " ;
runtime . mailer_app_args = " -t " ;
2008-04-18 17:03:34 +00:00
runtime . max_dtmf_duration = SWITCH_MAX_DTMF_DURATION ;
runtime . default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION ;
2009-09-16 21:24:22 +00:00
runtime . min_dtmf_duration = SWITCH_MIN_DTMF_DURATION ;
2010-10-21 16:18:54 -05:00
runtime . odbc_dbtype = DBTYPE_DEFAULT ;
2011-02-15 01:49:41 -05:00
runtime . dbname = NULL ;
2011-09-12 21:05:15 -05:00
# ifndef WIN32
2011-09-12 16:13:19 -05:00
runtime . cpu_count = sysconf ( _SC_NPROCESSORS_ONLN ) ;
2011-09-12 21:05:15 -05:00
# endif
2007-07-06 16:29:25 +00:00
2006-04-11 21:13:44 +00:00
/* INIT APR and Create the pool context */
if ( apr_initialize ( ) ! = SWITCH_STATUS_SUCCESS ) {
2008-01-07 10:55:15 +00:00
* err = " FATAL ERROR! Could not initialize APR \n " ;
2006-04-11 21:13:44 +00:00
return SWITCH_STATUS_MEMERR ;
}
2007-03-29 22:31:56 +00:00
if ( ! ( runtime . memory_pool = switch_core_memory_init ( ) ) ) {
2008-01-07 10:55:15 +00:00
* err = " FATAL ERROR! Could not allocate memory pool \n " ;
2006-04-11 21:13:44 +00:00
return SWITCH_STATUS_MEMERR ;
}
2007-12-11 19:23:57 +00:00
switch_assert ( runtime . memory_pool ! = NULL ) ;
2008-06-30 22:22:44 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . base_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . mod_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . conf_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . log_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
2009-09-04 18:26:15 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . run_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
2008-06-30 22:22:44 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . db_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . script_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . htdocs_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . grammar_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
2010-01-11 03:20:42 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . recordings_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
2010-01-11 16:32:35 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . sounds_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
2008-06-30 22:22:44 +00:00
switch_dir_make_recursive ( SWITCH_GLOBAL_dirs . temp_dir , SWITCH_DEFAULT_DIR_PERMS , runtime . memory_pool ) ;
2010-08-04 09:56:53 -05:00
2009-12-28 22:04:50 +00:00
switch_mutex_init ( & runtime . uuid_mutex , SWITCH_MUTEX_NESTED , runtime . memory_pool ) ;
2008-06-30 22:22:44 +00:00
2007-10-03 16:44:11 +00:00
switch_mutex_init ( & runtime . throttle_mutex , SWITCH_MUTEX_NESTED , runtime . memory_pool ) ;
2010-08-04 09:56:53 -05:00
2009-03-07 17:45:37 +00:00
switch_mutex_init ( & runtime . session_hash_mutex , SWITCH_MUTEX_NESTED , runtime . memory_pool ) ;
2007-12-22 00:32:20 +00:00
switch_mutex_init ( & runtime . global_mutex , SWITCH_MUTEX_NESTED , runtime . memory_pool ) ;
2011-07-12 20:36:36 -05:00
switch_thread_rwlock_create ( & runtime . global_var_rwlock , runtime . memory_pool ) ;
2007-03-29 22:31:56 +00:00
switch_core_set_globals ( ) ;
switch_core_session_init ( runtime . memory_pool ) ;
2010-05-25 16:54:13 -05:00
switch_event_create_plain ( & runtime . global_vars , SWITCH_EVENT_CHANNEL_DATA ) ;
2007-11-26 23:41:00 +00:00
switch_core_hash_init ( & runtime . mime_types , runtime . memory_pool ) ;
2010-10-08 17:04:22 -05:00
switch_core_hash_init_case ( & runtime . ptimes , runtime . memory_pool , SWITCH_FALSE ) ;
2007-11-26 23:41:00 +00:00
load_mime_types ( ) ;
2010-08-04 09:56:53 -05:00
runtime . flags | = flags ;
2007-10-03 16:44:11 +00:00
runtime . sps_total = 30 ;
2007-03-30 02:20:13 +00:00
2009-06-02 22:03:33 +00:00
* err = NULL ;
if ( console ) {
runtime . console = stdout ;
}
2011-11-29 15:35:36 -06:00
switch_ssl_init_ssl_locks ( ) ;
switch_curl_init ( ) ;
2011-02-02 15:43:26 -06:00
switch_core_set_variable ( " hostname " , runtime . hostname ) ;
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( guess_ip , sizeof ( guess_ip ) , & mask , AF_INET ) ;
2007-10-17 15:38:57 +00:00
switch_core_set_variable ( " local_ip_v4 " , guess_ip ) ;
2009-06-05 21:23:37 +00:00
in . s_addr = mask ;
switch_core_set_variable ( " local_mask_v4 " , inet_ntoa ( in ) ) ;
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( guess_ip , sizeof ( guess_ip ) , NULL , AF_INET6 ) ;
2007-10-17 15:38:57 +00:00
switch_core_set_variable ( " local_ip_v6 " , guess_ip ) ;
2007-12-06 19:51:55 +00:00
switch_core_set_variable ( " base_dir " , SWITCH_GLOBAL_dirs . base_dir ) ;
2010-01-11 03:20:42 +00:00
switch_core_set_variable ( " recordings_dir " , SWITCH_GLOBAL_dirs . recordings_dir ) ;
2010-01-11 16:32:35 +00:00
switch_core_set_variable ( " sound_prefix " , SWITCH_GLOBAL_dirs . sounds_dir ) ;
switch_core_set_variable ( " sounds_dir " , SWITCH_GLOBAL_dirs . sounds_dir ) ;
2009-05-20 23:04:05 +00:00
switch_core_set_serial ( ) ;
2008-07-11 14:35:08 +00:00
2009-12-14 20:10:06 +00:00
switch_console_init ( runtime . memory_pool ) ;
2008-03-03 20:51:50 +00:00
switch_event_init ( runtime . memory_pool ) ;
2006-06-05 18:36:02 +00:00
if ( switch_xml_init ( runtime . memory_pool , err ) ! = SWITCH_STATUS_SUCCESS ) {
2006-05-15 18:16:43 +00:00
apr_terminate ( ) ;
2006-05-10 03:23:05 +00:00
return SWITCH_STATUS_MEMERR ;
}
2008-03-26 22:14:09 +00:00
2009-06-02 22:03:33 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_USE_AUTO_NAT ) ) {
2011-04-01 12:30:24 -05:00
switch_nat_init ( runtime . memory_pool , switch_test_flag ( ( & runtime ) , SCF_USE_NAT_MAPPING ) ) ;
2009-06-02 22:03:33 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-11 14:35:08 +00:00
switch_log_init ( runtime . memory_pool , runtime . colorize_console ) ;
2007-05-10 16:56:29 +00:00
2010-09-14 11:48:43 -05:00
if ( flags & SCF_MINIMAL ) return SWITCH_STATUS_SUCCESS ;
2011-04-15 14:46:24 +00:00
runtime . tipping_point = 0 ;
2010-03-01 19:25:27 +00:00
runtime . timer_affinity = - 1 ;
2011-04-29 11:09:14 -05:00
runtime . microseconds_per_tick = 20000 ;
2009-06-02 22:03:33 +00:00
switch_load_core_config ( " switch.conf " ) ;
2006-06-05 18:36:02 +00:00
2009-06-02 22:03:33 +00:00
switch_core_state_machine_init ( runtime . memory_pool ) ;
2005-11-19 20:07:43 +00:00
2009-11-17 00:12:54 +00:00
if ( switch_core_sqldb_start ( runtime . memory_pool , switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ? SWITCH_TRUE : SWITCH_FALSE ) ! = SWITCH_STATUS_SUCCESS ) {
2011-10-17 09:34:50 -05:00
* err = " Error activating database " ;
return SWITCH_STATUS_FALSE ;
2007-09-29 01:06:08 +00:00
}
2009-11-17 00:12:54 +00:00
2009-05-22 05:33:21 +00:00
switch_scheduler_task_thread_start ( ) ;
2010-06-20 19:21:42 -05:00
switch_nat_late_init ( ) ;
2006-04-05 20:17:22 +00:00
switch_rtp_init ( runtime . memory_pool ) ;
2009-05-22 05:33:21 +00:00
2007-03-29 22:31:56 +00:00
runtime . running = 1 ;
2006-05-10 03:23:05 +00:00
runtime . initiated = switch_time_now ( ) ;
2010-02-17 19:50:25 +00:00
2009-01-25 21:23:07 +00:00
switch_scheduler_add_task ( switch_epoch_time_now ( NULL ) , heartbeat_callback , " heartbeat " , " core " , 0 , NULL , SSHF_NONE | SSHF_NO_DEL ) ;
2007-03-29 22:31:56 +00:00
2011-01-21 14:27:51 -06:00
switch_scheduler_add_task ( switch_epoch_time_now ( NULL ) , check_ip_callback , " check_ip " , " core " , 0 , NULL , SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD ) ;
2007-02-22 17:38:34 +00:00
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( runtime . uuid_str , & uuid ) ;
2011-11-29 11:13:11 -06:00
2007-02-22 17:38:34 +00:00
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-11-20 21:43:44 +00:00
2008-03-03 19:02:36 +00:00
2011-09-12 14:24:58 -05:00
# ifndef WIN32
static void handle_SIGCHLD ( int sig )
{
int status = 0 ;
int pid = 0 ;
2011-12-14 10:27:31 -05:00
if ( sig ) { } ;
2011-09-12 14:24:58 -05:00
pid = wait ( & status ) ;
if ( pid > 0 ) {
printf ( " ASS %d \n " , pid ) ;
}
return ;
}
# endif
2006-08-19 18:51:22 +00:00
# ifdef TRAP_BUS
2006-10-02 16:48:00 +00:00
static void handle_SIGBUS ( int sig )
2006-08-19 18:51:22 +00:00
{
2011-04-08 14:23:16 -05:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG1 , " Sig BUS! \n " ) ;
2006-10-02 16:48:00 +00:00
return ;
2006-08-19 18:51:22 +00:00
}
# endif
2005-11-19 20:07:43 +00:00
2007-12-06 19:51:55 +00:00
static void handle_SIGHUP ( int sig )
{
if ( sig ) {
switch_event_t * event ;
2008-05-27 04:30:03 +00:00
2007-12-06 19:51:55 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_TRAP ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Trapped-Signal " , " HUP " ) ;
switch_event_fire ( & event ) ;
}
}
return ;
}
2008-07-22 13:38:42 +00:00
2010-10-08 17:04:22 -05:00
SWITCH_DECLARE ( uint32_t ) switch_default_ptime ( const char * name , uint32_t number )
{
uint32_t * p ;
if ( ( p = switch_core_hash_find ( runtime . ptimes , name ) ) ) {
return * p ;
}
return 20 ;
}
static uint32_t d_30 = 30 ;
2008-07-22 13:38:42 +00:00
static void switch_load_core_config ( const char * file )
{
switch_xml_t xml = NULL , cfg = NULL ;
2010-02-06 03:38:24 +00:00
2011-02-03 16:27:22 -06:00
switch_core_hash_insert ( runtime . ptimes , " ilbc " , & d_30 ) ;
2010-10-08 17:04:22 -05:00
switch_core_hash_insert ( runtime . ptimes , " G723 " , & d_30 ) ;
2008-07-22 13:38:42 +00:00
if ( ( xml = switch_xml_open_cfg ( file , & cfg , NULL ) ) ) {
switch_xml_t settings , param ;
2010-02-06 03:38:24 +00:00
2010-10-08 17:04:22 -05:00
if ( ( settings = switch_xml_child ( cfg , " default-ptimes " ) ) ) {
for ( param = switch_xml_child ( settings , " codec " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " ptime " ) ;
if ( ! zstr ( var ) & & ! zstr ( val ) ) {
uint32_t * p ;
uint32_t v = ( unsigned long ) atol ( val ) ;
if ( ! strcasecmp ( var , " G723 " ) | | ! strcasecmp ( var , " iLBC " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Error adding %s, defaults cannot be changed \n " , var ) ;
continue ;
}
if ( v < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Error adding %s, invalid ptime \n " , var ) ;
continue ;
}
p = switch_core_alloc ( runtime . memory_pool , sizeof ( * p ) ) ;
* p = v ;
switch_core_hash_insert ( runtime . ptimes , var , p ) ;
}
}
}
2008-07-22 13:38:42 +00:00
if ( ( settings = switch_xml_child ( cfg , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " value " ) ;
2009-09-18 15:55:10 +00:00
if ( ! strcasecmp ( var , " loglevel " ) ) {
2008-07-22 13:38:42 +00:00
int level ;
if ( * val > 47 & & * val < 58 ) {
level = atoi ( val ) ;
} else {
level = switch_log_str2level ( val ) ;
}
if ( level ! = SWITCH_LOG_INVALID ) {
switch_core_session_ctl ( SCSC_LOGLEVEL , & level ) ;
}
# ifdef HAVE_SETRLIMIT
} else if ( ! strcasecmp ( var , " dump-cores " ) ) {
struct rlimit rlp ;
memset ( & rlp , 0 , sizeof ( rlp ) ) ;
rlp . rlim_cur = RLIM_INFINITY ;
rlp . rlim_max = RLIM_INFINITY ;
setrlimit ( RLIMIT_CORE , & rlp ) ;
# endif
2009-11-21 06:18:56 +00:00
} else if ( ! strcasecmp ( var , " debug-level " ) ) {
int tmp = atoi ( val ) ;
if ( tmp > - 1 & & tmp < 11 ) {
switch_core_session_ctl ( SCSC_DEBUG_LEVEL , & tmp ) ;
}
2011-03-04 13:52:30 -06:00
} else if ( ! strcasecmp ( var , " max-db-handles " ) ) {
long tmp = atol ( val ) ;
if ( tmp > 4 & & tmp < 5001 ) {
runtime . max_db_handles = ( uint32_t ) tmp ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " max-db-handles must be between 5 and 5000 \n " ) ;
}
} else if ( ! strcasecmp ( var , " db-handle-timeout " ) ) {
long tmp = atol ( val ) ;
if ( tmp > 0 & & tmp < 5001 ) {
runtime . db_handle_timeout = ( uint32_t ) tmp * 1000000 ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " db-handle-timeout must be between 1 and 5000 \n " ) ;
}
2011-02-17 12:12:43 -06:00
} else if ( ! strcasecmp ( var , " multiple-registrations " ) ) {
runtime . multiple_registrations = switch_true ( val ) ;
2010-09-14 16:19:03 -05:00
} else if ( ! strcasecmp ( var , " sql-buffer-len " ) ) {
int tmp = atoi ( val ) ;
if ( end_of ( val ) = = ' k ' ) {
tmp * = 1024 ;
} else if ( end_of ( val ) = = ' m ' ) {
tmp * = ( 1024 * 1024 ) ;
}
if ( tmp > = 32000 & & tmp < 10500000 ) {
runtime . sql_buffer_len = tmp ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " sql-buffer-len: Value is not within rage 32k to 10m \n " ) ;
}
} else if ( ! strcasecmp ( var , " max-sql-buffer-len " ) ) {
int tmp = atoi ( val ) ;
if ( end_of ( val ) = = ' k ' ) {
tmp * = 1024 ;
} else if ( end_of ( val ) = = ' m ' ) {
tmp * = ( 1024 * 1024 ) ;
}
if ( tmp < runtime . sql_buffer_len ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Value is not larger than sql-buffer-len \n " ) ;
} else if ( tmp > = 32000 & & tmp < 10500000 ) {
runtime . sql_buffer_len = tmp ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " max-sql-buffer-len: Value is not within rage 32k to 10m \n " ) ;
}
2010-08-04 09:56:53 -05:00
} else if ( ! strcasecmp ( var , " auto-create-schemas " ) ) {
if ( switch_true ( val ) ) {
switch_set_flag ( ( & runtime ) , SCF_AUTO_SCHEMAS ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_AUTO_SCHEMAS ) ;
}
2011-08-24 13:36:13 -05:00
} else if ( ! strcasecmp ( var , " auto-clear-sql " ) ) {
if ( switch_true ( val ) ) {
switch_set_flag ( ( & runtime ) , SCF_CLEAR_SQL ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_CLEAR_SQL ) ;
}
2009-12-11 00:28:54 +00:00
} else if ( ! strcasecmp ( var , " enable-early-hangup " ) & & switch_true ( val ) ) {
switch_set_flag ( ( & runtime ) , SCF_EARLY_HANGUP ) ;
2008-07-22 13:38:42 +00:00
} else if ( ! strcasecmp ( var , " colorize-console " ) & & switch_true ( val ) ) {
runtime . colorize_console = SWITCH_TRUE ;
2009-10-23 16:03:42 +00:00
} else if ( ! strcasecmp ( var , " mailer-app " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
runtime . mailer_app = switch_core_strdup ( runtime . memory_pool , val ) ;
} else if ( ! strcasecmp ( var , " mailer-app-args " ) & & val ) {
runtime . mailer_app_args = switch_core_strdup ( runtime . memory_pool , val ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! strcasecmp ( var , " sessions-per-second " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
switch_core_sessions_per_second ( atoi ( val ) ) ;
2009-12-14 16:39:15 +00:00
} else if ( ! strcasecmp ( var , " max-dtmf-duration " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
int tmp = atoi ( val ) ;
if ( tmp > 0 ) {
switch_core_max_dtmf_duration ( ( uint32_t ) tmp ) ;
}
2009-12-14 16:39:15 +00:00
} else if ( ! strcasecmp ( var , " min-dtmf-duration " ) & & ! zstr ( val ) ) {
2009-09-16 21:24:22 +00:00
int tmp = atoi ( val ) ;
if ( tmp > 0 ) {
switch_core_min_dtmf_duration ( ( uint32_t ) tmp ) ;
}
2009-12-14 16:39:15 +00:00
} else if ( ! strcasecmp ( var , " default-dtmf-duration " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
int tmp = atoi ( val ) ;
if ( tmp > 0 ) {
switch_core_default_dtmf_duration ( ( uint32_t ) tmp ) ;
}
2009-12-29 23:21:20 +00:00
} else if ( ! strcasecmp ( var , " enable-monotonic-timing " ) ) {
2011-03-28 13:50:42 -05:00
switch_time_set_monotonic ( switch_true ( val ) ) ;
2011-03-21 20:49:39 -05:00
} else if ( ! strcasecmp ( var , " enable-softtimer-timerfd " ) ) {
2011-03-28 13:50:42 -05:00
switch_time_set_timerfd ( switch_true ( val ) ) ;
2009-12-29 23:21:20 +00:00
} else if ( ! strcasecmp ( var , " enable-clock-nanosleep " ) ) {
2011-03-28 13:50:42 -05:00
switch_time_set_nanosleep ( switch_true ( val ) ) ;
2009-12-30 15:47:31 +00:00
} else if ( ! strcasecmp ( var , " enable-cond-yield " ) ) {
2011-03-28 13:50:42 -05:00
switch_time_set_cond_yield ( switch_true ( val ) ) ;
2009-12-30 20:55:04 +00:00
} else if ( ! strcasecmp ( var , " enable-timer-matrix " ) ) {
2011-03-28 13:50:42 -05:00
switch_time_set_matrix ( switch_true ( val ) ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! strcasecmp ( var , " max-sessions " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
switch_core_session_limit ( atoi ( val ) ) ;
2010-04-27 16:52:29 -05:00
} else if ( ! strcasecmp ( var , " verbose-channel-events " ) & & ! zstr ( val ) ) {
int v = switch_true ( val ) ;
if ( v ) {
switch_set_flag ( ( & runtime ) , SCF_VERBOSE_EVENTS ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_VERBOSE_EVENTS ) ;
}
2011-09-12 14:24:58 -05:00
} else if ( ! strcasecmp ( var , " threaded-system-exec " ) & & ! zstr ( val ) ) {
# ifdef WIN32
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " threaded-system-exec is not implemented on this platform \n " ) ;
# else
int v = switch_true ( val ) ;
if ( v ) {
switch_set_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ;
}
# endif
2010-03-10 20:21:34 +00:00
} else if ( ! strcasecmp ( var , " min-idle-cpu " ) & & ! zstr ( val ) ) {
switch_core_min_idle_cpu ( atof ( val ) ) ;
2010-01-14 16:02:46 +00:00
} else if ( ! strcasecmp ( var , " tipping-point " ) & & ! zstr ( val ) ) {
runtime . tipping_point = atoi ( val ) ;
2011-04-29 11:09:14 -05:00
} else if ( ! strcasecmp ( var , " 1ms-timer " ) & & switch_true ( val ) ) {
runtime . microseconds_per_tick = 1000 ;
2010-02-17 19:50:25 +00:00
} else if ( ! strcasecmp ( var , " timer-affinity " ) & & ! zstr ( val ) ) {
if ( ! strcasecmp ( val , " disabled " ) ) {
runtime . timer_affinity = - 1 ;
} else {
runtime . timer_affinity = atoi ( val ) ;
}
2009-10-23 16:03:42 +00:00
} else if ( ! strcasecmp ( var , " rtp-start-port " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
switch_rtp_set_start_port ( ( switch_port_t ) atoi ( val ) ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! strcasecmp ( var , " rtp-end-port " ) & & ! zstr ( val ) ) {
2008-07-22 13:38:42 +00:00
switch_rtp_set_end_port ( ( switch_port_t ) atoi ( val ) ) ;
2011-02-15 01:49:41 -05:00
} else if ( ! strcasecmp ( var , " core-db-name " ) & & ! zstr ( val ) ) {
runtime . dbname = switch_core_strdup ( runtime . memory_pool , val ) ;
2009-11-17 00:12:54 +00:00
} else if ( ! strcasecmp ( var , " core-db-dsn " ) & & ! zstr ( val ) ) {
if ( switch_odbc_available ( ) ) {
runtime . odbc_dsn = switch_core_strdup ( runtime . memory_pool , val ) ;
if ( ( runtime . odbc_user = strchr ( runtime . odbc_dsn , ' : ' ) ) ) {
* runtime . odbc_user + + = ' \0 ' ;
if ( ( runtime . odbc_pass = strchr ( runtime . odbc_user , ' : ' ) ) ) {
* runtime . odbc_pass + + = ' \0 ' ;
}
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ODBC IS NOT AVAILABLE! \n " ) ;
}
2011-10-17 09:34:50 -05:00
} else if ( ! strcasecmp ( var , " core-odbc-required " ) & & ! zstr ( val ) ) {
switch_set_flag ( ( & runtime ) , SCF_CORE_ODBC_REQ ) ;
2010-10-21 16:18:54 -05:00
} else if ( ! strcasecmp ( var , " core-dbtype " ) & & ! zstr ( val ) ) {
if ( ! strcasecmp ( val , " MSSQL " ) ) {
runtime . odbc_dbtype = DBTYPE_MSSQL ;
} else {
runtime . odbc_dbtype = DBTYPE_DEFAULT ;
}
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
} else if ( ! strcasecmp ( var , " rtp-enable-zrtp " ) ) {
switch_core_set_variable ( " zrtp_enabled " , val ) ;
# endif
2011-04-29 10:24:50 -05:00
} else if ( ! strcasecmp ( var , " switchname " ) & & ! zstr ( val ) ) {
runtime . switchname = switch_core_strdup ( runtime . memory_pool , val ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Set switchname to %s \n " , runtime . switchname ) ;
2008-07-22 13:38:42 +00:00
}
}
}
if ( ( settings = switch_xml_child ( cfg , " variables " ) ) ) {
for ( param = switch_xml_child ( settings , " variable " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " name " ) ;
const char * val = switch_xml_attr_soft ( param , " value " ) ;
2008-08-25 16:40:39 +00:00
if ( var & & val ) {
switch_core_set_variable ( var , val ) ;
}
2008-07-22 13:38:42 +00:00
}
}
switch_xml_free ( xml ) ;
}
}
2010-01-22 02:42:05 +00:00
SWITCH_DECLARE ( const char * ) switch_core_banner ( void )
2010-01-15 21:48:08 +00:00
{
2010-01-22 02:42:05 +00:00
return ( " \n "
" _____ ______ _____ _____ ____ _ _ \n "
" | ___| __ ___ ___/ ___ \\ \\ / /_ _|_ _/ ___| | | | \n "
" | |_ | '__/ _ \\ / _ \\ ___ \\ \\ \\ / \\ / / | | | || | | |_| | \n "
" | _|| | | __/ __/___) | \\ V V / | | | || |___| _ | \n "
" |_| |_| \\ ___| \\ ___|____/ \\ _/ \\ _/ |___| |_| \\ ____|_| |_| \n "
" \n "
" ************************************************************ \n "
" * Anthony Minessale II, Michael Jerris, Brian West, Others * \n "
" * FreeSWITCH (http://www.freeswitch.org) * \n "
" * Paypal Donations Appreciated: paypal@freeswitch.org * \n "
2010-02-06 03:38:24 +00:00
" * Brought to you by ClueCon http://www.cluecon.com/ * \n " " ************************************************************ \n " " \n " ) ;
2010-01-15 21:48:08 +00:00
}
2007-12-06 13:40:00 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_init_and_modload ( switch_core_flag_t flags , switch_bool_t console , const char * * err )
2006-08-19 18:51:22 +00:00
{
switch_event_t * event ;
2008-07-22 13:38:42 +00:00
2007-12-06 13:40:00 +00:00
if ( switch_core_init ( flags , console , err ) ! = SWITCH_STATUS_SUCCESS ) {
2006-08-19 18:51:22 +00:00
return SWITCH_STATUS_GENERR ;
}
2010-08-04 09:56:53 -05:00
2010-01-04 19:03:43 +00:00
if ( runtime . runlevel > 1 ) {
/* one per customer */
return SWITCH_STATUS_SUCCESS ;
}
runtime . runlevel + + ;
2011-04-08 13:46:02 -05:00
switch_core_set_signal_handlers ( ) ;
2009-01-14 13:37:12 +00:00
2006-08-19 18:51:22 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Bringing up environment. \n " ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Loading Modules. \n " ) ;
2010-09-14 11:48:43 -05:00
if ( switch_loadable_module_init ( SWITCH_TRUE ) ! = SWITCH_STATUS_SUCCESS ) {
2006-08-19 18:51:22 +00:00
* err = " Cannot load modules " ;
2007-11-23 18:50:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Error: %s \n " , * err ) ;
2006-08-19 18:51:22 +00:00
return SWITCH_STATUS_GENERR ;
}
2008-07-22 13:38:42 +00:00
switch_load_network_lists ( SWITCH_FALSE ) ;
switch_load_core_config ( " post_load_switch.conf " ) ;
2011-04-08 13:46:02 -05:00
switch_core_set_signal_handlers ( ) ;
2006-08-19 18:51:22 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_STARTUP ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Event-Info " , " System Ready " ) ;
switch_event_fire ( & event ) ;
}
2010-01-22 02:42:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " %s " , switch_core_banner ( ) ) ;
2010-02-06 03:38:24 +00:00
2006-08-19 18:51:22 +00:00
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE ,
2009-09-18 15:55:10 +00:00
" \n FreeSWITCH Version %s Started. \n Max Sessions[%u] \n Session Rate[%d] \n SQL [%s] \n " , SWITCH_VERSION_FULL ,
2007-09-29 01:06:08 +00:00
switch_core_session_limit ( 0 ) ,
2008-05-27 04:30:03 +00:00
switch_core_sessions_per_second ( 0 ) , switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ? " Enabled " : " Disabled " ) ;
2007-07-06 16:29:25 +00:00
2007-09-29 01:06:08 +00:00
switch_clear_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
2007-07-06 16:29:25 +00:00
2006-08-19 18:51:22 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2005-11-19 20:07:43 +00:00
2006-05-10 03:23:05 +00:00
SWITCH_DECLARE ( void ) switch_core_measure_time ( switch_time_t total_ms , switch_core_time_duration_t * duration )
{
2007-03-29 22:31:56 +00:00
switch_time_t temp = total_ms / 1000 ;
2006-05-10 04:05:07 +00:00
memset ( duration , 0 , sizeof ( * duration ) ) ;
2007-03-29 22:31:56 +00:00
duration - > mms = ( uint32_t ) ( total_ms % 1000 ) ;
duration - > ms = ( uint32_t ) ( temp % 1000 ) ;
temp = temp / 1000 ;
duration - > sec = ( uint32_t ) ( temp % 60 ) ;
2006-05-10 04:42:31 +00:00
temp = temp / 60 ;
2007-03-29 22:31:56 +00:00
duration - > min = ( uint32_t ) ( temp % 60 ) ;
temp = temp / 60 ;
duration - > hr = ( uint32_t ) ( temp % 24 ) ;
2006-05-10 04:42:31 +00:00
temp = temp / 24 ;
2007-03-29 22:31:56 +00:00
duration - > day = ( uint32_t ) ( temp % 365 ) ;
duration - > yr = ( uint32_t ) ( temp / 365 ) ;
2006-05-10 03:23:05 +00:00
}
SWITCH_DECLARE ( switch_time_t ) switch_core_uptime ( void )
{
2009-01-25 21:23:07 +00:00
return switch_micro_time_now ( ) - runtime . initiated ;
2006-05-10 03:23:05 +00:00
}
2009-10-16 16:54:54 +00:00
# ifdef _MSC_VER
static void win_shutdown ( void )
{
2010-02-06 03:38:24 +00:00
HANDLE shutdown_event ;
2009-10-16 16:54:54 +00:00
char path [ 512 ] ;
/* for windows we need the event to signal for shutting down a background FreeSWITCH */
snprintf ( path , sizeof ( path ) , " Global \\ Freeswitch.%d " , getpid ( ) ) ;
2010-02-06 03:38:24 +00:00
2009-10-16 16:54:54 +00:00
/* open the event so we can signal it */
shutdown_event = OpenEvent ( EVENT_MODIFY_STATE , FALSE , path ) ;
2010-02-06 03:38:24 +00:00
2009-10-16 16:54:54 +00:00
if ( shutdown_event ) {
/* signal the event to shutdown */
SetEvent ( shutdown_event ) ;
/* cleanup */
CloseHandle ( shutdown_event ) ;
}
}
# endif
2011-04-08 13:46:02 -05:00
SWITCH_DECLARE ( void ) switch_core_set_signal_handlers ( void )
{
/* set signal handlers */
signal ( SIGINT , SIG_IGN ) ;
2011-09-12 14:24:58 -05:00
# ifndef WIN32
2011-09-12 16:14:30 -05:00
if ( switch_test_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ) {
signal ( SIGCHLD , SIG_DFL ) ;
} else {
signal ( SIGCHLD , handle_SIGCHLD ) ;
}
2011-09-12 14:24:58 -05:00
# endif
2011-04-08 13:46:02 -05:00
# ifdef SIGPIPE
2011-08-26 12:59:01 -05:00
signal ( SIGPIPE , SIG_IGN ) ;
2011-04-08 13:46:02 -05:00
# endif
# ifdef SIGQUIT
2011-08-26 12:59:01 -05:00
signal ( SIGQUIT , SIG_IGN ) ;
2011-04-08 13:46:02 -05:00
# endif
# ifdef SIGPOLL
2011-08-26 12:59:01 -05:00
signal ( SIGPOLL , SIG_IGN ) ;
2011-04-08 13:46:02 -05:00
# endif
# ifdef SIGIO
2011-08-26 12:59:01 -05:00
signal ( SIGIO , SIG_IGN ) ;
2011-04-08 13:46:02 -05:00
# endif
# ifdef TRAP_BUS
signal ( SIGBUS , handle_SIGBUS ) ;
# endif
# ifdef SIGUSR1
signal ( SIGUSR1 , handle_SIGHUP ) ;
# endif
signal ( SIGHUP , handle_SIGHUP ) ;
}
2009-11-20 23:12:07 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_debug_level ( void )
{
return runtime . debug_level ;
}
2010-03-10 20:21:34 +00:00
SWITCH_DECLARE ( int32_t ) switch_core_session_ctl ( switch_session_ctl_t cmd , void * val )
2006-09-20 20:25:26 +00:00
{
2010-03-10 20:21:34 +00:00
int * intval = ( int * ) val ;
2010-04-27 16:52:29 -05:00
int oldintval = 0 , newintval = 0 ;
if ( intval ) {
oldintval = * intval ;
}
2010-03-10 20:21:34 +00:00
2007-09-29 01:06:08 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_SHUTTING_DOWN ) ) {
2006-09-20 20:25:26 +00:00
return - 1 ;
}
switch ( cmd ) {
2010-04-27 16:52:29 -05:00
case SCSC_VERBOSE_EVENTS :
if ( intval ) {
if ( oldintval > - 1 ) {
if ( oldintval ) {
switch_set_flag ( ( & runtime ) , SCF_VERBOSE_EVENTS ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_VERBOSE_EVENTS ) ;
}
}
newintval = switch_test_flag ( ( & runtime ) , SCF_VERBOSE_EVENTS ) ;
}
break ;
2011-09-12 14:24:58 -05:00
case SCSC_THREADED_SYSTEM_EXEC :
if ( intval ) {
if ( oldintval > - 1 ) {
if ( oldintval ) {
switch_set_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ;
}
}
newintval = switch_test_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ;
}
break ;
2010-01-14 16:02:46 +00:00
case SCSC_CALIBRATE_CLOCK :
switch_time_calibrate_clock ( ) ;
break ;
2009-12-17 00:03:17 +00:00
case SCSC_FLUSH_DB_HANDLES :
switch_cache_db_flush_handles ( ) ;
break ;
2008-10-21 19:05:25 +00:00
case SCSC_SEND_SIGHUP :
handle_SIGHUP ( 1 ) ;
break ;
2008-01-11 00:43:49 +00:00
case SCSC_SYNC_CLOCK :
switch_time_sync ( ) ;
2010-04-27 16:52:29 -05:00
newintval = 0 ;
2008-01-11 00:43:49 +00:00
break ;
2011-10-12 14:55:32 -05:00
case SCSC_SYNC_CLOCK_WHEN_IDLE :
newintval = switch_core_session_sync_clock ( ) ;
break ;
2006-09-20 20:25:26 +00:00
case SCSC_PAUSE_INBOUND :
2010-04-27 16:52:29 -05:00
if ( oldintval ) {
2007-09-29 01:06:08 +00:00
switch_set_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
} else {
switch_clear_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
}
2006-09-20 20:25:26 +00:00
break ;
case SCSC_HUPALL :
switch_core_session_hupall ( SWITCH_CAUSE_MANAGER_REQUEST ) ;
break ;
2008-10-03 14:58:36 +00:00
case SCSC_CANCEL_SHUTDOWN :
switch_clear_flag ( ( & runtime ) , SCF_SHUTDOWN_REQUESTED ) ;
break ;
2010-01-14 21:00:32 +00:00
case SCSC_SAVE_HISTORY :
switch_console_save_history ( ) ;
break ;
case SCSC_CRASH :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Declinatio Mortuus Obfirmo! \n " ) ;
switch_console_save_history ( ) ;
abort ( ) ;
break ;
2010-01-08 22:10:03 +00:00
case SCSC_SHUTDOWN_NOW :
2010-01-14 21:00:32 +00:00
switch_console_save_history ( ) ;
2010-01-08 22:10:03 +00:00
exit ( 0 ) ;
break ;
2008-10-02 16:46:20 +00:00
case SCSC_SHUTDOWN_ELEGANT :
2008-10-21 19:05:25 +00:00
case SCSC_SHUTDOWN_ASAP :
2008-10-02 16:46:20 +00:00
{
int x = 19 ;
2008-10-21 19:05:25 +00:00
uint32_t count ;
2008-10-03 14:58:36 +00:00
switch_set_flag ( ( & runtime ) , SCF_SHUTDOWN_REQUESTED ) ;
2008-10-21 19:05:25 +00:00
if ( cmd = = SCSC_SHUTDOWN_ASAP ) {
switch_set_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
}
2008-10-03 14:58:36 +00:00
2010-02-06 03:38:24 +00:00
while ( runtime . running & & switch_test_flag ( ( & runtime ) , SCF_SHUTDOWN_REQUESTED ) & & ( count = switch_core_session_count ( ) ) ) {
2008-10-02 16:46:20 +00:00
switch_yield ( 500000 ) ;
if ( + + x = = 20 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING ,
" Shutdown in progress, %u session(s) remain. \n Shutting down %s \n " ,
count , cmd = = SCSC_SHUTDOWN_ASAP ? " ASAP " : " once there are no active calls. " ) ;
2008-10-02 16:46:20 +00:00
x = 0 ;
}
}
2010-02-06 03:38:24 +00:00
2008-10-03 14:58:36 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_SHUTDOWN_REQUESTED ) ) {
2008-10-21 19:05:25 +00:00
switch_set_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
2009-10-16 16:54:54 +00:00
# ifdef _MSC_VER
win_shutdown ( ) ;
# endif
2010-04-27 16:52:29 -05:00
if ( oldintval ) {
2008-10-03 14:58:36 +00:00
switch_set_flag ( ( & runtime ) , SCF_RESTART ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Restarting \n " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Shutting down \n " ) ;
2009-10-16 16:54:54 +00:00
# ifdef _MSC_VER
fclose ( stdin ) ;
# endif
2008-10-03 14:58:36 +00:00
}
runtime . running = 0 ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Shutdown Cancelled \n " ) ;
switch_clear_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
}
2008-10-02 16:46:20 +00:00
}
break ;
2011-06-27 10:09:15 -05:00
case SCSC_PAUSE_CHECK :
newintval = ! ! switch_test_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
break ;
case SCSC_READY_CHECK :
newintval = switch_core_ready ( ) ;
break ;
2010-06-29 23:00:24 -04:00
case SCSC_SHUTDOWN_CHECK :
newintval = ! ! switch_test_flag ( ( & runtime ) , SCF_SHUTDOWN_REQUESTED ) ;
break ;
2006-09-20 20:25:26 +00:00
case SCSC_SHUTDOWN :
2009-10-16 15:48:40 +00:00
# ifdef _MSC_VER
2009-10-16 16:54:54 +00:00
win_shutdown ( ) ;
2009-10-16 15:48:40 +00:00
# endif
2010-04-27 16:52:29 -05:00
if ( oldintval ) {
2008-10-02 16:46:20 +00:00
switch_set_flag ( ( & runtime ) , SCF_RESTART ) ;
2008-10-03 14:58:36 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Restarting \n " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Shutting down \n " ) ;
2009-10-16 15:48:40 +00:00
# ifdef _MSC_VER
fclose ( stdin ) ;
# endif
2008-10-02 16:46:20 +00:00
}
2008-10-03 14:58:36 +00:00
runtime . running = 0 ;
2006-09-20 20:25:26 +00:00
break ;
case SCSC_CHECK_RUNNING :
2010-04-27 16:52:29 -05:00
newintval = runtime . running ;
2006-09-20 20:25:26 +00:00
break ;
2007-10-03 23:43:01 +00:00
case SCSC_LOGLEVEL :
2010-04-27 16:52:29 -05:00
if ( oldintval > - 1 ) {
runtime . hard_log_level = oldintval ;
2007-10-03 23:43:01 +00:00
}
2007-10-04 17:25:06 +00:00
if ( runtime . hard_log_level > SWITCH_LOG_DEBUG ) {
runtime . hard_log_level = SWITCH_LOG_DEBUG ;
2007-10-03 23:43:01 +00:00
}
2010-04-27 16:52:29 -05:00
newintval = runtime . hard_log_level ;
2007-10-03 23:43:01 +00:00
break ;
2009-11-20 23:12:07 +00:00
case SCSC_DEBUG_LEVEL :
2010-04-27 16:52:29 -05:00
if ( oldintval > - 1 ) {
if ( oldintval > 10 )
newintval = 10 ;
runtime . debug_level = oldintval ;
2010-03-10 20:21:34 +00:00
}
2010-04-27 16:52:29 -05:00
newintval = runtime . debug_level ;
2010-03-10 20:21:34 +00:00
break ;
case SCSC_MIN_IDLE_CPU :
{
double * dval = ( double * ) val ;
2010-04-27 16:52:29 -05:00
if ( dval ) {
* dval = switch_core_min_idle_cpu ( * dval ) ;
}
intval = NULL ;
2009-11-20 23:12:07 +00:00
}
break ;
2007-10-05 13:42:11 +00:00
case SCSC_MAX_SESSIONS :
2010-04-27 16:52:29 -05:00
newintval = switch_core_session_limit ( oldintval ) ;
2007-10-05 13:42:11 +00:00
break ;
2007-10-04 21:35:50 +00:00
case SCSC_LAST_SPS :
2010-04-27 16:52:29 -05:00
newintval = runtime . sps_last ;
2007-10-04 21:35:50 +00:00
break ;
2008-04-18 17:03:34 +00:00
case SCSC_MAX_DTMF_DURATION :
2010-04-27 16:52:29 -05:00
newintval = switch_core_max_dtmf_duration ( oldintval ) ;
2008-04-18 17:03:34 +00:00
break ;
2009-09-16 21:24:22 +00:00
case SCSC_MIN_DTMF_DURATION :
2010-04-27 16:52:29 -05:00
newintval = switch_core_min_dtmf_duration ( oldintval ) ;
2009-09-16 21:24:22 +00:00
break ;
2008-04-18 17:03:34 +00:00
case SCSC_DEFAULT_DTMF_DURATION :
2010-04-27 16:52:29 -05:00
newintval = switch_core_default_dtmf_duration ( oldintval ) ;
2008-04-18 17:03:34 +00:00
break ;
2007-10-04 14:19:51 +00:00
case SCSC_SPS :
switch_mutex_lock ( runtime . throttle_mutex ) ;
2010-04-27 16:52:29 -05:00
if ( oldintval > 0 ) {
runtime . sps_total = oldintval ;
2007-10-04 14:19:51 +00:00
}
2010-04-27 16:52:29 -05:00
newintval = runtime . sps_total ;
2007-10-04 14:19:51 +00:00
switch_mutex_unlock ( runtime . throttle_mutex ) ;
break ;
2007-10-04 17:25:06 +00:00
case SCSC_RECLAIM :
switch_core_memory_reclaim_all ( ) ;
2010-04-27 16:52:29 -05:00
newintval = 0 ;
2007-10-04 17:25:06 +00:00
break ;
2006-09-20 20:25:26 +00:00
}
2010-04-27 16:52:29 -05:00
if ( intval ) {
* intval = newintval ;
}
2008-10-02 16:46:20 +00:00
2006-09-20 20:25:26 +00:00
return 0 ;
}
2007-09-29 01:06:08 +00:00
SWITCH_DECLARE ( switch_core_flag_t ) switch_core_flags ( void )
{
return runtime . flags ;
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( switch_bool_t ) switch_core_ready ( void )
{
2007-09-29 01:06:08 +00:00
return ( switch_test_flag ( ( & runtime ) , SCF_SHUTTING_DOWN ) | | switch_test_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ) ? SWITCH_FALSE : SWITCH_TRUE ;
2007-03-29 22:31:56 +00:00
}
2007-03-01 17:23:02 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_destroy ( void )
2005-11-19 20:07:43 +00:00
{
2006-08-19 18:51:22 +00:00
switch_event_t * event ;
2009-02-20 01:10:59 +00:00
2006-08-19 18:51:22 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_SHUTDOWN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Event-Info " , " System Shutting Down " ) ;
switch_event_fire ( & event ) ;
}
2007-09-29 01:06:08 +00:00
switch_set_flag ( ( & runtime ) , SCF_NO_NEW_SESSIONS ) ;
switch_set_flag ( ( & runtime ) , SCF_SHUTTING_DOWN ) ;
2010-02-06 03:38:24 +00:00
2006-08-19 18:51:22 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " End existing sessions \n " ) ;
2006-09-20 20:25:26 +00:00
switch_core_session_hupall ( SWITCH_CAUSE_SYSTEM_SHUTDOWN ) ;
2006-08-19 18:51:22 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Clean up modules. \n " ) ;
2007-03-28 23:37:12 +00:00
2009-02-20 01:10:59 +00:00
switch_loadable_module_shutdown ( ) ;
2010-02-06 03:38:24 +00:00
2011-05-25 14:45:55 -05:00
switch_ssl_destroy_ssl_locks ( ) ;
2007-09-29 01:06:08 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ) {
switch_core_sqldb_stop ( ) ;
}
2007-03-29 22:31:56 +00:00
switch_scheduler_task_thread_stop ( ) ;
2010-02-06 03:38:24 +00:00
2007-12-11 19:15:02 +00:00
switch_rtp_shutdown ( ) ;
2010-09-14 11:48:43 -05:00
2009-06-02 16:55:10 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_USE_AUTO_NAT ) ) {
switch_nat_shutdown ( ) ;
}
2006-05-10 03:23:05 +00:00
switch_xml_destroy ( ) ;
2009-02-20 01:10:59 +00:00
2009-12-14 20:10:06 +00:00
switch_console_shutdown ( ) ;
2009-02-20 01:10:59 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Closing Event Engine. \n " ) ;
switch_event_shutdown ( ) ;
2006-08-15 19:02:06 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Finalizing Shutdown. \n " ) ;
2006-08-15 17:52:12 +00:00
switch_log_shutdown ( ) ;
2007-03-28 23:37:12 +00:00
2009-03-03 20:16:05 +00:00
switch_core_unset_variables ( ) ;
2009-02-20 01:10:59 +00:00
switch_core_memory_stop ( ) ;
2007-12-07 02:04:23 +00:00
if ( runtime . console & & runtime . console ! = stdout & & runtime . console ! = stderr ) {
2006-02-26 03:13:01 +00:00
fclose ( runtime . console ) ;
runtime . console = NULL ;
}
2005-12-14 21:29:46 +00:00
2007-03-11 01:07:47 +00:00
switch_safe_free ( SWITCH_GLOBAL_dirs . base_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . mod_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . conf_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . log_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . db_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . script_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . htdocs_dir ) ;
switch_safe_free ( SWITCH_GLOBAL_dirs . grammar_dir ) ;
2010-04-21 10:11:13 -05:00
switch_safe_free ( SWITCH_GLOBAL_dirs . storage_dir ) ;
2010-01-11 03:20:42 +00:00
switch_safe_free ( SWITCH_GLOBAL_dirs . recordings_dir ) ;
2010-01-11 16:32:35 +00:00
switch_safe_free ( SWITCH_GLOBAL_dirs . sounds_dir ) ;
2010-04-21 10:11:13 -05:00
switch_safe_free ( SWITCH_GLOBAL_dirs . run_dir ) ;
2007-03-11 01:07:47 +00:00
switch_safe_free ( SWITCH_GLOBAL_dirs . temp_dir ) ;
2006-08-20 03:36:14 +00:00
2010-05-25 16:54:13 -05:00
switch_event_destroy ( & runtime . global_vars ) ;
2010-10-08 17:04:22 -05:00
switch_core_hash_destroy ( & runtime . ptimes ) ;
2007-11-26 23:41:00 +00:00
switch_core_hash_destroy ( & runtime . mime_types ) ;
2007-09-29 01:06:08 +00:00
2010-04-21 10:11:13 -05:00
if ( IP_LIST . hash ) {
switch_core_hash_destroy ( & IP_LIST . hash ) ;
}
if ( IP_LIST . pool ) {
switch_core_destroy_memory_pool ( & IP_LIST . pool ) ;
}
2007-01-22 17:16:25 +00:00
if ( runtime . memory_pool ) {
apr_pool_destroy ( runtime . memory_pool ) ;
2009-03-04 00:06:52 +00:00
apr_terminate ( ) ;
2007-01-22 17:16:25 +00:00
}
2010-02-06 03:38:24 +00:00
2008-10-02 16:46:20 +00:00
return switch_test_flag ( ( & runtime ) , SCF_RESTART ) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS ;
2005-11-19 20:07:43 +00:00
}
2006-11-27 22:30:48 +00:00
2007-12-11 19:15:02 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_management_exec ( char * relative_oid , switch_management_action_t action , char * data , switch_size_t datalen )
{
const switch_management_interface_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
if ( ( ptr = switch_loadable_module_get_management_interface ( relative_oid ) ) ) {
status = ptr - > management_function ( relative_oid , action , data , datalen ) ;
}
return status ;
}
2007-10-04 17:25:06 +00:00
SWITCH_DECLARE ( void ) switch_core_memory_reclaim_all ( void )
{
2008-05-27 04:30:03 +00:00
switch_core_memory_reclaim_logger ( ) ;
2007-10-04 17:25:06 +00:00
switch_core_memory_reclaim_events ( ) ;
switch_core_memory_reclaim ( ) ;
}
2007-02-21 21:46:32 +00:00
2008-09-26 15:50:12 +00:00
struct system_thread_handle {
2010-02-06 03:38:24 +00:00
const char * cmd ;
2008-09-26 15:50:12 +00:00
switch_thread_cond_t * cond ;
switch_mutex_t * mutex ;
switch_memory_pool_t * pool ;
int ret ;
} ;
2010-02-06 03:38:24 +00:00
static void * SWITCH_THREAD_FUNC system_thread ( switch_thread_t * thread , void * obj )
2008-09-26 15:50:12 +00:00
{
2010-02-06 03:38:24 +00:00
struct system_thread_handle * sth = ( struct system_thread_handle * ) obj ;
2009-03-26 20:08:30 +00:00
2010-02-06 03:38:24 +00:00
#if 0 // if we are a luser we can never turn this back down, didn't we already set the stack size?
2009-03-11 15:58:11 +00:00
# if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
struct rlimit rlim ;
rlim . rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE ;
rlim . rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE ;
if ( setrlimit ( RLIMIT_STACK , & rlim ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Setting stack size failed! (%s) \n " , strerror ( errno ) ) ;
}
2009-03-26 20:08:30 +00:00
# endif
2009-03-11 15:58:11 +00:00
# endif
2008-09-26 15:50:12 +00:00
sth - > ret = system ( sth - > cmd ) ;
2009-03-26 20:08:30 +00:00
#if 0
2009-03-11 15:58:11 +00:00
# if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
rlim . rlim_cur = SWITCH_THREAD_STACKSIZE ;
2010-02-06 03:38:24 +00:00
rlim . rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE ;
2009-03-11 15:58:11 +00:00
if ( setrlimit ( RLIMIT_STACK , & rlim ) < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Setting stack size failed! (%s) \n " , strerror ( errno ) ) ;
}
2009-03-26 20:08:30 +00:00
# endif
2009-03-11 15:58:11 +00:00
# endif
2008-09-26 15:50:12 +00:00
switch_mutex_lock ( sth - > mutex ) ;
switch_thread_cond_signal ( sth - > cond ) ;
switch_mutex_unlock ( sth - > mutex ) ;
switch_core_destroy_memory_pool ( & sth - > pool ) ;
return NULL ;
}
2011-09-12 14:24:58 -05:00
static int switch_system_thread ( const char * cmd , switch_bool_t wait )
2008-09-26 15:50:12 +00:00
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr ;
int ret = 0 ;
struct system_thread_handle * sth ;
switch_memory_pool_t * pool ;
if ( switch_core_new_memory_pool ( & pool ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Pool Failure \n " ) ;
return 1 ;
}
if ( ! ( sth = switch_core_alloc ( pool , sizeof ( struct system_thread_handle ) ) ) ) {
switch_core_destroy_memory_pool ( & pool ) ;
return 1 ;
}
sth - > pool = pool ;
sth - > cmd = switch_core_strdup ( pool , cmd ) ;
switch_thread_cond_create ( & sth - > cond , sth - > pool ) ;
switch_mutex_init ( & sth - > mutex , SWITCH_MUTEX_NESTED , sth - > pool ) ;
switch_mutex_lock ( sth - > mutex ) ;
switch_threadattr_create ( & thd_attr , sth - > pool ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_SYSTEM_THREAD_STACKSIZE ) ;
2008-10-15 22:57:28 +00:00
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2008-09-26 15:50:12 +00:00
switch_thread_create ( & thread , thd_attr , system_thread , sth , sth - > pool ) ;
if ( wait ) {
switch_thread_cond_wait ( sth - > cond , sth - > mutex ) ;
ret = sth - > ret ;
}
switch_mutex_unlock ( sth - > mutex ) ;
return ret ;
}
2009-01-20 20:49:47 +00:00
2011-09-12 14:24:58 -05:00
# ifdef WIN32
static int switch_system_fork ( const char * cmd , switch_bool_t wait )
{
return switch_system_thread ( cmd , wait ) ;
}
# else
static int max_open ( void )
{
int max ;
# if defined(HAVE_GETDTABLESIZE)
max = getdtablesize ( ) ;
# else
max = sysconf ( _SC_OPEN_MAX ) ;
# endif
return max ;
}
static int switch_system_fork ( const char * cmd , switch_bool_t wait )
{
int pid ;
2011-11-28 16:45:59 -06:00
char * dcmd = strdup ( cmd ) ;
2011-09-12 14:24:58 -05:00
switch_core_set_signal_handlers ( ) ;
pid = fork ( ) ;
if ( pid ) {
if ( wait ) {
waitpid ( pid , NULL , 0 ) ;
}
2011-11-28 16:45:59 -06:00
free ( dcmd ) ;
2011-09-12 14:24:58 -05:00
} else {
int open_max = max_open ( ) ;
int i ;
for ( i = 3 ; i < open_max ; i + + ) {
close ( i ) ;
}
set_low_priority ( ) ;
2011-11-28 16:45:59 -06:00
i = system ( dcmd ) ;
free ( dcmd ) ;
2011-09-12 14:24:58 -05:00
exit ( 0 ) ;
}
return 0 ;
}
# endif
SWITCH_DECLARE ( int ) switch_system ( const char * cmd , switch_bool_t wait )
{
int ( * sys_p ) ( const char * cmd , switch_bool_t wait ) ;
sys_p = switch_test_flag ( ( & runtime ) , SCF_THREADED_SYSTEM_EXEC ) ? switch_system_thread : switch_system_fork ;
return sys_p ( cmd , wait ) ;
}
2009-01-20 20:49:47 +00:00
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2006-11-27 22:30:48 +00:00
*/