Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
0
/**
 * 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;
}