mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-02 19:16:15 +00:00
resource_channels.c: Fix memory leak in ast_ari_channels_external_media.
Between ast_ari_channels_external_media(), external_media_rtp_udp(),
and external_media_audiosocket_tcp(), the `variables` structure being passed
around wasn't being cleaned up properly when there was a failure.
* In ast_ari_channels_external_media(), the `variables` structure is now
defined with RAII_VAR to ensure it always gets cleaned up.
* The ast_variables_destroy() call was removed from external_media_rtp_udp().
* The ast_variables_destroy() call was removed from
external_media_audiosocket_tcp(), its `endpoint` allocation was changed to
to use ast_asprintf() as external_media_rtp_udp() does, and it now
returns an error on failure.
* ast_ari_channels_external_media() now checks the new return code from
external_media_audiosocket_tcp() and sets the appropriate error response.
Resolves: #1109
(cherry picked from commit 5267c17645
)
This commit is contained in:
committed by
Asterisk Development Team
parent
0e8bde6bde
commit
762c0187e1
@@ -2111,7 +2111,6 @@ static int external_media_rtp_udp(struct ast_ari_channels_external_media_args *a
|
|||||||
NULL,
|
NULL,
|
||||||
args->format,
|
args->format,
|
||||||
response);
|
response);
|
||||||
ast_variables_destroy(variables);
|
|
||||||
|
|
||||||
ast_free(endpoint);
|
ast_free(endpoint);
|
||||||
|
|
||||||
@@ -2129,24 +2128,23 @@ static int external_media_rtp_udp(struct ast_ari_channels_external_media_args *a
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void external_media_audiosocket_tcp(struct ast_ari_channels_external_media_args *args,
|
static int external_media_audiosocket_tcp(struct ast_ari_channels_external_media_args *args,
|
||||||
struct ast_variable *variables,
|
struct ast_variable *variables,
|
||||||
struct ast_ari_response *response)
|
struct ast_ari_response *response)
|
||||||
{
|
{
|
||||||
size_t endpoint_len;
|
|
||||||
char *endpoint;
|
char *endpoint;
|
||||||
struct ast_channel *chan;
|
struct ast_channel *chan;
|
||||||
struct varshead *vars;
|
struct varshead *vars;
|
||||||
|
|
||||||
if (ast_strlen_zero(args->data)) {
|
if (ast_strlen_zero(args->data)) {
|
||||||
ast_ari_response_error(response, 400, "Bad Request", "data can not be empty");
|
ast_ari_response_error(response, 400, "Bad Request", "data can not be empty");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint_len = strlen("AudioSocket/") + strlen(args->external_host) + 1 + strlen(args->data) + 1;
|
if (ast_asprintf(&endpoint, "AudioSocket/%s/%s",
|
||||||
endpoint = ast_alloca(endpoint_len);
|
args->external_host, args->data) == -1) {
|
||||||
/* The UUID is stored in the arbitrary data field */
|
return 1;
|
||||||
snprintf(endpoint, endpoint_len, "AudioSocket/%s/%s", args->external_host, args->data);
|
}
|
||||||
|
|
||||||
chan = ari_channels_handle_originate_with_id(
|
chan = ari_channels_handle_originate_with_id(
|
||||||
endpoint,
|
endpoint,
|
||||||
@@ -2164,10 +2162,11 @@ static void external_media_audiosocket_tcp(struct ast_ari_channels_external_medi
|
|||||||
NULL,
|
NULL,
|
||||||
args->format,
|
args->format,
|
||||||
response);
|
response);
|
||||||
ast_variables_destroy(variables);
|
|
||||||
|
ast_free(endpoint);
|
||||||
|
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
@@ -2177,6 +2176,7 @@ static void external_media_audiosocket_tcp(struct ast_ari_channels_external_medi
|
|||||||
}
|
}
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
ast_channel_unref(chan);
|
ast_channel_unref(chan);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "asterisk/config.h"
|
#include "asterisk/config.h"
|
||||||
@@ -2185,7 +2185,7 @@ static void external_media_audiosocket_tcp(struct ast_ari_channels_external_medi
|
|||||||
void ast_ari_channels_external_media(struct ast_variable *headers,
|
void ast_ari_channels_external_media(struct ast_variable *headers,
|
||||||
struct ast_ari_channels_external_media_args *args, struct ast_ari_response *response)
|
struct ast_ari_channels_external_media_args *args, struct ast_ari_response *response)
|
||||||
{
|
{
|
||||||
struct ast_variable *variables = NULL;
|
RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
|
||||||
char *external_host;
|
char *external_host;
|
||||||
char *host = NULL;
|
char *host = NULL;
|
||||||
char *port = NULL;
|
char *port = NULL;
|
||||||
@@ -2245,7 +2245,11 @@ void ast_ari_channels_external_media(struct ast_variable *headers,
|
|||||||
"An internal error prevented this request from being handled");
|
"An internal error prevented this request from being handled");
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(args->encapsulation, "audiosocket") == 0 && strcasecmp(args->transport, "tcp") == 0) {
|
} else if (strcasecmp(args->encapsulation, "audiosocket") == 0 && strcasecmp(args->transport, "tcp") == 0) {
|
||||||
external_media_audiosocket_tcp(args, variables, response);
|
if (external_media_audiosocket_tcp(args, variables, response)) {
|
||||||
|
ast_ari_response_error(
|
||||||
|
response, 500, "Internal Server Error",
|
||||||
|
"An internal error prevented this request from being handled");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ast_ari_response_error(
|
ast_ari_response_error(
|
||||||
response, 501, "Not Implemented",
|
response, 501, "Not Implemented",
|
||||||
|
Reference in New Issue
Block a user