/** * Loads the routing data from the database given in global * variable db_url and stores it in routing tree rd. * * @param rd Pointer to the route data tree where the routing data * shall be loaded into * * @return 0 means ok, -1 means an error occured * */ int load_route_data(struct rewrite_data * rd) { db_res_t * res = NULL; db_row_t * row = NULL; int i, ret; int carrier_count = 0; struct carrier * carriers = NULL, * tmp = NULL; static str query_str; str tmp_carrier; str tmp_domain; str tmp_scan_prefix; str tmp_rewrite_host; str tmp_rewrite_prefix; str tmp_rewrite_suffix; str tmp_host_name; str tmp_reply_code; str tmp_next_domain; str tmp_comment; int no_rows=10; if( (strlen("SELECT DISTINCT FROM WHERE = ") + db_table.len + columns[COL_DOMAIN]->len + columns[COL_CARRIER]->len + 20) > QUERY_LEN) { LM_ERR("query too long\n"); return -1; } if((carrier_count = store_carriers(&carriers)) <= 0){ LM_ERR("error while retrieving carriers\n"); goto errout; } if ((rd->carriers = shm_malloc(sizeof(struct carrier_tree *) * carrier_count)) == NULL) { LM_ERR("out of shared memory\n"); goto errout; } memset(rd->carriers, 0, sizeof(struct carrier_tree *) * carrier_count); rd->tree_num = carrier_count; tmp = carriers; for (i=0; i<carrier_count; i++) { memset(query, 0, QUERY_LEN); ret = snprintf(query, QUERY_LEN, "SELECT DISTINCT %.*s FROM %.*s WHERE %.*s=%i", columns[COL_DOMAIN]->len, columns[COL_DOMAIN]->s, db_table.len, db_table.s, columns[COL_CARRIER]->len, columns[COL_CARRIER]->s, tmp->id); if (ret < 0) { LM_ERR("error in snprintf"); goto errout; } query_str.s = query; query_str.len = ret; if (dbf.raw_query(dbh, &query_str, &res) < 0) { LM_ERR("Failed to query database.\n"); goto errout; } LM_INFO("name %s, id %i, trees: %i\n", tmp->name, tmp->id, RES_ROW_N(res)); tmp_carrier.s=tmp->name; tmp_carrier.len=strlen(tmp_carrier.s); if (add_carrier_tree(&tmp_carrier, tmp->id, rd, RES_ROW_N(res)) == NULL) { LM_ERR("can't add carrier %s\n", tmp->name); goto errout; } dbf.free_result(dbh, res); res = NULL; tmp = tmp->next; } if (dbf.use_table(dbh, &db_table) < 0) { LM_ERR("Cannot set database table '%.*s'.\n", db_table.len, db_table.s); return -1; } if (DB_CAPABILITY(dbf, DB_CAP_FETCH)) { if (dbf.query(dbh, NULL, NULL, NULL, (db_key_t *) columns, 0, COLUMN_NUM, NULL, NULL) < 0) { LM_ERR("Failed to query database to prepare fetchrow.\n"); return -1; } no_rows = estimate_available_rows( 4+64+64+64+4+4+4+64+4+64+64+128, COLUMN_NUM); if (no_rows==0) no_rows = 10; if(dbf.fetch_result(dbh, &res, no_rows) < 0) { LM_ERR("Fetching rows failed\n"); return -1; } } else { if (dbf.query(dbh, NULL, NULL, NULL, (db_key_t *)columns, 0, COLUMN_NUM, NULL, &res) < 0) { LM_ERR("Failed to query database.\n"); return -1; } } int n = 0; do { LM_DBG("loading, cycle %d", n++); for (i = 0; i < RES_ROW_N(res); ++i) { row = &RES_ROWS(res)[i]; tmp_domain.s=(char *)row->values[COL_DOMAIN].val.string_val; tmp_scan_prefix.s=(char *)row->values[COL_SCAN_PREFIX].val.string_val; tmp_rewrite_host.s=(char *)row->values[COL_REWRITE_HOST].val.string_val; tmp_rewrite_prefix.s=(char *)row->values[COL_REWRITE_PREFIX].val.string_val; tmp_rewrite_suffix.s=(char *)row->values[COL_REWRITE_SUFFIX].val.string_val; tmp_comment.s=(char *)row->values[COL_COMMENT].val.string_val; if (tmp_domain.s==NULL) tmp_domain.s=""; if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s=""; if (tmp_rewrite_host.s==NULL) tmp_rewrite_host.s=""; if (tmp_rewrite_prefix.s==NULL) tmp_rewrite_prefix.s=""; if (tmp_rewrite_suffix.s==NULL) tmp_rewrite_suffix.s=""; if (tmp_comment.s==NULL) tmp_comment.s=""; tmp_domain.len=strlen(tmp_domain.s); tmp_scan_prefix.len=strlen(tmp_scan_prefix.s); tmp_rewrite_host.len=strlen(tmp_rewrite_host.s); tmp_rewrite_prefix.len=strlen(tmp_rewrite_prefix.s); tmp_rewrite_suffix.len=strlen(tmp_rewrite_suffix.s); tmp_comment.len=strlen(tmp_comment.s); if (add_route(rd, row->values[COL_CARRIER].val.int_val, &tmp_domain, &tmp_scan_prefix, row->values[COL_FLAGS].val.int_val, row->values[COL_MASK].val.int_val, 0, row->values[COL_PROB].val.double_val, &tmp_rewrite_host, row->values[COL_STRIP].val.int_val, &tmp_rewrite_prefix, &tmp_rewrite_suffix, 1, 0, -1, NULL, &tmp_comment) == -1) { goto errout; } } if (DB_CAPABILITY(dbf, DB_CAP_FETCH)) { if(dbf.fetch_result(dbh, &res, no_rows) < 0) { LM_ERR("fetching rows failed\n"); dbf.free_result(dbh, res); return -1; } } else { break; } } while(RES_ROW_N(res) > 0); dbf.free_result(dbh, res); res = NULL; if (dbf.use_table(dbh, &db_failure_table) < 0) { LM_ERR("cannot set database table '%.*s'.\n", db_failure_table.len, db_failure_table.s); return -1; } if (dbf.query(dbh, NULL, NULL, NULL, (db_key_t *)failure_columns, 0, FAILURE_COLUMN_NUM, NULL, &res) < 0) { LM_ERR("failed to query database.\n"); return -1; } for (i = 0; i < RES_ROW_N(res); ++i) { row = &RES_ROWS(res)[i]; tmp_domain.s=(char *)row->values[FCOL_DOMAIN].val.string_val; tmp_scan_prefix.s=(char *)row->values[FCOL_SCAN_PREFIX].val.string_val; tmp_host_name.s=(char *)row->values[FCOL_HOST_NAME].val.string_val; tmp_reply_code.s=(char *)row->values[FCOL_REPLY_CODE].val.string_val; tmp_next_domain.s=(char *)row->values[FCOL_NEXT_DOMAIN].val.string_val; tmp_comment.s=(char *)row->values[FCOL_COMMENT].val.string_val; if (tmp_domain.s==NULL) tmp_domain.s=""; if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s=""; if (tmp_host_name.s==NULL) tmp_host_name.s=""; if (tmp_reply_code.s==NULL) tmp_reply_code.s=""; if (tmp_next_domain.s==NULL) tmp_next_domain.s=""; if (tmp_comment.s==NULL) tmp_comment.s=""; tmp_domain.len=strlen(tmp_domain.s); tmp_scan_prefix.len=strlen(tmp_scan_prefix.s); tmp_host_name.len=strlen(tmp_host_name.s); tmp_reply_code.len=strlen(tmp_reply_code.s); tmp_next_domain.len=strlen(tmp_next_domain.s); tmp_comment.len=strlen(tmp_comment.s); if (add_failure_route(rd, row->values[FCOL_CARRIER].val.int_val, &tmp_domain, &tmp_scan_prefix, &tmp_host_name, &tmp_reply_code, row->values[FCOL_FLAGS].val.int_val, row->values[FCOL_MASK].val.int_val, &tmp_next_domain, &tmp_comment) == -1) { goto errout; } } destroy_carriers(carriers); dbf.free_result(dbh, res); return 0; errout: destroy_carriers(carriers); if (res) { dbf.free_result(dbh, res); } return -1; }
/** * Loads the routing data from the config file given in global * variable config_data and stores it in routing tree rd. * * @param rd Pointer to the route data tree where the routing data * shall be loaded into * * @return 0 means ok, -1 means an error occured * */ int load_config(struct rewrite_data * rd) { cfg_t * cfg = NULL; int n, m, o, i, j, k,l; cfg_t * d, * p, * t; const char * domain = NULL, * prefix = NULL; double prob; const char * rewrite_prefix = NULL, * rewrite_suffix = NULL, * rewrite_host = NULL, * comment = NULL; int backed_up_size = 0; int * backed_up = NULL; int backup = 0; int status, hash_index, max_targets, strip; if ((cfg = parse_config()) == NULL) { return -1; } if ((rd->carriers = shm_malloc(sizeof(struct carrier_tree *))) == NULL) { LM_ERR("out of shared memory\n"); return -1; } memset(rd->carriers, 0, sizeof(struct carrier_tree *)); rd->tree_num = 1; n = cfg_size(cfg, "domain"); if (add_carrier_tree(default_tree, 1, rd, n) == NULL) { LM_ERR("couldn't add carrier tree\n"); return -1; } memset(rd->carriers[0]->trees, 0, sizeof(struct route_tree *) * n); for (i = 0; i < n; i++) { d = cfg_getnsec(cfg, "domain", i); domain = cfg_title(d); m = cfg_size(d, "prefix"); LM_INFO("loading domain %s\n", domain); for (j = 0; j < m; j++) { p = cfg_getnsec(d, "prefix", j); prefix = cfg_title(p); if (strcasecmp(prefix, SP_EMPTY_PREFIX) == 0) { prefix = NULL; } LM_INFO("loading prefix %s\n", prefix); max_targets = cfg_getint(p, "max_targets"); o = cfg_size(p, "target"); for (k = 0; k < o; k++) { t = cfg_getnsec(p, "target", k); rewrite_host = cfg_title(t); if (strcasecmp(rewrite_host, SP_EMPTY_PREFIX) == 0) { rewrite_host = 0; } LM_INFO("loading target %s\n", rewrite_host); prob = cfg_getfloat(t, "prob"); strip = cfg_getint(t, "strip"); rewrite_prefix = cfg_getstr(t, "rewrite_prefix"); rewrite_suffix = cfg_getstr(t, "rewrite_suffix"); hash_index = cfg_getint(t, "hash_index"); comment = cfg_getstr(t, "comment"); status = cfg_getint(t, "status"); if ((backed_up_size = cfg_size(t, "backed_up")) > 0) { if ((backed_up = pkg_malloc(sizeof(int) * (backed_up_size + 1))) == NULL) { LM_ERR("out of private memory\n"); return -1; } for (l = 0; l < backed_up_size; l++) { backed_up[l] = cfg_getnint(t, "backed_up", l); } backed_up[backed_up_size] = -1; } backup = cfg_getint(t, "backup"); LM_INFO("adding route for prefix %s, to host %s, prob %f, backed up: %i, backup: %i\n", prefix, rewrite_host, prob, backed_up_size, backup); if (add_route(rd, 1, domain, prefix, max_targets, prob, rewrite_host, strip, rewrite_prefix, rewrite_suffix, status, hash_index, backup, backed_up, comment) < 0) { LM_INFO("Error while adding route\n"); if (backed_up) { pkg_free(backed_up); } return -1; } if (backed_up) { pkg_free(backed_up); } backed_up = NULL; } } } cfg_free(cfg); return 0; }