From 4734904d2d42b29fac5dee8c10a6871abd96d613 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Wed, 10 Mar 2021 15:43:45 +0200 Subject: [PATCH 01/65] [mod_amr] introduce new cfg setting force-oa to change between OA/BE when originating, show session in debug logs, update configs. --- conf/testing/autoload_configs/amrwb.conf.xml | 22 +++++++++++++++++ conf/vanilla/autoload_configs/amr.conf.xml | 2 ++ conf/vanilla/autoload_configs/amrwb.conf.xml | 23 ++++++++++++++---- src/mod/codecs/mod_amr/mod_amr.c | 25 +++++++++++++------- 4 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 conf/testing/autoload_configs/amrwb.conf.xml diff --git a/conf/testing/autoload_configs/amrwb.conf.xml b/conf/testing/autoload_configs/amrwb.conf.xml new file mode 100644 index 0000000000..0bd8e6b733 --- /dev/null +++ b/conf/testing/autoload_configs/amrwb.conf.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/conf/vanilla/autoload_configs/amr.conf.xml b/conf/vanilla/autoload_configs/amr.conf.xml index e1c3e3cc1b..19b8cb8891 100644 --- a/conf/vanilla/autoload_configs/amr.conf.xml +++ b/conf/vanilla/autoload_configs/amr.conf.xml @@ -15,5 +15,7 @@ + + diff --git a/conf/vanilla/autoload_configs/amrwb.conf.xml b/conf/vanilla/autoload_configs/amrwb.conf.xml index 9dac3505a4..0bd8e6b733 100644 --- a/conf/vanilla/autoload_configs/amrwb.conf.xml +++ b/conf/vanilla/autoload_configs/amrwb.conf.xml @@ -1,7 +1,22 @@ - - - - + + + + + + + + + diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index 04717ca52c..e7c45c7aff 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -137,6 +137,7 @@ static struct { switch_byte_t volte; /* enable special fmtp for VoLTE compliance */ switch_byte_t adjust_bitrate; int debug; + switch_byte_t force_oa; /*force OA when originating*/ } globals; const int switch_amr_frame_sizes[] = {12,13,15,17,19,20,26,31,5,0,0,0,0,0,0,1}; @@ -179,7 +180,7 @@ static switch_bool_t switch_amr_pack_oa(unsigned char *shift_buf, int n) return SWITCH_TRUE; } -static switch_bool_t switch_amr_info(unsigned char *encoded_buf, int encoded_data_len, int payload_format, char *print_text) +static switch_bool_t switch_amr_info(switch_codec_t *codec, unsigned char *encoded_buf, int encoded_data_len, int payload_format, char *print_text) { uint8_t *tocs; int framesz, index, not_last_frame, q, ft; @@ -196,7 +197,7 @@ static switch_bool_t switch_amr_info(unsigned char *encoded_buf, int encoded_dat tocs = encoded_buf; index = (tocs[0] >> 3) & 0x0f; if (index > SWITCH_AMR_MODES && index != 0xf) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMR decoder (OA): Invalid Table Of Contents (TOC): 0x%x\n", index); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "AMR decoder (OA): Invalid Table Of Contents (TOC): 0x%x\n", index); return SWITCH_FALSE; } framesz = switch_amr_frame_sizes[index]; @@ -216,15 +217,15 @@ static switch_bool_t switch_amr_info(unsigned char *encoded_buf, int encoded_dat ft &= ~(1 << 5); /* Frame Type */ index = (shift_tocs[0] >> 3) & 0x0f; if (index > SWITCH_AMR_MODES && index != 0xf) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMR decoder (BE): Invalid Table Of Contents (TOC): 0x%x\n", index); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "AMR decoder (BE): Invalid Table Of Contents (TOC): 0x%x\n", index); return SWITCH_FALSE; } framesz = switch_amr_frame_sizes[index]; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s): FT: [0x%x] Q: [0x%x] Frame flag: [%d]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "%s (%s): FT: [0x%x] Q: [0x%x] Frame flag: [%d]\n", print_text, payload_format ? "OA":"BE", ft, q, not_last_frame); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s): AMR encoded voice payload sz: [%d] : | encoded_data_len: [%d]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "%s (%s): AMR encoded voice payload sz: [%d] : | encoded_data_len: [%d]\n", print_text, payload_format ? "OA":"BE", framesz, encoded_data_len); return SWITCH_TRUE; @@ -276,8 +277,11 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ * bandwidth-efficient operation is employed." * */ - switch_clear_flag(context, AMR_OPT_OCTET_ALIGN); - + if (!globals.force_oa) { + switch_clear_flag(context, AMR_OPT_OCTET_ALIGN); + } else { + switch_set_flag(context, AMR_OPT_OCTET_ALIGN); + } if (codec->fmtp_in) { argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); for (x = 0; x < argc; x++) { @@ -452,7 +456,7 @@ static switch_status_t switch_amr_encode(switch_codec_t *codec, } if (globals.debug) { - switch_amr_info(shift_buf, *encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR encoder"); + switch_amr_info(codec, shift_buf, *encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR encoder"); } return SWITCH_STATUS_SUCCESS; @@ -479,7 +483,7 @@ static switch_status_t switch_amr_decode(switch_codec_t *codec, } if (globals.debug) { - switch_amr_info(buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder"); + switch_amr_info(codec, buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder"); } if (switch_test_flag(context, AMR_OPT_OCTET_ALIGN)) { @@ -643,6 +647,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load) if (!strcasecmp(var, "adjust-bitrate")) { globals.adjust_bitrate = (switch_byte_t) atoi(val); } + if (!strcasecmp(var, "force-oa")) { + globals.force_oa = (switch_byte_t) atoi(val); + } } } } From b775c1f91a94d101e47a528db879ecb3007cf6c1 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Tue, 16 Mar 2021 14:45:12 +0000 Subject: [PATCH 03/65] [mod_enum] fix mem leak - ldns_resolver_new() - vanilla cfg. --- src/mod/applications/mod_enum/mod_enum.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index f6ca99abce..de5804e1fd 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -496,6 +496,9 @@ switch_status_t ldns_lookup(const char *number, const char *root, char *server_n if (!added_server) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No Nameservers specified, using host default\n"); /* create a new resolver from /etc/resolv.conf */ + if (res) { + ldns_resolver_free(res); + } s = ldns_resolver_new_frm_file(&res, NULL); } From e8fa2d37b2db06a4f80ddc38758db88c8efe3b7e Mon Sep 17 00:00:00 2001 From: surendrasignalwire <56929670+surendrasignalwire@users.noreply.github.com> Date: Tue, 29 Oct 2019 23:36:59 +0530 Subject: [PATCH 04/65] [Core] execute_on_audio_change on codec change --- src/switch_core_media.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 1449724782..0ae007ad90 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3860,8 +3860,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ end: if (resetting) { - switch_core_session_unlock_codec_write(session); - switch_core_session_unlock_codec_read(session); + switch_channel_execute_on(session->channel, "execute_on_audio_change"); + switch_core_session_unlock_codec_write(session); + switch_core_session_unlock_codec_read(session); } return status; From 16ee826e2b8172345aff12ac0c651c46791b5f67 Mon Sep 17 00:00:00 2001 From: surendrasignalwire <56929670+surendrasignalwire@users.noreply.github.com> Date: Sat, 21 Dec 2019 03:36:57 +0530 Subject: [PATCH 05/65] [mod_sofia] Url encode the sip_to_user before using in 200 ok contact --- src/mod/endpoints/mod_sofia/sofia.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7d8b2fe6eb..32ed268b7e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -10891,9 +10891,10 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia if (switch_channel_get_variable(channel, "sip_to_uri")) { const char *ipv6; const char *tmp, *at, *url = NULL; - + const char *tmp_user = switch_channel_get_variable(channel, "sip_to_user"); + + user = switch_core_session_url_encode(session, tmp_user); host = switch_channel_get_variable(channel, "sip_to_host"); - user = switch_channel_get_variable(channel, "sip_to_user"); switch_channel_set_variable(channel, "sip_to_comment", sip->sip_to->a_comment); From 21a536e774cfb389505831a8cfca72ec0e50564f Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 12 Mar 2020 22:01:56 +0800 Subject: [PATCH 06/65] [mod_video_filter] Disable waiting video ready which blocks the channel 10 seconds in early media --- src/mod/applications/mod_video_filter/mod_video_filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_video_filter/mod_video_filter.c b/src/mod/applications/mod_video_filter/mod_video_filter.c index 3cd8c84ce9..613f8d9195 100644 --- a/src/mod/applications/mod_video_filter/mod_video_filter.c +++ b/src/mod/applications/mod_video_filter/mod_video_filter.c @@ -970,7 +970,7 @@ SWITCH_STANDARD_APP(video_replace_start_function) return; } - switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL); + // switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL); context = (video_replace_context_t *) switch_core_session_alloc(session, sizeof(*context)); switch_assert(context != NULL); From 3c5773719e1908a5a31102dd1001318225b9e447 Mon Sep 17 00:00:00 2001 From: phonecomwire <62449660+phonecomwire@users.noreply.github.com> Date: Fri, 24 Apr 2020 15:10:41 -0700 Subject: [PATCH 07/65] [Core] Adding fix for switch_ivr_originate to not copy group_confirm variables to the channel --- src/switch_ivr_originate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 2ae0919519..99370d7e79 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -830,6 +830,12 @@ static uint8_t check_channel_status(originate_global_t *oglobals, uint32_t len, } } else if (switch_channel_test_flag(oglobals->originate_status[i].peer_channel, CF_WINNER)) { + /* unset group_confirm variables */ + switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_key", NULL); + switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_file", NULL); + switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_error_file", NULL); + switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_cancel_timeout", NULL); + switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_read_timeout", NULL); oglobals->idx = i; rval = 0; pindex = (uint32_t) i; From 9875e190aad74e47929703b1f9ceef144c7cd7c8 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Wed, 15 Apr 2020 10:36:32 +0800 Subject: [PATCH 08/65] [mod_av] enable resampler when sample rate mismatch (#153) --- src/mod/applications/mod_av/avformat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index ae7d2e840c..0b3a452325 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -702,7 +702,7 @@ GCC_DIAG_ON(deprecated-declarations) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "sample_rate: %d nb_samples: %d\n", mst->frame->sample_rate, mst->frame->nb_samples); - if (c->sample_fmt != AV_SAMPLE_FMT_S16) { + if (c->sample_fmt != AV_SAMPLE_FMT_S16 || c->sample_rate != mst->sample_rate) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "sample_fmt %d != AV_SAMPLE_FMT_S16, start resampler\n", c->sample_fmt); mst->resample_ctx = swr_alloc(); @@ -1231,7 +1231,7 @@ GCC_DIAG_ON(deprecated-declarations) context->audio_st[1].sample_rate = handle->samplerate; GCC_DIAG_OFF(deprecated-declarations) - if (context->audio_st[0].st->codec->sample_fmt != AV_SAMPLE_FMT_S16) { + if (context->audio_st[0].st->codec->sample_fmt != AV_SAMPLE_FMT_S16 || context->audio_st[0].st->codec->sample_rate != handle->samplerate) { GCC_DIAG_ON(deprecated-declarations) int x; for (x = 0; x < context->has_audio && x < 2 && c[x]; x++) { From 561a31d72374d81a7ce35701fb483334c8826fca Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 25 Apr 2020 04:47:45 +0800 Subject: [PATCH 09/65] [mod_sndfile] fix read sndfiles with float data --- src/mod/formats/mod_sndfile/mod_sndfile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index 5d2962a8c4..0977a4950b 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -309,6 +309,12 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha sf_command(context->handle, SFC_FILE_TRUNCATE, &frames, sizeof(frames)); } + /* + http://www.mega-nerd.com/libsndfile/api.html#note2 + */ + if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) { + sf_command(context->handle, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE); + } end: From b774c5e23f99c419c4421629f93a29710563d5fe Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Tue, 28 Apr 2020 17:46:15 +0100 Subject: [PATCH 10/65] [core] eavesdrop: reduce lock contention, fix error condition + enable eavesdrop stereo --- src/include/switch_types.h | 3 ++- src/switch_ivr_async.c | 33 +++++++++++++++++++++------------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 133422764b..2037889c01 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -353,7 +353,8 @@ typedef enum { ED_BRIDGE_READ = (1 << 4), ED_BRIDGE_WRITE = (1 << 5), ED_TAP_READ = (1 << 6), - ED_TAP_WRITE = (1 << 7) + ED_TAP_WRITE = (1 << 7), + ED_STEREO = (1 << 8) } switch_eavesdrop_flag_enum_t; typedef uint32_t switch_eavesdrop_flag_t; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 705142228c..cc5ec0581a 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2209,9 +2209,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session char cid_buf[1024] = ""; switch_caller_profile_t *cp = NULL; uint32_t sanity = 600; - switch_media_bug_flag_t read_flags = 0, write_flags = 0; + switch_media_bug_flag_t read_flags = 0, write_flags = 0, stereo_flag = 0; const char *vval; int buf_size = 0; + int channels; if (!switch_channel_media_up(channel)) { goto end; @@ -2280,8 +2281,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session ep = switch_core_session_alloc(session, sizeof(*ep)); - tlen = tread_impl.decoded_bytes_per_packet; - if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { goto end; @@ -2355,7 +2354,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session write_flags = SMBF_TAP_NATIVE_WRITE; read_flags = 0; } - + + if (flags & ED_STEREO) { + stereo_flag = SMBF_STEREO; + } if (switch_channel_test_flag(session->channel, CF_VIDEO) && switch_channel_test_flag(tsession->channel, CF_VIDEO)) { if ((vval = switch_channel_get_variable(session->channel, "eavesdrop_show_listener_video"))) { @@ -2384,7 +2386,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session if (switch_core_media_bug_add(tsession, "eavesdrop", uuid, eavesdrop_callback, ep, 0, - read_flags | write_flags | SMBF_READ_PING | SMBF_THREAD_LOCK | SMBF_NO_PAUSE, + read_flags | write_flags | SMBF_READ_PING | SMBF_THREAD_LOCK | SMBF_NO_PAUSE | stereo_flag, &bug) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n"); goto end; @@ -2561,18 +2563,27 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session switch_buffer_unlock(ep->w_buffer); } + channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : tread_impl.number_of_channels; + + if (channels == 0) { + channels = 1; + } + + tlen = tread_impl.decoded_bytes_per_packet * channels; + if (len > tlen) { len = tlen; } - if (ep->buffer && switch_buffer_inuse(ep->buffer) >= len) { - switch_buffer_lock(ep->buffer); + if (ep->buffer) { while (switch_buffer_inuse(ep->buffer) >= len) { int tchanged = 0, changed = 0; + switch_buffer_lock(ep->buffer); write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len); - write_frame.samples = write_frame.datalen / 2; - + switch_buffer_unlock(ep->buffer); + write_frame.samples = write_frame.datalen / 2 / channels; + write_frame.channels = channels; switch_core_session_get_read_impl(tsession, &tread_impl); switch_core_session_get_read_impl(session, &read_impl); @@ -2606,7 +2617,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session tread_impl.actual_samples_per_second, tread_impl.number_of_channels); - tlen = tread_impl.decoded_bytes_per_packet; + tlen = tread_impl.decoded_bytes_per_packet * channels; if (len > tlen) { len = tlen; @@ -2624,7 +2635,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); - switch_core_session_rwunlock(tsession); goto end; } } @@ -2646,7 +2656,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session break; } } - switch_buffer_unlock(ep->buffer); } } From bb6ec01d1e377572c5cc343bcf54678aec984548 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Tue, 12 May 2020 01:33:14 +0800 Subject: [PATCH 11/65] [mod_sofia] fix session log --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index e236b09a38..8ce1996ccb 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -5070,7 +5070,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (gateway_ptr && gateway_ptr->ob_vars) { switch_event_header_t *hp; for (hp = gateway_ptr->ob_vars->headers; hp; hp = hp->next) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n", switch_channel_get_name(nchannel), hp->name, hp->value); if (!strncmp(hp->name, "p:", 2)) { switch_channel_set_profile_var(nchannel, hp->name + 2, hp->value); From 09d4ec64338a32463577e8d7c48bf77cb0159418 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 19 May 2020 02:48:02 +0400 Subject: [PATCH 12/65] [Core] Fix multiple missing session unlocks in switch_core_media.c --- src/switch_core_media.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 0ae007ad90..d69e1286f5 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6791,6 +6791,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void } if (!(smh = session->media_handle)) { + switch_core_session_rwunlock(session); return NULL; } @@ -7301,12 +7302,14 @@ static void *SWITCH_THREAD_FUNC text_helper_thread(switch_thread_t *thread, void return NULL; } - mh->ready = 1; - if (!(smh = session->media_handle)) { + switch_core_session_rwunlock(session); + mh->ready = -1; return NULL; } + mh->ready = 1; + channel = switch_core_session_get_channel(session); if (switch_channel_var_true(session->channel, "fire_text_events")) { @@ -7460,12 +7463,14 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi return NULL; } - mh->ready = 1; - if (!(smh = session->media_handle)) { + switch_core_session_rwunlock(session); + mh->ready = -1; return NULL; } + mh->ready = 1; + channel = switch_core_session_get_channel(session); switch_core_autobind_cpu(); From a931220af6969edc0c9fda81e44efcf2867691b4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 19 May 2020 19:55:36 +0400 Subject: [PATCH 13/65] [Core] Fix wrong switch_assert expressions in switch_core_session_write_frame() --- src/switch_core_media.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d69e1286f5..810306a91d 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -16018,7 +16018,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->write_codec->cur_frame = frame; frame->codec->cur_frame = frame; switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); - switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); + switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, @@ -16026,7 +16026,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->write_impl.actual_samples_per_second, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); - switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); + switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); session->write_codec->cur_frame = NULL; frame->codec->cur_frame = NULL; @@ -16128,7 +16128,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->write_codec->cur_frame = frame; frame->codec->cur_frame = frame; switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); - switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); + switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, @@ -16136,7 +16136,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess rate, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); - switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); + switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE); session->write_codec->cur_frame = NULL; frame->codec->cur_frame = NULL; From 2dfda2f40947bb5c682e64f2756e774c4a7245f7 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 19 May 2020 20:29:25 +0400 Subject: [PATCH 14/65] [Core] Fix reference counter lock order when protect/unprotect interface. --- src/include/switch_module_interfaces.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index d49f7f3eb6..d347b1c7fb 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -854,8 +854,8 @@ struct switch_json_api_interface { struct switch_json_api_interface *next; }; -#define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); -#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); +#define PROTECT_INTERFACE(_it) if (_it) {switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); switch_mutex_lock(_it->reflock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); +#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); #include "switch_frame.h" From 7e2c9393dcdbf1620c39650cce6e0d21a7c1bf44 Mon Sep 17 00:00:00 2001 From: surendrasignalwire Date: Wed, 10 Jun 2020 20:09:01 +0400 Subject: [PATCH 15/65] [core] Fix ODBC column size performance issue --- src/switch_odbc.c | 57 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/switch_odbc.c b/src/switch_odbc.c index 31161ee158..9ea062d997 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -605,17 +605,66 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c for (x = 1; x <= c; x++) { SQLSMALLINT NameLength = 0, DataType = 0, DecimalDigits = 0, Nullable = 0; SQLULEN ColumnSize = 0; + SQLLEN numRecs = 0; + SQLCHAR SqlState[6], Msg[SQL_MAX_MESSAGE_LENGTH]; + SQLINTEGER NativeError; + SQLSMALLINT diagCount, MsgLen; names[y] = malloc(name_len); switch_assert(names[y]); memset(names[y], 0, name_len); SQLDescribeCol(stmt, x, (SQLCHAR *) names[y], (SQLSMALLINT) name_len, &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable); - if (!ColumnSize) { + if (ColumnSize <= 16383 || ColumnSize == 2147483647) { SQLCHAR val[16384] = { 0 }; + SQLLEN StrLen_or_IndPtr; + SQLRETURN rc; ColumnSize = 16384; - SQLGetData(stmt, x, SQL_C_CHAR, val, ColumnSize, NULL); - vals[y] = strdup((char *)val); + + /* check diag record and see if we can get real size + * https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/using-sqlgetdiagrec-and-sqlgetdiagfield?view=sql-server-ver15 + * szSqlState = "01004" and StrLen_or_IndPtr=15794 + */ + rc = SQLGetData(stmt, x, SQL_C_CHAR, val, ColumnSize, &StrLen_or_IndPtr); + + if (rc == SQL_SUCCESS_WITH_INFO) { + int truncated = 0; + diagCount = 1; + + SQLGetDiagField(SQL_HANDLE_STMT, stmt, 0, SQL_DIAG_NUMBER, &numRecs, 0, 0); + + while (diagCount <= numRecs) { + SQLGetDiagRec(SQL_HANDLE_STMT, stmt, diagCount, SqlState, &NativeError,Msg, sizeof(Msg), &MsgLen); + if (!strcmp((char*)SqlState,"01004")){ + truncated = 1; + break; + } + + diagCount++; + } + + if (truncated) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql data truncated - %s\n",SqlState); + if (StrLen_or_IndPtr && StrLen_or_IndPtr <= 268435456) { + ColumnSize = StrLen_or_IndPtr + 1; + vals[y] = malloc(ColumnSize); + switch_assert(vals[y]); + memset(vals[y], 0, ColumnSize); + SQLGetData(stmt, x, SQL_C_CHAR, (SQLCHAR *) vals[y], ColumnSize, NULL); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed"); + vals[y] = NULL; + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed"); + vals[y] = NULL; + } + } else if (rc == SQL_SUCCESS){ + vals[y] = strdup((char *)val); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed"); + vals[y] = NULL; + } } else { ColumnSize++; @@ -633,7 +682,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c for (x = 0; x < y; x++) { free(names[x]); - free(vals[x]); + switch_safe_free(vals[x]); } free(names); free(vals); From b5459fb5f558d79c7b87ac9d43f12d6eed3aceba Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 13 Jun 2020 06:53:25 +0800 Subject: [PATCH 16/65] [mod_av] remove extra space --- src/mod/applications/mod_av/avcodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index f1a58cb7d7..01c862cf11 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -110,7 +110,7 @@ static void dump_encoder_ctx(AVCodecContext *ctx) #ifdef DUMP_ENCODER_CTX #define STRINGIFY(x) #x #define my_dump_int(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %d\n", ctx->x); -#define my_dump_int64(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = % " SWITCH_INT64_T_FMT "\n", ctx->x); +#define my_dump_int64(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %" SWITCH_INT64_T_FMT "\n", ctx->x); #define my_dump_float(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %f\n", ctx->x); #define my_dump_enum(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %d\n", ctx->x); #define my_dump_uint(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = 0x%x\n", ctx->x); From 034a7eea5edeb313f40ce10ac84fcd8570115776 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 17 Jun 2020 18:52:20 +0400 Subject: [PATCH 17/65] [mod_pgsql] Fix potential hang when calling PQconsumeInput() while checking if db_is_up(). --- src/mod/databases/mod_pgsql/mod_pgsql.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/mod/databases/mod_pgsql/mod_pgsql.c b/src/mod/databases/mod_pgsql/mod_pgsql.c index a534594548..b94b1abc73 100644 --- a/src/mod/databases/mod_pgsql/mod_pgsql.c +++ b/src/mod/databases/mod_pgsql/mod_pgsql.c @@ -113,6 +113,7 @@ static int db_is_up(switch_pgsql_handle_t *handle) int max_tries = DEFAULT_PGSQL_RETRIES; int code = 0; int recon = 0; + switch_byte_t sanity = 255; if (handle) { max_tries = handle->num_retries; @@ -132,10 +133,24 @@ top: } /* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */ - PQconsumeInput(handle->con); + while (--sanity > 0) + { + if (PQisBusy(handle->con)) { + PQconsumeInput(handle->con); + switch_yield(1); + continue; + } + break; + } + + if (!sanity) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Can not check DB Connection status: sanity = 0. Reconnecting...\n"); + goto reset; + } if (PQstatus(handle->con) == CONNECTION_BAD) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n"); +reset: handle->state = SWITCH_PGSQL_STATE_ERROR; PQreset(handle->con); if (PQstatus(handle->con) == CONNECTION_BAD) { @@ -486,15 +501,13 @@ error: err_str = pgsql_handle_get_error(handle); if (zstr(err_str)) { - if (zstr(er)) { + if (!er) { err_str = strdup((char *)"SQL ERROR!"); } else { err_str = er; } } else { - if (!zstr(er)) { - free(er); - } + switch_safe_free(er); } if (err_str) { From cffc29927b45d4c36490d4e1b42f4df0761f439a Mon Sep 17 00:00:00 2001 From: surendrasignalwire <56929670+surendrasignalwire@users.noreply.github.com> Date: Fri, 10 Jul 2020 02:56:42 +0530 Subject: [PATCH 18/65] [Core] Fix crash while writing text_frame in conference --- src/switch_core_media.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 810306a91d..674c5b92f9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -15502,6 +15502,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_text_frame(switch_core t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT]; + if (!t_engine || !t_engine->tf) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text engine not available for processing\n"); + switch_goto_status(SWITCH_STATUS_BREAK, done); + } + if (!is_msrp && switch_channel_test_cap(session->channel, CC_RTP_RTT)) { if (frame) { From 23321373edfb5c568d5e604008ab5e3cbd43e5c1 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 7 Jul 2020 18:00:35 +0400 Subject: [PATCH 19/65] [Core] Fix double close of a socket in switch_rtp --- src/switch_rtp.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index e7aafd0482..e2e6dedc2d 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2991,7 +2991,7 @@ static void ping_socket(switch_rtp_t *rtp_session) switch_size_t len = sizeof(o); switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) &o, &len); - if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && rtp_session->rtcp_sock_input) { + if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_input != rtp_session->sock_input) { switch_socket_sendto(rtp_session->rtcp_sock_input, rtp_session->rtcp_local_addr, 0, (void *) &o, &len); } } @@ -5077,11 +5077,11 @@ SWITCH_DECLARE(void) switch_rtp_kill_socket(switch_rtp_t *rtp_session) } if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { - if (rtp_session->rtcp_sock_input) { + if (rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_input != rtp_session->sock_input) { ping_socket(rtp_session); switch_socket_shutdown(rtp_session->rtcp_sock_input, SWITCH_SHUTDOWN_READWRITE); } - if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { + if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { switch_socket_shutdown(rtp_session->rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE); } } @@ -5197,6 +5197,13 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session) free_dtls(&(*rtp_session)->rtcp_dtls); } + if ((*rtp_session)->rtcp_sock_input == (*rtp_session)->sock_input) { + (*rtp_session)->rtcp_sock_input = NULL; + } + + if ((*rtp_session)->rtcp_sock_output == (*rtp_session)->sock_output) { + (*rtp_session)->rtcp_sock_output = NULL; + } sock = (*rtp_session)->sock_input; (*rtp_session)->sock_input = NULL; @@ -5211,13 +5218,12 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session) if ((sock = (*rtp_session)->rtcp_sock_input)) { (*rtp_session)->rtcp_sock_input = NULL; switch_socket_close(sock); + } - if ((*rtp_session)->rtcp_sock_output && (*rtp_session)->rtcp_sock_output != sock) { - if ((sock = (*rtp_session)->rtcp_sock_output)) { - (*rtp_session)->rtcp_sock_output = NULL; - switch_socket_close(sock); - } - } + if ((*rtp_session)->rtcp_sock_output && (*rtp_session)->rtcp_sock_output != sock) { + sock = (*rtp_session)->rtcp_sock_output; + (*rtp_session)->rtcp_sock_output = NULL; + switch_socket_close(sock); } #ifdef ENABLE_SRTP From 167ab110064f45f9a52458b2300129d6f30e773a Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 17 Jul 2020 20:38:15 +0400 Subject: [PATCH 20/65] [mod_sofia] Fix potential leak of uuid in sofia_event_callback(). --- src/mod/endpoints/mod_sofia/sofia.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 32ed268b7e..7f7b0c2b75 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2435,11 +2435,16 @@ void sofia_event_callback(nua_event_t event, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid); if (!zstr(tech_pvt->call_id)) { + char *uuid = strdup(switch_core_session_get_uuid(session)); tech_pvt->sofia_private = NULL; tech_pvt->nh = NULL; sofia_set_flag(tech_pvt, TFLAG_BYE); switch_mutex_lock(profile->flag_mutex); - switch_core_hash_insert_auto_free(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session))); + + if (switch_core_hash_insert_auto_free(profile->chat_hash, tech_pvt->call_id, uuid) != SWITCH_STATUS_SUCCESS) { + switch_safe_free(uuid); + } + switch_mutex_unlock(profile->flag_mutex); nua_handle_destroy(nh); } else { From b220a05010679ca4760c32ec05bb4a601fc9831c Mon Sep 17 00:00:00 2001 From: surendrasignalwire <56929670+surendrasignalwire@users.noreply.github.com> Date: Thu, 23 Jul 2020 03:00:31 +0530 Subject: [PATCH 21/65] [Core] Fixed issue while setting mode on reinvite or outbound direction --- src/switch_core_media.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 674c5b92f9..4778edbf8c 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4815,11 +4815,7 @@ static void switch_core_media_set_rmode(switch_core_session_t *session, switch_m if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - if (!switch_channel_media_up(session->channel) && sdp_type == SDP_TYPE_REQUEST) { - engine->rmode = switch_core_session_remote_media_flow(other_session, type); - - media_flow_get_mode(engine->rmode, &rmode_str, &opp_rmode); - } else if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { + if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { switch_core_media_set_smode(other_session, type, rmode, sdp_type); } From f09ed875b95823e7a52c155e2152d9becb83f27f Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 24 Jul 2020 22:42:49 +0400 Subject: [PATCH 22/65] [Core] Fix buffer race in switch_ivr_eavesdrop_session() --- src/switch_ivr_async.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index cc5ec0581a..621836de00 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2576,12 +2576,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session } if (ep->buffer) { + switch_buffer_lock(ep->buffer); while (switch_buffer_inuse(ep->buffer) >= len) { int tchanged = 0, changed = 0; - switch_buffer_lock(ep->buffer); write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len); - switch_buffer_unlock(ep->buffer); write_frame.samples = write_frame.datalen / 2 / channels; write_frame.channels = channels; @@ -2635,6 +2634,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); + switch_buffer_unlock(ep->buffer); goto end; } } @@ -2655,7 +2655,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { break; } + + switch_buffer_unlock(ep->buffer); + switch_buffer_lock(ep->buffer); } + + switch_buffer_unlock(ep->buffer); } } From 4fe8aecbfb3f96de4a8b7afddc1c22b61d771370 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 27 Jul 2020 21:41:13 +0400 Subject: [PATCH 23/65] [Core] Make switch_core_media_set_codec() and switch_core_media_set_video_codec() thread-safe so there is no race when a session's codec is initiated by different threads simultaneously. --- src/include/private/switch_core_pvt.h | 1 + src/switch_core_media.c | 27 +++++++++++++++++++-------- src/switch_core_session.c | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index c3478f109e..68a8d9c463 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -132,6 +132,7 @@ struct switch_core_session { switch_mutex_t *mutex; switch_mutex_t *stack_count_mutex; switch_mutex_t *resample_mutex; + switch_mutex_t *codec_init_mutex; switch_mutex_t *codec_read_mutex; switch_mutex_t *codec_write_mutex; switch_mutex_t *video_codec_read_mutex; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 4778edbf8c..8173996e3d 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3587,24 +3587,27 @@ static void switch_core_session_parse_codec_settings(switch_core_session_t *sess //? SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force) { + switch_status_t status = SWITCH_STATUS_SUCCESS; switch_media_handle_t *smh; switch_rtp_engine_t *v_engine; switch_assert(session); + switch_mutex_lock(session->codec_init_mutex); + if (!(smh = session->media_handle)) { - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, end); } v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; if (!v_engine->codec_negotiated) { - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, end); } if (v_engine->read_codec.implementation && switch_core_codec_ready(&v_engine->read_codec)) { if (!force) { - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding) || v_engine->read_codec.implementation->samples_per_second != v_engine->cur_payload_map->rm_rate) { @@ -3616,7 +3619,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already using %s\n", v_engine->read_codec.implementation->iananame); - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } } @@ -3632,7 +3635,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, &v_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n"); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, end); } else { if (switch_core_codec_init(&v_engine->write_codec, v_engine->cur_payload_map->rm_encoding, @@ -3644,7 +3647,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, &v_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n"); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, end); } else { v_engine->read_frame.rate = v_engine->cur_payload_map->rm_rate; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n", @@ -3685,7 +3688,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_ptime", "%d", 0); } } - return SWITCH_STATUS_SUCCESS; + +end: + switch_mutex_unlock(session->codec_init_mutex); + + return status; } @@ -3698,9 +3705,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ switch_rtp_engine_t *a_engine; switch_assert(session); + + switch_mutex_lock(session->codec_init_mutex); if (!(smh = session->media_handle)) { - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, end); } a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; @@ -3865,6 +3874,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ switch_core_session_unlock_codec_read(session); } + switch_mutex_unlock(session->codec_init_mutex); + return status; } static void clear_ice(switch_core_session_t *session, switch_media_type_t type) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index ca58566b2f..36cf62f111 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -2417,6 +2417,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED, session->pool); switch_mutex_init(&session->stack_count_mutex, SWITCH_MUTEX_NESTED, session->pool); switch_mutex_init(&session->resample_mutex, SWITCH_MUTEX_NESTED, session->pool); + switch_mutex_init(&session->codec_init_mutex, SWITCH_MUTEX_NESTED, session->pool); switch_mutex_init(&session->codec_read_mutex, SWITCH_MUTEX_NESTED, session->pool); switch_mutex_init(&session->codec_write_mutex, SWITCH_MUTEX_NESTED, session->pool); switch_mutex_init(&session->video_codec_read_mutex, SWITCH_MUTEX_NESTED, session->pool); From 785d92a5f52d91f428677032235f27cc0365a570 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 4 Aug 2020 23:06:59 +0400 Subject: [PATCH 24/65] [mod_pgsql] Prevent a stall of PQconsumeInput(). --- src/mod/databases/mod_pgsql/mod_pgsql.c | 150 +++++++++++++----------- 1 file changed, 83 insertions(+), 67 deletions(-) diff --git a/src/mod/databases/mod_pgsql/mod_pgsql.c b/src/mod/databases/mod_pgsql/mod_pgsql.c index b94b1abc73..e2efa5252c 100644 --- a/src/mod/databases/mod_pgsql/mod_pgsql.c +++ b/src/mod/databases/mod_pgsql/mod_pgsql.c @@ -373,6 +373,20 @@ switch_status_t pgsql_handle_connect(switch_pgsql_handle_t *handle) return SWITCH_STATUS_FALSE; } + if (PQsetnonblocking(handle->con, 1) == -1) { + char *err_str; + + if ((err_str = pgsql_handle_get_error(handle))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err_str); + switch_safe_free(err_str); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to setup socket for the database [%s]\n", handle->dsn); + pgsql_handle_disconnect(handle); + } + + return SWITCH_STATUS_FALSE; + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Connected to [%s]\n", handle->dsn); handle->state = SWITCH_PGSQL_STATE_CONNECTED; handle->sock = PQsocket(handle->con); @@ -635,89 +649,91 @@ switch_status_t pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pg return SWITCH_STATUS_FALSE; } - /* Try to consume input that might be waiting right away */ - if (PQconsumeInput(handle->con)) { - /* And check to see if we have a full result ready for reading */ - if (PQisBusy(handle->con)) { + if (PQisBusy(handle->con)) { + /* Try to consume input that might be waiting right away */ + if (PQconsumeInput(handle->con)) { + /* And check to see if we have a full result ready for reading */ + if (PQisBusy(handle->con)) { - /* Wait for a result to become available, up to msec milliseconds */ - start = switch_micro_time_now(); - while ((ctime = switch_micro_time_now()) - start <= usec) { - switch_time_t wait_time = (usec - (ctime - start)) / 1000; - /* Wait for the PostgreSQL socket to be ready for data reads. */ + /* Wait for a result to become available, up to msec milliseconds */ + start = switch_micro_time_now(); + while ((ctime = switch_micro_time_now()) - start <= usec) { + switch_time_t wait_time = (usec - (ctime - start)) / 1000; + /* Wait for the PostgreSQL socket to be ready for data reads. */ #ifndef _WIN32 - fds[0].fd = handle->sock; - fds[0].events |= POLLIN; - fds[0].events |= POLLERR; - fds[0].events |= POLLNVAL; - fds[0].events |= POLLHUP; - fds[0].events |= POLLPRI; - fds[0].events |= POLLRDNORM; - fds[0].events |= POLLRDBAND; + fds[0].fd = handle->sock; + fds[0].events |= POLLIN; + fds[0].events |= POLLERR; + fds[0].events |= POLLNVAL; + fds[0].events |= POLLHUP; + fds[0].events |= POLLPRI; + fds[0].events |= POLLRDNORM; + fds[0].events |= POLLRDBAND; - poll_res = poll(&fds[0], 1, wait_time); + poll_res = poll(&fds[0], 1, wait_time); #else - struct timeval wait = { (long)wait_time * 1000, 0 }; - FD_ZERO(&rs); - FD_SET(handle->sock, &rs); - FD_ZERO(&es); - FD_SET(handle->sock, &es); - poll_res = select(0, &rs, 0, &es, &wait); + struct timeval wait = { (long)wait_time * 1000, 0 }; + FD_ZERO(&rs); + FD_SET(handle->sock, &rs); + FD_ZERO(&es); + FD_SET(handle->sock, &es); + poll_res = select(0, &rs, 0, &es, &wait); #endif - if (poll_res > 0) { + if (poll_res > 0) { #ifndef _WIN32 - if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql); - goto error; - } else if (fds[0].revents & POLLERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql); - goto error; - } else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) { + if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql); + goto error; + } else if (fds[0].revents & POLLERR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql); + goto error; + } else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) { #else - if (FD_ISSET(handle->sock, &rs)) { + if (FD_ISSET(handle->sock, &rs)) { #endif - /* Then try to consume any input waiting. */ - if (PQconsumeInput(handle->con)) { - if (PQstatus(handle->con) == CONNECTION_BAD) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n"); - handle->state = SWITCH_PGSQL_STATE_ERROR; + /* Then try to consume any input waiting. */ + if (PQconsumeInput(handle->con)) { + if (PQstatus(handle->con) == CONNECTION_BAD) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n"); + handle->state = SWITCH_PGSQL_STATE_ERROR; + goto error; + } + + /* And check to see if we have a full result ready for reading */ + if (!PQisBusy(handle->con)) { + /* If we can pull a full result without blocking, then break this loop */ + break; + } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + pgsql_cancel(handle); goto error; } - - /* And check to see if we have a full result ready for reading */ - if (!PQisBusy(handle->con)) { - /* If we can pull a full result without blocking, then break this loop */ - break; - } - } else { - /* If we had an error trying to consume input, report it and cancel the query. */ - err_str = pgsql_handle_get_error(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); - switch_safe_free(err_str); - pgsql_cancel(handle); - goto error; } + } else if (poll_res == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql); + goto error; } - } else if (poll_res == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql); + } + + /* If we broke the loop above because of a timeout, report that and cancel the query. */ + if (ctime - start > usec) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql); + pgsql_cancel(handle); goto error; } } - - /* If we broke the loop above because of a timeout, report that and cancel the query. */ - if (ctime - start > usec) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql); - pgsql_cancel(handle); - goto error; - } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + /* pgsql_cancel(handle); */ + goto error; } - } else { - /* If we had an error trying to consume input, report it and cancel the query. */ - err_str = pgsql_handle_get_error(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); - switch_safe_free(err_str); - /* pgsql_cancel(handle); */ - goto error; } /* At this point, we know we can read a full result without blocking. */ From 1fee1fc6adcdad2808716ed99d03831724349f01 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 12 Aug 2020 21:53:06 +0400 Subject: [PATCH 25/65] [Core] Fix SDP parsing causing segfault. --- src/switch_core_media.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 8173996e3d..23e77047b9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -9051,6 +9051,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi // goto video; //} + if (!t_engine->cur_payload_map) { + goto text_up; + } + if (switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) && t_engine->cur_payload_map->rm_encoding && t_engine->cur_payload_map->remote_sdp_port) { /******************************************************************************************/ if (t_engine->rtp_session && is_reinvite) { From 7b8a36c2a98281e2c31db1c908842a327d2cfdca Mon Sep 17 00:00:00 2001 From: surendrasignalwire Date: Thu, 13 Aug 2020 14:49:47 +0400 Subject: [PATCH 26/65] [mod_sofia] Fix recovery reinvite issue --- src/mod/endpoints/mod_sofia/sofia.c | 9 +++++++++ src/mod/endpoints/mod_sofia/sofia_glue.c | 11 +++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7f7b0c2b75..4975ca8feb 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1733,6 +1733,10 @@ static void our_sofia_event_callback(nua_event_t event, switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id); } + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + switch_channel_set_variable(channel, "dlg_req_swap_direction", "true"); + } + extract_header_vars(profile, sip, session, nh); switch_core_recovery_track(session); sofia_set_flag(tech_pvt, TFLAG_GOT_ACK); @@ -7111,8 +7115,13 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + switch_channel_set_variable(channel, "dlg_req_swap_direction", "true"); + } + extract_header_vars(profile, sip, session, nh); extract_vars(profile, sip, session); + switch_core_recovery_track(session); switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index a49bd998a9..2eea09bd5e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2235,7 +2235,7 @@ int sofia_recover_callback(switch_core_session_t *session) const char *rr; int r = 0; const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1); - + int swap = switch_channel_var_true(channel, "dlg_req_swap_direction"); if (zstr(profile_name)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Missing profile\n"); @@ -2275,10 +2275,9 @@ int sofia_recover_callback(switch_core_session_t *session) rr = switch_channel_get_variable(channel, "sip_invite_record_route"); if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - int break_rfc = switch_true(switch_channel_get_variable(channel, "sip_recovery_break_rfc")); tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_req_uri")); - switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, break_rfc ? "sip_full_to" : "sip_full_from")); - switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, break_rfc ? "sip_full_from" : "sip_full_to")); + switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, swap ? "sip_full_to" : "sip_full_from")); + switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, swap ? "sip_full_from" : "sip_full_to")); } else { const char *contact_params = switch_channel_get_variable(channel, "sip_contact_params"); const char *contact_uri = switch_channel_get_variable(channel, "sip_contact_uri"); @@ -2297,11 +2296,11 @@ int sofia_recover_callback(switch_core_session_t *session) tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_from_uri")); if (!switch_channel_get_variable_dup(channel, "sip_handle_full_from", SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, "sip_full_to")); + switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, swap ? "sip_full_from" :"sip_full_to")); } if (!switch_channel_get_variable_dup(channel, "sip_handle_full_to", SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, "sip_full_from")); + switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, swap ? "sip_full_to" : "sip_full_from")); } } From 3509ae537e944b967d29f23340baf358ade4314c Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Thu, 17 Sep 2020 00:20:17 +0300 Subject: [PATCH 27/65] [core] native tap fix (pass the copy of the frame to switch_core_session_write_frame() so it does not get encoded) --- src/switch_ivr_async.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 621836de00..a6972e847c 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2084,7 +2084,7 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data memcpy(frame.data, nframe->data, nframe->datalen); - if (switch_core_session_write_frame(ep->eavesdropper, nframe, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { + if (switch_core_session_write_frame(ep->eavesdropper, &frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { return SWITCH_FALSE; } } From 5aabb54f68f495bfd51c083bd89d4fdaa1a9ba6c Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Fri, 4 Sep 2020 08:57:28 +0000 Subject: [PATCH 28/65] [core] eavesdrop: init L16 codec at right ptime in certain conditions. [core] eavesdrop: avoid eavesdropping on itself and return error. [core] eavesdrop: adjust buffer operations for ptime mismatch and for when ptimes are the same. [core] eavesdrop: add buffering based on LCM (Least Common Multiple) when ptime mismatch, and have audio write thread enabled when ptime eavesdropee < ptime eavesdropper. [unit-tests] add unit-tests for eavesdrop. --- src/switch_ivr_async.c | 113 +++++- tests/unit/Makefile.am | 5 + tests/unit/conf_eavesdrop/freeswitch.xml | 238 +++++++++++++ tests/unit/conf_eavesdrop/gw/eavestest.xml | 14 + tests/unit/switch_eavesdrop.c | 392 +++++++++++++++++++++ 5 files changed, 743 insertions(+), 19 deletions(-) create mode 100644 tests/unit/conf_eavesdrop/freeswitch.xml create mode 100644 tests/unit/conf_eavesdrop/gw/eavestest.xml create mode 100644 tests/unit/switch_eavesdrop.c diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index a6972e847c..07f28a36e8 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2184,6 +2184,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_update_display(switch_core_ return status; } +/*Greatest Common Divisor*/ +static uint32_t switch_gcd(uint32_t x, uint32_t y) +{ + if (y == 0) { + return x; + } + + return switch_gcd(y, x % y); +} + +/*Least Common Multiple*/ +static uint32_t switch_lcm(uint32_t x, uint32_t y) +{ + uint32_t gcd = switch_gcd(x, y); + + if (gcd) return (x * y) / gcd; + + return 0; +} SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session_t *session, const char *uuid, const char *require_group, switch_eavesdrop_flag_t flags) @@ -2213,11 +2232,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session const char *vval; int buf_size = 0; int channels; + int lcm, buff_min_len, buffered = 1; if (!switch_channel_media_up(channel)) { goto end; } + if (tsession == session) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Eavesdrop target invalid.\n"); + goto end; + } + while(switch_channel_state_change_pending(tchannel) || !switch_channel_media_up(tchannel)) { switch_yield(10000); if (!--sanity) break; @@ -2286,8 +2311,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session goto end; } - - if (switch_core_codec_init(&codec, + if (tread_impl.decoded_bytes_per_packet < read_impl.decoded_bytes_per_packet) { + if (switch_core_codec_init(&codec, + "L16", + NULL, + NULL, + read_impl.actual_samples_per_second, + read_impl.microseconds_per_packet / 1000, + read_impl.number_of_channels, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); + goto end; + } + } else { + if (switch_core_codec_init(&codec, "L16", NULL, NULL, @@ -2298,10 +2336,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); goto end; + } + buffered = 0; } - switch_core_session_get_read_impl(session, &read_impl); - ep->read_impl = read_impl; ep->tread_impl = tread_impl; @@ -2440,6 +2478,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session switch_core_session_receive_message(tsession, &msg); } + lcm = switch_lcm(tread_impl.decoded_bytes_per_packet, read_impl.decoded_bytes_per_packet); + while (switch_channel_up_nosig(tchannel) && switch_channel_ready(channel)) { uint32_t len = sizeof(buf); switch_event_t *event = NULL; @@ -2569,15 +2609,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session channels = 1; } - tlen = tread_impl.decoded_bytes_per_packet * channels; + tlen = ep->read_impl.decoded_bytes_per_packet * channels; if (len > tlen) { len = tlen; } + if (buffered) { + buff_min_len = lcm * 2; + if (switch_buffer_inuse(ep->buffer) < buff_min_len) { + continue; + } + } else { + buff_min_len = len; + } + if (ep->buffer) { switch_buffer_lock(ep->buffer); - while (switch_buffer_inuse(ep->buffer) >= len) { + while (switch_buffer_inuse(ep->buffer) >= buff_min_len) { int tchanged = 0, changed = 0; write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len); @@ -2592,7 +2641,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session tchanged = 1; } - if (read_impl.number_of_channels != ep->tread_impl.number_of_channels || + if (read_impl.number_of_channels != ep->read_impl.number_of_channels || read_impl.actual_samples_per_second != ep->read_impl.actual_samples_per_second) { changed = 1; } @@ -2606,6 +2655,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session ep->read_impl.number_of_channels, read_impl.actual_samples_per_second, read_impl.number_of_channels); + + tlen = read_impl.decoded_bytes_per_packet * channels; + + if (len > tlen) { + len = tlen; + } + } if (tchanged) { @@ -2615,28 +2671,44 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session ep->tread_impl.number_of_channels, tread_impl.actual_samples_per_second, tread_impl.number_of_channels); + } + - tlen = tread_impl.decoded_bytes_per_packet * channels; - - if (len > tlen) { - len = tlen; - } - - switch_core_codec_destroy(&codec); + switch_core_codec_destroy(&codec); + if (tread_impl.decoded_bytes_per_packet < read_impl.decoded_bytes_per_packet) { if (switch_core_codec_init(&codec, "L16", NULL, NULL, - tread_impl.actual_samples_per_second, - tread_impl.microseconds_per_packet / 1000, - tread_impl.number_of_channels, + read_impl.actual_samples_per_second, + read_impl.microseconds_per_packet / 1000, + read_impl.number_of_channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); + switch_buffer_unlock(ep->buffer); + goto end; + } + buffered = 1; + lcm = switch_lcm(tread_impl.decoded_bytes_per_packet, read_impl.decoded_bytes_per_packet); + } else { + if (switch_core_codec_init(&codec, + "L16", + NULL, + NULL, + tread_impl.actual_samples_per_second, + tread_impl.microseconds_per_packet / 1000, + tread_impl.number_of_channels, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); switch_buffer_unlock(ep->buffer); goto end; } + if (buffered == 1) { + buffered = 0; + } } ep->read_impl = read_impl; @@ -2658,11 +2730,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session switch_buffer_unlock(ep->buffer); switch_buffer_lock(ep->buffer); - } + if (ep->tread_impl.decoded_bytes_per_packet == ep->read_impl.decoded_bytes_per_packet) { + /* push just the number of samples worth of a packet. */ + break; + } + } switch_buffer_unlock(ep->buffer); } - } end_loop: diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 6e7e128d62..2511a143c2 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -7,8 +7,13 @@ noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS) AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) +# "make check" will not run these. +examples = switch_eavesdrop + if HAVE_FVAD AM_CFLAGS += -DSWITCH_HAVE_FVAD endif TESTS = $(noinst_PROGRAMS) + +bin_PROGRAMS = $(examples) diff --git a/tests/unit/conf_eavesdrop/freeswitch.xml b/tests/unit/conf_eavesdrop/freeswitch.xml new file mode 100644 index 0000000000..4a65caf6d8 --- /dev/null +++ b/tests/unit/conf_eavesdrop/freeswitch.xml @@ -0,0 +1,238 @@ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/tests/unit/conf_eavesdrop/gw/eavestest.xml b/tests/unit/conf_eavesdrop/gw/eavestest.xml new file mode 100644 index 0000000000..a2f268424e --- /dev/null +++ b/tests/unit/conf_eavesdrop/gw/eavestest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/tests/unit/switch_eavesdrop.c b/tests/unit/switch_eavesdrop.c new file mode 100644 index 0000000000..867ad7a6bc --- /dev/null +++ b/tests/unit/switch_eavesdrop.c @@ -0,0 +1,392 @@ +#include +#include +#include + +static switch_memory_pool_t *pool = NULL; + +static switch_status_t test_detect_long_tone_in_file(const char *filepath, int rate, int freq, int ptime) { + teletone_multi_tone_t mt; + teletone_tone_map_t map; + int16_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; + size_t len = (rate * ptime / 1000) /*packet len in samples */ * 8; /*length of chunk that must contain tone*/ + size_t fin = 0; + switch_status_t status; + switch_file_handle_t fh = { 0 }; + uint8_t fail = 0, gaps = 0, audio = 0; + uint32_t pos = 0; + size_t full_len = 0; + + status = switch_core_file_open(&fh, filepath, 1, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL); + if (status != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open file [%s]\n", filepath); + return SWITCH_STATUS_FALSE; + } + + mt.sample_rate = rate; + map.freqs[0] = (teletone_process_t)freq; + + teletone_multi_tone_init(&mt, &map); + + len = (rate * 2 / 100) /*packet len in samples */ * 8; + + while (switch_core_file_read(&fh, &data, &len) == SWITCH_STATUS_SUCCESS) { + fin += len; + /*skip silence at the beginning of the file, 1 second max. */ + if (!teletone_multi_tone_detect(&mt, data, len)) { + if ((fin > rate && !audio) || gaps > 30) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many gaps in audio or no tone detected 1st second. [%u][%d]\n", fin, gaps); + fail = 1; + break; + } + gaps++; + continue; + } else { + audio++; + } + } + + switch_core_file_close(&fh); + + if (fail) { + return SWITCH_STATUS_FALSE; + } + return SWITCH_STATUS_SUCCESS; +} + +FST_CORE_BEGIN("./conf_eavesdrop") + +{ +FST_SUITE_BEGIN(switch_eavesdrop) +{ + FST_SETUP_BEGIN() + { + fst_requires_module("mod_loopback"); + fst_requires_module("mod_sofia"); + switch_core_set_variable("link_ip", switch_core_get_variable("local_ip_v4")); + } + FST_SETUP_END() + + FST_TEARDOWN_BEGIN() + { + } + FST_TEARDOWN_END() + + FST_TEST_BEGIN(test_eavesdrop_bridged_same_ptime_20ms) + { + switch_core_session_t *session1 = NULL; + switch_core_session_t *session2 = NULL; + switch_core_session_t *session3 = NULL; + + switch_channel_t *channel1 = NULL; + switch_channel_t *channel2 = NULL; + switch_channel_t *channel3 = NULL; + + switch_status_t status; + switch_call_cause_t cause; + switch_stream_handle_t stream = { 0 }; + char eavesdrop_command[256] = { 0 }; + char rec_path[256]; + char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; + char eaves_dialstr[256] = { 0 }; + + switch_uuid_str(rec_uuid, sizeof(rec_uuid)); + + /*parked 20 ms ptime */ + status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332220", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session1); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel1 = switch_core_session_get_channel(session1); + fst_requires(channel1); + + snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332230", rec_uuid); + + /*eavesdropper 20 ms ptime*/ + status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session2); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel2 = switch_core_session_get_channel(session2); + fst_requires(channel2); + + /*milliwatt tone 20 ms ptime*/ + status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session3); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel3 = switch_core_session_get_channel(session3); + fst_requires(channel3); + + SWITCH_STANDARD_STREAM(stream); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session1, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + switch_safe_free(stream.data); + + sleep(5); // it will record ~ 5 secs + + snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid); + + fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS); + + fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 20) == SWITCH_STATUS_SUCCESS); + + unlink(rec_path); + + switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING); + + switch_core_session_rwunlock(session1); + switch_core_session_rwunlock(session2); + switch_core_session_rwunlock(session3); + + } + FST_TEST_END() + + FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_20ms_30ms) + { + switch_core_session_t *session1 = NULL; + switch_core_session_t *session2 = NULL; + switch_core_session_t *session3 = NULL; + + switch_channel_t *channel1 = NULL; + switch_channel_t *channel2 = NULL; + switch_channel_t *channel3 = NULL; + + switch_status_t status; + switch_call_cause_t cause; + switch_stream_handle_t stream = { 0 }; + char eavesdrop_command[256] = { 0 }; + char rec_path[256]; + char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; + char eaves_dialstr[256] = { 0 }; + + switch_uuid_str(rec_uuid, sizeof(rec_uuid)); + + /*parked 20 ms ptime */ + status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332220", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session1); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel1 = switch_core_session_get_channel(session1); + fst_requires(channel1); + + snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332230", rec_uuid); + + /*eavesdropper 20 ms ptime*/ + status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session2); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel2 = switch_core_session_get_channel(session2); + fst_requires(channel2); + + /*milliwatt tone 30 ms ptime*/ + status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332222", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session3); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel3 = switch_core_session_get_channel(session3); + fst_requires(channel3); + + SWITCH_STANDARD_STREAM(stream); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session1, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + switch_safe_free(stream.data); + + sleep(5); // it will record ~ 5 secs + + snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid); + + fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS); + + fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 20) == SWITCH_STATUS_SUCCESS); + + unlink(rec_path); + + switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING); + + switch_core_session_rwunlock(session1); + switch_core_session_rwunlock(session2); + switch_core_session_rwunlock(session3); + + } + FST_TEST_END() + + FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_30ms_20ms) + { + switch_core_session_t *session1 = NULL; + switch_core_session_t *session2 = NULL; + switch_core_session_t *session3 = NULL; + + switch_channel_t *channel1 = NULL; + switch_channel_t *channel2 = NULL; + switch_channel_t *channel3 = NULL; + + switch_status_t status; + switch_call_cause_t cause; + switch_stream_handle_t stream = { 0 }; + char eavesdrop_command[256] = { 0 }; + char rec_path[256]; + char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; + char eaves_dialstr[256] = { 0 }; + + switch_uuid_str(rec_uuid, sizeof(rec_uuid)); + + /*parked 30 ms ptime */ + status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332231", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session1); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel1 = switch_core_session_get_channel(session1); + fst_requires(channel1); + + snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332240", rec_uuid); + + /*eavesdropper 30 ms ptime*/ + status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session2); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel2 = switch_core_session_get_channel(session2); + fst_requires(channel2); + + /*milliwatt tone 20 ms ptime*/ + status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session3); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel3 = switch_core_session_get_channel(session3); + fst_requires(channel3); + + SWITCH_STANDARD_STREAM(stream); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session1, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + switch_safe_free(stream.data); + + sleep(5); // it will record ~ 5 secs + + snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid); + + fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS); + + fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 30) == SWITCH_STATUS_SUCCESS); + + unlink(rec_path); + + switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING); + + switch_core_session_rwunlock(session1); + switch_core_session_rwunlock(session2); + switch_core_session_rwunlock(session3); + + } + FST_TEST_END() + + FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_reneg) + { + switch_core_session_t *session1 = NULL; + switch_core_session_t *session2 = NULL; + switch_core_session_t *session3 = NULL; + + switch_channel_t *channel1 = NULL; + switch_channel_t *channel2 = NULL; + switch_channel_t *channel3 = NULL; + + switch_status_t status; + switch_call_cause_t cause; + switch_stream_handle_t stream = { 0 }; + char eavesdrop_command[256] = { 0 }; + char rec_path[256]; + char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; + char eaves_dialstr[256] = { 0 }; + + switch_uuid_str(rec_uuid, sizeof(rec_uuid)); + + /*parked 30 ms ptime */ + status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332231", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session1); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel1 = switch_core_session_get_channel(session1); + fst_requires(channel1); + + snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332240", rec_uuid); + + /*eavesdropper 30 ms ptime*/ + status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session2); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel2 = switch_core_session_get_channel(session2); + fst_requires(channel2); + + /*milliwatt tone 20 ms ptime*/ + status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(session3); + fst_check(status == SWITCH_STATUS_SUCCESS); + channel3 = switch_core_session_get_channel(session3); + fst_requires(channel3); + + SWITCH_STANDARD_STREAM(stream); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session1, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + + sleep(2); + + // codec reneg for eavesdropper + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_media_reneg %s = PCMU@20i", switch_core_session_get_uuid(session2)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + + sleep(1); + + // codec reneg for eavesdroppee + memset(eavesdrop_command, 0, sizeof(eavesdrop_command)); + switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_media_reneg %s = PCMU@30i", switch_core_session_get_uuid(session3)); + switch_api_execute("bgapi", eavesdrop_command, session3, &stream); + switch_safe_free(stream.data); + + sleep(2); + + snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid); + + fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS); + + fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 30) == SWITCH_STATUS_SUCCESS); + + unlink(rec_path); + + switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING); + + switch_core_session_rwunlock(session1); + switch_core_session_rwunlock(session2); + switch_core_session_rwunlock(session3); + + } + FST_TEST_END() + +} +FST_SUITE_END() +} +FST_CORE_END() + From dbc894d95912d903ed5e5a7acccdea1c03e0b10f Mon Sep 17 00:00:00 2001 From: surendrasignalwire <56929670+surendrasignalwire@users.noreply.github.com> Date: Tue, 29 Sep 2020 20:40:33 +0530 Subject: [PATCH 29/65] [Core] Reuse caller profile --- src/include/switch_types.h | 2 ++ src/mod/applications/mod_dptools/mod_dptools.c | 8 ++++++++ src/switch_ivr.c | 11 +++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 2037889c01..79ef9caa26 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1416,6 +1416,7 @@ CF_HOLD_BLEG - B leg is on hold CF_SERVICE - Channel has a service thread CF_TAGGED - Channel is tagged CF_WINNER - Channel is the winner +CF_REUSE_CALLER_PROFILE - Channel reuse caller profile CF_CONTROLLED - Channel is under control CF_PROXY_MODE - Channel has no media CF_SUSPEND - Suspend i/o @@ -1468,6 +1469,7 @@ typedef enum { CF_SERVICE, CF_TAGGED, CF_WINNER, + CF_REUSE_CALLER_PROFILE, CF_CONTROLLED, CF_PROXY_MODE, CF_PROXY_OFF, diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index f891c6a513..43329eb006 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1150,6 +1150,13 @@ SWITCH_STANDARD_APP(break_function) } } +SWITCH_STANDARD_APP(reuse_caller_profile_function) +{ + switch_channel_t *channel; + channel = switch_core_session_get_channel(session); + switch_channel_set_flag(channel, CF_REUSE_CALLER_PROFILE); +} + SWITCH_STANDARD_APP(queue_dtmf_function) { switch_channel_queue_dtmf_string(switch_core_session_get_channel(session), (const char *) data); @@ -6551,6 +6558,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "deflect", "Send call deflect", "Send a call deflect.", deflect_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "recovery_refresh", "Send call recovery_refresh", "Send a call recovery_refresh.", recovery_refresh_function, "", SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "reuse_caller_profile", "Reuse the caller profile", "Reuse the caller profile", reuse_caller_profile_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "queue_dtmf", "Queue dtmf to be sent", "Queue dtmf to be sent from a session", queue_dtmf_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "send_dtmf", "Send dtmf to be sent", "Send dtmf to be sent from a session", send_dtmf_function, "", diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 8d21513388..be319e353e 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2192,7 +2192,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ extension = "service"; } - new_profile = switch_caller_profile_clone(session, profile); + + if (switch_channel_test_flag(channel, CF_REUSE_CALLER_PROFILE)){ + new_profile = switch_channel_get_caller_profile(channel); + } else { + new_profile = switch_caller_profile_clone(session, profile); + } new_profile->dialplan = switch_core_strdup(new_profile->pool, use_dialplan); new_profile->context = switch_core_strdup(new_profile->pool, use_context); @@ -2238,7 +2243,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ switch_core_session_rwunlock(other_session); } - switch_channel_set_caller_profile(channel, new_profile); + if (!switch_channel_test_flag(channel, CF_REUSE_CALLER_PROFILE)){ + switch_channel_set_caller_profile(channel, new_profile); + } switch_channel_set_state(channel, CS_ROUTING); switch_channel_audio_sync(channel); From 22ae5a1ba124632c17159edfe0cc51deff76e859 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 5 Oct 2020 02:49:08 +0400 Subject: [PATCH 30/65] [Core] Fix memory leak of local_var_event in switch_ivr_originate() when caller_channel is not ready. --- src/switch_ivr_originate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 99370d7e79..d2baeb2741 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2861,6 +2861,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (oglobals.session) { if (!switch_channel_ready(caller_channel)) { status = SWITCH_STATUS_FALSE; + if (local_var_event) switch_event_destroy(&local_var_event); goto done; } From 8e4b418ee4d85545d20f3af08ae25311a9920ea9 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Tue, 6 Oct 2020 11:26:42 -0400 Subject: [PATCH 31/65] [core] fix leak in http request parser --- src/switch_utils.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index e4e26a6eef..5d6b8f2aaf 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4176,11 +4176,12 @@ SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char * char *q; char *next; char *name, *val; + char *dup = NULL; if (qs) { q = qs; } else { /*parse our own qs, dup to avoid modify the original string */ - q = strdup(request->qs); + dup = q = strdup(request->qs); } switch_assert(q); @@ -4207,9 +4208,7 @@ SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char * q = next; } while (q); - if (!qs) { - switch_safe_free(q); - } + switch_safe_free(dup); } /* clean the uri to protect us from vulnerability attack */ From dcb75a79e36cb131cc6fa8827ffdfcd852fa5adf Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 7 Oct 2020 03:21:16 +0400 Subject: [PATCH 32/65] [mod_sofia] Fix multiple memory leaks in sofia_presence_handle_sip_i_subscribe() --- src/mod/endpoints/mod_sofia/sofia_presence.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index e1c31c99c8..e27b0495ff 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -4284,7 +4284,11 @@ void sofia_presence_handle_sip_i_subscribe(int status, } } } + + switch_xml_free(xml); } + + switch_safe_free(pd_dup); } switch_event_fire(&event); } else if (!strcasecmp(event, "message-summary")) { From 3065cb9168e994b5388c37170c61b0956c91e0d2 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Oct 2020 23:49:36 +0400 Subject: [PATCH 33/65] [mod_sofia] Fix memory leaks caused by improper profile destroy. Add a unit-test. --- src/mod/endpoints/mod_sofia/sofia.c | 25 +++-- tests/unit/Makefile.am | 2 +- tests/unit/conf_sofia/freeswitch.xml | 144 +++++++++++++++++++++++++++ tests/unit/test_sofia.c | 31 ++++++ 4 files changed, 191 insertions(+), 11 deletions(-) create mode 100644 tests/unit/conf_sofia/freeswitch.xml create mode 100644 tests/unit/test_sofia.c diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 4975ca8feb..87b09e5406 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3180,7 +3180,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void if (!sofia_glue_init_sql(profile)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name); sofia_profile_start_failure(profile, profile->name); - sofia_glue_del_profile(profile); goto end; } @@ -3332,7 +3331,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } sofia_profile_start_failure(profile, profile->name); - sofia_glue_del_profile(profile); goto end; } @@ -3500,6 +3498,20 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } } + /* Do gateway cleanups */ + sofia_glue_del_every_gateway(profile); + sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); + sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL)); + sofia_glue_fire_events(profile); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n"); + + if (worker_thread) { + switch_thread_join(&st, worker_thread); + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n"); + } sofia_reg_unregister(profile); nua_shutdown(profile->nua); @@ -3514,13 +3526,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void sofia_clear_pflag_locked(profile, PFLAG_RUNNING); sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n"); - - if ( worker_thread ) { - switch_thread_join(&st, worker_thread); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n"); - } sanity = 4; while (profile->inuse) { @@ -3569,6 +3574,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } } + end: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name); switch_thread_rwlock_wrlock(profile->rwlock); @@ -3590,7 +3596,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void sofia_profile_destroy(profile); - end: switch_mutex_lock(mod_sofia_globals.mutex); mod_sofia_globals.threads--; switch_mutex_unlock(mod_sofia_globals.mutex); diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 2511a143c2..231225c5aa 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/build/modmake.rulesam noinst_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils switch_core switch_console switch_vpx switch_core_file \ switch_ivr_play_say switch_core_codec switch_rtp switch_xml -noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr +noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr test_sofia AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS) AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) diff --git a/tests/unit/conf_sofia/freeswitch.xml b/tests/unit/conf_sofia/freeswitch.xml new file mode 100644 index 0000000000..793ac5a04a --- /dev/null +++ b/tests/unit/conf_sofia/freeswitch.xml @@ -0,0 +1,144 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
diff --git a/tests/unit/test_sofia.c b/tests/unit/test_sofia.c new file mode 100644 index 0000000000..e45bd5d3fd --- /dev/null +++ b/tests/unit/test_sofia.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018-2019, Signalwire, Inc. ALL RIGHTS RESERVED + * test_sofia.c -- Tests mod_sofia for memory leaks + */ + +#include +#include + +FST_CORE_DB_BEGIN("conf_sofia") +{ + FST_SUITE_BEGIN(switch_sofia) + { + FST_SETUP_BEGIN() + { + fst_requires_module("mod_sofia"); + } + FST_SETUP_END() + + FST_TEARDOWN_BEGIN() + { + } + FST_TEARDOWN_END() + + FST_TEST_BEGIN(sofia_leaks) + { + } + FST_TEST_END() + } + FST_SUITE_END() +} +FST_CORE_END() From 5ed17dd19cdda148c6d9f48b0dcc7ea9afb653cf Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 23 Oct 2020 21:48:53 +0400 Subject: [PATCH 34/65] [Core] Scheduler: Fix race between switch_scheduler_add_task() and task_thread_loop(). Add new switch_scheduler_add_task_ex() method. --- src/include/switch_scheduler.h | 17 +++++++++++++++++ src/switch_scheduler.c | 26 +++++++++++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/include/switch_scheduler.h b/src/include/switch_scheduler.h index 14403917ca..1100fdb052 100644 --- a/src/include/switch_scheduler.h +++ b/src/include/switch_scheduler.h @@ -66,6 +66,23 @@ SWITCH_DECLARE(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); +/*! + \brief Schedule a task in the future + \param task_runtime the time in epoch seconds to execute the task. + \param func the callback function to execute when the task is executed. + \param desc an arbitrary description of the task. + \param group a group id tag to link multiple tasks to a single entity. + \param cmd_id an arbitrary index number be used in the callback. + \param cmd_arg user data to be passed to the callback. + \param flags flags to alter behaviour + \param task_id pointer to put the id of the task to + \return the id of the task +*/ + +SWITCH_DECLARE(uint32_t) switch_scheduler_add_task_ex(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, uint32_t *task_id); + /*! \brief Delete a scheduled task \param task_id the id of the task diff --git a/src/switch_scheduler.c b/src/switch_scheduler.c index c08d1071b4..9c0f29a35b 100644 --- a/src/switch_scheduler.c +++ b/src/switch_scheduler.c @@ -209,9 +209,21 @@ static void *SWITCH_THREAD_FUNC switch_scheduler_task_thread(switch_thread_t *th } SWITCH_DECLARE(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) + switch_scheduler_func_t func, + const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags) { + uint32_t task_id; + + switch_scheduler_add_task_ex(task_runtime, func, desc, group, cmd_id, cmd_arg, flags, &task_id); + + return task_id; +} + +SWITCH_DECLARE(uint32_t) switch_scheduler_add_task_ex(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, uint32_t *task_id) +{ + uint32_t result; switch_scheduler_task_container_t *container, *tp; switch_event_t *event; switch_time_t now = switch_epoch_time_now(NULL); @@ -220,6 +232,7 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_mutex_lock(globals.task_mutex); switch_zmalloc(container, sizeof(*container)); switch_assert(func); + switch_assert(task_id); if (task_runtime < now) { container->task.repeat = (uint32_t)task_runtime; @@ -246,8 +259,6 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, for (container->task.task_id = 0; !container->task.task_id; container->task.task_id = ++globals.task_id); - switch_mutex_unlock(globals.task_mutex); - tp = container; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added task %u %s (%s) to run at %" SWITCH_INT64_T_FMT "\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group), tp->task.runtime); @@ -260,7 +271,12 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_queue_push(globals.event_queue, event); event = NULL; } - return container->task.task_id; + + result = *task_id = container->task.task_id; + + switch_mutex_unlock(globals.task_mutex); + + return result; } SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_id(uint32_t task_id) From eaf5a70246e2786bd02c257e26946eb07d58c090 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 17 Mar 2021 01:15:42 +0300 Subject: [PATCH 35/65] [Unit-tests] Fix build issues in switch_eavesdrop.c test file. --- tests/unit/switch_eavesdrop.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/tests/unit/switch_eavesdrop.c b/tests/unit/switch_eavesdrop.c index 867ad7a6bc..18c293f833 100644 --- a/tests/unit/switch_eavesdrop.c +++ b/tests/unit/switch_eavesdrop.c @@ -1,20 +1,15 @@ -#include #include #include -static switch_memory_pool_t *pool = NULL; - static switch_status_t test_detect_long_tone_in_file(const char *filepath, int rate, int freq, int ptime) { teletone_multi_tone_t mt; teletone_tone_map_t map; int16_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; - size_t len = (rate * ptime / 1000) /*packet len in samples */ * 8; /*length of chunk that must contain tone*/ - size_t fin = 0; + switch_size_t len = (rate * ptime / 1000) /*packet len in samples */ * 8; /*length of chunk that must contain tone*/ + switch_size_t fin = 0; switch_status_t status; switch_file_handle_t fh = { 0 }; uint8_t fail = 0, gaps = 0, audio = 0; - uint32_t pos = 0; - size_t full_len = 0; status = switch_core_file_open(&fh, filepath, 1, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL); if (status != SWITCH_STATUS_SUCCESS) { @@ -34,7 +29,7 @@ static switch_status_t test_detect_long_tone_in_file(const char *filepath, int r /*skip silence at the beginning of the file, 1 second max. */ if (!teletone_multi_tone_detect(&mt, data, len)) { if ((fin > rate && !audio) || gaps > 30) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many gaps in audio or no tone detected 1st second. [%u][%d]\n", fin, gaps); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many gaps in audio or no tone detected 1st second. [%" SWITCH_SIZE_T_FMT "][%d]\n", fin, gaps); fail = 1; break; } @@ -85,9 +80,9 @@ FST_SUITE_BEGIN(switch_eavesdrop) switch_call_cause_t cause; switch_stream_handle_t stream = { 0 }; char eavesdrop_command[256] = { 0 }; - char rec_path[256]; + char rec_path[1024]; char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - char eaves_dialstr[256] = { 0 }; + char eaves_dialstr[512] = { 0 }; switch_uuid_str(rec_uuid, sizeof(rec_uuid)); @@ -160,9 +155,9 @@ FST_SUITE_BEGIN(switch_eavesdrop) switch_call_cause_t cause; switch_stream_handle_t stream = { 0 }; char eavesdrop_command[256] = { 0 }; - char rec_path[256]; + char rec_path[1024]; char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - char eaves_dialstr[256] = { 0 }; + char eaves_dialstr[512] = { 0 }; switch_uuid_str(rec_uuid, sizeof(rec_uuid)); @@ -235,9 +230,9 @@ FST_SUITE_BEGIN(switch_eavesdrop) switch_call_cause_t cause; switch_stream_handle_t stream = { 0 }; char eavesdrop_command[256] = { 0 }; - char rec_path[256]; + char rec_path[1024]; char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - char eaves_dialstr[256] = { 0 }; + char eaves_dialstr[512] = { 0 }; switch_uuid_str(rec_uuid, sizeof(rec_uuid)); @@ -310,9 +305,9 @@ FST_SUITE_BEGIN(switch_eavesdrop) switch_call_cause_t cause; switch_stream_handle_t stream = { 0 }; char eavesdrop_command[256] = { 0 }; - char rec_path[256]; + char rec_path[1024]; char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; - char eaves_dialstr[256] = { 0 }; + char eaves_dialstr[512] = { 0 }; switch_uuid_str(rec_uuid, sizeof(rec_uuid)); From a746d12f6c8f5651fc52c3c63bf5f8e3eeae51c1 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 29 Oct 2020 00:14:00 +0400 Subject: [PATCH 36/65] [mod_sofia] Keep noreg gateways as NOREG, mark unregistered gateways as DOWN. Co-authored-by: Mike Jerris --- src/mod/endpoints/mod_sofia/mod_sofia.c | 33 ++++++++++++++++--------- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia_reg.c | 3 ++- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 8ce1996ccb..3143fffa42 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2740,6 +2740,7 @@ const char *sofia_state_names[] = { "FAIL_WAIT", "EXPIRED", "NOREG", + "DOWN", "TIMEOUT", NULL }; @@ -3653,15 +3654,19 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t if (!strcasecmp(gname, "all")) { for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) { - gateway_ptr->retry = 0; - gateway_ptr->state = REG_STATE_UNREGED; + if (gateway_ptr->state != REG_STATE_NOREG) { + gateway_ptr->retry = 0; + gateway_ptr->state = REG_STATE_UNREGED; + } } stream->write_function(stream, "+OK\n"); } else if ((gateway_ptr = sofia_reg_find_gateway(gname))) { - gateway_ptr->retry = 0; - gateway_ptr->state = REG_STATE_UNREGED; - stream->write_function(stream, "+OK\n"); - sofia_reg_release_gateway(gateway_ptr); + if (gateway_ptr->state != REG_STATE_NOREG) { + gateway_ptr->retry = 0; + gateway_ptr->state = REG_STATE_UNREGED; + stream->write_function(stream, "+OK\n"); + sofia_reg_release_gateway(gateway_ptr); + } } else { stream->write_function(stream, "Invalid gateway!\n"); } @@ -3680,15 +3685,19 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t if (!strcasecmp(gname, "all")) { for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) { - gateway_ptr->retry = 0; - gateway_ptr->state = REG_STATE_UNREGISTER; + if (gateway_ptr->state != REG_STATE_NOREG) { + gateway_ptr->retry = 0; + gateway_ptr->state = REG_STATE_UNREGISTER; + } } stream->write_function(stream, "+OK\n"); } else if ((gateway_ptr = sofia_reg_find_gateway(gname))) { - gateway_ptr->retry = 0; - gateway_ptr->state = REG_STATE_UNREGISTER; - stream->write_function(stream, "+OK\n"); - sofia_reg_release_gateway(gateway_ptr); + if (gateway_ptr->state != REG_STATE_NOREG) { + gateway_ptr->retry = 0; + gateway_ptr->state = REG_STATE_UNREGISTER; + stream->write_function(stream, "+OK\n"); + sofia_reg_release_gateway(gateway_ptr); + } } else { stream->write_function(stream, "Invalid gateway!\n"); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 3249533730..d4631b02d6 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -432,6 +432,7 @@ typedef enum { REG_STATE_FAIL_WAIT, REG_STATE_EXPIRED, REG_STATE_NOREG, + REG_STATE_DOWN, REG_STATE_TIMEOUT, REG_STATE_LAST } reg_state_t; diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 81d2ffdabd..b1586405b7 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -398,6 +398,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) } switch (ostate) { + case REG_STATE_DOWN: case REG_STATE_NOREG: if (!gateway_ptr->ping && !gateway_ptr->pinging && gateway_ptr->status != SOFIA_GATEWAY_UP) { gateway_ptr->status = SOFIA_GATEWAY_UP; @@ -432,7 +433,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) case REG_STATE_UNREGISTER: sofia_reg_kill_reg(gateway_ptr); - gateway_ptr->state = REG_STATE_NOREG; + gateway_ptr->state = REG_STATE_DOWN; gateway_ptr->status = SOFIA_GATEWAY_DOWN; break; case REG_STATE_UNREGED: From 96e139854e57cdce3c3dccc0206b76fc5d8cee4a Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 13 Nov 2020 21:23:20 +0400 Subject: [PATCH 37/65] [mod_sofia] Prevent crash in sofia_handle_sip_i_state on switch_channel_set_state() when PFLAG_3PCC_PROXY flag is set. --- src/mod/endpoints/mod_sofia/sofia.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 87b09e5406..7e71717aff 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7930,7 +7930,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, //switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION); //Moves into CS_INIT so call moves forward into the dialplan - switch_channel_set_state(channel, CS_INIT); + if (switch_channel_get_state(channel) == CS_NEW) { + switch_channel_set_state(channel, CS_INIT); + } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n"); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED"); From 7539921ecae86df78b7c198e31103d817c4ad307 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Mon, 16 Nov 2020 17:08:43 -0700 Subject: [PATCH 38/65] [core] improve logging on oversized fields in odbc --- src/switch_odbc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/switch_odbc.c b/src/switch_odbc.c index 9ea062d997..4445eb4c1f 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -644,25 +644,25 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c } if (truncated) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql data truncated - %s\n",SqlState); if (StrLen_or_IndPtr && StrLen_or_IndPtr <= 268435456) { ColumnSize = StrLen_or_IndPtr + 1; vals[y] = malloc(ColumnSize); switch_assert(vals[y]); memset(vals[y], 0, ColumnSize); SQLGetData(stmt, x, SQL_C_CHAR, (SQLCHAR *) vals[y], ColumnSize, NULL); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQLGetData large column [%lu]\n", (unsigned long)ColumnSize); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql data truncated - %s\n",SqlState); vals[y] = NULL; } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed\n"); vals[y] = NULL; } } else if (rc == SQL_SUCCESS){ vals[y] = strdup((char *)val); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed\n"); vals[y] = NULL; } } else { From 81aa6fa9d0417ea43be32f06671e7d3e3cfb9092 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Wed, 18 Nov 2020 00:01:03 +0400 Subject: [PATCH 39/65] [Core] ODBC: Fix large column logic and improve error handling. --- src/switch_odbc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/switch_odbc.c b/src/switch_odbc.c index 4445eb4c1f..fbad0e371a 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -645,12 +645,21 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c if (truncated) { if (StrLen_or_IndPtr && StrLen_or_IndPtr <= 268435456) { + int ValLen = strlen((char*)val); ColumnSize = StrLen_or_IndPtr + 1; vals[y] = malloc(ColumnSize); switch_assert(vals[y]); memset(vals[y], 0, ColumnSize); - SQLGetData(stmt, x, SQL_C_CHAR, (SQLCHAR *) vals[y], ColumnSize, NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQLGetData large column [%lu]\n", (unsigned long)ColumnSize); + strcpy(vals[y], (char*)val); + rc = SQLGetData(stmt, x, SQL_C_CHAR, (SQLCHAR *)vals[y] + ValLen, ColumnSize - ValLen, NULL); + if (rc != SQL_SUCCESS +#if (ODBCVER >= 0x0300) + && rc != SQL_NO_DATA +#endif + ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData was truncated and failed to complete.\n"); + switch_safe_free(vals[y]); + } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql data truncated - %s\n",SqlState); vals[y] = NULL; From 9608a5687399223910690adb8318f80b6ad4d3cc Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 18 Nov 2020 21:50:04 +0400 Subject: [PATCH 40/65] [Core] Fix leaks in switch_ivr_park when initially no rate. --- src/switch_ivr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index be319e353e..9aa05fcd73 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1011,7 +1011,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session, rate = read_impl.actual_samples_per_second; bpf = read_impl.decoded_bytes_per_packet; - if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) { + if (rate && (var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) { switch_core_session_get_read_impl(session, &imp); if (switch_core_codec_init(&codec, From 90c35685c315b0deb2413d623839e2f3641140a6 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 19 Nov 2020 21:18:09 +0400 Subject: [PATCH 41/65] [mod_mongo, mod_redis, mod_voicemail] Fix leaking hash iterators. --- src/mod/applications/mod_mongo/mod_mongo.c | 1 + src/mod/applications/mod_redis/mod_redis.c | 2 ++ src/mod/applications/mod_voicemail/mod_voicemail.c | 1 + 3 files changed, 4 insertions(+) diff --git a/src/mod/applications/mod_mongo/mod_mongo.c b/src/mod/applications/mod_mongo/mod_mongo.c index aac3221fe7..b66b01369a 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.c +++ b/src/mod/applications/mod_mongo/mod_mongo.c @@ -698,6 +698,7 @@ SWITCH_LIMIT_RELEASE(mod_mongo_limit_release) if (mod_mongo_increment(session, (const char *)p_key, -1, 0, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Couldn't decrement %s\n", (const char *)p_key); status = SWITCH_STATUS_FALSE; + free(hi); break; } else { switch_core_hash_delete(pvt->resources, (const char *) p_key); diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index 7f140fe7d6..5d4c132cd7 100644 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -197,11 +197,13 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) if (credis_decr(redis, (const char*)p_key, &val) != 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", (char *)p_key); + free(hi); switch_goto_status(SWITCH_STATUS_FALSE, end); } p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_switchname(), (char *)p_key); if (credis_decr(redis,p_uuid_key,&uuid_val) != 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", p_uuid_key); + free(hi); switch_goto_status(SWITCH_STATUS_FALSE, end); } switch_core_hash_delete(pvt->hash, (const char *) p_key); diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index aba1dc4cf0..dd3a74a463 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -3855,6 +3855,7 @@ SWITCH_STANDARD_API(boxcount_api_function) total_new_messages = total_saved_messages = 0; message_count(profile, id, domain, "inbox", &total_new_messages, &total_saved_messages, &total_new_urgent_messages, &total_saved_urgent_messages); + free(hi); } switch_mutex_unlock(globals.mutex); } From b78c9a115e4ce43e7d37c65816c82f078fd6466c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 30 Nov 2020 22:24:21 +0400 Subject: [PATCH 42/65] [mod_sofia] Properly handle nua events came without nua handles. --- src/mod/endpoints/mod_sofia/sofia.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7e71717aff..dcedbc7e43 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2282,7 +2282,7 @@ void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) profile->queued_events--; switch_mutex_unlock(profile->flag_mutex); - nua_handle_unref(nh); + if (nh) nua_handle_unref(nh); nua_unref(nua); } @@ -2516,7 +2516,7 @@ void sofia_event_callback(nua_event_t event, de = su_alloc(nua_handle_get_home(nh), sizeof(*de)); memset(de, 0, sizeof(*de)); nua_save_event(nua, de->event); - de->nh = nua_handle_ref(nh); + de->nh = nh ? nua_handle_ref(nh) : NULL; de->data = nua_event_data(de->event); de->sip = sip_object(de->data->e_msg); de->profile = profile; From e3e0c7c2596c3870db79eedb51fe77cf45a89fc7 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 1 Dec 2020 04:21:57 +0400 Subject: [PATCH 43/65] [mod_sofia] Protect insertion into profile->reg_nh_hash with a mutex. --- src/mod/endpoints/mod_sofia/sofia_reg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index b1586405b7..5eee1c17e3 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1933,7 +1933,6 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu switch_mutex_lock(profile->flag_mutex); hnh = switch_core_hash_find(profile->reg_nh_hash, key); - switch_mutex_unlock(profile->flag_mutex); if (!hnh) { if (!(sofia_private = su_alloc(nua_handle_get_home(nh), sizeof(*sofia_private)))) { @@ -1954,6 +1953,8 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu nua_handle_ref(nh); switch_core_hash_insert(profile->reg_nh_hash, key, nh); } + + switch_mutex_unlock(profile->flag_mutex); } From f6e076507e6645745b733e0c91305bba7a832473 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 15 Dec 2020 00:46:08 +0400 Subject: [PATCH 44/65] [mod_loopback] Fix new_session leak in the case of a hangup_cause. --- src/mod/endpoints/mod_loopback/mod_loopback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 88400fcaf6..6fa0d4fbd4 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1700,6 +1700,7 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t * if (hangup_cause || !strncmp(caller_profile->destination_number, "cause-", 6)) { if (!hangup_cause) hangup_cause = caller_profile->destination_number + 6; + switch_core_session_destroy(new_session); return switch_channel_str2cause(hangup_cause); } From 82b6f01b692afe3a76a28e6650b7b51361300bbe Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 16 Jan 2021 22:53:23 +0300 Subject: [PATCH 45/65] [Core] Fix codec ready checks in switch_core_session_read_frame() --- src/switch_core_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 22d0474e3e..1d5ff7510b 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -227,7 +227,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert((*frame)->codec != NULL); - if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) { + if (!switch_core_codec_ready(session->read_codec) || !switch_core_codec_ready((*frame)->codec)) { status = SWITCH_STATUS_FALSE; goto done; } From 29b50439042d012d0eb020efc94201df38b0a6f8 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 20 Jan 2021 18:30:32 +0300 Subject: [PATCH 46/65] [mod_shout] Fix memory leak in do_telecast --- src/mod/formats/mod_shout/mod_shout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 6799b38391..14cba068d3 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -1333,8 +1333,6 @@ void do_telecast(switch_stream_handle_t *stream) end: - switch_safe_free(uuid); - if (gfp) { lame_close(gfp); gfp = NULL; @@ -1350,6 +1348,8 @@ void do_telecast(switch_stream_handle_t *stream) switch_core_session_rwunlock(tsession); } + + switch_safe_free(uuid); } void do_broadcast(switch_stream_handle_t *stream) From c8e7a57b4c177c19d9289e0c5db76a720c9a1e16 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 20 Jan 2021 22:31:35 +0300 Subject: [PATCH 47/65] [Unit-Tests] Fix leak of arg in the case of an error in fct_clp__parse() --- src/include/test/switch_fct.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/include/test/switch_fct.h b/src/include/test/switch_fct.h index a9b3595d0e..f88821b49c 100644 --- a/src/include/test/switch_fct.h +++ b/src/include/test/switch_fct.h @@ -1716,6 +1716,12 @@ fct_clp__parse(fct_clp_t *clp, int argc, char const *argv[]) arg =NULL; } } + + if (arg != NULL) + { + free(arg); + arg = NULL; + } } From 3e7ba04cbecb12642373ae1215925372c5137cd3 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 21 Jan 2021 00:46:40 +0300 Subject: [PATCH 48/65] [mod_curl] Avoid passing null pointer value via data parameter of do_lookup_url() --- src/mod/applications/mod_curl/mod_curl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index e82502cb6c..f0c952a215 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -799,7 +799,7 @@ SWITCH_STANDARD_APP(curl_app_function) switch_channel_t *channel = switch_core_session_get_channel(session); char *url = NULL; char *method = NULL; - char *postdata = NULL; + char *postdata = ""; char *content_type = NULL; switch_bool_t do_headers = SWITCH_FALSE; switch_bool_t do_json = SWITCH_FALSE; @@ -920,7 +920,7 @@ SWITCH_STANDARD_API(curl_function) char *mydata = NULL; char *url = NULL; char *method = NULL; - char *postdata = NULL; + char *postdata = ""; char *content_type = NULL; switch_bool_t do_headers = SWITCH_FALSE; switch_bool_t do_json = SWITCH_FALSE; From e614f08c9342062b4bdb5dc52809d8c25eb05744 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 21 Jan 2021 17:40:29 +0300 Subject: [PATCH 49/65] [mod_httapi] Fix memory leak of dup_creds in httapi_sync() --- src/mod/applications/mod_httapi/mod_httapi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 76d273d020..cc2c857a58 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1534,6 +1534,7 @@ static switch_status_t httapi_sync(client_t *client) char *q, *p = strstr(dynamic_url, "://"); use_url++; + switch_safe_free(dup_creds); dup_creds = strdup(p+3); *p = '\0'; From c282386fdb9d8944eaf2414ec817da936c4500cb Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 21 Jan 2021 18:29:44 +0300 Subject: [PATCH 50/65] [mod_pgsql] Fix memory leek in the case of an empty string of err_str in pgsql_handle_exec_base_detailed() --- src/mod/databases/mod_pgsql/mod_pgsql.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/databases/mod_pgsql/mod_pgsql.c b/src/mod/databases/mod_pgsql/mod_pgsql.c index e2efa5252c..f7c2983f91 100644 --- a/src/mod/databases/mod_pgsql/mod_pgsql.c +++ b/src/mod/databases/mod_pgsql/mod_pgsql.c @@ -515,6 +515,7 @@ error: err_str = pgsql_handle_get_error(handle); if (zstr(err_str)) { + switch_safe_free(err_str); if (!er) { err_str = strdup((char *)"SQL ERROR!"); } else { From be6b40b024d38b64ca515be3087a5a39db0f867b Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 21 Jan 2021 18:43:02 +0300 Subject: [PATCH 51/65] [mod_lcr] Fix order_by and sql_stream streams leaking in the case of a DB error in lcr_load_config() --- src/mod/applications/mod_lcr/mod_lcr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index a9adb3db10..ab7c163ce5 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1186,6 +1186,8 @@ static switch_status_t lcr_load_config() if (db_check("ALTER TABLE carrier_gateway add codec varchar(255);") == SWITCH_TRUE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "adding codec field your lcr carrier_gateway database schema.\n"); } else { + switch_safe_free(order_by.data); + switch_safe_free(sql_stream.data); switch_goto_status(SWITCH_STATUS_FALSE, done); } } @@ -1197,6 +1199,8 @@ static switch_status_t lcr_load_config() if (db_check("ALTER TABLE lcr add cid varchar(32);") == SWITCH_TRUE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n"); } else { + switch_safe_free(order_by.data); + switch_safe_free(sql_stream.data); switch_goto_status(SWITCH_STATUS_FALSE, done); } } @@ -1205,6 +1209,8 @@ static switch_status_t lcr_load_config() if (db_check("ALTER TABLE lcr ADD lrn BOOLEAN NOT NULL DEFAULT false")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding lrn field to your lcr database schema.\n"); } else { + switch_safe_free(order_by.data); + switch_safe_free(sql_stream.data); switch_goto_status(SWITCH_STATUS_FALSE, done); } } From 91066f56fa85d1ca592d78a61846c45cc7409b0c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 21 Jan 2021 19:38:37 +0300 Subject: [PATCH 52/65] [Core] Fix leaking stream in switch_event_expand_headers_check() --- src/switch_event.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index efe43e603a..295708eda3 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -2464,8 +2464,6 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, char *expanded = NULL; char *expanded_vname = NULL; - SWITCH_STANDARD_STREAM(stream); - if ((expanded_vname = switch_event_expand_headers_check(event, (char *) vname, var_list, api_list, recur+1)) == vname) { expanded_vname = NULL; } else { @@ -2482,6 +2480,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, func_val = NULL; sub_val = ""; } else { + SWITCH_STANDARD_STREAM(stream); if (switch_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) { func_val = stream.data; sub_val = func_val; From 2a8804af9760b8038cc3edc58741f4f0626c5af6 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 21 Jan 2021 22:32:12 +0300 Subject: [PATCH 53/65] [Core] Fix leak of switch_event_header_t in switch_event_base_add_header(). Code cleanup. --- src/switch_event.c | 88 ++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index 295708eda3..709ea95e7e 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -129,6 +129,8 @@ static char *my_dup(const char *s) #define FREE(ptr) switch_safe_free(ptr) #endif +static void free_header(switch_event_header_t **header); + /* make sure this is synced with the switch_event_types_t enum in switch_types.h also never put any new ones before EVENT_ALL */ @@ -891,27 +893,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *even if (hp == event->last_header || !hp->next) { event->last_header = lp; } - FREE(hp->name); - - if (hp->idx) { - int i = 0; - - for (i = 0; i < hp->idx; i++) { - FREE(hp->array[i]); - } - FREE(hp->array); - } - - FREE(hp->value); - - memset(hp, 0, sizeof(*hp)); -#ifdef SWITCH_EVENT_RECYCLE - if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, hp) != SWITCH_STATUS_SUCCESS) { - FREE(hp); - } -#else - FREE(hp); -#endif + free_header(&hp); status = SWITCH_STATUS_SUCCESS; } else { lp = hp; @@ -944,6 +926,37 @@ static switch_event_header_t *new_header(const char *header_name) } +static void free_header(switch_event_header_t **header) +{ + assert(header); + + if (*header) { + if ((*header)->idx) { + if (!(*header)->array) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INDEX WITH NO ARRAY ?? [%s][%s]\n", (*header)->name, (*header)->value); + } else { + int i = 0; + + for (i = 0; i < (*header)->idx; i++) { + FREE((*header)->array[i]); + } + FREE((*header)->array); + } + } + + FREE((*header)->name); + FREE((*header)->value); + +#ifdef SWITCH_EVENT_RECYCLE + if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, *header) != SWITCH_STATUS_SUCCESS) { + FREE(*header); + } +#else + FREE(*header); +#endif + } +} + SWITCH_DECLARE(int) switch_event_add_array(switch_event_t *event, const char *var, const char *val) { char *data; @@ -1012,10 +1025,11 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc } if (index_ptr || (stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) { + switch_event_header_t *tmp_header = NULL; if (!(header = switch_event_get_header_ptr(event, header_name)) && index_ptr) { - header = new_header(header_name); + tmp_header = header = new_header(header_name); if (switch_test_flag(event, EF_UNIQ_HEADERS)) { switch_event_del_header(event, header_name); @@ -1049,6 +1063,8 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc goto redraw; } + } else if (tmp_header) { + free_header(&tmp_header); } goto end; } else { @@ -1266,33 +1282,7 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event) for (hp = ep->headers; hp;) { this = hp; hp = hp->next; - - if (this->idx) { - if (!this->array) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INDEX WITH NO ARRAY WTF?? [%s][%s]\n", this->name, this->value); - } else { - int i = 0; - - for (i = 0; i < this->idx; i++) { - FREE(this->array[i]); - } - FREE(this->array); - } - } - - FREE(this->name); - FREE(this->value); - - -#ifdef SWITCH_EVENT_RECYCLE - if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, this) != SWITCH_STATUS_SUCCESS) { - FREE(this); - } -#else - FREE(this); -#endif - - + free_header(&this); } FREE(ep->body); FREE(ep->subclass_name); From d127eeeeccc4f3c137e5d6f8195d45c0710140fc Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Jan 2021 21:45:37 +0300 Subject: [PATCH 54/65] [mod_snom, mod_snmp] Replace strncpy with snprintf --- src/mod/applications/mod_snom/mod_snom.c | 2 +- src/mod/event_handlers/mod_snmp/subagent.c | 28 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/mod/applications/mod_snom/mod_snom.c b/src/mod/applications/mod_snom/mod_snom.c index af460e7523..2f706c2556 100644 --- a/src/mod/applications/mod_snom/mod_snom.c +++ b/src/mod/applications/mod_snom/mod_snom.c @@ -143,7 +143,7 @@ SWITCH_STANDARD_API(snom_command_api_function) } if (switch_inet_pton(AF_INET, argv[0], &ip)) { - strncpy(host, argv[0], sizeof(host)); + snprintf(host, sizeof(host), "%s", argv[0]); } else { char *sql = NULL; char *ret = NULL; diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index dd29939e6a..cd61955461 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -79,22 +79,22 @@ static int channelList_callback(void *pArg, int argc, char **argv, char **column row->data = entry; entry->idx = idx++; - strncpy(entry->uuid, switch_str_nil(argv[0]), sizeof(entry->uuid)); - strncpy(entry->direction, switch_str_nil(argv[1]), sizeof(entry->direction)); + snprintf(entry->uuid, sizeof(entry->uuid), "%s", switch_str_nil(argv[0])); + snprintf(entry->direction, sizeof(entry->direction), "%s", switch_str_nil(argv[1])); entry->created_epoch = atoi(argv[3]); - strncpy(entry->name, switch_str_nil(argv[4]), sizeof(entry->name)); - strncpy(entry->state, switch_str_nil(argv[5]), sizeof(entry->state)); - strncpy(entry->cid_name, switch_str_nil(argv[6]), sizeof(entry->cid_name)); - strncpy(entry->cid_num, switch_str_nil(argv[7]), sizeof(entry->cid_num)); - strncpy(entry->dest, switch_str_nil(argv[9]), sizeof(entry->dest)); - strncpy(entry->application, switch_str_nil(argv[10]), sizeof(entry->application)); - strncpy(entry->application_data, switch_str_nil(argv[11]), sizeof(entry->application_data)); - strncpy(entry->dialplan, switch_str_nil(argv[12]), sizeof(entry->dialplan)); - strncpy(entry->context, switch_str_nil(argv[13]), sizeof(entry->context)); - strncpy(entry->read_codec, switch_str_nil(argv[14]), sizeof(entry->read_codec)); + snprintf(entry->name, sizeof(entry->name), "%s", switch_str_nil(argv[4])); + snprintf(entry->state, sizeof(entry->state), "%s", switch_str_nil(argv[5])); + snprintf(entry->cid_name, sizeof(entry->cid_name), "%s", switch_str_nil(argv[6])); + snprintf(entry->cid_num, sizeof(entry->cid_num), "%s", switch_str_nil(argv[7])); + snprintf(entry->dest, sizeof(entry->dest), "%s", switch_str_nil(argv[9])); + snprintf(entry->application, sizeof(entry->application), "%s", switch_str_nil(argv[10])); + snprintf(entry->application_data, sizeof(entry->application_data), "%s", switch_str_nil(argv[11])); + snprintf(entry->dialplan, sizeof(entry->dialplan), "%s", switch_str_nil(argv[12])); + snprintf(entry->context, sizeof(entry->context), "%s", switch_str_nil(argv[13])); + snprintf(entry->read_codec, sizeof(entry->read_codec), "%s", switch_str_nil(argv[14])); entry->read_rate = atoi(switch_str_nil(argv[15])); entry->read_bitrate = atoi(switch_str_nil(argv[16])); - strncpy(entry->write_codec, switch_str_nil(argv[17]), sizeof(entry->write_codec)); + snprintf(entry->write_codec, sizeof(entry->write_codec), "%s", switch_str_nil(argv[17])); entry->write_rate = atoi(switch_str_nil(argv[18])); entry->write_bitrate = atoi(switch_str_nil(argv[19])); @@ -186,7 +186,7 @@ int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration * snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); break; case ID_UUID: - strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); + snprintf(uuid, sizeof(uuid), "%s", switch_core_get_uuid()); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); break; default: From 97930570dce98a436ce720ec00e886c8458979b9 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Jan 2021 21:57:24 +0300 Subject: [PATCH 55/65] [Core] Fix possible memory leak of switch_core_session_message_t in switch_core_session_queue_indication() --- src/switch_core_session.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 36cf62f111..4dde4cba84 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1026,8 +1026,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_indication(switch_core msg->message_id = indication; msg->from = __FILE__; switch_set_flag(msg, SCSMF_DYNAMIC); - switch_core_session_queue_message(session, msg); - return SWITCH_STATUS_SUCCESS; + + if (switch_core_session_queue_message(session, msg) == SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_SUCCESS; + } + + free(msg); } return SWITCH_STATUS_FALSE; From 4aa1c1736fb46887dc89194a79a188506321f074 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 20 Jan 2021 18:48:01 +0300 Subject: [PATCH 56/65] [mod_sofia] scan-build in sofia_glue_do_invite(): Null pointer passed as an argument to a 'nonnull' parameter --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 2eea09bd5e..0c0035412f 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1211,7 +1211,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } sofia_glue_get_url_from_contact(rpid_domain, 0); - if ((rpid_domain = strrchr(rpid_domain, '@'))) { + if (rpid_domain && (rpid_domain = strrchr(rpid_domain, '@'))) { rpid_domain++; if ((p = strchr(rpid_domain, ';'))) { *p = '\0'; From cfdd1d9be89ae4b1e9d654ff84512671ff73bc2c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 26 Jan 2021 20:26:14 +0300 Subject: [PATCH 57/65] [mod_http_cache] Handle error cases to avoid using uninitialized variables in aws logic. --- src/mod/applications/mod_http_cache/aws.c | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/mod/applications/mod_http_cache/aws.c b/src/mod/applications/mod_http_cache/aws.c index 740fe2e9c4..cc02b4e5b5 100644 --- a/src/mod/applications/mod_http_cache/aws.c +++ b/src/mod/applications/mod_http_cache/aws.c @@ -144,10 +144,12 @@ static char* aws_s3_signature_key(char* key_signing, switch_aws_s3_profile* aws_ char key_service[SHA256_DIGEST_LENGTH]; char* aws4_secret_access_key = switch_mprintf("AWS4%s", aws_s3_profile->access_key_secret); - hmac256(key_date, SHA256_DIGEST_LENGTH, aws4_secret_access_key, strlen(aws4_secret_access_key), aws_s3_profile->date_stamp); - hmac256(key_region, SHA256_DIGEST_LENGTH, key_date, SHA256_DIGEST_LENGTH, aws_s3_profile->region); - hmac256(key_service, SHA256_DIGEST_LENGTH, key_region, SHA256_DIGEST_LENGTH, "s3"); - hmac256(key_signing, SHA256_DIGEST_LENGTH, key_service, SHA256_DIGEST_LENGTH, "aws4_request"); + if (!hmac256(key_date, SHA256_DIGEST_LENGTH, aws4_secret_access_key, (unsigned int)strlen(aws4_secret_access_key), aws_s3_profile->date_stamp) + || !hmac256(key_region, SHA256_DIGEST_LENGTH, key_date, SHA256_DIGEST_LENGTH, aws_s3_profile->region) + || !hmac256(key_service, SHA256_DIGEST_LENGTH, key_region, SHA256_DIGEST_LENGTH, "s3") + || !hmac256(key_signing, SHA256_DIGEST_LENGTH, key_service, SHA256_DIGEST_LENGTH, "aws4_request")) { + key_signing = NULL; + } switch_safe_free(aws4_secret_access_key); @@ -166,7 +168,7 @@ static char* aws_s3_standardized_query_string(switch_aws_s3_profile* aws_s3_prof char* standardized_query_string; credential = switch_mprintf("%s%%2F%s%%2F%s%%2Fs3%%2Faws4_request", aws_s3_profile->access_key_id, aws_s3_profile->date_stamp, aws_s3_profile->region); - switch_snprintf(expires, 9, "%ld", aws_s3_profile->expires); + switch_snprintf(expires, 9, "%" SWITCH_TIME_T_FMT, aws_s3_profile->expires); standardized_query_string = switch_mprintf( "X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=%s&X-Amz-Date=%s&X-Amz-Expires=%s&X-Amz-SignedHeaders=host", @@ -243,13 +245,14 @@ static char *aws_s3_authentication_create(switch_aws_s3_profile* aws_s3_profile) string_to_sign = aws_s3_string_to_sign(standardized_request, aws_s3_profile); // Get signature_key - aws_s3_signature_key(signature_key, aws_s3_profile); - - // Get signature - hmac256_hex(signature, signature_key, SHA256_DIGEST_LENGTH, string_to_sign); - - // Build final query string - query_param = switch_mprintf("%s&X-Amz-Signature=%s", standardized_query_string, signature); + if (!aws_s3_signature_key(signature_key, aws_s3_profile) + // Get signature + || !hmac256_hex(signature, signature_key, SHA256_DIGEST_LENGTH, string_to_sign)) { + query_param = NULL; + } else { + // Build final query string + query_param = switch_mprintf("%s&X-Amz-Signature=%s", standardized_query_string, signature); + } switch_safe_free(string_to_sign); switch_safe_free(standardized_query_string); From f348ab9d3893ad116e7c94a7fd2d42f4307b7313 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 26 Jan 2021 20:23:52 +0300 Subject: [PATCH 58/65] [mod_sofia] Fix use of uninitialized network_ip in sofia_handle_sip_r_invite() --- src/mod/endpoints/mod_sofia/sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index dcedbc7e43..e1e6435670 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6516,7 +6516,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status const char *uuid; switch_core_session_t *other_session; private_object_t *tech_pvt = switch_core_session_get_private(session); - char network_ip[80]; + char network_ip[80] = ""; int network_port = 0; switch_caller_profile_t *caller_profile = NULL; int has_t38 = 0; From 3134c9aa578d119528a610c5d1fcfa2ec1ac4c6e Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 26 Jan 2021 20:24:38 +0300 Subject: [PATCH 59/65] [mod_callcenter] Fix use of uninitialized res variable in cc_agent_update() --- src/mod/applications/mod_callcenter/mod_callcenter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 58816ea0ac..cba6dc84f4 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -998,7 +998,7 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen { cc_status_t result = CC_STATUS_SUCCESS; char *sql; - char res[256]; + char res[256] = ""; switch_event_t *event; /* Check to see if agent already exist */ From e6e227d1f4f44f64966417f37b2cb9bb7fd6daae Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 28 Jan 2021 03:13:13 +0300 Subject: [PATCH 60/65] [Core] Fix leaking stream in switch_channel_expand_variables_check() --- src/switch_channel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_channel.c b/src/switch_channel.c index c5c61d43ae..09a0697f9f 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -4175,6 +4175,7 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c if (!switch_core_test_flag(SCF_API_EXPANSION) || (api_list && !switch_event_check_permission_list(api_list, vname))) { func_val = NULL; sub_val = ""; + free(stream.data); } else { if (switch_api_execute(vname, vval, channel->session, &stream) == SWITCH_STATUS_SUCCESS) { func_val = stream.data; From 2ca0d02531f91f66cc2f34b909eb14221dc04f54 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 18 Feb 2021 19:02:03 +0300 Subject: [PATCH 61/65] [Core] Fix leaking codec, timer and abuf in switch_ivr_play_file() in the case of failing switch_ivr_phrase_macro() or switch_ivr_speak_text() --- src/switch_ivr_play_say.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index e217950958..a8cb5fd4a1 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1309,8 +1309,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess *arg++ = '\0'; } if ((status = switch_ivr_phrase_macro(session, dup, arg, lang, args)) != SWITCH_STATUS_SUCCESS) { - arg_recursion_check_stop(args); - return status; + break; } continue; } else { @@ -1327,8 +1326,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (engine && text) { if ((status = switch_ivr_speak_text(session, engine, voice, (char *)text, args)) != SWITCH_STATUS_SUCCESS) { - arg_recursion_check_stop(args); - return status; + break; } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Args\n"); From 8e2234a205f9b19b628670df6d517974c62b2317 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 20 Feb 2021 21:14:15 +0300 Subject: [PATCH 62/65] [Core] Fix race between switch_ivr_park_session() and the state machine. switch_core_session_run() wants to clear the CF_TRANSFER flag on state change while parking sets the flag. --- src/switch_ivr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 9aa05fcd73..f1493a723d 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -3522,8 +3522,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_json_cdr(switch_core_session SWITCH_DECLARE(void) switch_ivr_park_session(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_set_state(channel, CS_PARK); switch_channel_set_flag(channel, CF_TRANSFER); + switch_channel_set_state(channel, CS_PARK); } From 9e49a4176b3f1583eb3064076f8676918e4dcf35 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Sat, 20 Feb 2021 19:17:50 +0000 Subject: [PATCH 63/65] [test] Fix fst_session_park() to wait for CF_PARK instead of CS_PARK. CF_PARK will be set when the channel has actually parked. --- src/include/test/switch_test.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/test/switch_test.h b/src/include/test/switch_test.h index eb6f7f3ee6..3413884145 100644 --- a/src/include/test/switch_test.h +++ b/src/include/test/switch_test.h @@ -141,7 +141,7 @@ static switch_status_t fst_init_core_and_modload(const char *confdir, const char */ #define fst_session_park(session) \ switch_ivr_park_session(session); \ - switch_channel_wait_for_state(switch_core_session_get_channel(session), NULL, CS_PARK); + switch_channel_wait_for_flag(switch_core_session_get_channel(session), CF_PARK, SWITCH_TRUE, 10000, NULL); /** * check for test requirement - execute teardown on failure From 0059f0cc1b34a59818a7bfc5074b7be94b2e432a Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 18 Mar 2021 00:53:38 +0300 Subject: [PATCH 64/65] [mod_sofia] Gateways DOWN state introduced a regression: REG gateways in DOWN state could not be killed. NOREG gateways could change state in some conditions. Register and Unregister commands will now error if a gateway is NOREG. --- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++++ src/mod/endpoints/mod_sofia/sofia_reg.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 3143fffa42..ecc925cf78 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3666,6 +3666,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t gateway_ptr->state = REG_STATE_UNREGED; stream->write_function(stream, "+OK\n"); sofia_reg_release_gateway(gateway_ptr); + } else { + stream->write_function(stream, "-ERR NOREG gateway [%s] can't be registered!\n", gname); } } else { stream->write_function(stream, "Invalid gateway!\n"); @@ -3697,6 +3699,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t gateway_ptr->state = REG_STATE_UNREGISTER; stream->write_function(stream, "+OK\n"); sofia_reg_release_gateway(gateway_ptr); + } else { + stream->write_function(stream, "-ERR NOREG gateway [%s] can't be unregistered!\n", gname); } } else { stream->write_function(stream, "Invalid gateway!\n"); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 5eee1c17e3..22997cecae 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -323,7 +323,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) free(pkey); } - if (gateway_ptr->state == REG_STATE_NOREG) { + if (gateway_ptr->state == REG_STATE_NOREG || gateway_ptr->state == REG_STATE_DOWN) { if (last) { last->next = gateway_ptr->next; @@ -356,7 +356,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) char *user_via = NULL; char *register_host = NULL; - if (!now) { + if (!now && ostate != REG_STATE_NOREG) { gateway_ptr->state = ostate = REG_STATE_UNREGED; gateway_ptr->expires_str = "0"; } From 9c589b7750f277a52e82c7c773cd093af40c4e6a Mon Sep 17 00:00:00 2001 From: sergey-safarov Date: Fri, 19 Mar 2021 00:30:08 +0300 Subject: [PATCH 65/65] [Build-System] freeswitch.spec update * freeswitch.spec: mod_shout - build always enabled * Removed not nessary erlang spec file * freeswitch.spec: Added cache direcory to http_cache module * freeswitch.spec: added zrtp feature in packaging * freeswitch.spec: added dependency for gumbo-parser-devel on fedora dist (HTML parser for MSRP) * remove autoload_configs dir dublication --- erlang.spec | 297 ------------------------------------------------ freeswitch.spec | 21 ++-- 2 files changed, 7 insertions(+), 311 deletions(-) delete mode 100644 erlang.spec diff --git a/erlang.spec b/erlang.spec deleted file mode 100644 index 6cdd7245b9..0000000000 --- a/erlang.spec +++ /dev/null @@ -1,297 +0,0 @@ -%define ver %{VERSION_NUMBER} -%define rel %{RELEASE_NUMBER} - -Name: erlang -Version: %{ver} -Release: %{rel}.1%{?dist} -Summary: General-purpose programming language and runtime environment - -Group: Development/Languages -License: ERPL -URL: http://www.erlang.org -Source: http://www.erlang.org/download/otp_src_R14B03.tar.gz -Source1: http://www.erlang.org/download/otp_doc_html_R14B03.tar.gz -Source2: http://www.erlang.org/download/otp_doc_man_R14B03.tar.gz -Patch1: otp-R14B-00-0001-Do-not-format-man-pages.patch -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -BuildRequires: ncurses-devel -BuildRequires: openssl-devel -BuildRequires: unixODBC-devel -BuildRequires: tcl-devel -BuildRequires: tk-devel -BuildRequires: gd-devel -# BuildRequires: jdk -BuildRequires: flex -BuildRequires: m4 - -Requires: tk - -# Added virtual Provides for each erlang module -Provides: erlang-appmon = %{version}-%{release} -Provides: erlang-asn1 = %{version}-%{release} -Provides: erlang-common_test = %{version}-%{release} -Provides: erlang-compiler = %{version}-%{release} -Provides: erlang-cosEvent = %{version}-%{release} -Provides: erlang-cosEventDomain = %{version}-%{release} -Provides: erlang-cosFileTransfer = %{version}-%{release} -Provides: erlang-cosNotification = %{version}-%{release} -Provides: erlang-cosProperty = %{version}-%{release} -Provides: erlang-cosTime = %{version}-%{release} -Provides: erlang-cosTransactions = %{version}-%{release} -Provides: erlang-crypto = %{version}-%{release} -Provides: erlang-debugger = %{version}-%{release} -Provides: erlang-dialyzer = %{version}-%{release} -Provides: erlang-docbuilder = %{version}-%{release} -Provides: erlang-edoc = %{version}-%{release} -Provides: erlang-erts = %{version}-%{release} -Provides: erlang-et = %{version}-%{release} -Provides: erlang-eunit = %{version}-%{release} -Provides: erlang-gs = %{version}-%{release} -Provides: erlang-hipe = %{version}-%{release} -Provides: erlang-ic = %{version}-%{release} -Provides: erlang-inets = %{version}-%{release} -Provides: erlang-inviso = %{version}-%{release} -Provides: erlang-kernel = %{version}-%{release} -Provides: erlang-megaco = %{version}-%{release} -Provides: erlang-mnesia = %{version}-%{release} -Provides: erlang-observer = %{version}-%{release} -Provides: erlang-odbc = %{version}-%{release} -Provides: erlang-orber = %{version}-%{release} -Provides: erlang-os_mon = %{version}-%{release} -Provides: erlang-otp_mibs = %{version}-%{release} -Provides: erlang-parsetools = %{version}-%{release} -Provides: erlang-percept = %{version}-%{release} -Provides: erlang-pman = %{version}-%{release} -Provides: erlang-public_key = %{version}-%{release} -Provides: erlang-runtime_tools = %{version}-%{release} -Provides: erlang-sasl = %{version}-%{release} -Provides: erlang-snmp = %{version}-%{release} -Provides: erlang-ssh = %{version}-%{release} -Provides: erlang-ssl = %{version}-%{release} -Provides: erlang-stdlib = %{version}-%{release} -Provides: erlang-syntax_tools = %{version}-%{release} -Provides: erlang-test_server = %{version}-%{release} -Provides: erlang-toolbar = %{version}-%{release} -Provides: erlang-tools = %{version}-%{release} -Provides: erlang-tv = %{version}-%{release} -Provides: erlang-typer = %{version}-%{release} -Provides: erlang-webtool = %{version}-%{release} -Provides: erlang-xmerl = %{version}-%{release} - -%description -Erlang is a general-purpose programming language and runtime -environment. Erlang has built-in support for concurrency, distribution -and fault tolerance. Erlang is used in several large telecommunication -systems from Ericsson. - - -%package doc -Summary: Erlang documentation -Group: Development/Languages - -%description doc -Documentation for Erlang. - - -%prep -%setup -q -n otp_src_%{ver}%{rel} -#%setup -q -n otp_src_%{ver} - -%build -# WARN: --enable-dynamic-ssl-lib needed for preventing strange messages about missing dependencies on EPEL -# see https://bugzilla.redhat.com/458646 and https://bugzilla.redhat.com/499525 -%ifarch sparcv9 sparc64 -CFLAGS="$RPM_OPT_FLAGS -mcpu=ultrasparc -fno-strict-aliasing" %configure --enable-dynamic-ssl-lib -%else -CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" %configure --enable-dynamic-ssl-lib -%endif -chmod -R u+w . -make - - -%install -rm -rf $RPM_BUILD_ROOT -make INSTALL_PREFIX=$RPM_BUILD_ROOT install - -# clean up -find $RPM_BUILD_ROOT%{_libdir}/erlang -perm 0775 | xargs chmod 755 -find $RPM_BUILD_ROOT%{_libdir}/erlang -name Makefile | xargs chmod 644 -find $RPM_BUILD_ROOT%{_libdir}/erlang -name \*.o | xargs chmod 644 -find $RPM_BUILD_ROOT%{_libdir}/erlang -name \*.bat | xargs rm -f -find $RPM_BUILD_ROOT%{_libdir}/erlang -name index.txt.old | xargs rm -f - -# doc -mkdir -p erlang_doc -tar -C erlang_doc -zxf %{SOURCE1} -tar -C $RPM_BUILD_ROOT/%{_libdir}/erlang -zxf %{SOURCE2} - -# make links to binaries -#mkdir -p $RPM_BUILD_ROOT/%{_bindir} -#cd $RPM_BUILD_ROOT/%{_bindir} -#for file in erl erlc escript dialyzer -#do -# ln -sf ../%{_lib}/erlang/bin/$file . -#done - -# remove buildroot from installed files -cd $RPM_BUILD_ROOT/%{_libdir}/erlang -sed -i "s|$RPM_BUILD_ROOT||" erts*/bin/{erl,start} releases/RELEASES bin/{erl,start} - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%files -%defattr(-,root,root) -%doc AUTHORS EPLICENCE README.md -%{_bindir}/* -%{_libdir}/erlang - - -%files doc -%defattr(-,root,root) -%doc erlang_doc/* - - -%post -%{_libdir}/erlang/Install -minimal %{_libdir}/erlang >/dev/null 2>/dev/null - - -%changelog -* Wed Sep 29 2010 Anthony Molinaro - R14B-00.1 -- modified R13B04 spec to work with R14B - -* Wed Jul 7 2010 Anthony Molinaro - R13B-04.1 -- modified the R12B spec to work with R13B04 - -* Mon Jun 7 2010 Peter Lemenkov - R12B-5.10 -- Added missing virtual provides erlang-erts - -* Tue May 25 2010 Peter Lemenkov - R12B-5.9 -- Use java-1.4.2 only for EL-[45] -- Added virtual provides for each erlang module -- Small typo fix - -* Mon Apr 19 2010 Peter Lemenkov - R12B-5.8 -- Patches rebased -- Added patches 6,7 from trunk -- Use %%configure - -* Tue Apr 21 2009 Debarshi Ray R12B-5.7 -- Updated rpath patch. -- Fixed configure to respect $RPM_OPT_FLAGS. - -* Sun Mar 1 2009 Gerard Milmeister - R12B-5.6 -- new release R12B-5 -- link escript and dialyzer to %{_bindir} - -* Tue Feb 24 2009 Fedora Release Engineering - R12B-5.5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild - -* Sat Feb 14 2009 Dennis Gilmore - R12B-4.5 -- fix sparc arches to compile - -* Fri Jan 16 2009 Tomas Mraz - R12B-4.4 -- rebuild with new openssl - -* Sat Oct 25 2008 Gerard Milmeister - R12B-4.1 -- new release R12B-4 - -* Fri Sep 5 2008 Gerard Milmeister - R12B-3.3 -- fixed sslrpath patch - -* Thu Jul 17 2008 Tom "spot" Callaway - R12B-3.2 -- fix license tag - -* Sun Jul 6 2008 Gerard Milmeister - R12B-3.1 -- new release R12B-3 - -* Thu Mar 27 2008 Gerard Milmeister - R12B-1.1 -- new release R12B-1 - -* Sat Feb 23 2008 Gerard Milmeister - R12B-0.3 -- disable strict aliasing optimization - -* Mon Feb 18 2008 Fedora Release Engineering - R12B-0.2 -- Autorebuild for GCC 4.3 - -* Sat Dec 8 2007 Gerard Milmeister - R12B-0.1 -- new release R12B-0 - -* Wed Dec 05 2007 Release Engineering - R11B-6 - - Rebuild for deps - -* Sun Aug 19 2007 Gerard Milmeister - R11B-5.3 -- fix some permissions - -* Sat Aug 18 2007 Gerard Milmeister - R11B-5.2 -- enable dynamic linking for ssl - -* Sat Aug 18 2007 Gerard Milmeister - R11B-5.1 -- new release R11B-5 - -* Sat Mar 24 2007 Thomas Fitzsimmons - R11B-2.4 -- Require java-1.5.0-gcj-devel for build. - -* Sun Dec 31 2006 Gerard Milmeister - R11B-2.3 -- remove buildroot from installed files - -* Sat Dec 30 2006 Gerard Milmeister - R11B-2.2 -- added patch for compiling with glibc 2.5 - -* Sat Dec 30 2006 Gerard Milmeister - R11B-2.1 -- new version R11B-2 - -* Mon Aug 28 2006 Gerard Milmeister - R11B-0.3 -- Rebuild for FE6 - -* Wed Jul 5 2006 Gerard Milmeister - R11B-0.2 -- add BR m4 - -* Thu May 18 2006 Gerard Milmeister - R11B-0.1 -- new version R11B-0 - -* Wed May 3 2006 Gerard Milmeister - R10B-10.3 -- added patch for run_erl by Knut-HÃ¥vard Aksnes - -* Mon Mar 13 2006 Gerard Milmeister - R10B-10.1 -- new version R10B-10 - -* Thu Dec 29 2005 Gerard Milmeister - R10B-9.1 -- New Version R10B-9 - -* Sat Oct 29 2005 Gerard Milmeister - R10B-8.2 -- updated rpath patch - -* Sat Oct 29 2005 Gerard Milmeister - R10B-8.1 -- New Version R10B-8 - -* Sat Oct 1 2005 Gerard Milmeister - R10B-6.4 -- Added tk-devel and tcl-devel to buildreq -- Added tk to req - -* Tue Sep 6 2005 Gerard Milmeister - R10B-6.3 -- Remove perl BuildRequires - -* Tue Aug 30 2005 Gerard Milmeister - R10B-6.2 -- change /usr/lib to %%{_libdir} -- redirect output in %%post to /dev/null -- add unixODBC-devel to BuildRequires -- split doc off to erlang-doc package - -* Sat Jun 25 2005 Gerard Milmeister - R10B-6.1 -- New Version R10B-6 - -* Sun Feb 13 2005 Gerard Milmeister - R10B-3.1 -- New Version R10B-3 - -* Mon Dec 27 2004 Gerard Milmeister - 0:R10B-2-0.fdr.1 -- New Version R10B-2 - -* Wed Oct 6 2004 Gerard Milmeister - 0:R10B-0.fdr.1 -- New Version R10B - -* Thu Oct 16 2003 Gerard Milmeister - 0:R9B-1.fdr.1 -- First Fedora release diff --git a/freeswitch.spec b/freeswitch.spec index 4cf49c2118..66bd762caa 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -37,7 +37,6 @@ %define build_mod_esl 0 %define build_mod_rayo 1 %define build_mod_ssml 1 -%define build_mod_shout 1 %define build_mod_opusfile 0 %define build_mod_v8 0 @@ -47,7 +46,6 @@ %{?with_py26_esl:%define build_py26_esl 1 } %{?with_timerfd:%define build_timerfd 1 } %{?with_mod_esl:%define build_mod_esl 1 } -%{?with_mod_shout:%define build_mod_shout 1 } %{?with_mod_opusfile:%define build_mod_opusfile 1 } %{?with_mod_v8:%define build_mod_v8 1 } @@ -176,6 +174,9 @@ Requires: libsndfile PreReq: %insserv_prereq %fillup_prereq %endif +%if 0%{?fedora} +BuildRequires: gumbo-parser-devel +%endif ###################################################################################################################### # @@ -1078,7 +1079,6 @@ Mod shell stream is a FreeSWITCH module to allow you to stream audio from an arbitrary shell command. You could use it to read audio from a database, from a soundcard, etc. -%if %{build_mod_shout} %package format-mod-shout Summary: Implements Media Steaming from arbitrary shell commands for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1093,7 +1093,6 @@ BuildRequires: lame-devel %description format-mod-shout Mod Shout is a FreeSWITCH module to allow you to stream audio from MP3s or a i shoutcast stream. -%endif %if %{build_mod_opusfile} %package format-mod-opusfile @@ -1503,10 +1502,7 @@ EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo" # ###################################################################################################################### FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_portaudio_stream \ - formats/mod_shell_stream formats/mod_sndfile formats/mod_tone_stream" -%if %{build_mod_shout} -FORMATS_MODULES+=" formats/mod_shout " -%endif + formats/mod_shell_stream formats/mod_shout formats/mod_sndfile formats/mod_tone_stream" %if %{build_mod_ssml} FORMATS_MODULES+=" formats/mod_ssml" %endif @@ -1622,6 +1618,7 @@ autoreconf --force --install --with-odbc \ --with-erlang \ --with-openssl \ +--enable-zrtp \ %{?configure_options} unset MODULES @@ -1645,6 +1642,7 @@ cd libs/esl %{__mkdir} -p %{buildroot}%{prefix}/log %{__mkdir} -p %{buildroot}%{logfiledir} %{__mkdir} -p %{buildroot}%{runtimedir} +%{__mkdir} -p %{buildroot}%{_localstatedir}/cache/freeswitch #install the esl stuff cd libs/esl @@ -2073,6 +2071,7 @@ fi %{MODINSTDIR}/mod_httapi.so* %files application-http-cache +%dir %attr(0750, freeswitch, daemon) %{_localstatedir}/cache/freeswitch %{MODINSTDIR}/mod_http_cache.so* %files application-lcr @@ -2324,10 +2323,8 @@ fi %files format-shell-stream %{MODINSTDIR}/mod_shell_stream.so* -%if %{build_mod_shout} %files format-mod-shout %{MODINSTDIR}/mod_shout.so* -%endif %if %{build_mod_ssml} %files format-ssml @@ -2344,18 +2341,15 @@ fi ###################################################################################################################### %files lua %{MODINSTDIR}/mod_lua*.so* -%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/lua.conf.xml %files perl %{MODINSTDIR}/mod_perl*.so* %{prefix}/perl/* -%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/perl.conf.xml %files python %{MODINSTDIR}/mod_python*.so* -%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/python.conf.xml %if %{build_mod_v8} @@ -2365,7 +2359,6 @@ fi %{LIBDIR}/libicui18n.so %{LIBDIR}/libicuuc.so %endif -%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/v8.conf.xml ######################################################################################################################