pjsip show channelstats: Prevent possible segfault when faxing
Under rare circumstances, it's possible for the original audio
session in the active_media_state default_session to be corrupted
instead of removed when switching to the t38/image media session
during fax negotiation. This can cause a segfault when a "pjsip
show channelstats" attempts to print that audio media session's
rtp statistics. In these cases, the active_media_state
topology is correctly showing only a single t38/image stream
so we now check that there's an audio stream in the topology
before attempting to use the audio media session to get the rtp
statistics.
Resolves: #592
(cherry picked from commit cb057a6381
)
This commit is contained in:
parent
6df5fbee65
commit
f770c9c92c
|
@ -343,6 +343,7 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags)
|
|||
struct ast_sip_session *session;
|
||||
struct ast_sip_session_media *media;
|
||||
struct ast_rtp_instance_stats stats;
|
||||
struct ast_stream *stream;
|
||||
char *print_name = NULL;
|
||||
char *print_time = alloca(32);
|
||||
char codec_in_use[7];
|
||||
|
@ -359,16 +360,29 @@ static int cli_channelstats_print_body(void *obj, void *arg, int flags)
|
|||
|
||||
cpvt = ast_channel_tech_pvt(channel);
|
||||
session = cpvt ? cpvt->session : NULL;
|
||||
if (!session) {
|
||||
|
||||
if (!session
|
||||
|| !session->active_media_state
|
||||
|| !session->active_media_state->topology) {
|
||||
ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
|
||||
ast_channel_unlock(channel);
|
||||
ao2_cleanup(channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream = ast_stream_topology_get_first_stream_by_type(
|
||||
session->active_media_state->topology, AST_MEDIA_TYPE_AUDIO);
|
||||
|
||||
if (!stream) {
|
||||
ast_str_append(&context->output_buffer, 0, " %s no audio streams\n", snapshot->base->name);
|
||||
ast_channel_unlock(channel);
|
||||
ao2_cleanup(channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
|
||||
if (!media || !media->rtp) {
|
||||
ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
|
||||
if (!media || media->type != AST_MEDIA_TYPE_AUDIO || !media->rtp) {
|
||||
ast_str_append(&context->output_buffer, 0, " %s corrupted default audio session\n", snapshot->base->name);
|
||||
ast_channel_unlock(channel);
|
||||
ao2_cleanup(channel);
|
||||
return 0;
|
||||
|
|
|
@ -2460,6 +2460,10 @@ int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp
|
|||
{
|
||||
int res;
|
||||
|
||||
if (!instance || !instance->engine || !stats) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (instance->engine->get_stat) {
|
||||
ao2_lock(instance);
|
||||
res = instance->engine->get_stat(instance, stats, stat);
|
||||
|
|
Loading…
Reference in New Issue