FreeSWITCH API Documentation  1.7.0
switch_core.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Michael Jerris <mike@jerris.com>
28  * Paul D. Tinsley <pdt at jackhammer.org>
29  * Marcel Barbulescu <marcelbarbulescu@gmail.com>
30  * Joseph Sullivan <jossulli@amazon.com>
31  * Seven Du <dujinfang@gmail.com>
32  *
33  * switch_core.c -- Main Core Library
34  *
35  */
36 
37 
38 
39 #include <switch.h>
40 #include <switch_ssl.h>
41 #include <switch_stun.h>
42 #include <switch_nat.h>
44 #include <switch_curl.h>
45 #ifndef WIN32
46 #include <switch_private.h>
47 #ifdef HAVE_SETRLIMIT
48 #include <sys/resource.h>
49 #endif
50 #endif
51 #include <errno.h>
52 #include <sqlite3.h>
53 #ifdef HAVE_SYS_PRCTL_H
54 #include <sys/prctl.h>
55 #endif
56 #ifdef SOLARIS_PRIVILEGES
57 #include <priv.h>
58 #endif
59 
62 
63 /* The main runtime obj we keep this hidden for ourselves */
64 struct switch_runtime runtime = { 0 };
65 static void switch_load_core_config(const char *file);
66 
67 static void send_heartbeat(void)
68 {
69  switch_event_t *event;
71 
73 
75  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
77  "%u year%s, "
78  "%u day%s, "
79  "%u hour%s, "
80  "%u minute%s, "
81  "%u second%s, "
82  "%u millisecond%s, "
83  "%u microsecond%s",
84  duration.yr, duration.yr == 1 ? "" : "s",
85  duration.day, duration.day == 1 ? "" : "s",
86  duration.hr, duration.hr == 1 ? "" : "s",
87  duration.min, duration.min == 1 ? "" : "s",
88  duration.sec, duration.sec == 1 ? "" : "s",
89  duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s");
90 
91  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", "%s", switch_version_full());
95  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
96  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Max", "%u", runtime.sps_peak);
97  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-FiveMin", "%u", runtime.sps_peak_fivemin);
98  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
99  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Peak-Max", "%u", runtime.sessions_peak);
100  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Peak-FiveMin", "%u", runtime.sessions_peak_fivemin);
102  switch_event_fire(&event);
103  }
104 }
105 
106 static char main_ip4[256] = "";
107 static char main_ip6[256] = "";
108 
109 static void check_ip(void)
110 {
111  char guess_ip4[256] = "";
112  char guess_ip6[256] = "";
113  char old_ip4[256] = "";
114  char old_ip6[256] = "";
115  int ok4 = 1, ok6 = 1;
116  int mask = 0;
117  switch_status_t check6, check4;
118  switch_event_t *event;
119  char *hostname = switch_core_get_variable("hostname");
120 
121  gethostname(runtime.hostname, sizeof(runtime.hostname));
122 
123  if (zstr(hostname)) {
124  switch_core_set_variable("hostname", runtime.hostname);
125  } else if (strcmp(hostname, runtime.hostname)) {
127  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "hostname-change");
128  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "old-hostname", hostname ? hostname : "nil");
129  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "new-hostname", runtime.hostname);
130  switch_event_fire(&event);
131  }
132 
133  switch_core_set_variable("hostname", runtime.hostname);
134  }
135 
136  check4 = switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET);
137  check6 = switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6);
138 
139  if (check6 != SWITCH_STATUS_SUCCESS && (zstr(main_ip6) || !strcasecmp(main_ip6, "::1"))) {
140  check6 = SWITCH_STATUS_SUCCESS;
141  }
142 
143  if (check4 != SWITCH_STATUS_SUCCESS) {
144  ok4 = 2;
145  } else if (!*main_ip4) {
146  switch_set_string(main_ip4, guess_ip4);
147  } else {
148  if (!(ok4 = !strcmp(main_ip4, guess_ip4))) {
149  struct in_addr in;
150 
151  in.s_addr = mask;
152  switch_set_string(old_ip4, main_ip4);
153  switch_set_string(main_ip4, guess_ip4);
154  switch_core_set_variable("local_ip_v4", guess_ip4);
155  switch_core_set_variable("local_mask_v4", inet_ntoa(in));
156  }
157  }
158 
159  if (check6 != SWITCH_STATUS_SUCCESS) {
160  ok6 = 2;
161  } else if (!*main_ip6) {
162  switch_set_string(main_ip6, guess_ip6);
163  } else {
164  if (!(ok6 = !strcmp(main_ip6, guess_ip6))) {
165  switch_set_string(old_ip6, main_ip6);
166  switch_set_string(main_ip6, guess_ip6);
167  switch_core_set_variable("local_ip_v6", guess_ip6);
168  }
169  }
170 
171  if (!ok4 || !ok6) {
173  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");
174  if (!ok4) {
175  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4);
176  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4);
177  }
178  if (!ok6) {
179  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6);
180  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6);
181  }
182  switch_event_fire(&event);
183  }
184  }
185 
186  if (ok4 == 2 || ok6 == 2) {
188  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-outage");
189 
190  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-status-v4", ok4 == 2 ? "disconnected" : "active");
191  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-v4", main_ip4);
192 
193  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-status-v6", ok6 == 2 ? "disconnected" : "active");
194  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-v6", main_ip6);
195 
196  switch_event_fire(&event);
197  }
198  }
199 
200 }
201 
202 SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
203 {
204  send_heartbeat();
205 
206  /* reschedule this task */
207  task->runtime = switch_epoch_time_now(NULL) + 20;
208 }
209 
210 
211 SWITCH_STANDARD_SCHED_FUNC(check_ip_callback)
212 {
213  check_ip();
214 
215  /* reschedule this task */
216  task->runtime = switch_epoch_time_now(NULL) + 60;
217 }
218 
219 
221 {
222  if ((runtime.console = fopen(console, "a")) == 0) {
223  fprintf(stderr, "Cannot open output file %s.\n", console);
224  return SWITCH_STATUS_FALSE;
225  }
226 
227  return SWITCH_STATUS_SUCCESS;
228 }
229 
231 {
232  return runtime.console;
233 }
234 
235 #ifdef HAVE_SYS_IOCTL_H
236 #include <sys/ioctl.h>
237 #endif
239 {
240 
241 #ifdef WIN32
242  CONSOLE_SCREEN_BUFFER_INFO csbi;
243  int ret;
244 
245  if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) {
246  if (x) *x = csbi.dwSize.X;
247  if (y) *y = csbi.dwSize.Y;
248  }
249 
250 #elif defined(TIOCGWINSZ)
251  struct winsize w;
252  ioctl(0, TIOCGWINSZ, &w);
253 
254  if (x) *x = w.ws_col;
255  if (y) *y = w.ws_row;
256 #else
257  if (x) *x = 80;
258  if (y) *y = 24;
259 #endif
260 
261 }
262 
264 {
265  FILE *handle = stdout;
266 
267  switch (channel) {
270  handle = runtime.console;
271  break;
272  default:
273  handle = runtime.console;
274  break;
275  }
276 
277  return handle;
278 }
279 
280 
282 {
283  int index, tmp_index = 0;
285 
287 
288  for (index = 0; index < runtime.state_handler_index; index++) {
289  const switch_state_handler_table_t *cur = runtime.state_handlers[index];
290  runtime.state_handlers[index] = NULL;
291  if (cur == state_handler) {
292  continue;
293  }
294  tmp[tmp_index++] = cur;
295  }
296 
297  runtime.state_handler_index = 0;
298 
299  for (index = 0; index < tmp_index; index++) {
300  runtime.state_handlers[runtime.state_handler_index++] = tmp[index];
301  }
303 }
304 
305 
307 {
308  int index;
309 
311  index = runtime.state_handler_index++;
312 
314  index = -1;
315  } else {
316  runtime.state_handlers[index] = state_handler;
317  }
318 
320  return index;
321 }
322 
324 {
325 
326  if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) {
327  return NULL;
328  }
329 
330  return runtime.state_handlers[index];
331 }
332 
334 {
336 
338  for (hi = runtime.global_vars->headers; hi; hi = hi->next) {
339  stream->write_function(stream, "%s=%s\n", hi->name, hi->value);
340  }
342 }
343 
345 {
346  return runtime.hostname;
347 }
348 
350 {
351  if (!zstr(runtime.switchname)) return runtime.switchname;
352  return runtime.hostname;
353 }
354 
356 {
357  char *domain;
358  const char *var;
359 
361  if (!(var = switch_core_get_variable("domain"))) {
362  var = "freeswitch.local";
363  }
364  if (dup) {
365  domain = strdup(var);
366  } else {
367  domain = (char *) var;
368  }
370 
371  return domain;
372 }
373 
375 {
376  switch_status_t status;
378  status = switch_event_dup(event, runtime.global_vars);
380  return status;
381 }
382 
383 SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)
384 {
385  char *val;
387  val = (char *) switch_event_get_header(runtime.global_vars, varname);
389  return val;
390 }
391 
392 SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname)
393 {
394  char *val = NULL, *v;
395 
396  if (varname) {
398  if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {
399  val = strdup(v);
400  }
402  }
403 
404  return val;
405 }
406 
408 {
409  char *val = NULL, *v;
410 
411  if (varname) {
413  if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) {
414  val = switch_core_strdup(pool, v);
415  }
417  }
418 
419  return val;
420 }
421 
423 {
428 }
429 
430 SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value)
431 {
432  char *val;
433 
434  if (varname) {
436  val = (char *) switch_event_get_header(runtime.global_vars, varname);
437  if (val) {
438  switch_event_del_header(runtime.global_vars, varname);
439  }
440  if (value) {
441  char *v = strdup(value);
444  } else {
445  switch_event_del_header(runtime.global_vars, varname);
446  }
448  }
449 }
450 
451 SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)
452 {
453  char *val;
454 
455  if (varname) {
457  val = (char *) switch_event_get_header(runtime.global_vars, varname);
458 
459  if (val) {
460  if (!val2 || strcmp(val, val2) != 0) {
462  return SWITCH_FALSE;
463  }
464  switch_event_del_header(runtime.global_vars, varname);
465  } else if (!zstr(val2)) {
467  return SWITCH_FALSE;
468  }
469 
470  if (value) {
471  char *v = strdup(value);
474  } else {
475  switch_event_del_header(runtime.global_vars, varname);
476  }
478  }
479  return SWITCH_TRUE;
480 }
481 
483 {
484  return runtime.uuid_str;
485 }
486 
487 
489 {
490  switch_core_session_t *session = obj;
491  switch_channel_t *channel;
492  switch_frame_t *read_frame;
493 
494 // switch_assert(thread != NULL);
495 // switch_assert(session != NULL);
496 
498  return NULL;
499  }
500 
502 
503  channel = switch_core_session_get_channel(session);
504 
506  while (switch_channel_test_flag(channel, CF_SERVICE)) {
507 
509  switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
512  case SWITCH_STATUS_BREAK:
513  break;
514  default:
516  break;
517  }
518  }
519 
521  switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) {
524  case SWITCH_STATUS_BREAK:
525  break;
526  default:
528  break;
529  }
530  }
531  }
532 
534 
537 
539 
540  return NULL;
541 }
542 
543 /* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
545 {
546  switch_channel_t *channel;
547  switch_assert(session);
548 
549  channel = switch_core_session_get_channel(session);
550  switch_assert(channel);
551 
555 
557 
558 }
559 
561 {
562  switch_channel_t *channel;
563  switch_assert(session);
564 
565  channel = switch_core_session_get_channel(session);
566  switch_assert(channel);
567 
568  if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO);
569  if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO);
570 
571  switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session);
572 }
573 
574 /* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
575  a void object and trust that that the function will be run in a thread with arg This lets
576  you request and activate a thread without giving up any knowledge about what is in the thread
577  neither the core nor the calling module know anything about each other.
578 
579  This thread is expected to never exit until the application exits so the func is responsible
580  to make sure that is the case.
581 
582  The typical use for this is so switch_loadable_module.c can start up a thread for each module
583  passing the table of module methods as a session obj into the core without actually allowing
584  the core to have any clue and keeping switch_loadable_module.c from needing any thread code.
585 
586 */
587 
589 {
590  switch_thread_t *thread = NULL;
591  switch_threadattr_t *thd_attr = NULL;
593  int mypool;
594 
595  mypool = pool ? 0 : 1;
596 
597  if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
598  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n");
599  return NULL;
600  }
601 
602  switch_threadattr_create(&thd_attr, pool);
603 
604  if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) {
605  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n");
606  } else {
607  if (mypool) {
608  ts->pool = pool;
609  }
610  ts->objs[0] = obj;
611  ts->objs[1] = thread;
614  switch_thread_create(&thread, thd_attr, func, ts, pool);
615  }
616 
617  return thread;
618 }
619 
621 {
622 #define BUFSIZE 1024
623 #ifdef WIN32
624  char lpPathBuffer[BUFSIZE];
625  DWORD dwBufSize = BUFSIZE;
626  char base_dir[1024];
627  char *lastbacklash;
628  char *tmp;
629 
630  GetModuleFileName(NULL, base_dir, BUFSIZE);
631  lastbacklash = strrchr(base_dir, '\\');
632  base_dir[(lastbacklash - base_dir)] = '\0';
633  /* 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 */
634  SetCurrentDirectory(base_dir);
635  tmp = switch_string_replace(base_dir, "\\", "/");
636  strcpy(base_dir, tmp);
637  free(tmp);
638 
639 #else
640  char base_dir[1024] = SWITCH_PREFIX_DIR;
641 #endif
642 
643  /* Order of precedence for, eg, rundir:
644  * -run
645  * -base
646  * --with-rundir
647  * --prefix
648  */
649 
650  if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) {
653  else
654 #ifdef SWITCH_MOD_DIR
656 #else
658 #endif
659  }
660 
661  if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) {
664  else
665 #ifdef SWITCH_LIB_DIR
666  switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR);
667 #else
669 #endif
670  }
671 
672  if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) {
675  else
676 #ifdef SWITCH_CONF_DIR
678 #else
680 #endif
681  }
682 
683  if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) {
686  else
687 #ifdef SWITCH_LOG_DIR
689 #else
691 #endif
692  }
693 
694  if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) {
697  else
698 #ifdef SWITCH_RUN_DIR
700 #else
702 #endif
703  }
704 
708  else
709 #ifdef SWITCH_RECORDINGS_DIR
711 #else
713 #endif
714  }
715 
716  if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) {
719  else
720 #ifdef SWITCH_SOUNDS_DIR
722 #else
724 #endif
725  }
726 
730  else
731 #ifdef SWITCH_STORAGE_DIR
733 #else
735 #endif
736  }
737 
738  if (!SWITCH_GLOBAL_dirs.cache_dir && (SWITCH_GLOBAL_dirs.cache_dir = (char *) malloc(BUFSIZE))) {
741  else
742 #ifdef SWITCH_CACHE_DIR
744 #else
746 #endif
747  }
748 
749  if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) {
752  else
753 #ifdef SWITCH_DB_DIR
755 #else
757 #endif
758  }
759 
760  if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) {
763  else
764 #ifdef SWITCH_SCRIPT_DIR
766 #else
768 #endif
769  }
770 
771  if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {
774  else
775 #ifdef SWITCH_HTDOCS_DIR
777 #else
779 #endif
780  }
781 
785  else
786 #ifdef SWITCH_GRAMMAR_DIR
788 #else
790 #endif
791  }
792 
793  if (!SWITCH_GLOBAL_dirs.fonts_dir && (SWITCH_GLOBAL_dirs.fonts_dir = (char *) malloc(BUFSIZE))) {
796  else
797 #ifdef SWITCH_FONTS_DIR
799 #else
801 #endif
802  }
803 
804  if (!SWITCH_GLOBAL_dirs.images_dir && (SWITCH_GLOBAL_dirs.images_dir = (char *) malloc(BUFSIZE))) {
807  else
808 #ifdef SWITCH_IMAGES_DIR
810 #else
812 #endif
813  }
814 
815  if (!SWITCH_GLOBAL_dirs.data_dir && (SWITCH_GLOBAL_dirs.data_dir = (char *) malloc(BUFSIZE))) {
818  else
819 #ifdef SWITCH_DATA_DIR
821 #else
823 #endif
824  }
825 
829  else
830 #ifdef SWITCH_LOCALSTATE_DIR
832 #else
834 #endif
835  }
836 
837  if (!SWITCH_GLOBAL_dirs.certs_dir && (SWITCH_GLOBAL_dirs.certs_dir = (char *) malloc(BUFSIZE))) {
840  else
841 #ifdef SWITCH_CERTS_DIR
843 #else
845 #endif
846  }
847 
848  if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) {
849 #ifdef SWITCH_TEMP_DIR
850  switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR);
851 #else
852 #ifdef WIN32
853  GetTempPath(dwBufSize, lpPathBuffer);
854  lpPathBuffer[strlen(lpPathBuffer)-1] = 0;
855  tmp = switch_string_replace(lpPathBuffer, "\\", "/");
856  strcpy(lpPathBuffer, tmp);
857  free(tmp);
858  switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer);
859 #else
861 #endif
862 #endif
863  }
864 
866  switch_snprintf(SWITCH_GLOBAL_filenames.conf_name, BUFSIZE, "%s", "freeswitch.xml");
867  }
868 
869  /* Do this last because it being empty is part of the above logic */
870  if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) {
872  }
873 
892 
894 }
895 
896 
898 {
899 #ifdef SOLARIS_PRIVILEGES
900  priv_set_t *basicset;
901 
902  /* make the process privilege-aware */
903  setpflags(PRIV_AWARE, 1);
904 
905  /* reset the privileges to basic */
906  basicset = priv_str_to_set("basic", ",", NULL);
907  if (setppriv(PRIV_SET, PRIV_EFFECTIVE, basicset) != 0) {
908  fprintf(stderr, "ERROR: Failed to acquire basic privileges (%s)\n", strerror(errno));
909  }
910 
911  /* we need high-resolution clock, and this requires a non-basic privilege */
912  if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_CLOCK_HIGHRES, NULL) < 0) {
913  fprintf(stderr, "ERROR: Failed to acquire proc_clock_highres privilege (%s)\n", strerror(errno));
914  return -1;
915  }
916 
917  /* need this for setrlimit */
918  if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_RESOURCE, NULL) < 0) {
919  fprintf(stderr, "ERROR: Failed to acquire sys_resource privilege (%s)\n", strerror(errno));
920  return -1;
921  }
922 
923  /* we need to read directories belonging to other uid */
924  if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_SEARCH, NULL) < 0) {
925  fprintf(stderr, "ERROR: Failed to acquire file_dac_search privilege (%s)\n", strerror(errno));
926  return -1;
927  }
928 #endif
929  return 0;
930 }
931 
933 {
934 #ifdef WIN32
935  return SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
936 #else
937 #if defined(USE_SCHED_SETSCHEDULER) && ! defined(SOLARIS_PRIVILEGES)
938  /*
939  * Try to use a normal scheduler
940  */
941  struct sched_param sched = { 0 };
942  sched.sched_priority = 0;
943  if (sched_setscheduler(0, SCHED_OTHER, &sched) < 0) {
944  fprintf(stderr, "ERROR: Failed to set SCHED_OTHER scheduler (%s)\n", strerror(errno));
945  return -1;
946  }
947 #endif
948 
949 #ifdef HAVE_SETPRIORITY
950  /*
951  * setpriority() works on FreeBSD (6.2), nice() doesn't
952  */
953  if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) {
954  fprintf(stderr, "ERROR: Could not set nice level\n");
955  return -1;
956  }
957 #else
958  if (nice(19) != 19) {
959  fprintf(stderr, "ERROR: Could not set nice level\n");
960  return -1;
961  }
962 #endif
963 
964  return 0;
965 #endif
966 }
967 
969 {
970 #ifdef WIN32
971  return SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
972 #else
973 #ifdef USE_SCHED_SETSCHEDULER
974  /*
975  * Try to use a round-robin scheduler
976  * with a fallback if that does not work
977  */
978  struct sched_param sched = { 0 };
979  sched.sched_priority = SWITCH_PRI_LOW;
980 #endif
981 
982 #ifdef SOLARIS_PRIVILEGES
983  /* request the privileges to elevate the priority */
984  if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_PRIOCNTL, NULL) < 0) {
985 #ifdef PRIV_PROC_PRIOUP
986  /* fallback to PRIV_PROC_PRIOUP on SmartOS */
987  fprintf(stderr, "WARN: Failed to acquire proc_priocntl privilege (%s)\n", strerror(errno));
988  if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_PRIOUP, NULL) < 0) {
989  fprintf(stderr, "ERROR: Failed to acquire proc_prioup privilege (%s)\n", strerror(errno));
990  return -1;
991  }
992 #else
993  fprintf(stderr, "ERROR: Failed to acquire proc_priocntl privilege (%s)\n", strerror(errno));
994  return -1;
995 #endif
996  }
997 
998  if (sched_setscheduler(0, SCHED_FIFO, &sched) < 0) {
999  fprintf(stderr, "WARN: Failed to set SCHED_FIFO scheduler (%s)\n", strerror(errno));
1000  } else {
1001  return 0;
1002  }
1003 
1004  if (setpriority(PRIO_PROCESS, 0, -10) < 0) {
1005  fprintf(stderr, "ERROR: Could not set nice level\n");
1006  return -1;
1007  }
1008 
1009  return 0;
1010 #else
1011 
1012 #ifdef USE_SCHED_SETSCHEDULER
1013  if (sched_setscheduler(0, SCHED_FIFO, &sched) < 0) {
1014  fprintf(stderr, "ERROR: Failed to set SCHED_FIFO scheduler (%s)\n", strerror(errno));
1015  sched.sched_priority = 0;
1016  if (sched_setscheduler(0, SCHED_OTHER, &sched) < 0 ) {
1017  fprintf(stderr, "ERROR: Failed to set SCHED_OTHER scheduler (%s)\n", strerror(errno));
1018  return -1;
1019  }
1020  }
1021 #endif
1022 
1023 #ifdef HAVE_SETPRIORITY
1024  /*
1025  * setpriority() works on FreeBSD (6.2), nice() doesn't
1026  */
1027  if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) {
1028  fprintf(stderr, "ERROR: Could not set nice level\n");
1029  return -1;
1030  }
1031 #else
1032  if (nice(-10) != -10) {
1033  fprintf(stderr, "ERROR: Could not set nice level\n");
1034  return -1;
1035  }
1036 #endif
1037 #endif
1038  return 0;
1039 #endif
1040 }
1041 
1043 {
1044  return runtime.cpu_count;
1045 }
1046 
1048 {
1049  return 0;
1050 }
1051 
1053 {
1054 #ifndef WIN32
1055  runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);
1056 #else
1057  SYSTEM_INFO sysinfo;
1058  GetSystemInfo( &sysinfo );
1059  runtime.cpu_count = sysinfo.dwNumberOfProcessors;
1060 #endif
1061 
1062  if (!runtime.cpu_count) runtime.cpu_count = 1;
1063 
1064  return set_realtime_priority();
1065 
1066 
1067  // ERROR: code not reachable on Windows Visual Studio Express 2008 return 0;
1068 }
1069 
1070 SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group)
1071 {
1072 #ifndef WIN32
1073  uid_t runas_uid = 0;
1074  gid_t runas_gid = 0;
1075  struct passwd *runas_pw = NULL;
1076 
1077  if (user) {
1078  /*
1079  * Lookup user information in the system's db
1080  */
1081  runas_pw = getpwnam(user);
1082  if (!runas_pw) {
1083  fprintf(stderr, "ERROR: Unknown user \"%s\"\n", user);
1084  return -1;
1085  }
1086  runas_uid = runas_pw->pw_uid;
1087  }
1088 
1089  if (group) {
1090  struct group *gr = NULL;
1091 
1092  /*
1093  * Lookup group information in the system's db
1094  */
1095  gr = getgrnam(group);
1096  if (!gr) {
1097  fprintf(stderr, "ERROR: Unknown group \"%s\"\n", group);
1098  return -1;
1099  }
1100  runas_gid = gr->gr_gid;
1101  }
1102 
1103  if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) {
1104  /* already running as the right user and group, nothing to do! */
1105  return 0;
1106  }
1107 
1108  if (runas_uid) {
1109 #ifdef SOLARIS_PRIVILEGES
1110  /* request the privilege to set the UID */
1111  if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_SETID, NULL) < 0) {
1112  fprintf(stderr, "ERROR: Failed to acquire proc_setid privilege (%s)\n", strerror(errno));
1113  return -1;
1114  }
1115 #endif
1116 #ifdef HAVE_SETGROUPS
1117  /*
1118  * Drop all group memberships prior to changing anything
1119  * or else we're going to inherit the parent's list of groups
1120  * (which is not what we want...)
1121  */
1122  if (setgroups(0, NULL) < 0) {
1123  fprintf(stderr, "ERROR: Failed to drop group access list\n");
1124  return -1;
1125  }
1126 #endif
1127  if (runas_gid) {
1128  /*
1129  * A group has been passed, switch to it
1130  * (without loading the user's other groups)
1131  */
1132  if (setgid(runas_gid) < 0) {
1133  fprintf(stderr, "ERROR: Failed to change gid!\n");
1134  return -1;
1135  }
1136  } else {
1137  /*
1138  * No group has been passed, use the user's primary group in this case
1139  */
1140  if (setgid(runas_pw->pw_gid) < 0) {
1141  fprintf(stderr, "ERROR: Failed to change gid!\n");
1142  return -1;
1143  }
1144 #ifdef HAVE_INITGROUPS
1145  /*
1146  * Set all the other groups the user is a member of
1147  * (This can be really useful for fine-grained access control)
1148  */
1149  if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) {
1150  fprintf(stderr, "ERROR: Failed to set group access list for user\n");
1151  return -1;
1152  }
1153 #endif
1154  }
1155 
1156  /*
1157  * Finally drop all privileges by switching to the new userid
1158  */
1159  if (setuid(runas_uid) < 0) {
1160  fprintf(stderr, "ERROR: Failed to change uid!\n");
1161  return -1;
1162  }
1163 #ifdef HAVE_SYS_PRCTL_H
1164  if (prctl(PR_SET_DUMPABLE, 1) < 0) {
1165  fprintf(stderr, "ERROR: Failed to enable core dumps!\n");
1166  return -1;
1167  }
1168 #endif
1169  }
1170 #endif
1171  return 0;
1172 }
1173 
1175 {
1176 #ifdef WIN32
1177  HANDLE shutdown_event;
1178  char path[256] = "";
1179 #endif
1180  if (bg) {
1181 #ifdef WIN32
1182  switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
1183  shutdown_event = CreateEvent(NULL, FALSE, FALSE, path);
1184  if (shutdown_event) {
1185  WaitForSingleObject(shutdown_event, INFINITE);
1186  }
1187 #else
1188  runtime.running = 1;
1189  while (runtime.running) {
1190  switch_yield(1000000);
1191  }
1192 #endif
1193  } else {
1194  /* wait for console input */
1196  }
1197 }
1198 
1199 SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)
1200 {
1201  if (!ext) {
1202  return NULL;
1203  }
1204  return (const char *) switch_core_hash_find(runtime.mime_types, ext);
1205 }
1206 
1207 SWITCH_DECLARE(const char *) switch_core_mime_type2ext(const char *mime)
1208 {
1209  if (!mime) {
1210  return NULL;
1211  }
1212  return (const char *) switch_core_hash_find(runtime.mime_type_exts, mime);
1213 }
1214 
1216 {
1217  return switch_core_hash_first(runtime.mime_types);
1218 }
1219 
1220 SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext)
1221 {
1222  char *ptype = NULL;
1223  char *ext_list = NULL;
1224  int argc = 0;
1225  char *argv[20] = { 0 };
1226  int x;
1228 
1229  switch_assert(type);
1230  switch_assert(ext);
1231 
1232  ptype = switch_core_permanent_strdup(type);
1233  ext_list = strdup(ext);
1234 
1235  switch_assert(ext_list);
1236 
1237  /* Map each file extension to this MIME type if not already mapped. Map the MIME type to the first file extension in the list if not already mapped. */
1238  if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1239  int is_mapped_type = switch_core_hash_find(runtime.mime_type_exts, ptype) != NULL;
1240  for (x = 0; x < argc; x++) {
1241  if (argv[x] && ptype) {
1242  if (!switch_core_hash_find(runtime.mime_types, ext)) {
1243  switch_core_hash_insert(runtime.mime_types, argv[x], ptype);
1244  }
1245  if (!is_mapped_type) {
1247  is_mapped_type = 1;
1248  }
1249  }
1250  }
1251 
1252  status = SWITCH_STATUS_SUCCESS;
1253  }
1254 
1255  free(ext_list);
1256 
1257  return status;
1258 }
1259 
1260 static void load_mime_types(void)
1261 {
1262  char *cf = "mime.types";
1263  FILE *fd = NULL;
1264  char *line_buf = NULL;
1265  switch_size_t llen = 0;
1266  char *mime_path = NULL;
1267 
1268  mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf);
1269  switch_assert(mime_path);
1270 
1271  fd = fopen(mime_path, "rb");
1272 
1273  if (fd == NULL) {
1274  goto end;
1275  }
1276 
1277  while ((switch_fp_read_dline(fd, &line_buf, &llen))) {
1278  char *p;
1279  char *type = line_buf;
1280 
1281  if (*line_buf == '#') {
1282  continue;
1283  }
1284 
1285  if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) {
1286  *p = '\0';
1287  }
1288 
1289  if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) {
1290  *p++ = '\0';
1291 
1292  while (*p == ' ' || *p == '\t') {
1293  p++;
1294  }
1295 
1296  switch_core_mime_add_type(type, p);
1297  }
1298 
1299  }
1300 
1301  switch_safe_free(line_buf);
1302 
1303  if (fd) {
1304  fclose(fd);
1305  fd = NULL;
1306  }
1307 
1308  end:
1309 
1310  switch_safe_free(mime_path);
1311 
1312 }
1313 
1315 {
1316 #ifdef HAVE_SETRLIMIT
1317  struct rlimit rlp;
1318 
1319  /*
1320  Setting the stack size on FreeBSD results in an instant crash.
1321 
1322  If anyone knows how to fix this,
1323  feel free to submit a patch to https://freeswitch.org/jira
1324  */
1325 
1326 #ifndef __FreeBSD__
1327  memset(&rlp, 0, sizeof(rlp));
1328  rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
1329  rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
1330  setrlimit(RLIMIT_STACK, &rlp);
1331 #endif
1332 
1333  memset(&rlp, 0, sizeof(rlp));
1334  rlp.rlim_cur = 999999;
1335  rlp.rlim_max = 999999;
1336  setrlimit(RLIMIT_NOFILE, &rlp);
1337 
1338  memset(&rlp, 0, sizeof(rlp));
1339  rlp.rlim_cur = RLIM_INFINITY;
1340  rlp.rlim_max = RLIM_INFINITY;
1341 
1342  setrlimit(RLIMIT_CPU, &rlp);
1343  setrlimit(RLIMIT_DATA, &rlp);
1344  setrlimit(RLIMIT_FSIZE, &rlp);
1345 #ifdef RLIMIT_NPROC
1346  setrlimit(RLIMIT_NPROC, &rlp);
1347 #endif
1348 #ifdef RLIMIT_RTPRIO
1349  setrlimit(RLIMIT_RTPRIO, &rlp);
1350 #endif
1351 
1352 #if !defined(__OpenBSD__) && !defined(__NetBSD__)
1353  setrlimit(RLIMIT_AS, &rlp);
1354 #endif
1355 #endif
1356  return;
1357 }
1358 
1359 typedef struct {
1363 
1364 static switch_ip_list_t IP_LIST = { 0 };
1365 
1366 SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
1367 {
1368  switch_network_list_t *list;
1369  ip_t ip, mask, net;
1370  uint32_t bits;
1371  char *ipv6 = strchr(ip_str,':');
1373  char *ipv4 = NULL;
1374 
1375  if ((ipv4 = switch_network_ipv4_mapped_ipv6_addr(ip_str))) {
1376  ip_str = ipv4;
1377  ipv6 = NULL;
1378  }
1379 
1381  if (ipv6) {
1382  switch_inet_pton(AF_INET6, ip_str, &ip);
1383  } else {
1384  switch_inet_pton(AF_INET, ip_str, &ip);
1385  ip.v4 = htonl(ip.v4);
1386  }
1387 
1388  if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
1389  if (ipv6) {
1390  ok = switch_network_list_validate_ip6_token(list, ip, token);
1391  } else {
1392  ok = switch_network_list_validate_ip_token(list, ip.v4, token);
1393  }
1394  } else if (strchr(list_name, '/')) {
1395  if (strchr(list_name, ',')) {
1396  char *list_name_dup = strdup(list_name);
1397  char *argv[32];
1398  int argc;
1399 
1400  switch_assert(list_name_dup);
1401 
1402  if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1403  int i;
1404  for (i = 0; i < argc; i++) {
1405  switch_parse_cidr(argv[i], &net, &mask, &bits);
1406  if (ipv6) {
1407  if ((ok = switch_testv6_subnet(ip, net, mask))){
1408  break;
1409  }
1410  } else {
1411  if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) {
1412  break;
1413  }
1414  }
1415  }
1416  }
1417  free(list_name_dup);
1418  } else {
1419  switch_parse_cidr(list_name, &net, &mask, &bits);
1420 
1421  if (ipv6) {
1422  ok = switch_testv6_subnet(ip, net, mask);
1423  } else {
1424  ok = switch_test_subnet(ip.v4, net.v4, mask.v4);
1425  }
1426  }
1427  }
1428 
1429  switch_safe_free(ipv4);
1431 
1432  return ok;
1433 }
1434 
1435 
1437 {
1438  switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;
1439  switch_network_list_t *rfc_list, *list;
1440  char guess_ip[16] = "";
1441  int mask = 0;
1442  char guess_mask[16] = "";
1443  char *tmp_name;
1444  struct in_addr in;
1445 
1446  switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
1447  in.s_addr = mask;
1448  switch_set_string(guess_mask, inet_ntoa(in));
1449 
1451 
1452  if (IP_LIST.hash) {
1453  switch_core_hash_destroy(&IP_LIST.hash);
1454  }
1455 
1456  if (IP_LIST.pool) {
1458  }
1459 
1460  memset(&IP_LIST, 0, sizeof(IP_LIST));
1462  switch_core_hash_init(&IP_LIST.hash);
1463 
1464 
1465  tmp_name = "rfc6598.auto";
1466  switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1467  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1468  switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_TRUE);
1469  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1470 
1471  tmp_name = "rfc1918.auto";
1472  switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1473  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1474  switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
1475  switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
1476  switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
1477  switch_network_list_add_cidr(rfc_list, "fe80::/10", SWITCH_TRUE);
1478  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1479 
1480  tmp_name = "wan.auto";
1481  switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
1482  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
1483  switch_network_list_add_cidr(rfc_list, "0.0.0.0/8", SWITCH_FALSE);
1484  switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
1485  switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
1486  switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
1487  switch_network_list_add_cidr(rfc_list, "169.254.0.0/16", SWITCH_FALSE);
1488  switch_network_list_add_cidr(rfc_list, "fe80::/10", SWITCH_FALSE);
1489  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1490 
1491  tmp_name = "wan_v6.auto";
1492  switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
1493  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
1494  switch_network_list_add_cidr(rfc_list, "0.0.0.0/0", SWITCH_FALSE);
1495  switch_network_list_add_cidr(rfc_list, "fe80::/10", SWITCH_FALSE);
1496  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1497 
1498 
1499  tmp_name = "wan_v4.auto";
1500  switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
1501  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
1502  switch_network_list_add_cidr(rfc_list, "0.0.0.0/8", SWITCH_FALSE);
1503  switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
1504  switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
1505  switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
1506  switch_network_list_add_cidr(rfc_list, "169.254.0.0/16", SWITCH_FALSE);
1507  switch_network_list_add_cidr(rfc_list, "::/0", SWITCH_FALSE);
1508  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1509 
1510 
1511  tmp_name = "any_v6.auto";
1512  switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
1513  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
1514  switch_network_list_add_cidr(rfc_list, "0.0.0.0/0", SWITCH_FALSE);
1515  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1516 
1517 
1518  tmp_name = "any_v4.auto";
1519  switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool);
1520  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name);
1521  switch_network_list_add_cidr(rfc_list, "::/0", SWITCH_FALSE);
1522  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1523 
1524 
1525  tmp_name = "nat.auto";
1526  switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1527  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1528  if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1529  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name);
1530  }
1531  switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE);
1532  switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE);
1533  switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE);
1534  switch_network_list_add_cidr(rfc_list, "100.64.0.0/10", SWITCH_TRUE);
1535  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1536 
1537  tmp_name = "loopback.auto";
1538  switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1539  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1540  switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE);
1541  switch_network_list_add_cidr(rfc_list, "::1/128", SWITCH_TRUE);
1542  switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
1543 
1544  tmp_name = "localnet.auto";
1545  switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool);
1546  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name);
1547 
1548  if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
1549  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name);
1550  }
1551  switch_core_hash_insert(IP_LIST.hash, tmp_name, list);
1552 
1553 
1554  if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {
1555  if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
1556  for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
1557  const char *name = switch_xml_attr(x_list, "name");
1558  const char *dft = switch_xml_attr(x_list, "default");
1559  switch_bool_t default_type = SWITCH_TRUE;
1560 
1561  if (zstr(name)) {
1562  continue;
1563  }
1564 
1565  if (dft) {
1566  default_type = switch_true(dft);
1567  }
1568 
1569  if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
1570  abort();
1571  }
1572 
1573  if (reload) {
1574  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
1575  } else {
1576  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
1577  }
1578 
1579 
1580  for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
1581  const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL;
1582  switch_bool_t ok = default_type;
1583  const char *type = switch_xml_attr(x_node, "type");
1584 
1585  if (type) {
1586  ok = switch_true(type);
1587  }
1588 
1589  cidr = switch_xml_attr(x_node, "cidr");
1590  host = switch_xml_attr(x_node, "host");
1591  mask = switch_xml_attr(x_node, "mask");
1592  domain = switch_xml_attr(x_node, "domain");
1593 
1594  if (domain) {
1595  switch_event_t *my_params = NULL;
1596  switch_xml_t x_domain, xml_root;
1597  switch_xml_t gt, gts, ut, uts;
1598 
1600  switch_assert(my_params);
1601  switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);
1602  switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");
1603 
1604  if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
1605  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
1606  switch_event_destroy(&my_params);
1607  continue;
1608  }
1609 
1610  switch_event_destroy(&my_params);
1611 
1612  if ((ut = switch_xml_child(x_domain, "users"))) {
1613  x_domain = ut;
1614  }
1615 
1616  for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {
1617  const char *user_cidr = switch_xml_attr(ut, "cidr");
1618  const char *id = switch_xml_attr(ut, "id");
1619 
1620  if (id && user_cidr) {
1621  char *token = switch_mprintf("%s@%s", id, domain);
1622  switch_assert(token);
1623  switch_network_list_add_cidr_token(list, user_cidr, ok, token);
1624  free(token);
1625  }
1626  }
1627 
1628  for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) {
1629  for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
1630  for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
1631  for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
1632  const char *user_cidr = switch_xml_attr(ut, "cidr");
1633  const char *id = switch_xml_attr(ut, "id");
1634 
1635  if (id && user_cidr) {
1636  char *token = switch_mprintf("%s@%s", id, domain);
1637  switch_assert(token);
1638  switch_network_list_add_cidr_token(list, user_cidr, ok, token);
1639  free(token);
1640  }
1641  }
1642  }
1643  }
1644  }
1645 
1646  switch_xml_free(xml_root);
1647  } else if (cidr) {
1648  switch_network_list_add_cidr(list, cidr, ok);
1649  } else if (host && mask) {
1650  switch_network_list_add_host_mask(list, host, mask, ok);
1651  }
1652 
1653  switch_core_hash_insert(IP_LIST.hash, name, list);
1654  }
1655  }
1656  }
1657 
1658  switch_xml_free(xml);
1659  }
1660 
1662 }
1663 
1664 SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration)
1665 {
1666  if (duration) {
1667  if (duration > SWITCH_MAX_DTMF_DURATION) {
1668  duration = SWITCH_MAX_DTMF_DURATION;
1669  }
1670  if (duration < SWITCH_MIN_DTMF_DURATION) {
1671  duration = SWITCH_MIN_DTMF_DURATION;
1672  }
1673  runtime.max_dtmf_duration = duration;
1674  if (duration < runtime.min_dtmf_duration) {
1675  runtime.min_dtmf_duration = duration;
1676  }
1677  }
1678  return runtime.max_dtmf_duration;
1679 }
1680 
1682 {
1683  if (duration) {
1684  if (duration < SWITCH_MIN_DTMF_DURATION) {
1685  duration = SWITCH_MIN_DTMF_DURATION;
1686  }
1687  if (duration > SWITCH_MAX_DTMF_DURATION) {
1688  duration = SWITCH_MAX_DTMF_DURATION;
1689  }
1690  runtime.default_dtmf_duration = duration;
1691 
1692  if (duration < runtime.min_dtmf_duration) {
1693  runtime.min_dtmf_duration = duration;
1694  }
1695 
1696  if (duration > runtime.max_dtmf_duration) {
1697  runtime.max_dtmf_duration = duration;
1698  }
1699 
1700  }
1701  return runtime.default_dtmf_duration;
1702 }
1703 
1704 SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration)
1705 {
1706  if (duration) {
1707  if (duration < SWITCH_MIN_DTMF_DURATION) {
1708  duration = SWITCH_MIN_DTMF_DURATION;
1709  }
1710  if (duration > SWITCH_MAX_DTMF_DURATION) {
1711  duration = SWITCH_MAX_DTMF_DURATION;
1712  }
1713 
1714  runtime.min_dtmf_duration = duration;
1715 
1716  if (duration > runtime.max_dtmf_duration) {
1717  runtime.max_dtmf_duration = duration;
1718  }
1719  }
1720  return runtime.min_dtmf_duration;
1721 }
1722 
1724 {
1726 
1727  if (cpu > -1) {
1728 
1729 #ifdef HAVE_CPU_SET_MACROS
1730  cpu_set_t set;
1731 
1732  CPU_ZERO(&set);
1733  CPU_SET(cpu, &set);
1734 
1735  if (!sched_setaffinity(0, sizeof(set), &set)) {
1736  status = SWITCH_STATUS_SUCCESS;
1737  }
1738 
1739 #else
1740 #if WIN32
1741  if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) {
1742  status = SWITCH_STATUS_SUCCESS;
1743  }
1744 #endif
1745 #endif
1746  }
1747 
1748  return status;
1749 }
1750 
1751 
1752 #ifdef ENABLE_ZRTP
1753 static void switch_core_set_serial(void)
1754 {
1755  char buf[13] = "";
1756  char path[256];
1757 
1758  int fd = -1, write_fd = -1;
1759  switch_ssize_t bytes = 0;
1760 
1761  switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR);
1762 
1763 
1764  if ((fd = open(path, O_RDONLY, 0)) < 0) {
1765  char *ip = switch_core_get_variable_dup("local_ip_v4");
1766  uint32_t ipi = 0;
1767  switch_byte_t *byte;
1768  int i = 0;
1769 
1770  if (ip) {
1771  switch_inet_pton(AF_INET, ip, &ipi);
1772  free(ip);
1773  ip = NULL;
1774  }
1775 
1776 
1777  byte = (switch_byte_t *) & ipi;
1778 
1779  for (i = 0; i < 8; i += 2) {
1780  switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte);
1781  byte++;
1782  }
1783 
1784  switch_stun_random_string(buf + 8, 4, "0123456789abcdef");
1785 
1786  if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) {
1787  bytes = write(write_fd, buf, sizeof(buf));
1788  bytes++;
1789  close(write_fd);
1790  }
1791  } else {
1792  bytes = read(fd, buf, sizeof(buf) - 1);
1793  close(fd);
1794  }
1795 
1796  switch_core_set_variable("switch_serial", buf);
1797 }
1798 #endif
1799 
1801 {
1802  return switch_test_flag((&runtime), flag);
1803 }
1804 
1805 
1807 {
1808  switch_uuid_t uuid;
1809  char guess_ip[256];
1810  int mask = 0;
1811  struct in_addr in;
1812 
1813 
1814  if (runtime.runlevel > 0) {
1815  /* one per customer */
1816  return SWITCH_STATUS_SUCCESS;
1817  }
1818 
1819  memset(&runtime, 0, sizeof(runtime));
1820  gethostname(runtime.hostname, sizeof(runtime.hostname));
1821 
1822  runtime.max_db_handles = 50;
1823  runtime.db_handle_timeout = 5000000;
1824 
1825  runtime.runlevel++;
1826  runtime.dummy_cng_frame.data = runtime.dummy_data;
1827  runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);
1828  runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);
1829  runtime.dbname = "core";
1831  switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
1832  switch_set_flag((&runtime), SCF_CLEAR_SQL);
1833  switch_set_flag((&runtime), SCF_API_EXPANSION);
1835 #ifdef WIN32
1837 #endif
1838  switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
1839  runtime.hard_log_level = SWITCH_LOG_DEBUG;
1840  runtime.mailer_app = "sendmail";
1841  runtime.mailer_app_args = "-t";
1845  runtime.odbc_dbtype = DBTYPE_DEFAULT;
1846  runtime.dbname = NULL;
1847 #ifndef WIN32
1848  runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN);
1849 #else
1850  {
1851  SYSTEM_INFO sysinfo;
1852  GetSystemInfo( &sysinfo );
1853  runtime.cpu_count = sysinfo.dwNumberOfProcessors;
1854  }
1855 #endif
1856 
1857  if (!runtime.cpu_count) runtime.cpu_count = 1;
1858 
1859  if (sqlite3_initialize() != SQLITE_OK) {
1860  *err = "FATAL ERROR! Could not initialize SQLite\n";
1861  return SWITCH_STATUS_MEMERR;
1862  }
1863 
1864  /* INIT APR and Create the pool context */
1865  if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
1866  *err = "FATAL ERROR! Could not initialize APR\n";
1867  return SWITCH_STATUS_MEMERR;
1868  }
1869 
1870  if (!(runtime.memory_pool = switch_core_memory_init())) {
1871  *err = "FATAL ERROR! Could not allocate memory pool\n";
1872  return SWITCH_STATUS_MEMERR;
1873  }
1874  switch_assert(runtime.memory_pool != NULL);
1875 
1891 
1893 
1895 
1898 
1906  load_mime_types();
1907  runtime.flags |= flags;
1908  runtime.sps_total = 30;
1909 
1910  *err = NULL;
1911 
1912  if (console) {
1913  runtime.console = stdout;
1914  }
1915 
1916  SSL_library_init();
1918  switch_curl_init();
1919 
1920  switch_core_set_variable("hostname", runtime.hostname);
1921  switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET);
1922  switch_core_set_variable("local_ip_v4", guess_ip);
1923  in.s_addr = mask;
1924  switch_core_set_variable("local_mask_v4", inet_ntoa(in));
1925 
1926 
1927  switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6);
1928  switch_core_set_variable("local_ip_v6", guess_ip);
1949 #ifdef ENABLE_ZRTP
1950  switch_core_set_serial();
1951 #endif
1953  switch_event_init(runtime.memory_pool);
1955 
1956  if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {
1957  apr_terminate();
1958  return SWITCH_STATUS_MEMERR;
1959  }
1960 
1961  if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
1963  }
1964 
1965  switch_log_init(runtime.memory_pool, runtime.colorize_console);
1966 
1967  runtime.tipping_point = 0;
1968  runtime.timer_affinity = -1;
1969  runtime.microseconds_per_tick = 20000;
1970 
1971  if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS;
1972 
1973  switch_load_core_config("switch.conf");
1974 
1976 
1978  *err = "Error activating database";
1979  return SWITCH_STATUS_FALSE;
1980  }
1983 
1985 
1986  switch_rtp_init(runtime.memory_pool);
1987 
1988  runtime.running = 1;
1990 
1991  switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
1992 
1993  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);
1994 
1995  switch_uuid_get(&uuid);
1996  switch_uuid_format(runtime.uuid_str, &uuid);
1997  switch_core_set_variable("core_uuid", runtime.uuid_str);
1998 
1999 
2000  return SWITCH_STATUS_SUCCESS;
2001 }
2002 
2003 
2004 #ifdef TRAP_BUS
2005 static void handle_SIGBUS(int sig)
2006 {
2008  return;
2009 }
2010 #endif
2011 
2012 static void handle_SIGHUP(int sig)
2013 {
2014  if (sig) {
2015  switch_event_t *event;
2016 
2018  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP");
2019  switch_event_fire(&event);
2020  }
2021  }
2022  return;
2023 }
2024 
2025 
2026 SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)
2027 {
2028  uint32_t *p;
2029 
2030  if ((p = switch_core_hash_find(runtime.ptimes, name))) {
2031  return *p;
2032  }
2033 
2034  return 20;
2035 }
2036 
2037 SWITCH_DECLARE(uint32_t) switch_default_rate(const char *name, uint32_t number)
2038 {
2039 
2040  if (!strcasecmp(name, "opus")) {
2041  return 48000;
2042  } else if (!strncasecmp(name, "h26", 3)) { // h26x
2043  return 90000;
2044  } else if (!strncasecmp(name, "vp", 2)) { // vp8, vp9
2045  return 90000;
2046  }
2047 
2048  return 8000;
2049 }
2050 
2051 static uint32_t d_30 = 30;
2052 
2053 static void switch_load_core_config(const char *file)
2054 {
2055  switch_xml_t xml = NULL, cfg = NULL;
2056 
2057  switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30);
2058  switch_core_hash_insert(runtime.ptimes, "isac", &d_30);
2059  switch_core_hash_insert(runtime.ptimes, "G723", &d_30);
2060 
2061 
2062  if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) {
2063  switch_xml_t settings, param;
2064 
2065  if ((settings = switch_xml_child(cfg, "default-ptimes"))) {
2066  for (param = switch_xml_child(settings, "codec"); param; param = param->next) {
2067  const char *var = switch_xml_attr_soft(param, "name");
2068  const char *val = switch_xml_attr_soft(param, "ptime");
2069 
2070  if (!zstr(var) && !zstr(val)) {
2071  uint32_t *p;
2072  uint32_t v = switch_atoul(val);
2073 
2074  if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) {
2075  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var);
2076  continue;
2077  }
2078 
2079  if (v == 0) {
2080  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var);
2081  continue;
2082  }
2083 
2084  p = switch_core_alloc(runtime.memory_pool, sizeof(*p));
2085  *p = v;
2086  switch_core_hash_insert(runtime.ptimes, var, p);
2087  }
2088 
2089  }
2090  }
2091 
2092  if ((settings = switch_xml_child(cfg, "settings"))) {
2093  for (param = switch_xml_child(settings, "param"); param; param = param->next) {
2094  const char *var = switch_xml_attr_soft(param, "name");
2095  const char *val = switch_xml_attr_soft(param, "value");
2096 
2097  if (!strcasecmp(var, "loglevel")) {
2098  int level;
2099  if (*val > 47 && *val < 58) {
2100  level = atoi(val);
2101  } else {
2102  level = switch_log_str2level(val);
2103  }
2104 
2105  if (level != SWITCH_LOG_INVALID) {
2107  }
2108 #ifdef HAVE_SETRLIMIT
2109  } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) {
2110  struct rlimit rlp;
2111  memset(&rlp, 0, sizeof(rlp));
2112  rlp.rlim_cur = RLIM_INFINITY;
2113  rlp.rlim_max = RLIM_INFINITY;
2114  setrlimit(RLIMIT_CORE, &rlp);
2115 #endif
2116  } else if (!strcasecmp(var, "debug-level")) {
2117  int tmp = atoi(val);
2118  if (tmp > -1 && tmp < 11) {
2120  }
2121  } else if (!strcasecmp(var, "max-db-handles")) {
2122  long tmp = atol(val);
2123 
2124  if (tmp > 4 && tmp < 5001) {
2125  runtime.max_db_handles = (uint32_t) tmp;
2126  } else {
2127  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n");
2128  }
2129  } else if (!strcasecmp(var, "db-handle-timeout")) {
2130  long tmp = atol(val);
2131 
2132  if (tmp > 0 && tmp < 5001) {
2133  runtime.db_handle_timeout = (uint32_t) tmp * 1000000;
2134  } else {
2135  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n");
2136  }
2137 
2138  } else if (!strcasecmp(var, "multiple-registrations")) {
2139  runtime.multiple_registrations = switch_true(val);
2140  } else if (!strcasecmp(var, "auto-create-schemas")) {
2141  if (switch_true(val)) {
2142  switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
2143  } else {
2144  switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS);
2145  }
2146  } else if (!strcasecmp(var, "session-thread-pool")) {
2147  if (switch_true(val)) {
2149  } else {
2151  }
2152  } else if (!strcasecmp(var, "auto-clear-sql")) {
2153  if (switch_true(val)) {
2154  switch_set_flag((&runtime), SCF_CLEAR_SQL);
2155  } else {
2156  switch_clear_flag((&runtime), SCF_CLEAR_SQL);
2157  }
2158  } else if (!strcasecmp(var, "api-expansion")) {
2159  if (switch_true(val)) {
2160  switch_set_flag((&runtime), SCF_API_EXPANSION);
2161  } else {
2162  switch_clear_flag((&runtime), SCF_API_EXPANSION);
2163  }
2164  } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
2165  switch_set_flag((&runtime), SCF_EARLY_HANGUP);
2166  } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
2167  runtime.colorize_console = SWITCH_TRUE;
2168  } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) {
2170  } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) {
2172  } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) {
2174  } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) {
2176  } else if (!strcasecmp(var, "dialplan-timestamps")) {
2177  if (switch_true(val)) {
2179  } else {
2181  }
2182  } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {
2183  runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val);
2184  } else if (!strcasecmp(var, "mailer-app-args") && val) {
2185  runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val);
2186  } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) {
2188  } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) {
2189  int tmp = atoi(val);
2190  if (tmp > 0) {
2191  switch_core_max_dtmf_duration((uint32_t) tmp);
2192  }
2193  } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) {
2194  int tmp = atoi(val);
2195  if (tmp > 0) {
2196  switch_core_min_dtmf_duration((uint32_t) tmp);
2197  }
2198  } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) {
2199  int tmp = atoi(val);
2200  if (tmp > 0) {
2201  switch_core_default_dtmf_duration((uint32_t) tmp);
2202  }
2203  } else if (!strcasecmp(var, "enable-use-system-time")) {
2205  } else if (!strcasecmp(var, "enable-monotonic-timing")) {
2207  } else if (!strcasecmp(var, "enable-softtimer-timerfd")) {
2208  int ival = 0;
2209  if (val) {
2210  if (switch_true(val)) {
2211  ival = 2;
2212  } else {
2213  if (strcasecmp(val, "broadcast")) {
2214  ival = 1;
2215  } else if (strcasecmp(val, "fd-per-timer")) {
2216  ival = 2;
2217  }
2218  }
2219  }
2221  } else if (!strcasecmp(var, "enable-clock-nanosleep")) {
2223  } else if (!strcasecmp(var, "enable-cond-yield")) {
2225  } else if (!strcasecmp(var, "enable-timer-matrix")) {
2227  } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
2228  switch_core_session_limit(atoi(val));
2229  } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) {
2230  int v = switch_true(val);
2231  if (v) {
2232  switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);
2233  } else {
2235  }
2236  } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) {
2237 #ifdef WIN32
2238  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");
2239 #else
2240  int v = switch_true(val);
2241  if (v) {
2243  } else {
2245  }
2246 #endif
2247  } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
2248  switch_core_min_idle_cpu(atof(val));
2249  } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
2250  runtime.tipping_point = atoi(val);
2251  } else if (!strcasecmp(var, "cpu-idle-smoothing-depth") && !zstr(val)) {
2252  runtime.cpu_idle_smoothing_depth = atoi(val);
2253  } else if (!strcasecmp(var, "events-use-dispatch") && !zstr(val)) {
2254  runtime.events_use_dispatch = switch_true(val);
2255  } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) {
2256  int tmp;
2257 
2258  if (!runtime.events_use_dispatch) {
2259  runtime.events_use_dispatch = 1;
2261  "Implicitly setting events-use-dispatch based on usage of this initial-event-threads parameter.\n");
2262  }
2263 
2264  tmp = atoi(val);
2265 
2266  if (tmp > runtime.cpu_count / 2) {
2267  tmp = runtime.cpu_count / 2;
2268  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n",
2269  runtime.cpu_count / 2);
2270  }
2271 
2272  if (tmp < 1) {
2273  tmp = 1;
2274  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n");
2275  }
2276 
2278 
2279  } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) {
2280  runtime.microseconds_per_tick = 1000;
2281  } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
2282  if (!strcasecmp(val, "disabled")) {
2283  runtime.timer_affinity = -1;
2284  } else {
2285  runtime.timer_affinity = atoi(val);
2286  }
2287  } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
2289  } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
2291  } else if (!strcasecmp(var, "rtp-port-usage-robustness") && switch_true(val)) {
2292  runtime.port_alloc_flags |= SPF_ROBUST_UDP;
2293  } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) {
2294  runtime.dbname = switch_core_strdup(runtime.memory_pool, val);
2295  } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {
2297  runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);
2298  } else {
2299  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n");
2300  }
2301  } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) {
2303  } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {
2304  if (!strcasecmp(val, "MSSQL")) {
2305  runtime.odbc_dbtype = DBTYPE_MSSQL;
2306  } else {
2307  runtime.odbc_dbtype = DBTYPE_DEFAULT;
2308  }
2309 #ifdef ENABLE_ZRTP
2310  } else if (!strcasecmp(var, "rtp-enable-zrtp")) {
2311  switch_core_set_variable("zrtp_enabled", val);
2312 #endif
2313  } else if (!strcasecmp(var, "switchname") && !zstr(val)) {
2314  runtime.switchname = switch_core_strdup(runtime.memory_pool, val);
2315  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname);
2316  } else if (!strcasecmp(var, "rtp-retain-crypto-keys")) {
2317  if (switch_true(val)) {
2319  "rtp-retain-crypto-keys enabled. Could be used to decrypt secure media.\n");
2320  }
2321  switch_core_set_variable("rtp_retain_crypto_keys", val);
2322  }
2323  }
2324  }
2325 
2326  if ((settings = switch_xml_child(cfg, "variables"))) {
2327  for (param = switch_xml_child(settings, "variable"); param; param = param->next) {
2328  const char *var = switch_xml_attr_soft(param, "name");
2329  const char *val = switch_xml_attr_soft(param, "value");
2330  if (var && val) {
2331  switch_core_set_variable(var, val);
2332  }
2333  }
2334  }
2335 
2336  switch_xml_free(xml);
2337  }
2338 
2339 
2340 }
2341 
2343 {
2344 
2345  return ("\n"
2346  ".=============================================================.\n"
2347  "| _____ ______ _____ _____ ____ _ _ |\n"
2348  "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n"
2349  "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n"
2350  "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n"
2351  "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n"
2352  "| |\n"
2353  ".=============================================================."
2354  "\n"
2355 
2356  "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n"
2357  "| FreeSWITCH (http://www.freeswitch.org) |\n"
2358  "| Paypal Donations Appreciated: paypal@freeswitch.org |\n"
2359  "| Brought to you by ClueCon http://www.cluecon.com/ |\n"
2360  ".=============================================================.\n"
2361  "\n");
2362 }
2363 
2364 
2366 {
2367  switch_event_t *event;
2368  char *cmd;
2369  int x = 0;
2370  const char *use = NULL;
2371 #include "cc.h"
2372 
2373 
2374  if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) {
2375  return SWITCH_STATUS_GENERR;
2376  }
2377 
2378  if (runtime.runlevel > 1) {
2379  /* one per customer */
2380  return SWITCH_STATUS_SUCCESS;
2381  }
2382 
2383  runtime.runlevel++;
2384  runtime.events_use_dispatch = 1;
2385 
2388 
2389  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
2392  *err = "Cannot load modules";
2394  return SWITCH_STATUS_GENERR;
2395  }
2396 
2398 
2399  switch_load_core_config("post_load_switch.conf");
2400 
2402 
2404  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
2405  switch_event_fire(&event);
2406  }
2407 
2408  switch_core_screen_size(&x, NULL);
2409 
2410  use = (x > 100) ? cc : cc_s;
2411 
2412 #ifdef WIN32
2414 #else
2418  switch_core_banner(),
2420 
2421 #endif
2422 
2423 
2425  "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n",
2428  switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled");
2429 
2430 
2431  if (x < 160) {
2432  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n");
2433  }
2434 
2436 
2437  if ((cmd = switch_core_get_variable_dup("api_on_startup"))) {
2438  switch_stream_handle_t stream = { 0 };
2439  SWITCH_STANDARD_STREAM(stream);
2440  switch_console_execute(cmd, 0, &stream);
2441  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data);
2442  free(stream.data);
2443  free(cmd);
2444  }
2445 
2446  return SWITCH_STATUS_SUCCESS;
2447 
2448 }
2449 
2451 {
2452  switch_time_t temp = total_ms / 1000;
2453  memset(duration, 0, sizeof(*duration));
2454  duration->mms = (uint32_t) (total_ms % 1000);
2455  duration->ms = (uint32_t) (temp % 1000);
2456  temp = temp / 1000;
2457  duration->sec = (uint32_t) (temp % 60);
2458  temp = temp / 60;
2459  duration->min = (uint32_t) (temp % 60);
2460  temp = temp / 60;
2461  duration->hr = (uint32_t) (temp % 24);
2462  temp = temp / 24;
2463  duration->day = (uint32_t) (temp % 365);
2464  duration->yr = (uint32_t) (temp / 365);
2465 }
2466 
2468 {
2469  return switch_mono_micro_time_now() - runtime.initiated;
2470 }
2471 
2472 
2473 #ifdef _MSC_VER
2474 static void win_shutdown(void)
2475 {
2476 
2477  HANDLE shutdown_event;
2478  char path[512];
2479  /* for windows we need the event to signal for shutting down a background FreeSWITCH */
2480  snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
2481 
2482  /* open the event so we can signal it */
2483  shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path);
2484 
2485  if (shutdown_event) {
2486  /* signal the event to shutdown */
2487  SetEvent(shutdown_event);
2488  /* cleanup */
2489  CloseHandle(shutdown_event);
2490  }
2491 }
2492 #endif
2493 
2495 {
2496  /* set signal handlers */
2497  signal(SIGINT, SIG_IGN);
2498 #ifdef SIGPIPE
2499  signal(SIGPIPE, SIG_IGN);
2500 #endif
2501 #ifdef SIGALRM
2502  signal(SIGALRM, SIG_IGN);
2503 #endif
2504 #ifdef SIGQUIT
2505  signal(SIGQUIT, SIG_IGN);
2506 #endif
2507 #ifdef SIGPOLL
2508  signal(SIGPOLL, SIG_IGN);
2509 #endif
2510 #ifdef SIGIO
2511  signal(SIGIO, SIG_IGN);
2512 #endif
2513 #ifdef TRAP_BUS
2514  signal(SIGBUS, handle_SIGBUS);
2515 #endif
2516 #ifdef SIGUSR1
2517  signal(SIGUSR1, handle_SIGHUP);
2518 #endif
2519  signal(SIGHUP, handle_SIGHUP);
2520 }
2521 
2523 {
2524  return runtime.debug_level;
2525 }
2526 
2527 
2529 {
2530  int *intval = (int *) val;
2531  int oldintval = 0, newintval = 0;
2532 
2533  if (intval) {
2534  oldintval = *intval;
2535  }
2536 
2537  if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
2538  return -1;
2539  }
2540 
2541  switch (cmd) {
2542  case SCSC_RECOVER:
2543  {
2544  char *arg = (char *) val;
2545  char *tech = NULL, *prof = NULL;
2546  int r, flush = 0;
2547 
2548  if (!zstr(arg)) {
2549  tech = strdup(arg);
2550 
2551  if ((prof = strchr(tech, ':'))) {
2552  *prof++ = '\0';
2553  }
2554 
2555  if (!strcasecmp(tech, "flush")) {
2556  flush++;
2557  tech = NULL;
2558 
2559  if (prof) {
2560  tech = prof;
2561  if ((prof = strchr(tech, ':'))) {
2562  *prof++ = '\0';
2563  }
2564  }
2565  }
2566 
2567  }
2568 
2569  if (flush) {
2570  switch_core_recovery_flush(tech, prof);
2571  r = -1;
2572  } else {
2573  r = switch_core_recovery_recover(tech, prof);
2574  }
2575 
2576  switch_safe_free(tech);
2577  return r;
2578 
2579  }
2580  break;
2581  case SCSC_DEBUG_SQL:
2582  {
2583  if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {
2584  switch_clear_flag((&runtime), SCF_DEBUG_SQL);
2585  newintval = 0;
2586  } else {
2587  switch_set_flag((&runtime), SCF_DEBUG_SQL);
2588  newintval = 1;
2589  }
2590  }
2591  break;
2592  case SCSC_VERBOSE_EVENTS:
2593  if (intval) {
2594  if (oldintval > -1) {
2595  if (oldintval) {
2596  switch_set_flag((&runtime), SCF_VERBOSE_EVENTS);
2597  } else {
2599  }
2600  }
2601  newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS);
2602  }
2603  break;
2604  case SCSC_API_EXPANSION:
2605  if (intval) {
2606  if (oldintval > -1) {
2607  if (oldintval) {
2608  switch_set_flag((&runtime), SCF_API_EXPANSION);
2609  } else {
2610  switch_clear_flag((&runtime), SCF_API_EXPANSION);
2611  }
2612  }
2613  newintval = switch_test_flag((&runtime), SCF_API_EXPANSION);
2614  }
2615  break;
2617  if (intval) {
2618  if (oldintval > -1) {
2619  if (oldintval) {
2621  } else {
2623  }
2624  }
2625  newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
2626  }
2627  break;
2628  case SCSC_CALIBRATE_CLOCK:
2630  break;
2631  case SCSC_FLUSH_DB_HANDLES:
2633  break;
2634  case SCSC_SEND_SIGHUP:
2635  handle_SIGHUP(1);
2636  break;
2637  case SCSC_SYNC_CLOCK:
2638  switch_time_sync();
2639  newintval = 0;
2640  break;
2642  newintval = switch_core_session_sync_clock();
2643  break;
2644  case SCSC_SQL:
2645  if (oldintval) {
2647  } else {
2649  }
2650  break;
2651  case SCSC_PAUSE_ALL:
2652  if (oldintval) {
2653  switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
2654  } else {
2656  }
2657  break;
2658  case SCSC_PAUSE_INBOUND:
2659  if (oldintval) {
2661  } else {
2663  }
2664  break;
2665  case SCSC_PAUSE_OUTBOUND:
2666  if (oldintval) {
2668  } else {
2670  }
2671  break;
2672  case SCSC_HUPALL:
2674  break;
2675  case SCSC_CANCEL_SHUTDOWN:
2677  break;
2678  case SCSC_SAVE_HISTORY:
2680  break;
2681  case SCSC_CRASH:
2682  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n");
2684  abort();
2685  break;
2686  case SCSC_SHUTDOWN_NOW:
2688  exit(0);
2689  break;
2690  case SCSC_REINCARNATE_NOW:
2692  exit(SWITCH_STATUS_RESTART);
2693  break;
2694  case SCSC_SHUTDOWN_ELEGANT:
2695  case SCSC_SHUTDOWN_ASAP:
2696  {
2697  int x = 19;
2698  uint32_t count;
2699 
2701  if (cmd == SCSC_SHUTDOWN_ASAP) {
2702  switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
2703  }
2704 
2705  while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) {
2706  switch_yield(500000);
2707  if (++x == 20) {
2709  "Shutdown in progress, %u session(s) remain.\nShutting down %s\n",
2710  count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls.");
2711  x = 0;
2712  }
2713  }
2714 
2715  if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) {
2716  switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
2717 #ifdef _MSC_VER
2718  win_shutdown();
2719 #endif
2720 
2721  if (oldintval) {
2722  switch_set_flag((&runtime), SCF_RESTART);
2724  } else {
2726 #ifdef _MSC_VER
2727  fclose(stdin);
2728 #endif
2729  }
2730  runtime.running = 0;
2731  } else {
2732  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n");
2734  }
2735  }
2736  break;
2737  case SCSC_PAUSE_CHECK:
2738  newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS);
2739  break;
2741  newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS);
2742  break;
2744  newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS);
2745  break;
2746  case SCSC_READY_CHECK:
2747  newintval = switch_core_ready();
2748  break;
2749  case SCSC_SHUTDOWN_CHECK:
2750  newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED);
2751  break;
2752  case SCSC_SHUTDOWN:
2753 
2754 #ifdef _MSC_VER
2755  win_shutdown();
2756 #endif
2757 
2758  if (oldintval) {
2759  switch_set_flag((&runtime), SCF_RESTART);
2761  } else {
2763 #ifdef _MSC_VER
2764  fclose(stdin);
2765 #endif
2766  }
2767  runtime.running = 0;
2768  break;
2769  case SCSC_CHECK_RUNNING:
2770  newintval = runtime.running;
2771  break;
2772  case SCSC_LOGLEVEL:
2773  if (oldintval > -1) {
2774  runtime.hard_log_level = oldintval;
2775  }
2776 
2777  if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
2778  runtime.hard_log_level = SWITCH_LOG_DEBUG;
2779  }
2780  newintval = runtime.hard_log_level;
2781  break;
2782  case SCSC_DEBUG_LEVEL:
2783  if (oldintval > -1) {
2784  if (oldintval > 10)
2785  newintval = 10;
2786  runtime.debug_level = oldintval;
2787  }
2788  newintval = runtime.debug_level;
2789  break;
2790  case SCSC_MIN_IDLE_CPU:
2791  {
2792  double *dval = (double *) val;
2793  if (dval) {
2794  *dval = switch_core_min_idle_cpu(*dval);
2795  }
2796  intval = NULL;
2797  }
2798  break;
2799  case SCSC_MAX_SESSIONS:
2800  newintval = switch_core_session_limit(oldintval);
2801  break;
2802  case SCSC_LAST_SPS:
2803  newintval = runtime.sps_last;
2804  break;
2805  case SCSC_SPS_PEAK:
2806  if (oldintval == -1) {
2807  runtime.sps_peak = 0;
2808  }
2809  newintval = runtime.sps_peak;
2810  break;
2811  case SCSC_SPS_PEAK_FIVEMIN:
2812  newintval = runtime.sps_peak_fivemin;
2813  break;
2814  case SCSC_SESSIONS_PEAK:
2815  newintval = runtime.sessions_peak;
2816  break;
2818  newintval = runtime.sessions_peak_fivemin;
2819  break;
2821  newintval = switch_core_max_dtmf_duration(oldintval);
2822  break;
2824  newintval = switch_core_min_dtmf_duration(oldintval);
2825  break;
2827  newintval = switch_core_default_dtmf_duration(oldintval);
2828  break;
2829  case SCSC_SPS:
2831  if (oldintval > 0) {
2832  runtime.sps_total = oldintval;
2833  }
2834  newintval = runtime.sps_total;
2836  break;
2837 
2838  case SCSC_RECLAIM:
2840  newintval = 0;
2841  break;
2842  }
2843 
2844  if (intval) {
2845  *intval = newintval;
2846  }
2847 
2848 
2849  return 0;
2850 }
2851 
2853 {
2854  return runtime.flags;
2855 }
2856 
2858 {
2859  return runtime.running ? SWITCH_TRUE : SWITCH_FALSE;
2860 }
2861 
2863 {
2865 }
2866 
2868 {
2870 }
2871 
2873 {
2875 }
2876 
2878 {
2879  switch_event_t *event;
2880 
2882  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");
2883  switch_event_fire(&event);
2884  }
2885 
2886  switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
2887  switch_set_flag((&runtime), SCF_SHUTTING_DOWN);
2888 
2889  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");
2891  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
2892 
2894 
2896 
2897  if (switch_test_flag((&runtime), SCF_USE_SQL)) {
2899  }
2901 
2903 
2904  if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
2906  }
2910 
2911  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n");
2913 
2914  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
2916 
2920 
2921  if (runtime.console && runtime.console != stdout && runtime.console != stderr) {
2922  fclose(runtime.console);
2923  runtime.console = NULL;
2924  }
2925 
2944 
2946  switch_core_hash_destroy(&runtime.ptimes);
2949 
2950  if (IP_LIST.hash) {
2951  switch_core_hash_destroy(&IP_LIST.hash);
2952  }
2953 
2954  if (IP_LIST.pool) {
2956  }
2957 
2959 
2960  if (runtime.memory_pool) {
2961  apr_pool_destroy(runtime.memory_pool);
2962  apr_terminate();
2963  }
2964 
2965  sqlite3_shutdown();
2966 
2968 }
2969 
2971 {
2972  const switch_management_interface_t *ptr;
2974 
2975  if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
2976  status = ptr->management_function(relative_oid, action, data, datalen);
2977  }
2978 
2979  return status;
2980 }
2981 
2983 {
2987 }
2988 
2989 
2991  const char *cmd;
2995  int ret;
2996  int *fds;
2997 };
2998 
3000 {
3001  struct system_thread_handle *sth = (struct system_thread_handle *) obj;
3002 
3003 #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
3004  struct rlimit rlim;
3005  struct rlimit rlim_save;
3006 
3007  memset(&rlim, 0, sizeof(rlim));
3008  getrlimit(RLIMIT_STACK, &rlim);
3009 
3010  memset(&rlim_save, 0, sizeof(rlim_save));
3011  getrlimit(RLIMIT_STACK, &rlim_save);
3012 
3013  rlim.rlim_cur = rlim.rlim_max;
3014  if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
3015  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
3016  }
3017 #endif
3018 
3019  if (sth->fds) {
3020  dup2(sth->fds[1], STDOUT_FILENO);
3021  }
3022 
3023  sth->ret = system(sth->cmd);
3024 
3025 #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
3026  if (setrlimit(RLIMIT_STACK, &rlim_save) < 0) {
3027  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
3028  }
3029 #endif
3030 
3031  switch_mutex_lock(sth->mutex);
3033  switch_mutex_unlock(sth->mutex);
3034 
3036 
3037  return NULL;
3038 }
3039 
3040 
3041 static int switch_system_thread(const char *cmd, switch_bool_t wait)
3042 {
3044  switch_threadattr_t *thd_attr;
3045  int ret = 0;
3046  struct system_thread_handle *sth;
3048 
3051  return 1;
3052  }
3053 
3054  if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) {
3056  return 1;
3057  }
3058 
3059  sth->pool = pool;
3060  sth->cmd = switch_core_strdup(pool, cmd);
3061 
3062  switch_thread_cond_create(&sth->cond, sth->pool);
3064  switch_mutex_lock(sth->mutex);
3065 
3066  switch_threadattr_create(&thd_attr, sth->pool);
3068  switch_threadattr_detach_set(thd_attr, 1);
3069  switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool);
3070 
3071  if (wait) {
3072  switch_thread_cond_wait(sth->cond, sth->mutex);
3073  ret = sth->ret;
3074  }
3075  switch_mutex_unlock(sth->mutex);
3076 
3077  return ret;
3078 }
3079 
3081 {
3082  int max = 0;
3083 
3084 #ifndef WIN32
3085 #if defined(HAVE_GETDTABLESIZE)
3086  max = getdtablesize();
3087 #else
3088  max = sysconf(_SC_OPEN_MAX);
3089 #endif
3090 #endif
3091 
3092  return max;
3093 
3094 }
3095 
3096 SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl)
3097 {
3098  int open_max = switch_max_file_desc();
3099  int i, j;
3100 
3101  for (i = 3; i < open_max; i++) {
3102  if (keep) {
3103  for (j = 0; j < keep_ttl; j++) {
3104  if (i == keep[j]) {
3105  goto skip;
3106  }
3107  }
3108  }
3109 
3110  close(i);
3111 
3112  skip:
3113 
3114  continue;
3115 
3116  }
3117 }
3118 
3119 
3120 #ifdef WIN32
3121 static int switch_system_fork(const char *cmd, switch_bool_t wait)
3122 {
3123  return switch_system_thread(cmd, wait);
3124 }
3125 
3126 SWITCH_DECLARE(pid_t) switch_fork(void)
3127 {
3128  return -1;
3129 }
3130 
3131 
3132 #else
3133 
3135 {
3136  int i = fork();
3137 
3138  if (!i) {
3139  set_low_priority();
3140  }
3141 
3142  return i;
3143 }
3144 
3145 
3146 
3147 static int switch_system_fork(const char *cmd, switch_bool_t wait)
3148 {
3149  int pid;
3150  char *dcmd = strdup(cmd);
3151 #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
3152  struct rlimit rlim;
3153  struct rlimit rlim_save;
3154 #endif
3155 
3157 
3158  pid = switch_fork();
3159 
3160  if (pid) {
3161  if (wait) {
3162  waitpid(pid, NULL, 0);
3163  }
3164  free(dcmd);
3165  } else {
3166  switch_close_extra_files(NULL, 0);
3167 
3168 #if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__)
3169  memset(&rlim, 0, sizeof(rlim));
3170  getrlimit(RLIMIT_STACK, &rlim);
3171 
3172  memset(&rlim_save, 0, sizeof(rlim_save));
3173  getrlimit(RLIMIT_STACK, &rlim_save);
3174 
3175  rlim.rlim_cur = rlim.rlim_max;
3176  if (setrlimit(RLIMIT_STACK, &rlim) < 0) {
3177  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno));
3178  }
3179 #endif
3180 
3181  if (system(dcmd) == -1) {
3182  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd);
3183  }
3184  free(dcmd);
3185  exit(0);
3186  }
3187 
3188  return 0;
3189 }
3190 #endif
3191 
3192 
3193 
3194 SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
3195 {
3196  int (*sys_p)(const char *cmd, switch_bool_t wait);
3197 
3199 
3200  return sys_p(cmd, wait);
3201 
3202 }
3203 
3204 
3205 
3207 {
3208 #ifdef WIN32
3209  return switch_system(cmd, SWITCH_TRUE);
3210 #else
3211  int fds[2], pid = 0;
3212 
3213  if (pipe(fds)) {
3214  goto end;
3215  } else { /* good to go */
3216  pid = switch_fork();
3217 
3218  if (pid < 0) { /* ok maybe not */
3219  close(fds[0]);
3220  close(fds[1]);
3221  goto end;
3222  } else if (pid) { /* parent */
3223  char buf[1024] = "";
3224  int bytes;
3225  close(fds[1]);
3226  while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {
3227  stream->raw_write_function(stream, (unsigned char *)buf, bytes);
3228  }
3229  close(fds[0]);
3230  waitpid(pid, NULL, 0);
3231  } else { /* child */
3232  switch_close_extra_files(fds, 2);
3233  close(fds[0]);
3234  dup2(fds[1], STDOUT_FILENO);
3235  switch_system(cmd, SWITCH_TRUE);
3236  close(fds[1]);
3237  exit(0);
3238  }
3239  }
3240 
3241  end:
3242 
3243  return 0;
3244 
3245 #endif
3246 
3247 }
3248 
3250 {
3251 #ifdef HAVE_SETRLIMIT
3252  struct rlimit rlp;
3253 
3254  memset(&rlp, 0, sizeof(rlp));
3255  getrlimit(RLIMIT_STACK, &rlp);
3256 
3257  *cur = rlp.rlim_cur;
3258  *max = rlp.rlim_max;
3259 
3260  return SWITCH_STATUS_SUCCESS;
3261 
3262 #else
3263 
3264  return SWITCH_STATUS_FALSE;
3265 
3266 #endif
3267 
3268 
3269 
3270 }
3271 
3272 
3274 {
3275 #ifdef WIN32
3276  stream->write_function(stream, "Capturing output not supported.\n");
3277  return switch_system(cmd, SWITCH_TRUE);
3278 #else
3279  return switch_stream_system_fork(cmd, stream);
3280 #endif
3281 
3282 }
3283 
3285 {
3286  uint16_t start_port = 0;
3287 
3288  /* By default pass rtp port range start value as zero in order to get actual
3289  * RTP port range start value as configured */
3290  start_port = (uint16_t)switch_rtp_set_start_port((switch_port_t)start_port);
3291 
3292  return start_port;
3293 }
3294 
3296 {
3297  uint16_t end_port = 0;
3298 
3299  /* By default pass rtp port range end value as zero in order to get actual
3300  * RTP port range end value as configured */
3301  end_port = (uint16_t)switch_rtp_set_end_port((switch_port_t)end_port);
3302 
3303  return end_port;
3304 }
3305 
3306 /* For Emacs:
3307  * Local Variables:
3308  * mode:c
3309  * indent-tabs-mode:t
3310  * tab-width:4
3311  * c-basic-offset:4
3312  * End:
3313  * For VIM:
3314  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3315  */
void switch_channel_global_uninit(void)
void switch_core_set_signal_handlers(void)
Definition: switch_core.c:2494
switch_memory_pool_t * switch_core_memory_init(void)
#define switch_core_permanent_strdup(_todup)
Copy a string using permanent memory allocation.
Definition: switch_core.h:705
int32_t change_user_group(const char *user, const char *group)
Change user and/or group of the running process.
Definition: switch_core.c:1070
const char * switch_core_get_switchname(void)
Definition: switch_core.c:349
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
void switch_time_sync(void)
Definition: switch_time.c:589
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
uint32_t min_dtmf_duration
char * core_db_inner_post_trans_execute
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_status_t switch_core_mime_add_type(const char *type, const char *ext)
Definition: switch_core.c:1220
const char * switch_xml_attr_soft(_In_ switch_xml_t xml, _In_z_ const char *attr)
returns the value of the requested tag attribute, or "" if not found
static void check_ip(void)
Definition: switch_core.c:109
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:350
switch_frame_t dummy_cng_frame
switch_memory_pool_t * pool
Definition: switch_core.c:1360
switch_status_t switch_xml_locate_domain(_In_z_ const char *domain_name, _In_opt_ switch_event_t *params, _Out_ switch_xml_t *root, _Out_ switch_xml_t *domain)
void switch_core_memory_reclaim_logger(void)
Definition: switch_log.c:544
switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
#define switch_test_subnet(_ip, _net, _mask)
#define SWITCH_THREAD_FUNC
void switch_core_dump_variables(switch_stream_handle_t *stream)
Definition: switch_core.c:333
switch_text_channel_t
A target to write log/debug info to.
void switch_nat_shutdown(void)
Shuts down the NAT Traversal System.
Definition: switch_nat.c:741
switch_bool_t switch_pgsql_available(void)
Definition: switch_pgsql.c:819
#define SWITCH_CHANNEL_LOG
switch_time_t initiated
switch_time_t switch_core_uptime(void)
Number of microseconds the system has been up.
Definition: switch_core.c:2467
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
#define SWITCH_IMAGES_DIR
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
#define SWITCH_RECORDINGS_DIR
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
#define switch_event_del_header(_e, _h)
Definition: switch_event.h:211
const switch_state_handler_table_t * state_handlers[SWITCH_MAX_STATE_HANDLERS]
uint32_t switch_core_sessions_per_second(_In_ uint32_t new_limit)
Set/Get Session Rate Limit.
int switch_core_test_flag(int flag)
Definition: switch_core.c:1800
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
int switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)
Definition: switch_core.c:306
const char * switch_version_full(void)
void switch_ssl_init_ssl_locks(void)
void switch_time_set_nanosleep(switch_bool_t enable)
Definition: switch_time.c:365
int32_t timer_affinity
switch_status_t switch_network_list_create(switch_network_list_t **list, const char *name, switch_bool_t default_type, switch_memory_pool_t *pool)
Definition: switch_utils.c:404
switch_status_t switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token)
Definition: switch_utils.c:552
char * core_db_post_trans_execute
#define SWITCH_CONF_DIR
int32_t set_low_priority(void)
Definition: switch_core.c:932
#define SWITCH_CACHE_DIR
switch_mutex_t * mutex
Definition: switch_core.c:2993
void switch_core_memory_stop(void)
switch_bool_t switch_core_running(void)
Definition: switch_core.c:2857
void switch_scheduler_task_thread_start(void)
Start the scheduler system.
switch_bool_t
Definition: switch_types.h:405
int switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp)
Definition: switch_utils.c:607
int switch_max_file_desc(void)
Definition: switch_core.c:3080
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
void switch_close_extra_files(int *keep, int keep_ttl)
Definition: switch_core.c:3096
int switch_core_session_sync_clock(void)
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
switch_status_t switch_core_session_read_video_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a video frame from a session.
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
const char * cc
Definition: cc.h:2
void switch_core_set_globals(void)
Initiate Globals.
Definition: switch_core.c:620
void switch_core_session_init(switch_memory_pool_t *pool)
An event Header.
Definition: switch_event.h:65
#define switch_network_list_add_cidr(_list, _cidr_str, _ok)
switch_thread_rwlock_t * global_var_rwlock
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
void switch_event_launch_dispatch_threads(uint32_t max)
Definition: switch_event.c:623
switch_management_interface_t * switch_loadable_module_get_management_interface(const char *relative_oid)
Retrieve the management interface by it's registered name.
switch_status_t switch_core_destroy(void)
Destroy the core.
Definition: switch_core.c:2877
const char * cc_s
Definition: cc.h:3
uint16_t switch_core_get_rtp_port_range_start_port()
Get RTP port range start value.
Definition: switch_core.c:3284
switch_event_t * global_vars
void switch_scheduler_task_thread_stop(void)
Stop the scheduler system.
char hostname[256]
#define SWITCH_DECLARE_DATA
uint32_t switch_default_ptime(const char *name, uint32_t number)
Definition: switch_core.c:2026
switch_bool_t switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token)
Definition: switch_utils.c:441
A representation of an XML tree.
Definition: switch_xml.h:76
switch_mutex_t * throttle_mutex
#define SWITCH_DEFAULT_DTMF_DURATION
Definition: switch_types.h:115
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
Definition: switch_apr.c:355
uint32_t switch_core_cpu_count(void)
Definition: switch_core.c:1042
#define SWITCH_MOD_DIR
const char * switch_core_mime_type2ext(const char *mime)
Definition: switch_core.c:1207
#define BUFSIZE
switch_status_t switch_console_shutdown(void)
switch_status_t switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
Definition: switch_core.c:2365
static void switch_load_core_config(const char *file)
Definition: switch_core.c:2053
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
void switch_time_set_timerfd(int enable)
Definition: switch_time.c:347
pack cur
#define SWITCH_MAX_STATE_HANDLERS
Definition: switch_types.h:559
static switch_thread_t * thread
Definition: switch_log.c:279
switch_status_t switch_core_thread_set_cpu_affinity(int cpu)
Definition: switch_core.c:1723
switch_thread_cond_t * cond
Definition: switch_core.c:2992
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_status_t switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max)
Definition: switch_core.c:3249
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
switch_port_t switch_rtp_set_start_port(switch_port_t port)
Set/Get RTP start port.
Definition: switch_rtp.c:2387
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
uint32_t switch_core_flag_t
Definition: switch_types.h:376
uint32_t microseconds_per_tick
struct switch_runtime runtime
Definition: switch_core.c:64
uint32_t switch_scheduler_add_task(time_t task_runtime, switch_scheduler_func_t func, const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
Schedule a task in the future.
struct apr_thread_cond_t switch_thread_cond_t
Definition: switch_apr.h:463
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
void switch_loadable_module_shutdown(void)
Shutdown the module backend and call the shutdown routine in all loaded modules.
int switch_stream_system(const char *cmd, switch_stream_handle_t *stream)
Definition: switch_core.c:3273
#define SWITCH_HTDOCS_DIR
uint8_t switch_byte_t
Definition: switch_types.h:246
switch_hash_index_t * switch_core_mime_index(void)
Definition: switch_core.c:1215
switch_memory_pool_t * pool
Definition: switch_core.h:223
#define zstr(x)
Definition: switch_utils.h:281
#define SWITCH_PREFIX_DIR
switch_size_t switch_core_session_id(void)
Provide the current session_id.
const switch_state_handler_table_t * switch_core_get_state_handler(int index)
Definition: switch_core.c:323
uint32_t switch_core_max_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1664
char * switch_core_get_domain(switch_bool_t dup)
Definition: switch_core.c:355
switch_bool_t switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token)
Definition: switch_utils.c:468
#define SWITCH_STORAGE_DIR
#define SWITCH_SEQ_FYELLOW
Definition: switch_types.h:94
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
void switch_core_media_deinit(void)
switch_status_t switch_event_shutdown(void)
Stop the eventing system.
Definition: switch_event.c:524
void switch_rtp_init(switch_memory_pool_t *pool)
Initilize the RTP System.
Definition: switch_rtp.c:1442
int switch_system(const char *cmd, switch_bool_t wait)
Definition: switch_core.c:3194
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:227
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_event_init(switch_memory_pool_t *pool)
Start the eventing system.
Definition: switch_event.c:664
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
uint32_t switch_core_min_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1704
switch_hash_t * hash
Definition: switch_core.c:1361
switch_hash_t * ptimes
void switch_channel_global_init(switch_memory_pool_t *pool)
int32_t set_auto_priority(void)
Definition: switch_core.c:1052
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
static int switch_system_thread(const char *cmd, switch_bool_t wait)
Definition: switch_core.c:3041
switch_dbtype_t odbc_dbtype
void switch_nat_init(switch_memory_pool_t *pool, switch_bool_t mapping)
Initilize the NAT Traversal System.
Definition: switch_nat.c:399
uint16_t switch_core_get_rtp_port_range_end_port()
Get RTP port range end value.
Definition: switch_core.c:3295
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:655
int64_t switch_time_t
Definition: switch_apr.h:188
double switch_core_idle_cpu(void)
uint32_t buflen
Definition: switch_frame.h:59
int32_t sessions_peak_fivemin
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok)
Definition: switch_utils.c:579
static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj)
Definition: switch_core.c:488
switch_byte_t switch_byte_t * buf
switch_status_t switch_core_get_variables(switch_event_t **event)
Definition: switch_core.c:374
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
switch_bool_t colorize_console
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uint32_t datalen
Definition: switch_frame.h:57
static char main_ip6[256]
Definition: switch_core.c:107
static switch_bool_t switch_string_var_check(char *s, switch_bool_t disable)
Definition: switch_utils.h:691
char * switch_core_get_uuid(void)
Retrieve the unique identifier from the core.
Definition: switch_core.c:482
switch_bool_t switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _mask)
Definition: switch_utils.c:428
switch_mutex_t * frame_read_mutex
#define SWITCH_MAX_DTMF_DURATION
Definition: switch_types.h:117
void switch_time_set_matrix(switch_bool_t enable)
Definition: switch_time.c:359
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_core_flag_t switch_core_flags(void)
return core flags
Definition: switch_core.c:2852
void switch_core_thread_session_end(switch_core_session_t *session)
Definition: switch_core.c:544
void switch_core_session_uninit(void)
switch_log_level_t switch_log_str2level(_In_z_ const char *str)
Return the level number of the specified log level name.
uint32_t v4
Definition: switch_utils.h:247
void switch_core_setrlimits(void)
Definition: switch_core.c:1314
void switch_core_session_hupall(_In_ switch_call_cause_t cause)
Hangup all sessions.
intptr_t switch_ssize_t
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
Abstract interface to a management module.
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
#define SWITCH_SYSTEM_THREAD_STACKSIZE
Definition: switch_types.h:552
switch_session_ctl_t
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
void switch_core_memory_reclaim_all(void)
Definition: switch_core.c:2982
#define SWITCH_LOG_DIR
static uint32_t d_30
Definition: switch_core.c:2051
switch_port_t switch_rtp_set_end_port(switch_port_t port)
Set/Get RTP end port.
Definition: switch_rtp.c:2401
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
int32_t set_normal_priority(void)
Set the maximum priority the process can obtain.
Definition: switch_core.c:1047
unsigned long switch_atoul(const char *nptr)
static void load_mime_types(void)
Definition: switch_core.c:1260
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
void switch_core_sqldb_resume(void)
switch_status_t switch_console_init(switch_memory_pool_t *pool)
char * switch_network_ipv4_mapped_ipv6_addr(const char *ip_str)
Definition: switch_utils.c:494
#define SWITCH_TIME_T_FMT
static switch_ip_list_t IP_LIST
Definition: switch_core.c:1364
switch_bool_t switch_odbc_available(void)
Definition: switch_odbc.c:738
switch_hash_t * mime_type_exts
static void send_heartbeat(void)
Definition: switch_core.c:67
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
void switch_core_set_variable(const char *varname, const char *value)
Definition: switch_core.c:430
uint32_t db_handle_timeout
FILE * switch_core_data_channel(switch_text_channel_t channel)
Retrieve a FILE stream of a given text channel name.
Definition: switch_core.c:263
uint16_t switch_port_t
switch_size_t switch_fp_read_dline(FILE *fd, char **buf, switch_size_t *len)
Definition: switch_utils.c:757
int switch_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.c:74
void switch_core_runtime_loop(int bg)
Run endlessly until the system is shutdown.
Definition: switch_core.c:1174
switch_mutex_t * session_hash_mutex
#define SWITCH_STANDARD_STREAM(s)
uint32_t switch_core_session_count(void)
Provide the total number of sessions.
double switch_core_min_idle_cpu(double new_limit)
void switch_nat_late_init(void)
Initilize the rest of the NAT Traversal System.
Definition: switch_nat.c:708
static void handle_SIGHUP(int sig)
Definition: switch_core.c:2012
static char main_ip4[256]
Definition: switch_core.c:106
pid_t switch_fork(void)
Definition: switch_core.c:3134
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:385
static int switch_system_fork(const char *cmd, switch_bool_t wait)
Definition: switch_core.c:3147
void * objs[SWITCH_MAX_CORE_THREAD_SESSION_OBJS]
Definition: switch_core.h:220
void switch_core_memory_reclaim_events(void)
Definition: switch_event.c:499
switch_status_t switch_xml_destroy(void)
Definition: switch_xml.c:2358
#define SWITCH_RUN_DIR
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
int32_t set_realtime_priority(void)
Definition: switch_core.c:968
switch_status_t switch_log_shutdown(void)
Shut down the logging engine.
Definition: switch_log.c:560
switch_mutex_t * global_mutex
void switch_rtp_shutdown(void)
Definition: switch_rtp.c:2348
void switch_core_sqldb_pause(void)
#define SWITCH_DB_DIR
void switch_cache_db_flush_handles(void)
switch_status_t switch_thread_cond_signal(switch_thread_cond_t *cond)
Definition: switch_apr.c:371
#define SWITCH_SOUNDS_DIR
switch_hash_t * mime_types
#define SWITCH_DEFAULT_DIR_PERMS
Definition: switch_types.h:118
uint32_t max_dtmf_duration
switch_bool_t switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)
Definition: switch_core.c:451
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1681
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1055
char * switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool)
Definition: switch_core.c:407
uint32_t switch_core_session_limit(_In_ uint32_t new_limit)
Set/Get Session Limit.
#define SWITCH_MIN_DTMF_DURATION
Definition: switch_types.h:116
void switch_time_set_monotonic(switch_bool_t enable)
Definition: switch_time.c:330
struct apr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj)
Definition: switch_core.c:2999
switch_status_t
Common return values.
char * switch_string_replace(const char *string, const char *search, const char *replace)
struct switch_event_header * next
Definition: switch_event.h:76
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
const char * switch_core_get_hostname(void)
Definition: switch_core.c:344
#define SWITCH_GRAMMAR_DIR
#define SWITCH_SCRIPT_DIR
switch_status_t switch_dir_make_recursive(const char *path, switch_fileperms_t perm, switch_memory_pool_t *pool)
Definition: switch_apr.c:528
void switch_console_save_history(void)
static void switch_core_unset_variables(void)
Definition: switch_core.c:422
void *SWITCH_THREAD_FUNC * switch_thread_start_t(switch_thread_t *, void *)
Definition: switch_apr.h:950
void switch_core_sqldb_stop(void)
switch_status_t switch_core_hash_init_case(_Out_ switch_hash_t **hash, switch_bool_t case_sensitive)
Initialize a hash table.
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
#define SWITCH_LOCALSTATE_DIR
switch_log_level_t hard_log_level
#define FALSE
void switch_time_calibrate_clock(void)
Definition: switch_time.c:207
Main Library Header.
uint32_t default_dtmf_duration
#define SWITCH_SEQ_DEFAULT_COLOR
Definition: switch_types.h:69
uint32_t tipping_point
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
switch_bool_t switch_core_ready_outbound(void)
Determines if the core is ready to place outbound calls.
Definition: switch_core.c:2872
const char * switch_core_banner(void)
Definition: switch_core.c:2342
int32_t sps_peak_fivemin
void switch_core_recovery_flush(const char *technology, const char *profile_name)
#define SWITCH_DECLARE(type)
switch_filenames SWITCH_GLOBAL_filenames
Definition: switch_core.c:61
void switch_uuid_get(switch_uuid_t *uuid)
Definition: switch_apr.c:1067
uint32_t max_db_handles
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
switch_time_t switch_mono_micro_time_now(void)
Definition: switch_time.c:315
#define switch_channel_set_flag(_c, _f)
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
switch_status_t switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
Definition: switch_core.c:1806
#define SWITCH_FONTS_DIR
SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
Definition: switch_core.c:202
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:665
void switch_time_set_use_system_time(switch_bool_t enable)
Definition: switch_time.c:341
int switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)
Definition: switch_core.c:3206
char * core_db_pre_trans_execute
uint32_t port_alloc_flags
static const char * skip(const char *in)
Definition: switch_json.c:270
void switch_time_set_cond_yield(switch_bool_t enable)
Definition: switch_time.c:372
const char * switch_core_mime_ext2type(const char *ext)
Definition: switch_core.c:1199
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
#define SWITCH_SEQ_BBLUE
Definition: switch_types.h:103
switch_bool_t switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
Definition: switch_core.c:1366
switch_status_t switch_loadable_module_init(switch_bool_t autoload)
Initilize the module backend and load all the modules.
A generic object to pass as a thread's session object to allow mutiple arguements and a pool...
Definition: switch_core.h:214
switch_mutex_t * uuid_mutex
char * switch_core_get_variable(const char *varname)
Definition: switch_core.c:383
uint32_t switch_core_debug_level(void)
Definition: switch_core.c:2522
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_thread_rwlock_create(switch_thread_rwlock_t **rwlock, switch_memory_pool_t *pool)
Definition: switch_apr.c:212
switch_memory_pool_t * memory_pool
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_log_init(_In_ switch_memory_pool_t *pool, _In_ switch_bool_t colorize)
Initilize the logging engine.
switch_status_t switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
Execute a management operation.
Definition: switch_core.c:2970
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
switch_status_t switch_console_execute(char *xcmd, int rec, switch_stream_handle_t *istream)
switch_status_t switch_find_local_ip(_Out_opt_bytecapcount_(len) char *buf, _In_ int len, _In_opt_ int *mask, _In_ int family)
find local ip of the box
uint32_t debug_level
FILE * switch_core_get_console(void)
Get the output console.
Definition: switch_core.c:230
void switch_load_network_lists(switch_bool_t reload)
Definition: switch_core.c:1436
char * switch_core_get_variable_dup(const char *varname)
Definition: switch_core.c:392
void switch_event_destroy(switch_event_t **event)
Destroy an event.
int32_t switch_core_set_process_privileges(void)
Switch on the privilege awareness for the process and request required privileges.
Definition: switch_core.c:897
void switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)
Definition: switch_core.c:560
switch_status_t(* management_function)(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
uint32_t cpu_idle_smoothing_depth
void switch_core_memory_reclaim(void)
const char * switch_version_revision_human(void)
int32_t switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
send a control message to the core
Definition: switch_core.c:2528
void switch_core_media_init(void)
char * core_db_inner_pre_trans_execute
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
void switch_curl_init(void)
Definition: switch_curl.c:51
#define switch_assert(expr)
int switch_core_recovery_recover(const char *technology, const char *profile_name)
void switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
Definition: switch_core.c:281
void switch_core_state_machine_init(switch_memory_pool_t *pool)
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1352
switch_bool_t switch_core_ready_inbound(void)
Determines if the core is ready to take inbound calls.
Definition: switch_core.c:2867
#define switch_core_hash_first(_h)
Definition: switch_core.h:1501
switch_bool_t switch_core_ready(void)
Determines if the core is ready to take calls.
Definition: switch_core.c:2862
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
void switch_console_loop(void)
A simple comand loop that reads input from the terminal.
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1]
memset(buf, 0, buflen)
#define SWITCH_DATA_DIR
void switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration)
Breakdown a number of milliseconds into various time spec.
Definition: switch_core.c:2450
switch_thread_t * switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool)
Definition: switch_core.c:588
#define SWITCH_SIZE_T_FMT
void switch_ssl_destroy_ssl_locks(void)
void switch_core_screen_size(int *x, int *y)
Definition: switch_core.c:238
switch_management_action_t
Definition: switch_types.h:449
switch_event_header_t * headers
Definition: switch_event.h:90
uint32_t switch_default_rate(const char *name, uint32_t number)
Definition: switch_core.c:2037
switch_status_t switch_xml_init(_In_ switch_memory_pool_t *pool, _Out_ const char **err)
initilize the core XML backend
void switch_core_session_launch_thread(_In_ switch_core_session_t *session, _In_ void *(*func)(switch_thread_t *, void *), _In_opt_ void *obj)
Launch a thread designed to exist within the scope of a given session.
#define SWITCH_CERTS_DIR
switch_memory_pool_t * pool
Definition: switch_core.c:2994
switch_status_t switch_core_set_console(const char *console)
Set the output console to the desired file.
Definition: switch_core.c:220
switch_status_t switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority)
Definition: switch_apr.c:665