Fix reconnecting to pgsql database after connection loss.
authorRichard Mudgett <rmudgett@digium.com>
Mon, 13 Feb 2012 17:25:41 +0000 (17:25 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 13 Feb 2012 17:25:41 +0000 (17:25 +0000)
There can only be one database connection in res_config_pgsql just like
res_config_sqlite.  If the connection is lost, the connection may not get
reestablished to the same database if the res_pgsql.conf and
extconfig.conf files are inconsistent.

* Made only use the configured database from res_pgsql.conf.

* Fixed potential buffer overwrite of last[] in config_pgsql().

(closes issue ASTERISK-16982)
Reported by: german aracil boned

Review: https://reviewboard.asterisk.org/r/1731/
........

Merged revisions 354953 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 354959 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@354964 65c4cc65-6c06-0410-ace0-fbb531ad65f3

configs/extconfig.conf.sample
res/res_config_pgsql.c

index 70d76ac..1d67fa5 100644 (file)
 ;    curl ... res_config_curl
 ;    ldap ... res_config_ldap
 ;
+; Note: The res_config_pgsql and res_config_sqlite backends configure the
+; database used in their respective configuration files and ignore the
+; database name configured in this file.
+;
 ;iaxusers => odbc,asterisk
 ;iaxpeers => odbc,asterisk
 ;sippeers => odbc,asterisk
index f8de865..8eae03f 100644 (file)
@@ -430,6 +430,12 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
        const char *newparam, *newval;
        struct ast_variable *var = NULL, *prev = NULL;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!tablename) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
                return NULL;
@@ -548,6 +554,12 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
        struct ast_config *cfg = NULL;
        struct ast_category *cat = NULL;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!table) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
                return NULL;
@@ -700,6 +712,12 @@ static int update_pgsql(const char *database, const char *tablename, const char
        struct tables *table;
        struct columns *column = NULL;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!tablename) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
                return -1;
@@ -830,6 +848,12 @@ static int update2_pgsql(const char *database, const char *tablename, va_list ap
        struct ast_str *where = ast_str_thread_get(&where_buf, 100);
        struct tables *table;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!tablename) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
                return -1;
@@ -939,6 +963,12 @@ static int store_pgsql(const char *database, const char *table, va_list ap)
        int pgresult;
        const char *newparam, *newval;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!table) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
                return -1;
@@ -1014,6 +1044,12 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke
        struct ast_str *buf1 = ast_str_thread_get(&where_buf, 60), *buf2 = ast_str_thread_get(&escapebuf_buf, 60);
        const char *newparam, *newval;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!table) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
                return -1;
@@ -1089,11 +1125,17 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
        struct ast_variable *new_v;
        struct ast_category *cur_cat = NULL;
        struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
-       char last[80] = "";
+       char last[80];
        int last_cat_metric = 0;
 
        last[0] = '\0';
 
+       /*
+        * Ignore database from the extconfig.conf since it is
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) {
                ast_log(LOG_WARNING, "PostgreSQL RealTime: Cannot configure myself.\n");
                return NULL;
@@ -1136,7 +1178,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
                                cur_cat = ast_category_new(field_category, "", 99999);
                                if (!cur_cat)
                                        break;
-                               strcpy(last, field_category);
+                               ast_copy_string(last, field_category, sizeof(last));
                                last_cat_metric = atoi(field_cat_metric);
                                ast_category_append(cfg, cur_cat);
                        }
@@ -1157,10 +1199,17 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 static int require_pgsql(const char *database, const char *tablename, va_list ap)
 {
        struct columns *column;
-       struct tables *table = find_table(database, tablename);
+       struct tables *table;
        char *elm;
        int type, size, res = 0;
 
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
+       table = find_table(database, tablename);
        if (!table) {
                ast_log(LOG_WARNING, "Table %s not found in database.  This table should exist if you're using realtime.\n", tablename);
                return -1;
@@ -1283,6 +1332,13 @@ static int require_pgsql(const char *database, const char *tablename, va_list ap
 static int unload_pgsql(const char *database, const char *tablename)
 {
        struct tables *cur;
+
+       /*
+        * Ignore database from the extconfig.conf since it was
+        * configured by res_pgsql.conf.
+        */
+       database = dbname;
+
        ast_debug(2, "About to lock table cache list\n");
        AST_LIST_LOCK(&psql_tables);
        ast_debug(2, "About to traverse table cache list\n");
@@ -1487,7 +1543,7 @@ static int pgsql_reconnect(const char *database)
 
        /* DB password can legitimately be 0-length */
        if ((!pgsqlConn) && (!ast_strlen_zero(dbhost) || !ast_strlen_zero(dbsock)) && !ast_strlen_zero(dbuser) && !ast_strlen_zero(my_database)) {
-               struct ast_str *connInfo = ast_str_create(32);
+               struct ast_str *connInfo = ast_str_create(128);
 
                ast_str_set(&connInfo, 0, "host=%s port=%d dbname=%s user=%s",
                        S_OR(dbhost, dbsock), dbport, my_database, dbuser);
@@ -1509,7 +1565,7 @@ static int pgsql_reconnect(const char *database)
                } else {
                        ast_log(LOG_ERROR,
                                        "PostgreSQL RealTime: Failed to connect database %s on %s: %s\n",
-                                       dbname, dbhost, PQresultErrorMessage(NULL));
+                                       my_database, dbhost, PQresultErrorMessage(NULL));
                        return 0;
                }
        } else {