/** * Convert a row from the result query into db API representation */ int db_postgres_convert_row(const db_con_t* _h, db_res_t* _r, db_row_t* _row, char **row_buf) { int col, len; if (!_h || !_r || !_row) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_row) = RES_COL_N(_r); /* For each column in the row */ for(col = 0; col < ROW_N(_row); col++) { /* compute the len of the value */ if ( row_buf[col]==NULL || row_buf[col][0]=='\0') len = 0; else len = strlen(row_buf[col]); /* Convert the string representation into the value representation */ if (db_postgres_str2val(RES_TYPES(_r)[col], &(ROW_VALUES(_row)[col]), row_buf[col], len) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %pn", _row); db_free_row(_row); return -3; } } return 0; }
/* * Convert a row from result into db API representation */ int convert_row(db_con_t* _h, db_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; #ifndef PARANOID if ((!_h) || (!_r) || (!_n)) { log(L_ERR, "convert_row(): Invalid parameter value\n"); return -1; } #endif ROW_VALUES(_r) = (db_val_t*)pkg_malloc(sizeof(db_val_t) * RES_COL_N(_res)); ROW_N(_r) = RES_COL_N(_res); if (!ROW_VALUES(_r)) { LOG(L_ERR, "convert_row(): No memory left\n"); return -1; } lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i]) < 0) { LOG(L_ERR, "convert_row(): Error while converting value\n"); free_row(_r); return -3; } } return 0; }
/*! * \brief Convert a row from the result query into db API representation * \param _h database connection * \param _r result set * \param _row row * \param row_buf row buffer * \return 0 on success, negative on error */ int db_postgres_convert_row(const db1_con_t* _h, db1_res_t* _r, db_row_t* _row, char **row_buf) { int col, col_len; if (!_h || !_r || !_row) { LM_ERR("invalid parameter value\n"); return -1; } if (db_allocate_row(_r, _row) != 0) { LM_ERR("could not allocate row\n"); return -2; } /* For each column in the row */ for(col = 0; col < ROW_N(_row); col++) { /* because it can contain NULL */ if (!row_buf[col]) { col_len = 0; } else { col_len = strlen(row_buf[col]); } /* Convert the string representation into the value representation */ if (db_postgres_str2val(RES_TYPES(_r)[col], &(ROW_VALUES(_row)[col]), row_buf[col], col_len) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _row); db_free_row(_row); return -3; } } return 0; }
/** * Allocate memory for row value. * \param _res result set * \param _row filled row * \return zero on success, negative on errors */ inline int db_allocate_row(const db1_res_t* _res, db_row_t* _row) { int len = sizeof(db_val_t) * RES_COL_N(_res); ROW_VALUES(_row) = (db_val_t*)pkg_malloc(len); if (!ROW_VALUES(_row)) { LM_ERR("no private memory left\n"); return -1; } LM_DBG("allocate %d bytes for row values at %p\n", len, ROW_VALUES(_row)); memset(ROW_VALUES(_row), 0, len); /* Save the number of columns in the ROW structure */ ROW_N(_row) = RES_COL_N(_res); return 0; }
/* * Convert a row from result into db API representation */ int db_unixodbc_convert_row(const db_con_t* _h, const db_res_t* _res, db_row_t* _r, const unsigned long* lengths) { int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); for(i = 0; i < RES_COL_N(_res); i++) { if (db_unixodbc_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((CON_ROW(_h))[i]), lengths[i]) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } return 0; }
/** * Convert a row from result into db API representation */ int db_mysql_convert_row(const db_con_t* _h, db_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); if (CON_HAS_PS(_h)) { for(i=0; i < CON_MYSQL_PS(_h)->cols_out; i++) { if (db_mysql_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), CON_PS_OUTCOL(_h, i).null?NULL:CON_PS_OUTCOL(_h, i).buf, CON_PS_OUTCOL(_h,i).len) < 0) { LM_ERR("failed to convert value from stmt\n"); db_free_row(_r); return -3; } } } else { lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (db_mysql_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i]) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } } return 0; }
/* * Matches from uri against patterns returned from database. Returns number * of matches or -1 if none of the patterns match. */ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) { int i, tag_avp_type; str uri, ruri; char uri_string[MAX_URI_SIZE+1]; char ruri_string[MAX_URI_SIZE+1]; db_row_t* row; db_val_t* val; regex_t preg; int_str tag_avp, avp_val; int count = 0; if (IS_SIP(msg)) { if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LM_ERR("message has From URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; ruri = msg->first_line.u.request.uri; if (ruri.len > MAX_URI_SIZE) { LM_ERR("message has Request URI too large\n"); return -1; } memcpy(ruri_string, ruri.s, ruri.len); ruri_string[ruri.len] = (char)0; } get_tag_avp(&tag_avp, &tag_avp_type); row = RES_ROWS(_r); for(i = 0; i < RES_ROW_N(_r); i++) { val = ROW_VALUES(row + i); if ((ROW_N(row + i) == 4) && (VAL_TYPE(val) == DB1_STRING) && !VAL_NULL(val) && match_proto(VAL_STRING(val), proto) && (VAL_NULL(val + 1) || ((VAL_TYPE(val + 1) == DB1_STRING) && !VAL_NULL(val + 1))) && (VAL_NULL(val + 2) || ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))) && (VAL_NULL(val + 3) || ((VAL_TYPE(val + 3) == DB1_STRING) && !VAL_NULL(val + 3)))) { if (IS_SIP(msg)) { if (!VAL_NULL(val + 1)) { if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) { LM_ERR("invalid regular expression\n"); if (VAL_NULL(val + 2)) { continue; } } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); continue; } regfree(&preg); } if (!VAL_NULL(val + 2)) { if (regcomp(&preg, (char *)VAL_STRING(val + 2), REG_NOSUB)) { LM_ERR("invalid regular expression\n"); continue; } if (regexec(&preg, ruri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); continue; } regfree(&preg); } } /* Found a match */ if (tag_avp.n && !VAL_NULL(val + 3)) { avp_val.s.s = (char *)VAL_STRING(val + 3); avp_val.s.len = strlen(avp_val.s.s); if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, avp_val) != 0) { LM_ERR("failed to set of tag_avp failed\n"); return -1; } } if (!peer_tag_mode) return 1; count++; } } if (!count) return -1; else return count; }
/* * Convert a row from result into db API representation */ static int dbt_convert_row(db_con_t* _h, db_res_t* _res, db_row_t* _r) { int i; if (!_h || !_r || !_res) { LM_ERR("invalid parameter value\n"); return -1; } ROW_N(_r) = RES_COL_N(_res); for(i = 0; i < RES_COL_N(_res); i++) { (ROW_VALUES(_r)[i]).nul = DBT_CON_ROW(_h)->fields[i].nul; switch(RES_TYPES(_res)[i]) { case DB_INT: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; case DB_BIGINT: VAL_BIGINT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.bigint_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_BIGINT; break; case DB_DOUBLE: VAL_DOUBLE(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.double_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_DOUBLE; break; case DB_STRING: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STRING; VAL_FREE(&(ROW_VALUES(_r)[i])) = 0; break; case DB_STR: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; VAL_FREE(&(ROW_VALUES(_r)[i])) = 0; break; case DB_DATETIME: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_DATETIME; break; case DB_BLOB: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_BLOB; VAL_FREE(&(ROW_VALUES(_r)[i])) = 0; break; case DB_BITMAP: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.bitmap_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; } } return 0; }
/* * Convert a row from result into db API representation */ int dbt_convert_row(db_con_t* _h, db_res_t* _res, db_row_t* _r) { int i; if ((!_h) || (!_r) || (!_res)) { #ifdef DBT_EXTRA_DEBUG LOG(L_ERR, "DBT:dbt_convert_row: Invalid parameter value\n"); #endif return -1; } ROW_VALUES(_r) = (db_val_t*)pkg_malloc(sizeof(db_val_t)*RES_COL_N(_res)); ROW_N(_r) = RES_COL_N(_res); if (!ROW_VALUES(_r)) { LOG(L_ERR, "DBT:dbt_convert_row: No memory left\n"); return -1; } for(i = 0; i < RES_COL_N(_res); i++) { (ROW_VALUES(_r)[i]).nul = DBT_CON_ROW(_h)->fields[i].nul; switch(RES_TYPES(_res)[i]) { case DB_INT: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; case DB_DOUBLE: VAL_DOUBLE(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.double_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_DOUBLE; break; case DB_STRING: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; break; case DB_STR: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; break; case DB_DATETIME: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; case DB_BLOB: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; break; case DB_BITMAP: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.bitmap_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; } } return 0; }
/** * Convert rows from Berkeley DB to db API representation */ int bdb_convert_row(db_res_t* _res, char *bdb_result, int* _lres) { int col, len, i, j; char **row_buf, *s; col = len = i = j = 0; struct db_row* row = NULL; if (!_res) { LM_ERR("invalid parameter\n"); return -1; } /* Save the number of rows in the current fetch */ RES_ROW_N(_res) = 1; row = RES_ROWS(_res); /* Save the number of columns in the ROW structure */ ROW_N(row) = RES_COL_N(_res); /* * Allocate an array of pointers one per column. * It that will be used to hold the address of the string * representation of each column. */ len = sizeof(char *) * RES_COL_N(_res); row_buf = (char **)pkg_malloc(len); if (!row_buf) { LM_ERR("no private memory left\n"); return -1; } LM_DBG("allocate for %d columns %d bytes in row buffer at %p\n", RES_COL_N(_res), len, row_buf); memset(row_buf, 0, len); /*populate the row_buf with bdb_result*/ /*bdb_result is memory from our callers stack so we copy here*/ LM_DBG("Found: [%s]\n",bdb_result); s = strsep(&bdb_result, DELIM); while( s!=NULL) { if(_lres) { /*only requested cols (_c was specified)*/ for(i=0; i<ROW_N(row); i++) { if (col == _lres[i]) { len = strlen(s); row_buf[i] = pkg_malloc(len+1); if (!row_buf[i]) { LM_ERR("no private memory left\n"); goto error; } LM_DBG("allocated %d bytes for row_buf[%d] at %p\n", len, i, row_buf[i]); memset(row_buf[i], 0, len+1); strncpy(row_buf[i], s, len); } } } else { /* TODO: TEST */ if( col >= RES_COL_N(_res)) break; len = strlen(s); row_buf[col] = pkg_malloc(len+1); if (!row_buf[col]) { LM_ERR("no private memory left\n"); return -1; } LM_DBG("allocated %d bytes for row_buf[%d] at %p\n", len, col, row_buf[col]); memset(row_buf[col], 0, len+1); strncpy(row_buf[col], s, len); } s = strsep(&bdb_result, DELIM); col++; } /*do the type conversion per col*/ for(col = 0; col < ROW_N(row); col++) { /*skip the unrequested cols (as already specified)*/ if(!row_buf[col]) continue; /* Convert the string representation into the value representation */ if (bdb_str2val(RES_TYPES(_res)[col], &(ROW_VALUES(row)[col]) , row_buf[col], strlen(row_buf[col])) < 0) { LM_ERR("while converting value\n"); goto error; } if( row->values[col].nul || row->values[col].type == DB_INT || row->values[col].type == DB_BIGINT || row->values[col].type == DB_DOUBLE || row->values[col].type == DB_DATETIME ) pkg_free(row_buf[col]); } LM_DBG("freeing row buffer at %p\n", row_buf); if( row_buf[col]) pkg_free(row_buf); row_buf = NULL; return 0; error: for(col = 0; col < ROW_N(row); col++) if( row_buf[col]) pkg_free(row_buf[col]); if( row_buf ) pkg_free(row_buf); return -1; }
/* * input: rule straight from the DDDS + avp-stack. * * output: adds found rules to the stack and return * 1 on success * 0 on failure */ static int check_rule(str *rule, char *service, int service_len, struct avp_stack *stack) { /* for the select */ db_key_t keys[2]; db_val_t vals[2]; db_key_t cols[4]; db1_res_t* res; db_row_t* row; db_val_t* val; int i; char *type; int type_len; LM_INFO("checking for '%.*s'.\n", rule->len, ZSW(rule->s)); if ((service_len != 11) || (strncasecmp("d2p+sip:fed", service, 11) && strncasecmp("d2p+sip:std", service, 11) && strncasecmp("d2p+sip:dom", service, 11))) { LM_ERR("can only cope with d2p+sip:fed, d2p+sip:std,and d2p+sip:dom " "for now (and not %.*s).\n", service_len, service); return(0); } type = service + 8; type_len = service_len - 8; if (domainpolicy_dbf.use_table(db_handle, &domainpolicy_table) < 0) { LM_ERR("failed to domainpolicy table\n"); return -1; } keys[0]=&domainpolicy_col_rule; keys[1]=&domainpolicy_col_type; cols[0]=&domainpolicy_col_rule; cols[1]=&domainpolicy_col_type; cols[2]=&domainpolicy_col_att; cols[3]=&domainpolicy_col_val; VAL_TYPE(&vals[0]) = DB1_STR; VAL_NULL(&vals[0]) = 0; VAL_STR(&vals[0]).s = rule->s; VAL_STR(&vals[0]).len = rule->len; VAL_TYPE(&vals[1]) = DB1_STR; VAL_NULL(&vals[1]) = 0; VAL_STR(&vals[1]).s = type; VAL_STR(&vals[1]).len = type_len; /* * SELECT rule, att, val from domainpolicy where rule = "..." */ if (domainpolicy_dbf.query(db_handle, keys, 0, vals, cols, 2, 4, 0, &res) < 0 ) { LM_ERR("querying database\n"); return -1; } LM_INFO("querying database OK\n"); if (RES_ROW_N(res) == 0) { LM_DBG("rule '%.*s' is not know.\n", rule->len, ZSW(rule->s)); domainpolicy_dbf.free_result(db_handle, res); return 0; } else { LM_DBG("rule '%.*s' is known\n", rule->len, ZSW(rule->s)); row = RES_ROWS(res); for(i = 0; i < RES_ROW_N(res); i++) { if (ROW_N(row + i) != 4) { LM_ERR("unexpected cell count\n"); return(-1); } val = ROW_VALUES(row + i); if ((VAL_TYPE(val) != DB1_STRING) || (VAL_TYPE(val+1) != DB1_STRING) || (VAL_TYPE(val+2) != DB1_STRING) || (VAL_TYPE(val+3) != DB1_STRING)) { LM_ERR("unexpected cell types\n"); return(-1); } if (VAL_NULL(val+2) || VAL_NULL(val+3)) { LM_INFO("db returned NULL values. Fine with us.\n"); continue; } LM_INFO("DB returned %s/%s \n",VAL_STRING(val+2),VAL_STRING(val+3)); if (!stack_push(stack, (char *) VAL_STRING(val+2), (char *) VAL_STRING(val+3))) { return(-1); } } domainpolicy_dbf.free_result(db_handle, res); return 1; } }
/* * Convert data fron db format to internal format */ static int convert_row(db_res_t* _res, db_row_t* _r, dmap_t* _d) { unsigned i, n = RES_COL_N(_res); ROW_N(_r) = n; for (i = 0; i < n; i++) { static const str dummy_string = {"", 0}; db_val_t* v = &ROW_VALUES(_r)[i]; db_type_t t = RES_TYPES(_res)[i]; if (_d->ind[i] == -1) { /* Initialize the string pointers to a dummy empty * string so that we do not crash when the NULL flag * is set but the module does not check it properly */ VAL_STRING(v) = dummy_string.s; VAL_STR(v) = dummy_string; VAL_BLOB(v) = dummy_string; VAL_TYPE(v) = t; VAL_NULL(v) = 1; continue; } if (_d->ind[i]) LM_WARN("truncated value in DB\n"); VAL_TYPE(v) = t; switch (t) { case DB_INT: VAL_INT(v) = *_d->pv[i].i; break; case DB_BIGINT: VAL_BIGINT(v) = *_d->pv[i].i; break; case DB_BITMAP: VAL_BITMAP(v) = *_d->pv[i].i; break; case DB_DOUBLE: VAL_DOUBLE(v) = *_d->pv[i].f; break; case DB_DATETIME: { struct tm tm; memset(&tm, 0, sizeof(tm)); OCIDateGetTime(_d->pv[i].o, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); OCIDateGetDate(_d->pv[i].o, &tm.tm_year, &tm.tm_mon, &tm.tm_mday); if (tm.tm_mon) --tm.tm_mon; if (tm.tm_year >= 1900) tm.tm_year -= 1900; VAL_TIME(v) = mktime(&tm); } break; case DB_STR: case DB_BLOB: case DB_STRING: { size_t len = _d->len[i]; char *pstr = pkg_malloc(len+1); if (pstr == NULL) return -1; memcpy(pstr, _d->pv[i].c, len); pstr[len] = '\0'; VAL_FREE(v) = 1; if (t == DB_STR) { VAL_STR(v).s = pstr; VAL_STR(v).len = len; } else if (t == DB_BLOB) { VAL_BLOB(v).s = pstr; VAL_BLOB(v).len = len; } else { VAL_STRING(v) = pstr; } } break; default: LM_ERR("unknown type mapping (%u)\n", t); return -2; } } return 0; }
/* * Reload addr table to new hash table and when done, make new hash table * current one. */ int reload_address_table(void) { db_key_t cols[5]; db1_res_t* res = NULL; db_row_t* row; db_val_t* val; struct addr_list **new_hash_table; struct subnet *new_subnet_table; struct domain_name_list **new_domain_name_table; int i; unsigned int gid; unsigned int port; unsigned int mask; str ips; ip_addr_t *ipa; char *tagv; cols[0] = &grp_col; cols[1] = &ip_addr_col; cols[2] = &mask_col; cols[3] = &port_col; cols[4] = &tag_col; if (perm_dbf.use_table(db_handle, &address_table) < 0) { LM_ERR("failed to use table\n"); return -1; } if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 5, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*addr_hash_table == addr_hash_table_1) { empty_addr_hash_table(addr_hash_table_2); new_hash_table = addr_hash_table_2; } else { empty_addr_hash_table(addr_hash_table_1); new_hash_table = addr_hash_table_1; } /* Choose new subnet table */ if (*subnet_table == subnet_table_1) { empty_subnet_table(subnet_table_2); new_subnet_table = subnet_table_2; } else { empty_subnet_table(subnet_table_1); new_subnet_table = subnet_table_1; } /* Choose new domain name table */ if (*domain_list_table == domain_list_table_1) { empty_domain_name_table(domain_list_table_2); new_domain_name_table = domain_list_table_2; } else { empty_domain_name_table(domain_list_table_1); new_domain_name_table = domain_list_table_1; } row = RES_ROWS(res); LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); /* basic checks to db values */ if (ROW_N(row + i) != 5) { LM_DBG("failure during checks of db address table: Colums %d - expected 5\n", ROW_N(row + i)); goto dberror; } if ((VAL_TYPE(val) != DB1_INT) || VAL_NULL(val) || (VAL_INT(val) <= 0)) { LM_DBG("failure during checks of database value 1 (group) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 1) != DB1_STRING) && (VAL_TYPE(val + 1) != DB1_STR)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - not a string value\n"); goto dberror; } if (VAL_NULL(val + 1)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - NULL value not permitted\n"); goto dberror; } if ((VAL_TYPE(val + 2) != DB1_INT) || VAL_NULL(val + 2)) { LM_DBG("failure during checks of database value 3 (subnet size/CIDR) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 3) != DB1_INT) || VAL_NULL(val + 3)) { LM_DBG("failure during checks of database value 4 (port) in address table\n"); goto dberror; } gid = VAL_UINT(val); ips.s = (char *)VAL_STRING(val + 1); ips.len = strlen(ips.s); mask = VAL_UINT(val + 2); port = VAL_UINT(val + 3); tagv = VAL_NULL(val + 4)?NULL:(char *)VAL_STRING(val + 4); ipa = strtoipX(&ips); if ( ipa==NULL ) { LM_DBG("Domain name: %.*s\n", ips.len, ips.s); // goto dberror; } else { if(ipa->af == AF_INET6) { if((int)mask<0 || mask>128) { LM_DBG("failure during IP mask check for v6\n"); goto dberror; } } else { if((int)mask<0 || mask>32) { LM_DBG("failure during IP mask check for v4\n"); goto dberror; } } } if ( ipa ) { if ( (ipa->af==AF_INET6 && mask==128) || (ipa->af==AF_INET && mask==32) ) { if (addr_hash_table_insert(new_hash_table, gid, ipa, port, tagv) == -1) { LM_ERR("hash table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into address hash table\n", gid, ips.s, port); } else { if (subnet_table_insert(new_subnet_table, gid, ipa, mask, port, tagv) == -1) { LM_ERR("subnet table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u, %u> inserted into subnet table\n", gid, ips.s, port, mask); } } else { if (domain_name_table_insert(new_domain_name_table, gid, &ips, port, tagv) == -1) { LM_ERR("domain name table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into domain name table\n", gid, ips.s, port); } } perm_dbf.free_result(db_handle, res); *addr_hash_table = new_hash_table; *subnet_table = new_subnet_table; *domain_list_table = new_domain_name_table; LM_DBG("address table reloaded successfully.\n"); return 1; dberror: LM_ERR("database problem - invalid record\n"); perm_dbf.free_result(db_handle, res); return -1; }
/* * Reload domain table to new hash table and when done, make new hash table * current one. */ int reload_domain_table ( void ) { /* db_key_t keys[] = {domain_col}; */ db_val_t vals[1]; db_key_t cols[1]; db_res_t* res; db_row_t* row; db_val_t* val; struct domain_list **new_hash_table; int i; cols[0] = domain_col.s; if (domain_dbf.use_table(db_handle, domain_table.s) < 0) { LOG(L_ERR, "reload_domain_table(): Error while trying to use domain table\n"); return -1; } VAL_TYPE(vals) = DB_STR; VAL_NULL(vals) = 0; if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 1, 0, &res) < 0) { LOG(L_ERR, "reload_domain_table(): Error while querying database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*hash_table == hash_table_1) { hash_table_free(hash_table_2); new_hash_table = hash_table_2; } else { hash_table_free(hash_table_1); new_hash_table = hash_table_1; } row = RES_ROWS(res); DBG("Number of rows in domain table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); if ((ROW_N(row) == 1) && (VAL_TYPE(val) == DB_STRING)) { DBG("Value: %s inserted into domain hash table\n", VAL_STRING(val)); if (hash_table_install(new_hash_table, (char *)(VAL_STRING(val))) == -1) { LOG(L_ERR, "domain_reload(): Hash table problem\n"); domain_dbf.free_result(db_handle, res); return -1; } } else { LOG(L_ERR, "domain_reload(): Database problem\n"); domain_dbf.free_result(db_handle, res); return -1; } } domain_dbf.free_result(db_handle, res); *hash_table = new_hash_table; return 1; }
/* * Reload trusted table to new hash table and when done, make new hash table * current one. */ int reload_trusted_table(void) { db_key_t cols[6]; db1_res_t* res = NULL; db_row_t* row; db_val_t* val; struct trusted_list **new_hash_table; struct trusted_list **old_hash_table; int i; int priority; char *pattern, *ruri_pattern, *tag; if (hash_table == 0) { LM_ERR("in-memory hash table not initialized\n"); return -1; } if (db_handle == 0) { LM_ERR("no connection to database\n"); return -1; } cols[0] = &source_col; cols[1] = &proto_col; cols[2] = &from_col; cols[3] = &ruri_col; cols[4] = &tag_col; cols[5] = &priority_col; if (perm_dbf.use_table(db_handle, &trusted_table) < 0) { LM_ERR("failed to use trusted table\n"); return -1; } if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 6, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*hash_table == hash_table_1) { new_hash_table = hash_table_2; } else { new_hash_table = hash_table_1; } empty_hash_table(new_hash_table); row = RES_ROWS(res); LM_DBG("number of rows in trusted table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); if ((ROW_N(row + i) == 6) && ((VAL_TYPE(val) == DB1_STRING) || (VAL_TYPE(val) == DB1_STR) ) && !VAL_NULL(val) && ((VAL_TYPE(val + 1) == DB1_STRING) || (VAL_TYPE(val + 1) == DB1_STR)) && !VAL_NULL(val + 1) && (VAL_NULL(val + 2) || (((VAL_TYPE(val + 2) == DB1_STRING) || (VAL_TYPE(val + 2) == DB1_STR)) && !VAL_NULL(val + 2))) && (VAL_NULL(val + 3) || (((VAL_TYPE(val + 3) == DB1_STRING) || (VAL_TYPE(val + 3) == DB1_STR) )&& !VAL_NULL(val + 3))) && (VAL_NULL(val + 4) || (((VAL_TYPE(val + 4) == DB1_STRING) || (VAL_TYPE(val + 4) == DB1_STR) )&& !VAL_NULL(val + 4)))) { if (VAL_NULL(val + 2)) { pattern = 0; } else { pattern = (char *)VAL_STRING(val + 2); } if (VAL_NULL(val + 3)) { ruri_pattern = 0; } else { ruri_pattern = (char *)VAL_STRING(val + 3); } if (VAL_NULL(val + 4)) { tag = 0; } else { tag = (char *)VAL_STRING(val + 4); } if (VAL_NULL(val + 5)) { priority = 0; } else { priority = (int)VAL_INT(val + 5); } if (hash_table_insert(new_hash_table, (char *)VAL_STRING(val), (char *)VAL_STRING(val + 1), pattern, ruri_pattern, tag, priority) == -1) { LM_ERR("hash table problem\n"); perm_dbf.free_result(db_handle, res); empty_hash_table(new_hash_table); return -1; } LM_DBG("tuple <%s, %s, %s, %s, %s> inserted into trusted hash " "table\n", VAL_STRING(val), VAL_STRING(val + 1), pattern, ruri_pattern, tag); } else { LM_ERR("database problem\n"); perm_dbf.free_result(db_handle, res); empty_hash_table(new_hash_table); return -1; } } perm_dbf.free_result(db_handle, res); old_hash_table = *hash_table; *hash_table = new_hash_table; empty_hash_table(old_hash_table); LM_DBG("trusted table reloaded successfully.\n"); return 1; }
/* * Release memory used by row */ inline int db_free_row(db_row_t* _r) { int col; db_val_t* _val; if (!_r) { LM_ERR("invalid parameter value\n"); return -1; } /* * Loop thru each columm, then check to determine if the storage pointed to * by db_val_t structure must be freed. This is required for all data types * which use a pointer to a buffer like DB1_STRING, DB1_STR and DB1_BLOB and * the database module copied them during the assignment. * If this is not done, a memory leak will happen. * Don't try to free the static dummy string (as indicated from the NULL value), * as this is not valid. */ for (col = 0; col < ROW_N(_r); col++) { _val = &(ROW_VALUES(_r)[col]); switch (VAL_TYPE(_val)) { case DB1_STRING: if ( (!VAL_NULL(_val)) && VAL_FREE(_val)) { LM_DBG("free VAL_STRING[%d] '%s' at %p\n", col, (char *)VAL_STRING(_val), (char *)VAL_STRING(_val)); pkg_free((char *)VAL_STRING(_val)); VAL_STRING(_val) = NULL; } break; case DB1_STR: if ( (!VAL_NULL(_val)) && VAL_FREE(_val)) { LM_DBG("free VAL_STR[%d] '%.*s' at %p\n", col, VAL_STR(_val).len, VAL_STR(_val).s, VAL_STR(_val).s); pkg_free(VAL_STR(_val).s); VAL_STR(_val).s = NULL; } break; case DB1_BLOB: if ( (!VAL_NULL(_val)) && VAL_FREE(_val)) { LM_DBG("free VAL_BLOB[%d] at %p\n", col, VAL_BLOB(_val).s); pkg_free(VAL_BLOB(_val).s); VAL_BLOB(_val).s = NULL; } break; default: break; } } /* now as we freed all, set number of colums to zero again */ ROW_N(_r) = 0; if (ROW_VALUES(_r)) { LM_DBG("freeing row values at %p\n", ROW_VALUES(_r)); pkg_free(ROW_VALUES(_r)); ROW_VALUES(_r) = NULL; } return 0; }
/** * Convert a row from result into db API representation */ int db_sqlite_convert_row(const db_con_t* _h, db_res_t* _res, db_row_t* _r) { int col; db_val_t* _v; const char* db_value; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } if (!CON_SQLITE_PS(_h)) { LM_ERR("conn has no prepared statement! sqlite requires one\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); for(col=0; col < RES_COL_N(_res); col++) { _v = &(ROW_VALUES(_r)[col]); if (sqlite3_column_type(CON_SQLITE_PS(_h), col) == SQLITE_NULL) { VAL_NULL(_v) = 1; continue; } switch (RES_TYPES(_res)[col]) { case DB_INT: VAL_INT(_v) = sqlite3_column_int(CON_SQLITE_PS(_h), col); VAL_TYPE(_v) = DB_INT; break; case DB_BIGINT: VAL_BIGINT(_v) = sqlite3_column_int64(CON_SQLITE_PS(_h), col); VAL_TYPE(_v) = DB_BIGINT; break; case DB_DATETIME: db_value = (char *)sqlite3_column_text(CON_SQLITE_PS(_h), col); if (db_str2time(db_value, &VAL_TIME(_v)) < 0) { LM_ERR("error while converting datetime value from string\n"); return -1; } VAL_TYPE(_v) = DB_DATETIME; break; case DB_DOUBLE: VAL_DOUBLE(_v) = sqlite3_column_double(CON_SQLITE_PS(_h), col); VAL_TYPE(_v) = DB_DOUBLE; break; case DB_BLOB: VAL_BLOB(_v).len = sqlite3_column_bytes(CON_SQLITE_PS(_h), col); db_value = sqlite3_column_blob(CON_SQLITE_PS(_h), col); VAL_BLOB(_v).s = pkg_malloc(VAL_BLOB(_v).len+1); memcpy(VAL_BLOB(_v).s, db_value, VAL_BLOB(_v).len); VAL_BLOB(_v).s[VAL_BLOB(_v).len]='\0'; VAL_TYPE(_v) = DB_BLOB; break; case DB_STRING: VAL_STR(_v).len = sqlite3_column_bytes(CON_SQLITE_PS(_h), col); db_value = (char *)sqlite3_column_text(CON_SQLITE_PS(_h), col); VAL_STR(_v).s = pkg_malloc(VAL_STR(_v).len+1); memcpy(VAL_STR(_v).s, db_value, VAL_STR(_v).len); VAL_STR(_v).s[VAL_STR(_v).len]='\0'; VAL_TYPE(_v) = DB_STR; break; default: LM_ERR("invalid type for sqlite!\n"); return -1; } } return 0; }