diff --git a/src/mod/applications/mod_hiredis/hiredis_profile.c b/src/mod/applications/mod_hiredis/hiredis_profile.c index 8d71f59bb1..704a2e7ed9 100644 --- a/src/mod/applications/mod_hiredis/hiredis_profile.c +++ b/src/mod/applications/mod_hiredis/hiredis_profile.c @@ -32,12 +32,28 @@ #include +/* auth if password is set */ +static switch_status_t hiredis_context_auth(hiredis_context_t *context) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + if ( !zstr(context->connection->password) ) { + redisReply *response = redisCommand(context->context, "AUTH %s", context->connection->password); + if ( !response || response->type == REDIS_REPLY_ERROR ) { + status = SWITCH_STATUS_FALSE; + } + if ( response ) { + freeReplyObject(response); + } + } + return status; +} + /* reconnect to redis server */ static switch_status_t hiredis_context_reconnect(hiredis_context_t *context) { redisFree(context->context); context->context = redisConnectWithTimeout(context->connection->host, context->connection->port, context->connection->timeout); - if ( context->context && !context->context->err ) { + if ( context->context && !context->context->err && hiredis_context_auth(context) == SWITCH_STATUS_SUCCESS ) { return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; @@ -64,7 +80,7 @@ static hiredis_context_t *hiredis_connection_get_context(hiredis_connection_t *c if ( !context->context ) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "hiredis: attempting[%s, %d]\n", conn->host, conn->port); context->context = redisConnectWithTimeout(conn->host, conn->port, conn->timeout); - if ( context->context && !context->context->err ) { + if ( context->context && !context->context->err && hiredis_context_auth(context) == SWITCH_STATUS_SUCCESS ) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "hiredis: connection success[%s, %d]\n", conn->host, conn->port); return context; } else { @@ -93,7 +109,7 @@ static hiredis_context_t *hiredis_connection_get_context(hiredis_connection_t *c return NULL; } -switch_status_t hiredis_profile_create(hiredis_profile_t **new_profile, char *name, uint8_t ignore_connect_fail) +switch_status_t hiredis_profile_create(hiredis_profile_t **new_profile, char *name, uint8_t ignore_connect_fail, uint8_t ignore_error) { hiredis_profile_t *profile = NULL; switch_memory_pool_t *pool = NULL; @@ -106,6 +122,7 @@ switch_status_t hiredis_profile_create(hiredis_profile_t **new_profile, char *na profile->name = name ? switch_core_strdup(profile->pool, name) : "default"; profile->conn_head = NULL; profile->ignore_connect_fail = ignore_connect_fail; + profile->ignore_error = ignore_error; switch_core_hash_insert(mod_hiredis_globals.profiles, name, (void *) profile); @@ -218,11 +235,16 @@ static switch_status_t hiredis_context_execute_sync(hiredis_context_t *context, case REDIS_REPLY_INTEGER: *resp = switch_mprintf("%lld", response->integer); break; - default: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "hiredis: response error[%s][%d]\n", response->str, response->type); + case REDIS_REPLY_ERROR: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "hiredis: error response[%s][%d]\n", response->str, response->type); freeReplyObject(response); *resp = NULL; return SWITCH_STATUS_GENERR; + default: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "hiredis: unsupported response[%s][%d]\n", response->str, response->type); + freeReplyObject(response); + *resp = NULL; + return SWITCH_STATUS_IGNORE; } freeReplyObject(response); diff --git a/src/mod/applications/mod_hiredis/hiredis_utils.c b/src/mod/applications/mod_hiredis/hiredis_utils.c index 98995a08f9..4dc9ce3973 100644 --- a/src/mod/applications/mod_hiredis/hiredis_utils.c +++ b/src/mod/applications/mod_hiredis/hiredis_utils.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2015, Anthony Minessale II +* Copyright (C) 2005-2016, Anthony Minessale II * * Version: MPL 1.1 * @@ -46,6 +46,7 @@ switch_status_t mod_hiredis_do_config() for (profile = switch_xml_child(profiles, "profile"); profile; profile = profile->next) { hiredis_profile_t *new_profile = NULL; uint8_t ignore_connect_fail = 0; + uint8_t ignore_error = 0; char *name = (char *) switch_xml_attr_soft(profile, "name"); // Load params @@ -54,11 +55,13 @@ switch_status_t mod_hiredis_do_config() char *var = (char *) switch_xml_attr_soft(param, "name"); if ( !strncmp(var, "ignore-connect-fail", 19) ) { ignore_connect_fail = switch_true(switch_xml_attr_soft(param, "value")); + } else if ( !strncmp(var, "ignore-error", 12) ) { + ignore_error = switch_true(switch_xml_attr_soft(param, "value")); } } } - if ( hiredis_profile_create(&new_profile, name, ignore_connect_fail) == SWITCH_STATUS_SUCCESS ) { + if ( hiredis_profile_create(&new_profile, name, ignore_connect_fail, ignore_error) == SWITCH_STATUS_SUCCESS ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created profile[%s]\n", name); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create profile[%s]\n", name); diff --git a/src/mod/applications/mod_hiredis/mod_hiredis.c b/src/mod/applications/mod_hiredis/mod_hiredis.c index 00b04c6a7b..ae10619004 100644 --- a/src/mod/applications/mod_hiredis/mod_hiredis.c +++ b/src/mod/applications/mod_hiredis/mod_hiredis.c @@ -158,9 +158,12 @@ SWITCH_LIMIT_INCR(hiredis_limit_incr) hashkey = switch_mprintf("incr %s", limit_key); if ( (status = hiredis_profile_execute_sync(profile, hashkey, &response, session)) != SWITCH_STATUS_SUCCESS ) { - if ( status == SWITCH_STATUS_SOCKERR && profile->ignore_connect_fail ) { + if ( status == SWITCH_STATUS_SOCKERR && profile->ignore_connect_fail) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "hiredis: ignoring profile[%s] connection error executing [%s]\n", realm, hashkey); switch_goto_status(SWITCH_STATUS_SUCCESS, done); + } else if ( profile->ignore_error ) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "hiredis: ignoring profile[%s] general error executing [%s]\n", realm, hashkey); + switch_goto_status(SWITCH_STATUS_SUCCESS, done); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", realm, hashkey, response ? response : ""); switch_channel_set_variable(channel, "hiredis_raw_response", response ? response : ""); @@ -253,6 +256,9 @@ SWITCH_LIMIT_RELEASE(hiredis_limit_release) if ( status == SWITCH_STATUS_SOCKERR && profile->ignore_connect_fail ) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "hiredis: ignoring profile[%s] connection error executing [%s]\n", realm, hashkey); switch_goto_status(SWITCH_STATUS_SUCCESS, done); + } else if ( profile->ignore_error ) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "hiredis: ignoring profile[%s] general error executing [%s]\n", realm, hashkey); + switch_goto_status(SWITCH_STATUS_SUCCESS, done); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", realm, hashkey, response ? response : ""); switch_channel_set_variable(channel, "hiredis_raw_response", response ? response : ""); diff --git a/src/mod/applications/mod_hiredis/mod_hiredis.h b/src/mod/applications/mod_hiredis/mod_hiredis.h index 51a72733ef..362c69cdd3 100644 --- a/src/mod/applications/mod_hiredis/mod_hiredis.h +++ b/src/mod/applications/mod_hiredis/mod_hiredis.h @@ -33,6 +33,7 @@ typedef struct hiredis_profile_s { switch_memory_pool_t *pool; char *name; uint8_t ignore_connect_fail; + uint8_t ignore_error; hiredis_connection_t *conn_head; } hiredis_profile_t; @@ -47,7 +48,7 @@ typedef struct hiredis_limit_pvt_s { } hiredis_limit_pvt_t; switch_status_t mod_hiredis_do_config(void); -switch_status_t hiredis_profile_create(hiredis_profile_t **new_profile, char *name, uint8_t ignore_connect_fail); +switch_status_t hiredis_profile_create(hiredis_profile_t **new_profile, char *name, uint8_t ignore_connect_fail, uint8_t ignore_error); switch_status_t hiredis_profile_destroy(hiredis_profile_t **old_profile); switch_status_t hiredis_profile_connection_add(hiredis_profile_t *profile, char *host, char *password, uint32_t port, uint32_t timeout_ms, uint32_t max_connections);