mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-04 19:31:56 +00:00
[mod_amqp] prevent segfault on double connection close
When a command response publish failed, `mod_amqp_command_response` closed the connection and cleared conn_active. The command thread teardown then called mod_amqp_connection_close(NULL), causing a segfault. Also fix amqp_error_string2() calls to pass status codes without erroneous negation.
This commit is contained in:
committed by
GitHub
parent
be554e4a08
commit
174b16a3d1
@@ -259,7 +259,8 @@ static void mod_amqp_command_response(mod_amqp_command_profile_t *profile, char
|
|||||||
switch_safe_free(json_output);
|
switch_safe_free(json_output);
|
||||||
|
|
||||||
if (amqp_status != AMQP_STATUS_OK) {
|
if (amqp_status != AMQP_STATUS_OK) {
|
||||||
const char *errstr = amqp_error_string2(-amqp_status);
|
const char *errstr = amqp_error_string2(amqp_status);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
|
||||||
profile->name, profile->conn_active->name, errstr);
|
profile->name, profile->conn_active->name, errstr);
|
||||||
|
|
||||||
@@ -498,8 +499,10 @@ void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void
|
|||||||
amqp_bytes_free(queueName);
|
amqp_bytes_free(queueName);
|
||||||
queueName.bytes = NULL;
|
queueName.bytes = NULL;
|
||||||
|
|
||||||
mod_amqp_connection_close(profile->conn_active);
|
if (profile->conn_active) {
|
||||||
profile->conn_active = NULL;
|
mod_amqp_connection_close(profile->conn_active);
|
||||||
|
profile->conn_active = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (profile->running) {
|
if (profile->running) {
|
||||||
/* We'll reconnect, but sleep to avoid hammering resources */
|
/* We'll reconnect, but sleep to avoid hammering resources */
|
||||||
|
|||||||
@@ -40,9 +40,15 @@
|
|||||||
|
|
||||||
void mod_amqp_connection_close(mod_amqp_connection_t *connection)
|
void mod_amqp_connection_close(mod_amqp_connection_t *connection)
|
||||||
{
|
{
|
||||||
amqp_connection_state_t old_state = connection->state;
|
amqp_connection_state_t old_state;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
|
if (!connection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_state = connection->state;
|
||||||
|
|
||||||
connection->state = NULL;
|
connection->state = NULL;
|
||||||
|
|
||||||
if (old_state != NULL) {
|
if (old_state != NULL) {
|
||||||
@@ -50,7 +56,8 @@ void mod_amqp_connection_close(mod_amqp_connection_t *connection)
|
|||||||
mod_amqp_log_if_amqp_error(amqp_connection_close(old_state, AMQP_REPLY_SUCCESS), "Closing connection");
|
mod_amqp_log_if_amqp_error(amqp_connection_close(old_state, AMQP_REPLY_SUCCESS), "Closing connection");
|
||||||
|
|
||||||
if ((status = amqp_destroy_connection(old_state))) {
|
if ((status = amqp_destroy_connection(old_state))) {
|
||||||
const char *errstr = amqp_error_string2(-status);
|
const char *errstr = amqp_error_string2(status);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error destroying amqp connection: %s\n", errstr);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error destroying amqp connection: %s\n", errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,7 +296,8 @@ switch_status_t mod_amqp_logging_send(mod_amqp_logging_profile_t *profile, mod_a
|
|||||||
amqp_cstring_bytes(msg->pjson));
|
amqp_cstring_bytes(msg->pjson));
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
const char *errstr = amqp_error_string2(-status);
|
const char *errstr = amqp_error_string2(status);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
|
||||||
profile->name, profile->conn_active->name, errstr);
|
profile->name, profile->conn_active->name, errstr);
|
||||||
|
|
||||||
|
|||||||
@@ -426,7 +426,8 @@ switch_status_t mod_amqp_producer_send(mod_amqp_producer_profile_t *profile, mod
|
|||||||
amqp_cstring_bytes(msg->pjson));
|
amqp_cstring_bytes(msg->pjson));
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
const char *errstr = amqp_error_string2(-status);
|
const char *errstr = amqp_error_string2(status);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
|
||||||
profile->name, profile->conn_active->name, errstr);
|
profile->name, profile->conn_active->name, errstr);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user