From c1b66f650f476437c7c2008fc73fb826742b310d Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Mon, 27 Jan 2020 15:39:59 +0000 Subject: [PATCH] [core] add audio channels limit when opening files, configurable through switch.conf.xml (param "max-audio-channels"), add unit-test. --- conf/testing/autoload_configs/switch.conf.xml | 4 +- conf/vanilla/autoload_configs/switch.conf.xml | 2 + src/include/private/switch_core_pvt.h | 1 + src/include/switch_core.h | 1 + src/switch_core.c | 11 ++++++ src/switch_core_file.c | 14 +++++++ tests/unit/switch_core_file.c | 39 +++++++++++++++++++ 7 files changed, 71 insertions(+), 1 deletion(-) diff --git a/conf/testing/autoload_configs/switch.conf.xml b/conf/testing/autoload_configs/switch.conf.xml index 69783e62c5..d07c1b2d6e 100644 --- a/conf/testing/autoload_configs/switch.conf.xml +++ b/conf/testing/autoload_configs/switch.conf.xml @@ -190,7 +190,9 @@ - + + + diff --git a/conf/vanilla/autoload_configs/switch.conf.xml b/conf/vanilla/autoload_configs/switch.conf.xml index 5b3930e796..714b62c54c 100644 --- a/conf/vanilla/autoload_configs/switch.conf.xml +++ b/conf/vanilla/autoload_configs/switch.conf.xml @@ -200,6 +200,8 @@ + + diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 0f46b8471d..c3478f109e 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -314,6 +314,7 @@ struct switch_runtime { int events_use_dispatch; uint32_t port_alloc_flags; char *event_channel_key_separator; + uint32_t max_audio_channels; }; extern struct switch_runtime runtime; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 8255e13c85..cad1e0cb17 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2702,6 +2702,7 @@ SWITCH_DECLARE(const char *) switch_core_banner(void); SWITCH_DECLARE(switch_bool_t) switch_core_session_in_thread(switch_core_session_t *session); SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number); SWITCH_DECLARE(uint32_t) switch_default_rate(const char *name, uint32_t number); +SWITCH_DECLARE(uint32_t) switch_core_max_audio_channels(uint32_t limit); /*! \brief Add user registration diff --git a/src/switch_core.c b/src/switch_core.c index d3150835c0..e7d478d2b8 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2383,6 +2383,8 @@ static void switch_load_core_config(const char *file) } else { switch_clear_flag((&runtime), SCF_EVENT_CHANNEL_LOG_UNDELIVERABLE_JSON); } + } else if (!strcasecmp(var, "max-audio-channels") && !zstr(val)) { + switch_core_max_audio_channels(atoi(val)); } } } @@ -2638,6 +2640,15 @@ SWITCH_DECLARE(int32_t) switch_core_sessions_peak_fivemin(void) return runtime.sessions_peak_fivemin; } +SWITCH_DECLARE(uint32_t) switch_core_max_audio_channels(uint32_t limit) +{ + if (limit) { + runtime.max_audio_channels = limit; + } + + return runtime.max_audio_channels; +} + SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val) { int *intval = (int *) val; diff --git a/src/switch_core_file.c b/src/switch_core_file.c index fb6f453a43..2ef1523d0c 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -76,6 +76,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, char *fp = NULL; int to = 0; int force_channels = 0; + uint32_t core_channel_limit; if (switch_test_flag(fh, SWITCH_FILE_OPEN)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle already open\n"); @@ -361,6 +362,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, goto fail; } + if (fh->channels > 2) { + /* just show a warning for more than 2 channels, no matter if we allow them or not */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File [%s] has more than 2 channels: [%u]\n", file_path, fh->channels); + } + + core_channel_limit = switch_core_max_audio_channels(0); + if (core_channel_limit && fh->channels > core_channel_limit) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File [%s] has more channels (%u) than limit (%u). Closing.\n", file_path, fh->channels, core_channel_limit); + fh->file_interface->file_close(fh); + UNPROTECT_INTERFACE(fh->file_interface); + switch_goto_status(SWITCH_STATUS_FALSE, fail); + } + if (!force_channels && !fh->real_channels) { fh->real_channels = fh->channels; diff --git a/tests/unit/switch_core_file.c b/tests/unit/switch_core_file.c index 3515e6787d..c6aa74a24e 100644 --- a/tests/unit/switch_core_file.c +++ b/tests/unit/switch_core_file.c @@ -185,6 +185,45 @@ FST_CORE_BEGIN("./conf") } FST_TEST_END() + FST_TEST_BEGIN(test_switch_core_file_open_max_audio_channels) + { + switch_file_handle_t fh = { 0 }; + switch_status_t status = SWITCH_STATUS_FALSE; + static char filename[] = "/tmp/fs_unit_test.wav"; + static char hdr[] = /*simplest wav file, hardcoded 8 channels*/ + "\x52\x49\x46\x46" + "\x24\x00\x00\x00" + "\x57\x41\x56\x45" + "\x66\x6d\x74\x20" + "\x10\x00\x00\x00" + "\x01\x00\x08\x00" + "\x44\xac\x00\x00" + "\x88\x58\x01\x00" + "\x02\x00\x10\x00" + "\x64\x61\x74\x61" + "\x00\x00"; + FILE *f = NULL; + + f = fopen(filename, "w"); + fst_check(f != NULL); + fwrite(hdr, 1, sizeof(hdr) ,f); + fclose(f); + + switch_core_max_audio_channels(6); + status = switch_core_file_open(&fh, filename, 1, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL); + fst_check(status == SWITCH_STATUS_FALSE); + + switch_core_max_audio_channels(8); + status = switch_core_file_open(&fh, filename, 1, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL); + fst_check(status == SWITCH_STATUS_SUCCESS); + + status = switch_core_file_close(&fh); + fst_check(status == SWITCH_STATUS_SUCCESS); + + unlink(filename); + } + FST_TEST_END() + } FST_SUITE_END() }