コード例 #1
0
static int select_entire_dialog_table(db_res_t ** res, int *no_rows)
{
	db_key_t query_cols[DIALOG_TABLE_TOTAL_COL_NO] = {	&h_entry_column,
			&h_id_column,		&call_id_column,	&from_uri_column,
			&from_tag_column,	&to_uri_column,		&to_tag_column,
			&start_time_column,	&state_column,		&timeout_column,
			&from_cseq_column,	&to_cseq_column,	&from_route_column,
			&to_route_column, 	&from_contact_column, &to_contact_column,
			&from_sock_column,	&to_sock_column,	&vars_column,
			&profiles_column,	&sflags_column,		&from_ping_cseq_column,
			&to_ping_cseq_column,&flags_column, &mangled_fu_column,&mangled_tu_column};

	if(use_dialog_table() != 0){
		return -1;
	}

	/* select the whole tabel and all the columns */
	if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH)) {
		if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0,
		DIALOG_TABLE_TOTAL_COL_NO, 0, 0) < 0) {
			LM_ERR("Error while querying (fetch) database\n");
			return -1;
		}
		*no_rows = estimate_available_rows( 4+4+128+64+32+54+32+4+4+4+16+16
			+256+256+64+64+32+32+256+256+4+4+4+4,DIALOG_TABLE_TOTAL_COL_NO );
		if (*no_rows==0) *no_rows = 10;
		if(dialog_dbf.fetch_result(dialog_db_handle,res,*no_rows)<0){
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0,
		DIALOG_TABLE_TOTAL_COL_NO, 0, res) < 0) {
			LM_ERR("Error while querying database\n");
			return -1;
		}
	}

	return 0;
}
コード例 #2
0
ファイル: mtree_mod.c プロジェクト: TheGrandWazoo/kamailio
static int mt_load_db_trees()
{
	db_key_t db_cols[3] = {&tname_column, &tprefix_column, &tvalue_column};
	str tprefix, tvalue, tname;
	db1_res_t* db_res = NULL;
	int i, ret;
	m_tree_t *new_head = NULL;
	m_tree_t *new_tree = NULL;
	m_tree_t *old_head = NULL;

	if(db_con==NULL)
	{
		LM_ERR("no db connection\n");
		return -1;
	}

	if (mt_dbf.use_table(db_con, &db_table) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH))
	{
		if(mt_dbf.query(db_con,0,0,0,db_cols,0,3,&tname_column,0) < 0)
		{
			LM_ERR("Error while querying db\n");
			return -1;
		}
		if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0)
		{
			LM_ERR("Error while fetching result\n");
			if (db_res)
				mt_dbf.free_result(db_con, db_res);
			goto error;
		} else {
			if(RES_ROW_N(db_res)==0)
			{
				return 0;
			}
		}
	} else {
		if((ret=mt_dbf.query(db_con, NULL, NULL, NULL, db_cols,
						0, 3, &tname_column, &db_res))!=0
				|| RES_ROW_N(db_res)<=0 )
		{
			mt_dbf.free_result(db_con, db_res);
			if( ret==0)
			{
				return 0;
			} else {
				goto error;
			}
		}
	}

	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			/* check for NULL values ?!?! */
			tname.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
			tname.len = strlen(tname.s);

			tprefix.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val);
			tprefix.len = strlen(tprefix.s);

			tvalue.s = (char*)(RES_ROWS(db_res)[i].values[2].val.string_val);
			tvalue.len = strlen(tvalue.s);

			if(tprefix.s==NULL || tvalue.s==NULL || tname.s==NULL ||
					tprefix.len<=0 || tvalue.len<=0 || tname.len<=0)
			{
				LM_ERR("Error - bad values in db\n");
				continue;
			}
			new_tree = mt_add_tree(&new_head, &tname, &db_table, NULL,
							_mt_tree_type, 0);
			if(new_tree==NULL)
			{
				LM_ERR("New tree cannot be initialized\n");
				goto error;
			}
			if(mt_add_to_tree(new_tree, &tprefix, &tvalue)<0)
			{
				LM_ERR("Error adding info to tree\n");
				goto error;
			}
		}
		if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) {
			if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) {
				LM_ERR("Error while fetching!\n");
				if (db_res)
					mt_dbf.free_result(db_con, db_res);
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(db_res)>0);
	mt_dbf.free_result(db_con, db_res);

	/* block all readers */
	lock_get( mt_lock );
	mt_reload_flag = 1;
	lock_release( mt_lock );

	while (mt_tree_refcnt) {
		sleep_us(10);
	}

	old_head = mt_swap_list_head(new_head);

	mt_reload_flag = 0;
	/* free old data */
	if (old_head!=NULL)
		mt_free_tree(old_head);

	return 0;

error:
	mt_dbf.free_result(db_con, db_res);
	if (new_head!=NULL)
		mt_free_tree(new_head);
	return -1;
}
コード例 #3
0
ファイル: mtree_mod.c プロジェクト: TheGrandWazoo/kamailio
static int mt_load_db(m_tree_t *pt)
{
	db_key_t db_cols[MT_MAX_COLS] = {&tprefix_column, &tvalue_column};
	db_key_t key_cols[1];
	db_op_t op[1] = {OP_EQ};
	db_val_t vals[1];
	str tprefix, tvalue;
	db1_res_t* db_res = NULL;
	int i, ret, c;
	m_tree_t new_tree;
	m_tree_t *old_tree = NULL;
	mt_node_t *bk_head = NULL;

	if(pt->ncols>0) {
		for(c=0; c<pt->ncols; c++) {
			db_cols[c] = &pt->scols[c];
		}
	} else {
		db_cols[0] = &tprefix_column;
		db_cols[1] = &tvalue_column;
		c = 2;
	}
	key_cols[0] = &tname_column;
	VAL_TYPE(vals) = DB1_STRING;
	VAL_NULL(vals) = 0;
	VAL_STRING(vals) = pt->tname.s;

	if(db_con==NULL)
	{
		LM_ERR("no db connection\n");
		return -1;
	}

	old_tree = mt_get_tree(&(pt->tname));
	if(old_tree==NULL)
	{
		LM_ERR("tree definition not found [%.*s]\n", pt->tname.len,
				pt->tname.s);
		return -1;
	}
	memcpy(&new_tree, old_tree, sizeof(m_tree_t));
	new_tree.head = 0;
	new_tree.next = 0;
	new_tree.nrnodes = 0;
	new_tree.nritems = 0;
	new_tree.memsize = 0;
	new_tree.reload_count++;
	new_tree.reload_time = (unsigned int)time(NULL);


	if (mt_dbf.use_table(db_con, &old_tree->dbtable) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) {
		if(mt_dbf.query(db_con, key_cols, op, vals, db_cols, pt->multi,
				c, 0, 0) < 0)
		{
			LM_ERR("Error while querying db\n");
			return -1;
		}
		if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0)
		{
			LM_ERR("Error while fetching result\n");
			goto error;
		} else {
			if(RES_ROW_N(db_res)==0)
			{
				goto dbreloaded;
			}
		}
	} else {
		if((ret=mt_dbf.query(db_con, key_cols, op, vals, db_cols,
						pt->multi, 2, 0, &db_res))!=0
				|| RES_ROW_N(db_res)<=0 )
		{
			if(ret==0)
			{
				goto dbreloaded;
			} else {
				goto error;
			}
		}
	}

	if(RES_ROW_N(db_res)>0)
	{
		if(RES_ROWS(db_res)[0].values[0].type != DB1_STRING
				|| RES_ROWS(db_res)[0].values[1].type != DB1_STRING)
		{
			LM_ERR("wrond column types in db table (%d / %d)\n",
					RES_ROWS(db_res)[0].values[0].type,
					RES_ROWS(db_res)[0].values[1].type);
			goto error;
		}
	}

	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			/* check for NULL values ?!?! */
			tprefix.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
			tprefix.len = strlen(ZSW(tprefix.s));

			if(c>2) {
				if(mt_pack_values(&new_tree, db_res, i, c, &tvalue)<0) {
					LM_ERR("Error packing values\n");
					goto error;
				}
			} else {
				tvalue.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val);
				tvalue.len = strlen(ZSW(tvalue.s));
			}

			if(tprefix.s==NULL || tvalue.s==NULL
					|| tprefix.len<=0 || tvalue.len<=0)
			{
				LM_ERR("Error - bad record in db"
						" (prefix: %p/%d - value: %p/%d)\n",
						tprefix.s, tprefix.len, tvalue.s, tvalue.len);
				continue;
			}

			if(mt_add_to_tree(&new_tree, &tprefix, &tvalue)<0)
			{
				LM_ERR("Error adding info to tree\n");
				goto error;
			}
		}
		if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) {
			if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) {
				LM_ERR("Error while fetching!\n");
				if (db_res)
					mt_dbf.free_result(db_con, db_res);
				goto error;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(db_res)>0);

dbreloaded:
	mt_dbf.free_result(db_con, db_res);


	/* block all readers */
	lock_get( mt_lock );
	mt_reload_flag = 1;
	lock_release( mt_lock );

	while (mt_tree_refcnt) {
		sleep_us(10);
	}

	bk_head = old_tree->head;
	old_tree->head = new_tree.head;
	old_tree->nrnodes = new_tree.nrnodes;
	old_tree->nritems = new_tree.nritems;
	old_tree->memsize = new_tree.memsize;
	old_tree->reload_count = new_tree.reload_count;
	old_tree->reload_time  = new_tree.reload_time;

	mt_reload_flag = 0;

	/* free old data */
	if (bk_head!=NULL)
		mt_free_node(bk_head, new_tree.type);

	return 0;

error:
	mt_dbf.free_result(db_con, db_res);
	if (new_tree.head!=NULL)
		mt_free_node(new_tree.head, new_tree.type);
	return -1;
}
コード例 #4
0
ファイル: clusterer.c プロジェクト: Danfx/opensips
/* loads data from the db */
table_entry_t* load_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table)
{
	int int_vals[7];
	char *str_vals[2];
	int no_of_results;
	int i, n;
	int no_rows = 5;
	int db_cols = 10;
	unsigned long last_attempt;
	static db_key_t clusterer_machine_id_key = &machine_id_col;
	static db_val_t clusterer_machine_id_value = {
		.type = DB_INT,
		.nul = 0,
	};

	VAL_INT(&clusterer_machine_id_value) = server_id;

	/* the columns from the db table */
	db_key_t columns[10];
	/* result from a db query */
	db_res_t* res;
	/* a row from the db table */
	db_row_t* row;
	/* the processed result */
	table_entry_t *data;

	res = 0;
	data = 0;

	columns[0] = &cluster_id_col;
	columns[1] = &machine_id_col;
	columns[2] = &state_col;
	columns[3] = &description_col;
	columns[4] = &url_col;
	columns[5] = &id_col;
	columns[6] = &last_attempt_col;
	columns[7] = &failed_attempts_col;
	columns[8] = &no_tries_col;
	columns[9] = &duration_col;

	CON_OR_RESET(db_hdl);

	/* checking if the table version is up to date*/
	if (db_check_table_version(dr_dbf, db_hdl, db_table, 1/*version*/) != 0)
		goto error;

	/* read data */
	if (dr_dbf->use_table(db_hdl, db_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", db_table->len, db_table->s);
		goto error;
	}

	LM_DBG("DB query - retrieve the clusters list"
		"in which the specified server runs\n");

	/* first we see in which clusters the specified server runs*/
	if (dr_dbf->query(db_hdl, &clusterer_machine_id_key, &op_eq,
		&clusterer_machine_id_value, columns, 1, 1, 0, &res) < 0) {
		LM_ERR("DB query failed - cannot retrieve the clusters list in which"
			" the specified server runs\n");
		goto error;
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	if (RES_ROW_N(res) == 0) {
		LM_WARN("No machines found in cluster %d\n", server_id);
		return 0;
	}

	clusterer_cluster_id_key = pkg_realloc(clusterer_cluster_id_key,
		RES_ROW_N(res) * sizeof(db_key_t));
	if (!clusterer_cluster_id_key) {
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++)
		clusterer_cluster_id_key[i] = &cluster_id_col;

	clusterer_cluster_id_value = pkg_realloc(clusterer_cluster_id_value,
		RES_ROW_N(res) * sizeof(db_val_t));

	if (!clusterer_cluster_id_value) {
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		VAL_TYPE(clusterer_cluster_id_value + i) = DB_INT;
		VAL_NULL(clusterer_cluster_id_value + i) = 0;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		row = RES_ROWS(res) + i;

		check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0);
		VAL_INT(clusterer_cluster_id_value + i) = VAL_INT(ROW_VALUES(row));
	}

	no_of_results = RES_ROW_N(res);
	dr_dbf->free_result(db_hdl, res);
	res = 0;

	LM_DBG("DB query - retrieve valid connections\n");

	/* fetch is the best strategy */
	CON_USE_OR_OP(db_hdl);
	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {

		if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0,
			clusterer_cluster_id_value, columns, no_of_results, db_cols, 0, 0) < 0) {
			LM_ERR("DB query failed - retrieve valid connections \n");
			goto error;
		}
		no_rows = estimate_available_rows(4 + 4 + 4 + 64 + 4 + 45 + 4 + 8 + 4 + 4, db_cols);
		if (no_rows == 0) no_rows = 5;
		if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0,
			clusterer_cluster_id_value, columns, no_of_results, db_cols, 0, &res) < 0) {
			LM_ERR("DB query failed - retrieve valid connections\n");
			goto error;
		}
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	n = 0;
	do {
		for (i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* CLUSTER ID column */
			check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0);
			int_vals[INT_VALS_CLUSTER_ID_COL] = VAL_INT(ROW_VALUES(row));
			/* MACHINE ID column */
			check_val(machine_id_col, ROW_VALUES(row) + 1, DB_INT, 1, 0);
			int_vals[INT_VALS_MACHINE_ID_COL] = VAL_INT(ROW_VALUES(row) + 1);
			/* STATE column */
			check_val(state_col, ROW_VALUES(row) + 2, DB_INT, 1, 0);
			int_vals[INT_VALS_STATE_COL] = VAL_INT(ROW_VALUES(row) + 2);
			/* DESCRIPTION column */
			check_val(description_col, ROW_VALUES(row) + 3, DB_STRING, 0, 0);
			str_vals[STR_VALS_DESCRIPTION_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 3);
			/* URL column */
			check_val(url_col, ROW_VALUES(row) + 4, DB_STRING, 1, 1);
			str_vals[STR_VALS_URL_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 4);
			/* CLUSTERER_ID column */
			check_val(id_col, ROW_VALUES(row) + 5, DB_INT, 1, 0);
			int_vals[INT_VALS_CLUSTERER_ID_COL] = VAL_INT(ROW_VALUES(row) + 5);
			/* LAST_ATTEMPT column */
			check_val(last_attempt_col, ROW_VALUES(row) + 6, DB_BIGINT, 1, 0);
			last_attempt = VAL_BIGINT(ROW_VALUES(row) + 6);
			/* FAILED_ATTEMPTS column */
			check_val(failed_attempts_col, ROW_VALUES(row) + 7, DB_INT, 1, 0);
			int_vals[INT_VALS_FAILED_ATTEMPTS_COL] = VAL_INT(ROW_VALUES(row) + 7);
			/* NO_TRIES column */
			check_val(no_tries_col, ROW_VALUES(row) + 8, DB_INT, 1, 0);
			int_vals[INT_VALS_NO_TRIES_COL] = VAL_INT(ROW_VALUES(row) + 8);
			/* DURATION column */
			check_val(duration_col, ROW_VALUES(row) + 9, DB_INT, 1, 0);
			int_vals[INT_VALS_DURATION_COL] = VAL_INT(ROW_VALUES(row) + 9);


			/* store data */
			if (add_info(&data, int_vals, last_attempt, str_vals) < 0) {
				LM_DBG("error while adding info to shm\n");
				goto error;
			}

			LM_DBG("machine id %d\n", int_vals[0]);
			LM_DBG("cluster id %d\n", int_vals[1]);
			LM_DBG("state %d\n", int_vals[2]);
			LM_DBG("clusterer_id %d\n", int_vals[3]);
			LM_DBG("description %s\n", str_vals[0]);
			LM_DBG("url %s\n", str_vals[1]);

			n++;
		}
		if (n == 1)
			LM_WARN("The server is the only one in the cluster\n");

		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
				LM_ERR("fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while (RES_ROW_N(res) > 0);

	LM_DBG("%d records found in %.*s\n",
		n, db_table->len, db_table->s);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	return data;
error:
	if (res)
		dr_dbf->free_result(db_hdl, res);
	if (data)
		free_data(data);
	data = NULL;
	return 0;
}

/* deallocates data */
void free_data(table_entry_t *data)
{
	table_entry_t *tmp_entry;
	table_entry_info_t *info;
	table_entry_info_t *tmp_info;
	table_entry_value_t *value;
	table_entry_value_t *tmp_value;

	struct module_timestamp *timestamp;
	struct module_timestamp *tmp_timestamp;

	while (data != NULL) {
		tmp_entry = data;
		data = data->next;
		info = tmp_entry->info;
		while (info != NULL) {
			value = info->value;
			while (value != NULL) {
				if (value->path.s)
					shm_free(value->path.s);
				if (value->description.s)
					shm_free(value->description.s);
				timestamp = value->in_timestamps;
				while (timestamp != NULL) {
					tmp_timestamp = timestamp;
					timestamp = timestamp->next;
					shm_free(tmp_timestamp);
				}
				tmp_value = value;
				value = value->next;
				shm_free(tmp_value);
			}
			tmp_info = info;
			info = info->next;
			shm_free(tmp_info);
		}
		shm_free(tmp_entry);
	}
}
コード例 #5
0
ファイル: frd_load.c プロジェクト: alias-neo/opensips
static int frd_load_data(dr_head_p drp, free_list_t **fl)
{
	static const size_t col_count = 16;
	db_res_t *res = NULL;
	unsigned int no_rows = 0, row_count, i;
	db_row_t *rows;
	db_val_t *values;

	db_key_t query_cols[] = {
		&rid_col, &pid_col, &prefix_col, &start_h_col, &end_h_col, &days_col,
		&cpm_thresh_warn_col, &cpm_thresh_crit_col, &calldur_thresh_warn_col,
		&calldur_thresh_crit_col, &totalc_thresh_warn_col, &totalc_thresh_crit_col,
		&concalls_thresh_warn_col, &concalls_thresh_crit_col, &seqcalls_thresh_warn_col,
		&seqcalls_thresh_crit_col
	};

	if (db_handle == NULL) {
		LM_ERR("Invalid db handler\n");
		return -1;
	}

	if (dbf.use_table(db_handle, &table_name) != 0) {
		LM_ERR("Cannot use table\n");
		return -1;
	}

	if (DB_CAPABILITY(dbf, DB_CAP_FETCH)) {
		if (dbf.query(db_handle, 0, 0, 0, query_cols, 0, col_count, 0, 0) != 0) {
			LM_ERR("Error while querying db\n");
			goto error;
		}
		/* estimate rows */
		no_rows = estimate_available_rows(4 + 64 + 5 + 5 + 64 + 5 * 2 * 4, col_count);

		if (no_rows == 0)
			no_rows = 10;

		if (dbf.fetch_result(db_handle, &res, no_rows) != 0) {
			LM_ERR("Error while fetching rows\n");
			goto error;
		}
	} else {
		/* No fetching capability */
		if (dbf.query(db_handle, 0, 0, 0, query_cols, 0, col_count, 0, &res) != 0) {
			LM_ERR("Error while querying db\n");
			goto error;
		}
	}

	/* Process the actual data */

	unsigned int rid, pid, j;
	str prefix, start_time, end_time, days;
	free_list_t *fl_it = NULL;
	*fl = NULL;

	do {
		row_count = RES_ROW_N(res);
		rows = RES_ROWS(res);
		fl_it = pkg_malloc(sizeof(free_list_t));
		if (fl_it == NULL) {
			LM_ERR ("no more pkg memory");
			dbf.free_result(db_handle, res);
			return -1;
		}
		fl_it ->next = *fl;
		*fl = fl_it;
		fl_it->trec = shm_malloc(sizeof(tmrec_t) * row_count);
		if (fl_it->trec == NULL)
			goto no_more_shm;
		fl_it->thr = shm_malloc(sizeof(frd_thresholds_t) * row_count);
		if (fl_it->thr == NULL)
			goto no_more_shm;
		fl_it->n = row_count;

		for (i = 0; i < row_count; ++i) {
			values = ROW_VALUES(rows + i);
			fl_it->trec[i].byday = NULL;

			/* rule id */
			if (VAL_NULL(values)) {
				LM_ERR("rule id cannot be NULL - skipping rule\n");
				continue;
			}
			rid = VAL_INT(values);

			/* profile id */
			if (VAL_NULL(values + 1)) {
				LM_ERR("profile id cannot be NULL - skipping rule\n");
				continue;
			}
			pid = VAL_INT(values + 1);

			get_str_from_dbval(prefix_col.s, values + 2, 1, 1, prefix, null_val);
			get_str_from_dbval(start_h_col.s, values + 3, 1, 1, start_time, null_val);
			get_str_from_dbval(end_h_col.s, values + 4, 1, 1, end_time, null_val);
			get_str_from_dbval(days_col.s, values + 5, 1, 1, days, null_val);

			if (create_time_rec(&start_time, &end_time, &days, fl_it->trec + i) != 0)
				goto null_val;

			/* Now load the thresholds */
			for (j = 0; j < 2 * 5; ++j) {
				if (VAL_NULL(values + 6 + j))
					goto null_val;
				memcpy((char*)fl_it->thr + i * sizeof(frd_thresholds_t) +
						j * sizeof(unsigned int), &VAL_INT(values + 6 + j),
						sizeof(unsigned int));
			}

			/* Rule OK, time to put it in DR */
			if (drb.add_rule(drp, rid, &prefix, pid, 0, fl_it->trec + i,
						(void*)(&fl_it->thr[i])) != 0) {

				LM_ERR("Cannot add rule in dr <%u>. Skipping...\n", rid);
			}

			null_val:
				continue;
		}

		if (DB_CAPABILITY(dbf, DB_CAP_FETCH)) {
			/* any more rows to fetch ? */
			if(dbf.fetch_result(db_handle, &res, no_rows)<0) {
				LM_ERR("error while fetching rows\n");
				goto error;
			}
			/* success in fetching more rows - continue the loop */
		} else
			break;

	} while (RES_ROW_N(res) > 0);

	dbf.free_result(db_handle, res);
	return 0;

no_more_shm:
	LM_ERR ("no more shm memory\n");
	dbf.free_result(db_handle, res);

error:
	return -1;
}
コード例 #6
0
ファイル: route_db.c プロジェクト: Enigmedia/opensips
/**
 * 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;
}
コード例 #7
0
static int load_dialog_info_from_db(int dlg_hash_size)
{
	db_res_t * res;
	db_val_t * values;
	db_row_t * rows;
	int i, nr_rows;
	struct dlg_cell *dlg;
	str callid, from_uri, to_uri, from_tag, to_tag;
	str cseq1,cseq2,contact1,contact2,rroute1,rroute2,mangled_fu,mangled_tu;
	unsigned int next_id;
	int no_rows = 10;
	struct socket_info *caller_sock,*callee_sock;

	res = 0;
	if((nr_rows = select_entire_dialog_table(&res,&no_rows)) < 0)
		goto end;

	nr_rows = RES_ROW_N(res);

	do {
		LM_DBG("loading information from database for %i dialogs\n", nr_rows);

		rows = RES_ROWS(res);

		/* for every row---dialog */
		for(i=0; i<nr_rows; i++){

			values = ROW_VALUES(rows + i);

			if (VAL_NULL(values) || VAL_NULL(values+1)) {
				LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
					h_entry_column.len, h_entry_column.s,
					h_id_column.len, h_id_column.s);
				continue;
			}

			if (VAL_NULL(values+7) || VAL_NULL(values+8)) {
				LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
					start_time_column.len, start_time_column.s,
					state_column.len, state_column.s);
				continue;
			}

			if ( VAL_INT(values+8) == DLG_STATE_DELETED ) {
				LM_DBG("dialog already terminated -> skipping\n");
				continue;
			}

			caller_sock = create_socket_info(values, 16);
			callee_sock = create_socket_info(values, 17);
			if (caller_sock == NULL || callee_sock == NULL) {
				LM_ERR("Dialog in DB doesn't match any listening sockets");
				continue;
			}

			/*restore the dialog info*/
			GET_STR_VALUE(callid, values, 2, 1, 0);
			GET_STR_VALUE(from_uri, values, 3, 1, 0);
			GET_STR_VALUE(from_tag, values, 4, 1, 0);
			GET_STR_VALUE(to_uri, values, 5, 1, 0);

			if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){
				LM_ERR("failed to build new dialog\n");
				goto error;
			}

			if(dlg->h_entry != VAL_INT(values)){
				LM_ERR("inconsistent hash data in the dialog database: "
					"you may have restarted opensips using a different "
					"hash_size: please erase %.*s database and restart\n", 
					dialog_table_name.len, dialog_table_name.s);
				shm_free(dlg);
				goto error;
			}

			/*link the dialog*/
			link_dlg(dlg, 0);

			dlg->h_id = VAL_INT(values+1);
			next_id = d_table->entries[dlg->h_entry].next_id;

			d_table->entries[dlg->h_entry].next_id =
				(next_id < dlg->h_id) ? (dlg->h_id+1) : next_id;

			GET_STR_VALUE(to_tag, values, 6, 1, 1);

			dlg->start_ts	= VAL_INT(values+7);

			dlg->state 		= VAL_INT(values+8);
			if (dlg->state==DLG_STATE_CONFIRMED_NA ||
			dlg->state==DLG_STATE_CONFIRMED) {
				active_dlgs_cnt++;
			} else if (dlg->state==DLG_STATE_EARLY) {
				early_dlgs_cnt++;
			}

			GET_STR_VALUE(cseq1, values, 10 , 1, 1);
			GET_STR_VALUE(cseq2, values, 11 , 1, 1);
			GET_STR_VALUE(rroute1, values, 12, 0, 0);
			GET_STR_VALUE(rroute2, values, 13, 0, 0);
			GET_STR_VALUE(contact1, values, 14, 0, 1);
			GET_STR_VALUE(contact2, values, 15, 0, 1);

			GET_STR_VALUE(mangled_fu, values, 24,0,1);
			GET_STR_VALUE(mangled_tu, values, 25,0,1);

			/* add the 2 legs */
			if ( (dlg_add_leg_info( dlg, &from_tag, &rroute1, &contact1,
			&cseq1, caller_sock,0,0)!=0) ||
			(dlg_add_leg_info( dlg, &to_tag, &rroute2, &contact2,
			&cseq2, callee_sock,&mangled_fu,&mangled_tu)!=0) ) {
				LM_ERR("dlg_set_leg_info failed\n");
				/* destroy the dialog */
				unref_dlg(dlg,1);
				continue;
			}
			dlg->legs_no[DLG_LEG_200OK] = DLG_FIRST_CALLEE_LEG;

			/* script variables */
			if (!VAL_NULL(values+18))
				read_dialog_vars( VAL_STR(values+18).s,
					VAL_STR(values+18).len, dlg);

			/* profiles */
			if (!VAL_NULL(values+19))
				read_dialog_profiles( VAL_STR(values+19).s,
					strlen(VAL_STR(values+19).s), dlg,0);


			/* script flags */
			if (!VAL_NULL(values+20)) {
				dlg->user_flags = VAL_INT(values+20);
			}

			/* top hiding */
			dlg->flags = VAL_INT(values+23);
			if (dlg_db_mode==DB_MODE_SHUTDOWN)
				dlg->flags |= DLG_FLAG_NEW;

			/* calculcate timeout */
			dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks();
			if (dlg->tl.timeout<=(unsigned int)time(0))
				dlg->tl.timeout = 0;
			else
				dlg->tl.timeout -= (unsigned int)time(0);

			/* restore the timer values */
			if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) {
				LM_CRIT("Unable to insert dlg %p [%u:%u] "
					"with clid '%.*s' and tags '%.*s' '%.*s'\n",
					dlg, dlg->h_entry, dlg->h_id,
					dlg->callid.len, dlg->callid.s,
					dlg->legs[DLG_CALLER_LEG].tag.len,
					dlg->legs[DLG_CALLER_LEG].tag.s,
					dlg->legs[callee_idx(dlg)].tag.len,
					ZSW(dlg->legs[callee_idx(dlg)].tag.s));
				/* destroy the dialog */
				unref_dlg(dlg,1);
				continue;
			}

			/* reference the dialog as kept in the timer list */
			ref_dlg(dlg,1);
			LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout);

			dlg->lifetime = 0;

			dlg->legs[DLG_CALLER_LEG].last_gen_cseq = 
				(unsigned int)(VAL_INT(values+21));
			dlg->legs[callee_idx(dlg)].last_gen_cseq = 
				(unsigned int)(VAL_INT(values+22));

			if (dlg->flags & DLG_FLAG_PING_CALLER || dlg->flags & DLG_FLAG_PING_CALLEE) {
				if (0 != insert_ping_timer(dlg)) 
					LM_CRIT("Unable to insert dlg %p into ping timer\n",dlg); 
				else {
					/* reference dialog as kept in ping timer list */
					ref_dlg(dlg,1);
				}
			}

			next_dialog:
			;
		}

		/* any more data to be fetched ?*/
		if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH)) {
			if (dialog_dbf.fetch_result( dialog_db_handle, &res,no_rows) < 0) {
				LM_ERR("fetching more rows failed\n");
				goto error;
			}
			nr_rows = RES_ROW_N(res);
		} else {
			nr_rows = 0;
		}

	}while (nr_rows>0);

end:
	dialog_dbf.free_result(dialog_db_handle, res);
	return 0;
error:
	dialog_dbf.free_result(dialog_db_handle, res);
	return -1;
}
コード例 #8
0
ファイル: tls_mgm.c プロジェクト: Danfx/opensips
/* loads data from the db */
int load_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table,
	struct tls_domain **serv_dom, struct tls_domain **cli_dom)
{
	int int_vals[4];
	char *str_vals[11];
	int i, n;
	int no_rows = 5;
	int db_cols = 15;

	/* the columns from the db table */
	db_key_t columns[15];
	/* result from a db query */
	db_res_t* res;
	/* a row from the db table */
	db_row_t* row;

	res = 0;

	columns[0] = &id_col;
	columns[1] = &address_col;
	columns[2] = &type_col;
	columns[3] = &method_col;
	columns[4] = &verify_cert_col;
	columns[5] = &require_cert_col;
	columns[6] = &certificate_col;
	columns[7] = &pk_col;
	columns[8] = &crl_check_col;
	columns[9] = &crl_dir_col;
	columns[10] = &calist_col;
	columns[11] = &cadir_col;
	columns[12] = &cplist_col;
	columns[13] = &dhparams_col;
	columns[14] = &eccurve_col;

	/* checking if the table version is up to date*/
	if (db_check_table_version(dr_dbf, db_hdl, db_table, 1/*version*/) != 0)
		goto error;

	/* table to use*/
	if (dr_dbf->use_table(db_hdl, db_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", db_table->len, db_table->s);
		goto error;
	}

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {

		if (dr_dbf->query(db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0) < 0) {
			LM_ERR("DB query failed - retrieve valid connections \n");
			goto error;
		}
		no_rows = estimate_available_rows(10 + 45 + 4 + 45 + 4 + 4 + 45 +
			45 + 4 + 45 + 45 + 45 + 45 + 45 + 45, db_cols);
		if (no_rows == 0) no_rows = 5;
		if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if (dr_dbf->query(db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) {
			LM_ERR("DB query failed - retrieve valid connections\n");
			goto error;
		}
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	n = 0;
	do {
		for (i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;

			check_val(id_col, ROW_VALUES(row), DB_STRING, 1, 1);
			str_vals[STR_VALS_ID_COL] = (char *) VAL_STRING(ROW_VALUES(row));

			check_val(address_col, ROW_VALUES(row) + 1, DB_STRING, 1, 1);
			str_vals[STR_VALS_ADDRESS_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 1);

			check_val(type_col, ROW_VALUES(row) + 2, DB_INT, 1, 0);
			int_vals[INT_VALS_TYPE_COL] = VAL_INT(ROW_VALUES(row) + 2);

			check_val(method_col, ROW_VALUES(row) + 3, DB_STRING, 0, 0);
			str_vals[STR_VALS_METHOD_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 3);

			check_val(verify_cert_col, ROW_VALUES(row) + 4, DB_INT, 0, 0);
			int_vals[INT_VALS_VERIFY_CERT_COL] = VAL_INT(ROW_VALUES(row) + 4);

			check_val(require_cert_col, ROW_VALUES(row) + 5, DB_INT, 0, 0);
			int_vals[INT_VALS_REQUIRE_CERT_COL] = VAL_INT(ROW_VALUES(row) + 5);

			check_val(certificate_col, ROW_VALUES(row) + 6, DB_STRING, 0, 0);
			str_vals[STR_VALS_CERTIFICATE_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 6);

			check_val(pk_col, ROW_VALUES(row) + 7, DB_STRING, 0, 0);
			str_vals[STR_VALS_PK_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 7);

			check_val(crl_check_col, ROW_VALUES(row) + 8, DB_INT, 0, 0);
			int_vals[INT_VALS_CRL_CHECK_COL] = VAL_INT(ROW_VALUES(row) + 8);

			check_val(crl_dir_col, ROW_VALUES(row) + 9, DB_STRING, 0, 0);
			str_vals[STR_VALS_CRL_DIR_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 9);

			check_val(calist_col, ROW_VALUES(row) + 10, DB_STRING, 0, 0);
			str_vals[STR_VALS_CALIST_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 10);

			check_val(cadir_col, ROW_VALUES(row) + 11, DB_STRING, 0, 0);
			str_vals[STR_VALS_CADIR_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 11);

			check_val(cplist_col, ROW_VALUES(row) + 12, DB_STRING, 0, 0);
			str_vals[STR_VALS_CPLIST_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 12);

			check_val(dhparams_col, ROW_VALUES(row) + 13, DB_STRING, 0, 0);
			str_vals[STR_VALS_DHPARAMS_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 13);

			check_val(eccurve_col, ROW_VALUES(row) + 14, DB_STRING, 0, 0);
			str_vals[STR_VALS_ECCURVE_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 14);

			tlsp_db_add_domain(str_vals, int_vals, serv_dom, cli_dom);
			
			n++;
		}

		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
				LM_ERR("fetching rows\n");
				goto error;
			}
		} else {
			break;
		}

	} while (RES_ROW_N(res) > 0);

	LM_DBG("%d records found in %.*s\n",
		n, db_table->len, db_table->s);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	return 0;
error:
	LM_ERR("database");
	return -1;
}
コード例 #9
0
static int sync_dlg_db_mem(void)
{
	db_res_t * res;
	db_val_t * values;
	db_row_t * rows;
	struct dlg_entry *d_entry;
	struct dlg_cell *it,*known_dlg,*dlg=NULL;
	int i, nr_rows,callee_leg_idx,next_id,db_timeout;
	int no_rows = 10;
	unsigned int db_caller_cseq,db_callee_cseq,dlg_caller_cseq,dlg_callee_cseq;
	struct socket_info *caller_sock,*callee_sock;
	str callid, from_uri, to_uri, from_tag, to_tag;
	str cseq1,cseq2,contact1,contact2,rroute1,rroute2,mangled_fu,mangled_tu;

	res = 0;
	if((nr_rows = select_entire_dialog_table(&res,&no_rows)) < 0)
		goto error;

	nr_rows = RES_ROW_N(res);

	do {
		LM_DBG("loading information from database for %i dialogs\n", nr_rows);

		rows = RES_ROWS(res);

		/* for every row---dialog */
		for(i=0; i<nr_rows; i++){

			values = ROW_VALUES(rows + i);

			if (VAL_NULL(values) || VAL_NULL(values+1)) {
				LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
					h_entry_column.len, h_entry_column.s,
					h_id_column.len, h_id_column.s);
				continue;
			}

			if (VAL_NULL(values+7) || VAL_NULL(values+8)) {
				LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
					start_time_column.len, start_time_column.s,
					state_column.len, state_column.s);
				continue;
			}

			if ( VAL_INT(values+8) == DLG_STATE_DELETED ) {
				LM_DBG("dialog already terminated -> skipping\n");
				continue;
			}

			/*restore the dialog info*/
			GET_STR_VALUE(callid, values, 2, 1, 0);
			GET_STR_VALUE(from_tag, values, 4, 1, 0);
			GET_STR_VALUE(to_tag, values, 6, 1, 1);

			/* TODO - check about hash resize ? maybe hash was lowered & we overflow the hash */
			known_dlg = 0;
			d_entry = &(d_table->entries[VAL_INT(values)]);

			for (it=d_entry->first;it;it=it->next)
				if (it->callid.len == callid.len && 
					it->legs[DLG_CALLER_LEG].tag.len == from_tag.len &&
					memcmp(it->callid.s,callid.s,callid.len)==0 &&
					memcmp(it->legs[DLG_CALLER_LEG].tag.s,from_tag.s,from_tag.len)==0) {
					/* callid & ftag match */
					callee_leg_idx = callee_idx(it);
					if (it->legs[callee_leg_idx].tag.len == to_tag.len &&
						memcmp(it->legs[callee_leg_idx].tag.s,to_tag.s,to_tag.len)==0) {
						/* full dlg match */
						known_dlg = it;
						break;
					}
				}

			if (known_dlg == 0) {
				LM_DBG("First seen dialog - load all stuff - callid = [%.*s]\n",callid.len,callid.s);
				GET_STR_VALUE(from_uri, values, 3, 1, 0);
				GET_STR_VALUE(to_uri, values, 5, 1, 0);

				caller_sock = create_socket_info(values, 16);
				callee_sock = create_socket_info(values, 17);
				if (caller_sock == NULL || callee_sock == NULL) {
					LM_ERR("Dialog in DB doesn't match any listening sockets");
					continue;
				}

				/* first time we see this dialog - build it from scratch */
				if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){
					LM_ERR("failed to build new dialog\n");
					goto error;
				}

				if(dlg->h_entry != VAL_INT(values)){
					LM_ERR("inconsistent hash data in the dialog database: "
						"you may have restarted opensips using a different "
						"hash_size: please erase %.*s database and restart\n", 
						dialog_table_name.len, dialog_table_name.s);
					shm_free(dlg);
					goto error;
				}

				/*link the dialog*/
				link_dlg(dlg, 0);

				dlg->h_id = VAL_INT(values+1);
				next_id = d_table->entries[dlg->h_entry].next_id;

				d_table->entries[dlg->h_entry].next_id =
					(next_id < dlg->h_id) ? (dlg->h_id+1) : next_id;

				dlg->start_ts	= VAL_INT(values+7);

				dlg->state 		= VAL_INT(values+8);
				if (dlg->state==DLG_STATE_CONFIRMED_NA ||
				dlg->state==DLG_STATE_CONFIRMED) {
					if_update_stat(dlg_enable_stats, active_dlgs, 1);
				} else if (dlg->state==DLG_STATE_EARLY) {
					if_update_stat(dlg_enable_stats, early_dlgs, 1);
				}

				GET_STR_VALUE(cseq1, values, 10 , 1, 1);
				GET_STR_VALUE(cseq2, values, 11 , 1, 1);
				GET_STR_VALUE(rroute1, values, 12, 0, 0);
				GET_STR_VALUE(rroute2, values, 13, 0, 0);
				GET_STR_VALUE(contact1, values, 14, 0, 1);
				GET_STR_VALUE(contact2, values, 15, 0, 1);

				GET_STR_VALUE(mangled_fu, values, 24,0,1);
				GET_STR_VALUE(mangled_tu, values, 25,0,1);

				/* add the 2 legs */
				if ( (dlg_add_leg_info( dlg, &from_tag, &rroute1, &contact1,
				&cseq1, caller_sock,0,0)!=0) ||
				(dlg_add_leg_info( dlg, &to_tag, &rroute2, &contact2,
				&cseq2, callee_sock,&mangled_fu,&mangled_tu)!=0) ) {
					LM_ERR("dlg_set_leg_info failed\n");
					/* destroy the dialog */
					unref_dlg(dlg,1);
					continue;
				}
				dlg->legs_no[DLG_LEG_200OK] = DLG_FIRST_CALLEE_LEG;

				/* script variables */
				if (!VAL_NULL(values+18))
					read_dialog_vars( VAL_STR(values+18).s,
						VAL_STR(values+18).len, dlg);

				/* profiles */
				if (!VAL_NULL(values+19))
					read_dialog_profiles( VAL_STR(values+19).s,
						strlen(VAL_STR(values+19).s), dlg,0);


				/* script flags */
				if (!VAL_NULL(values+20)) {
					dlg->user_flags = VAL_INT(values+20);
				}

				/* top hiding */
				dlg->flags = VAL_INT(values+23);
				if (dlg_db_mode==DB_MODE_SHUTDOWN)
					dlg->flags |= DLG_FLAG_NEW;

				/* calculcate timeout */
				dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks();
				if (dlg->tl.timeout<=(unsigned int)time(0))
					dlg->tl.timeout = 0;
				else
					dlg->tl.timeout -= (unsigned int)time(0);

				/* restore the timer values */
				if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) {
					LM_CRIT("Unable to insert dlg %p [%u:%u] "
						"with clid '%.*s' and tags '%.*s' '%.*s'\n",
						dlg, dlg->h_entry, dlg->h_id,
						dlg->callid.len, dlg->callid.s,
						dlg->legs[DLG_CALLER_LEG].tag.len,
						dlg->legs[DLG_CALLER_LEG].tag.s,
						dlg->legs[callee_idx(dlg)].tag.len,
						ZSW(dlg->legs[callee_idx(dlg)].tag.s));
					/* destroy the dialog */
					unref_dlg(dlg,1);
					continue;
				}

				/* reference the dialog as kept in the timer list */
				ref_dlg(dlg,1);
				LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout);

				dlg->lifetime = 0;

				dlg->legs[DLG_CALLER_LEG].last_gen_cseq = 
					(unsigned int)(VAL_INT(values+21));
				dlg->legs[callee_idx(dlg)].last_gen_cseq = 
					(unsigned int)(VAL_INT(values+22));

				if (dlg->flags & DLG_FLAG_PING_CALLER || dlg->flags & DLG_FLAG_PING_CALLEE) {
					if (0 != insert_ping_timer(dlg)) 
						LM_CRIT("Unable to insert dlg %p into ping timer\n",dlg); 
					else {
						/* reference dialog as kept in ping timer list */
						ref_dlg(dlg,1);
					}
				}
			} else {
				/* we already saw this dialog before
				 * check which is the newer version */

				if (known_dlg->state > VAL_INT(values+8)) {
					LM_DBG("mem has a newer state - ignore \n");
					/* we know a newer version compared to the DB
					 * ignore it */
					goto next_dialog;
				} else if (known_dlg->state == VAL_INT(values+8)) {
					LM_DBG("mem has same state as DB \n");
					/* same state :-( no way to tell which is newer */
					
					/* play nice and store longest timeout, although not always correct*/
					db_timeout = (unsigned int)(VAL_INT(values+9)) + 
						get_ticks();
					if (db_timeout<=(unsigned int)time(0))
						db_timeout = 0;
					else
						db_timeout -= (unsigned int)time(0);

					if (known_dlg->tl.timeout < db_timeout)
						known_dlg->tl.timeout = db_timeout;

					/* check with is newer cseq for caller leg */
					if (!VAL_NULL(values+10)) {
						cseq1.s = VAL_STR(values+10).s;
						cseq1.len = strlen(cseq1.s);
						
						str2int(&cseq1,&db_caller_cseq);
						str2int(&known_dlg->legs[DLG_CALLER_LEG].r_cseq,&dlg_caller_cseq);

						/* Is DB cseq newer ? */
						if (db_caller_cseq > dlg_caller_cseq) {
							if (known_dlg->legs[DLG_CALLER_LEG].r_cseq.len < cseq1.len) {
								known_dlg->legs[DLG_CALLER_LEG].r_cseq.s = 
									shm_realloc(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.len);
								if (!known_dlg->legs[DLG_CALLER_LEG].r_cseq.s) {
									LM_ERR("no more shm\n");
									goto next_dialog;
								}
							}
							memcpy(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.s,cseq1.len);
							known_dlg->legs[DLG_CALLER_LEG].r_cseq.len = cseq1.len;
						}
					} else {
						/* DB has a null cseq - just keep 
						 * what we have so far */
						;
					}

					/* check with is newer cseq for caller leg */
					if (!VAL_NULL(values+11)) {
						cseq2.s = VAL_STR(values+11).s;
						cseq2.len = strlen(cseq2.s);

						callee_leg_idx = callee_idx(known_dlg);
						str2int(&cseq2,&db_callee_cseq);
						str2int(&known_dlg->legs[callee_leg_idx].r_cseq,&dlg_callee_cseq);

						/* Is DB cseq newer ? */
						if (db_callee_cseq > dlg_callee_cseq) {
							if (known_dlg->legs[callee_leg_idx].r_cseq.len < cseq2.len) {
								known_dlg->legs[callee_leg_idx].r_cseq.s = 
									shm_realloc(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.len);
								if (!known_dlg->legs[callee_leg_idx].r_cseq.s) {
									LM_ERR("no more shm\n");
									goto next_dialog;
								}
							}
							memcpy(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.s,cseq2.len);
							known_dlg->legs[callee_leg_idx].r_cseq.len = cseq2.len;
						}
					} else {
						/* DB has a null cseq - just keep 
						 * what we have so far */
						;
					}

					/* update ping cseqs, whichever is newer */
					if (known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq <
						(unsigned int)(VAL_INT(values+21)))
						known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq =
							(unsigned int)(VAL_INT(values+21));
					if (known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq <
						(unsigned int)(VAL_INT(values+22)))
						known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq =
							(unsigned int)(VAL_INT(values+22));

					/* update script variables
					 * if already found, delete the old ones
					 * and replace with new one */
					if (!VAL_NULL(values+18))
						read_dialog_vars( VAL_STR(values+18).s,
							VAL_STR(values+18).len, known_dlg);

					/* skip flags - keep what we have - anyway can't tell which is new */

					/* profiles - do not insert into a profile
					 * is dlg is already in that profile*/
					if (!VAL_NULL(values+19))
						read_dialog_profiles( VAL_STR(values+19).s,
							strlen(VAL_STR(values+19).s), known_dlg,1);
				} else {
					/* DB has newer state, just update fields from DB */
					LM_DBG("DB has newer state \n");

					/* set new state */
					known_dlg->state = VAL_INT(values+8);

					/* update timeout */
					known_dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + 
						get_ticks();
					if (known_dlg->tl.timeout<=(unsigned int)time(0))
						known_dlg->tl.timeout = 0;
					else
						known_dlg->tl.timeout -= (unsigned int)time(0);

					/* update cseqs */
					if (!VAL_NULL(values+10)) {
						cseq1.s = VAL_STR(values+10).s;
						cseq1.len = strlen(cseq1.s);

						if (known_dlg->legs[DLG_CALLER_LEG].r_cseq.len < cseq1.len) {
							known_dlg->legs[DLG_CALLER_LEG].r_cseq.s = 
								shm_realloc(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.len);
							if (!known_dlg->legs[DLG_CALLER_LEG].r_cseq.s) {
								LM_ERR("no more shm\n");
								goto next_dialog;
							}
						}
						memcpy(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.s,cseq1.len);
						known_dlg->legs[DLG_CALLER_LEG].r_cseq.len = cseq1.len;
					}

					if (!VAL_NULL(values+11)) {
						cseq2.s = VAL_STR(values+11).s;
						cseq2.len = strlen(cseq1.s);
						callee_leg_idx = callee_idx(known_dlg);

						if (known_dlg->legs[callee_leg_idx].r_cseq.len < cseq2.len) {
							known_dlg->legs[callee_leg_idx].r_cseq.s = 
								shm_realloc(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.len);
							if (!known_dlg->legs[callee_leg_idx].r_cseq.s) {
								LM_ERR("no more shm\n");
								goto next_dialog;
							}
						}

						memcpy(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.s,cseq2.len);
						known_dlg->legs[callee_leg_idx].r_cseq.len = cseq2.len;
					}

					/* update ping cseqs */
					known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq = 
						(unsigned int)(VAL_INT(values+21));
					known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq = 
						(unsigned int)(VAL_INT(values+22));

					/* update flags */
					known_dlg->flags = VAL_INT(values+23);
					if (dlg_db_mode==DB_MODE_SHUTDOWN)
						known_dlg->flags |= DLG_FLAG_NEW;

					/* update script variables
					 * if already found, delete the old one
					 * and replace with new one */
					if (!VAL_NULL(values+18))
						read_dialog_vars( VAL_STR(values+18).s,
							VAL_STR(values+18).len, known_dlg);

					/* profiles - do not insert into a profile
					 * is dlg is already in that profile*/
					if (!VAL_NULL(values+19))
						read_dialog_profiles( VAL_STR(values+19).s,
							strlen(VAL_STR(values+19).s), known_dlg,1);
				}

			}
			next_dialog:
			;
		}

		/* any more data to be fetched ?*/
		if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH)) {
			if (dialog_dbf.fetch_result( dialog_db_handle, &res,no_rows) < 0) {
				LM_ERR("fetching more rows failed\n");
				goto error;
			}
			nr_rows = RES_ROW_N(res);
		} else {
			nr_rows = 0;
		}

	}while (nr_rows>0);

	return 0;
error:
	return -1;
}
コード例 #10
0
ファイル: dp_db.c プロジェクト: UIKit0/OpenSIPS
/*load rules from DB*/
int dp_load_db(void)
{
	int i, nr_rows;
	db_res_t * res = 0;
	db_val_t * values;
	db_row_t * rows;
	db_key_t query_cols[DP_TABLE_COL_NO] = {
		&dpid_column,	&pr_column,
		&match_op_column,	&match_exp_column,	&match_len_column,
		&subst_exp_column,	&repl_exp_column,	&attrs_column };
	db_key_t order = &pr_column;
	dpl_node_t *rule;
	int no_rows = 10;

	if( (*crt_idx) != (*next_idx)){
		LM_WARN("a load command already generated, aborting reload...\n");
		return 0;
	}

	if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){
		LM_ERR("error in use_table\n");
		return -1;
	}

	if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
				DP_TABLE_COL_NO, order, 0) < 0){
			LM_ERR("failed to query database!\n");
			return -1;
		}
		no_rows = estimate_available_rows( 4+4+4+64+4+64+64+128,
			DP_TABLE_COL_NO);
		if (no_rows==0) no_rows = 10;
		if(dp_dbf.fetch_result(dp_db_handle, &res, no_rows)<0) {
			LM_ERR("failed to fetch\n");
			if (res)
				dp_dbf.free_result(dp_db_handle, res);
			return -1;
		}
	} else {
		/*select the whole table and all the columns*/
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
			DP_TABLE_COL_NO, order, &res) < 0){
				LM_ERR("failed to query database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	lock_start_write( ref_lock );

	*next_idx = ((*crt_idx) == 0)? 1:0;

	if(nr_rows == 0){
		LM_WARN("no data in the db\n");
		goto end;
	}

	do {
		for(i=0; i<RES_ROW_N(res); i++){
			rows = RES_ROWS(res);
			values = ROW_VALUES(rows+i);

			if ((rule = build_rule(values)) == NULL ) {
				LM_WARN(" failed to build rule -> skipping\n");
				continue;
			}

			if(add_rule2hash(rule , *next_idx) != 0) {
				LM_ERR("add_rule2hash failed\n");
				goto err2;
			}
		}

		if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
			if(dp_dbf.fetch_result(dp_db_handle, &res, no_rows)<0) {
				LM_ERR("failure while fetching!\n");
				if (res)
					dp_dbf.free_result(dp_db_handle, res);
				lock_stop_write( ref_lock );
				return -1;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(res)>0);
	

end:
	destroy_hash(*crt_idx);
	/*update data*/
	*crt_idx = *next_idx;

	/* release the exclusive writing access */
	lock_stop_write( ref_lock );

	list_hash(*crt_idx);

	dp_dbf.free_result(dp_db_handle, res);
	return 0;

err2:
	if(rule)	destroy_rule(rule);
	destroy_hash(*next_idx);
	dp_dbf.free_result(dp_db_handle, res);
	*next_idx = *crt_idx; 
	/* if lock defined - release the exclusive writing access */
	if(ref_lock)
		/* release the readers */
		lock_stop_write( ref_lock );
	return -1;
}
コード例 #11
0
ファイル: reg_db_handler.c プロジェクト: alias-neo/opensips
int load_reg_info_from_db(unsigned int plist)
{
	db_res_t * res = NULL;
	db_val_t * values;
	db_row_t * rows;
	int i, nr_rows, ret;
	unsigned int n_result_cols = 0;
	unsigned int registrar_col;
	unsigned int proxy_col;
	unsigned int aor_col;
	unsigned int third_party_registrant_col;
	unsigned int username_col;
	unsigned int password_col;
	unsigned int binding_URI_col;
	unsigned int binding_params_col;
	unsigned int expiry_col;
	unsigned int forced_socket_col;
	db_key_t q_cols[REG_TABLE_TOTAL_COL_NO];

	char *p = NULL;
	int len = 0;
	str now = {NULL, 0};
	struct sip_uri uri;
	str forced_socket, host;
	int port, proto;
	uac_reg_map_t uac_param;

	p = int2str((unsigned long)(time(0)), &len);
	if (p && len>0) {
		now.s = (char *)pkg_malloc(len);
		if(now.s) {
			memcpy(now.s, p, len); now.len = len;
		} else {
			LM_ERR("oom\n"); return -1;
		}
	}

	if(use_reg_table()) return -1;

	q_cols[registrar_col = n_result_cols++] = &registrar_column;
	q_cols[proxy_col = n_result_cols++] = &proxy_column;
	q_cols[aor_col = n_result_cols++] = &aor_column;
	q_cols[third_party_registrant_col = n_result_cols++] =
					&third_party_registrant_column;
	q_cols[username_col = n_result_cols++] = &username_column;
	q_cols[password_col = n_result_cols++] = &password_column;
	q_cols[binding_URI_col = n_result_cols++] = &binding_URI_column;
	q_cols[binding_params_col = n_result_cols++] = &binding_params_column;
	q_cols[expiry_col = n_result_cols++] = &expiry_column;
	q_cols[forced_socket_col = n_result_cols++] = &forced_socket_column;

	/* select the whole tabel and all the columns */
	if (DB_CAPABILITY(reg_dbf, DB_CAP_FETCH)) {
		if(reg_dbf.query(reg_db_handle, 0, 0, 0, q_cols, 0,
				REG_TABLE_TOTAL_COL_NO, 0, 0) < 0) {
			LM_ERR("Error while querying (fetch) database\n");
			return -1;
		}
		if(reg_dbf.fetch_result(reg_db_handle, &res, REG_FETCH_SIZE)<0){
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if(reg_dbf.query(reg_db_handle, 0, 0, 0, q_cols, 0,
				REG_TABLE_TOTAL_COL_NO, 0, &res) < 0) {
			LM_ERR("Error while querying database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	do {
		LM_INFO("loading [%i] records from db\n", nr_rows);
		rows = RES_ROWS(res);
		/* for every row/record */
		for(i=0; i<nr_rows; i++){
			values = ROW_VALUES(rows + i);
			if (VAL_NULL(values+registrar_col) ||
				VAL_NULL(values+aor_col) ||
				VAL_NULL(values+binding_URI_col)) {
				LM_ERR("columns [%.*s] or/and [%.*s] or/and [%.*s]"
					" cannot be null -> skipping\n",
					registrar_column.len, registrar_column.s,
					aor_column.len, aor_column.s,
					binding_URI_column.len, binding_URI_column.s);
				continue;
			}

			memset(&uac_param, 0, sizeof(uac_reg_map_t));

			/* Get the registrar (mandatory parameter) */
			uac_param.registrar_uri.s =
				(char*)values[registrar_col].val.string_val;
			if (uac_param.registrar_uri.s)
				uac_param.registrar_uri.len =
					strlen(uac_param.registrar_uri.s);
			else {
				LM_ERR("ignoring empty registrar\n");
				continue;
			}
			if (parse_uri(uac_param.registrar_uri.s,
					uac_param.registrar_uri.len, &uri)<0) {
				LM_ERR("cannot parse registrar uri [%.*s]\n",
					uac_param.registrar_uri.len,
					uac_param.registrar_uri.s);
				continue;
			}
			if (uri.user.s && uri.user.len) {
				LM_ERR("registrant uri must not have user [%.*s]\n",
					uri.user.len, uri.user.s);
				continue;
			}

			/* Get the proxy */
			uac_param.proxy_uri.s =
				(char*)values[proxy_col].val.string_val;
			if (uac_param.proxy_uri.s)
				uac_param.proxy_uri.len =
					strlen(uac_param.proxy_uri.s);
			if (uac_param.proxy_uri.len) {
				if (parse_uri(uac_param.proxy_uri.s,
						uac_param.proxy_uri.len, &uri)<0) {
					LM_ERR("cannot parse proxy uri [%.*s]\n",
						uac_param.proxy_uri.len,
						uac_param.proxy_uri.s);
					continue;
				}
				if (uri.user.s && uri.user.len) {
					LM_ERR("proxy uri must not have user [%.*s]\n",
						uri.user.len, uri.user.s);
					continue;
				}
			} else {
				uac_param.proxy_uri.s = NULL;
			}

			/* Get the AOR (mandatory parameter) */
			uac_param.to_uri.s =
				(char*)values[aor_col].val.string_val;
			if (uac_param.to_uri.s)
				uac_param.to_uri.len = strlen(uac_param.to_uri.s);
			else {
				LM_ERR("ignoring empty AOR\n");
				continue;
			}
			if (parse_uri(uac_param.to_uri.s,uac_param.to_uri.len,&uri)<0) {
				LM_ERR("cannot parse aor uri [%.*s]\n",
					uac_param.to_uri.len, uac_param.to_uri.s);
				continue;
			}
			uac_param.hash_code =
				core_hash(&uac_param.to_uri, NULL, reg_hsize);

			/* Get the third party registrant */
			uac_param.from_uri.s =
				(char*)values[third_party_registrant_col].val.string_val;
			if (uac_param.from_uri.s)
				uac_param.from_uri.len = strlen(uac_param.from_uri.s);
			if (uac_param.from_uri.len) {
				if (parse_uri(uac_param.from_uri.s,
						uac_param.from_uri.len, &uri)<0) {
					LM_ERR("cannot parse third party registrant"
						" uri [%.*s]\n",
						uac_param.from_uri.len,
						uac_param.from_uri.s);
					continue;
				}
			} else {
				uac_param.from_uri.s = NULL;
			}

			/* Get the binding (manadatory parameter) */
			uac_param.contact_uri.s =
				(char*)values[binding_URI_col].val.string_val;
			if (uac_param.contact_uri.s)
				uac_param.contact_uri.len =
					strlen(uac_param.contact_uri.s);
			else {
				LM_ERR("ignoring empty binding\n");
				continue;
			}
			if (parse_uri(uac_param.contact_uri.s,
					uac_param.contact_uri.len, &uri)<0) {
				LM_ERR("cannot parse contact uri [%.*s]\n",
					uac_param.contact_uri.len,
					uac_param.contact_uri.s);
				continue;
			}

			/* Get the authentication user */
			uac_param.auth_user.s =
				(char*)values[username_col].val.string_val;
			if (uac_param.auth_user.s)
				uac_param.auth_user.len = strlen(uac_param.auth_user.s);
			if (uac_param.auth_user.len == 0) uac_param.auth_user.s = NULL;

			/* Get the authentication password */
			uac_param.auth_password.s =
				(char*)values[password_col].val.string_val;
			if (uac_param.auth_password.s)
				uac_param.auth_password.len =
					strlen(uac_param.auth_password.s);
			if (uac_param.auth_password.len == 0)
				uac_param.auth_password.s = NULL;

			/* Get the binding params */
			uac_param.contact_params.s =
				(char*)values[binding_params_col].val.string_val;
			if (uac_param.contact_params.s)
				uac_param.contact_params.len =
					strlen(uac_param.contact_params.s);
			if (uac_param.contact_params.len == 0)
				uac_param.contact_params.s = NULL;

			/* Get the expiration param */
			uac_param.expires = values[expiry_col].val.int_val;
			if (uac_param.expires <= timer_interval) {
				LM_ERR("Please decrease timer_interval=[%u]"
					" - requested expires=[%u] to small for AOR=[%.*s]\n",
					timer_interval, uac_param.expires,
					uac_param.to_uri.len, uac_param.to_uri.s);
				continue;
			}

			/* Get the socket */
			if (values[forced_socket_col].val.string_val &&
				(forced_socket.s = (char*)values[forced_socket_col].val.string_val)) {
				if((forced_socket.len = strlen(forced_socket.s))){
					if (parse_phostport(forced_socket.s,
							forced_socket.len,
							&host.s, &host.len,
							&port, &proto)<0) {
						LM_ERR("cannot parse forced socket [%.*s]\n",
							forced_socket.len, forced_socket.s);
						continue;
					}
					uac_param.send_sock = grep_sock_info(&host,
								(unsigned short) port,
								(unsigned short) proto);
					if (uac_param.send_sock==NULL) {
						LM_ERR("invalid forced socket [%.*s]\n",
							forced_socket.len, forced_socket.s);
						continue;
					}
				}
			}
			LM_DBG("registrar=[%.*s] AOR=[%.*s] auth_user=[%.*s] "
				"password=[%.*s] expire=[%d] proxy=[%.*s] "
				"contact=[%.*s] third_party=[%.*s]\n",
				uac_param.registrar_uri.len, uac_param.registrar_uri.s,
				uac_param.to_uri.len, uac_param.to_uri.s,
				uac_param.auth_user.len, uac_param.auth_user.s,
				uac_param.auth_password.len, uac_param.auth_password.s,
				uac_param.expires,
				uac_param.proxy_uri.len, uac_param.proxy_uri.s,
				uac_param.contact_uri.len, uac_param.contact_uri.s,
				uac_param.from_uri.len, uac_param.from_uri.s);
			lock_get(&reg_htable[uac_param.hash_code].lock);
			ret = add_record(&uac_param, &now, plist);
			lock_release(&reg_htable[uac_param.hash_code].lock);
			if(ret<0) {
				LM_ERR("can't load registrant\n");
				continue;
			}
		}

		/* any more data to be fetched ?*/
		if (DB_CAPABILITY(reg_dbf, DB_CAP_FETCH)) {
			if (reg_dbf.fetch_result(reg_db_handle, &res, REG_FETCH_SIZE)<0) {
				LM_ERR("fetching more rows failed\n");
				goto error;
			}
			nr_rows = RES_ROW_N(res);
		} else {
			nr_rows = 0;
		}
	}while (nr_rows>0);

	reg_dbf.free_result(reg_db_handle, res);
	if (now.s) pkg_free(now.s);
	return 0;
error:
	reg_dbf.free_result(reg_db_handle, res);
	if (now.s) pkg_free(now.s);
	return -1;
}
コード例 #12
0
ファイル: pua.c プロジェクト: Distrotech/opensips
static int db_restore(void)
{
	ua_pres_t* p= NULL;
	db_key_t result_cols[20];
	db_res_t *res= NULL;
	db_row_t *row = NULL;
	db_val_t *row_vals= NULL;
	str pres_uri, pres_id, to_uri;
	str etag, tuple_id;
	str watcher_uri, call_id;
	str to_tag, from_tag, remote_contact;
	str record_route, contact, extra_headers;
	int size= 0, i;
	int n_result_cols= 0;
	int puri_col,touri_col,pid_col,expires_col,flag_col,etag_col, desired_expires_col;
	int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col;
	int event_col,contact_col,tuple_col,record_route_col, extra_headers_col;
	int version_col;
	int no_rows = 10;

	result_cols[puri_col=n_result_cols++]	= &str_pres_uri_col;
	result_cols[touri_col=n_result_cols++]	= &str_to_uri_col;
	result_cols[pid_col=n_result_cols++]	= &str_pres_id_col;
	result_cols[expires_col=n_result_cols++]= &str_expires_col;
	result_cols[flag_col=n_result_cols++]	= &str_flag_col;
	result_cols[etag_col=n_result_cols++]	= &str_etag_col;
	result_cols[tuple_col=n_result_cols++]	= &str_tuple_id_col;
	result_cols[watcher_col=n_result_cols++]= &str_watcher_uri_col;
	result_cols[callid_col=n_result_cols++] = &str_call_id_col;
	result_cols[totag_col=n_result_cols++]	= &str_to_tag_col;
	result_cols[fromtag_col=n_result_cols++]= &str_from_tag_col;
	result_cols[cseq_col= n_result_cols++]	= &str_cseq_col;
	result_cols[event_col= n_result_cols++]	= &str_event_col;
	result_cols[record_route_col= n_result_cols++]	= &str_record_route_col;
	result_cols[contact_col= n_result_cols++]	= &str_contact_col;
	result_cols[remote_contact_col= n_result_cols++]	= &str_remote_contact_col;
	result_cols[extra_headers_col= n_result_cols++]	= &str_extra_headers_col;
	result_cols[desired_expires_col= n_result_cols++]	= &str_desired_expires_col;
	result_cols[version_col= n_result_cols++]	= &str_version_col;

	if(!pua_db)
	{
		LM_ERR("null database connection\n");
		return -1;
	}

	if(pua_dbf.use_table(pua_db, &db_table)< 0)
	{
		LM_ERR("in use table\n");
		return -1;
	}

	if (DB_CAPABILITY(pua_dbf, DB_CAP_FETCH)) {
		if(pua_dbf.query(pua_db,0, 0, 0, result_cols,0, n_result_cols, 0,0)< 0)
		{
			LM_ERR("while querying table\n");
			return -1;
		}
		no_rows = estimate_available_rows( 128+128+8+8+4+32+64+64+128+
			128+64+64+16+64, n_result_cols);
		if (no_rows==0) no_rows = 10;

		if(pua_dbf.fetch_result(pua_db, &res, no_rows)<0)
		{
			LM_ERR("Error fetching rows\n");
			return -1;
		}
	} else {
		if(pua_dbf.query(pua_db,0, 0, 0,result_cols,0,n_result_cols,0,&res)< 0)
		{
			LM_ERR("while querrying table\n");
			if(res)
			{
				pua_dbf.free_result(pua_db, res);
				res = NULL;
			}
			return -1;
		}
	}

	if(res== NULL)
		return -1;

	if(res->n<=0)
	{
		LM_INFO("the query returned no result\n");
		pua_dbf.free_result(pua_db, res);
		res = NULL;
		return 0;
	}

	LM_DBG("found %d db entries\n", res->n);

	do {
		for(i =0 ; i< res->n ; i++)
		{
			row = &res->rows[i];
			row_vals = ROW_VALUES(row);
			if(row_vals[expires_col].val.int_val < time(NULL))
				continue;

			pres_uri.s= (char*)row_vals[puri_col].val.string_val;
			pres_uri.len = strlen(pres_uri.s);

			LM_DBG("pres_uri= %.*s\n", pres_uri.len, pres_uri.s);

			memset(&etag,			 0, sizeof(str));
			memset(&tuple_id,		 0, sizeof(str));
			memset(&watcher_uri,	 0, sizeof(str));
			memset(&to_uri,          0, sizeof(str));
			memset(&call_id,		 0, sizeof(str));
			memset(&to_tag,			 0, sizeof(str));
			memset(&from_tag,		 0, sizeof(str));
			memset(&record_route,	 0, sizeof(str));
			memset(&pres_id,         0, sizeof(str));
			memset(&contact,         0, sizeof(str));
			memset(&remote_contact,  0, sizeof(str));
			memset(&extra_headers,   0, sizeof(str));

			pres_id.s= (char*)row_vals[pid_col].val.string_val;
			if(pres_id.s)
				pres_id.len = strlen(pres_id.s);

			if(row_vals[etag_col].val.string_val)
			{
				etag.s= (char*)row_vals[etag_col].val.string_val;
				etag.len = strlen(etag.s);

				tuple_id.s= (char*)row_vals[tuple_col].val.string_val;
				tuple_id.len = strlen(tuple_id.s);
			}

			if(row_vals[watcher_col].val.string_val)
			{
				watcher_uri.s= (char*)row_vals[watcher_col].val.string_val;
				watcher_uri.len = strlen(watcher_uri.s);

				to_uri.s= (char*)row_vals[touri_col].val.string_val;
				if(to_uri.s == NULL)
					to_uri = pres_uri;
				else
					to_uri.len = strlen(to_uri.s);
				LM_DBG("to_uri= %.*s\n", to_uri.len, to_uri.s);
				call_id.s= (char*)row_vals[callid_col].val.string_val;
				call_id.len = strlen(call_id.s);

				to_tag.s= (char*)row_vals[totag_col].val.string_val;
				to_tag.len = strlen(to_tag.s);

				from_tag.s= (char*)row_vals[fromtag_col].val.string_val;
				from_tag.len = strlen(from_tag.s);

				if(row_vals[record_route_col].val.string_val)
				{
					record_route.s= (char*)
						row_vals[record_route_col].val.string_val;
					record_route.len= strlen(record_route.s);
				}

				contact.s= (char*)row_vals[contact_col].val.string_val;
				contact.len = strlen(contact.s);

				remote_contact.s=
					(char*)row_vals[remote_contact_col].val.string_val;
				if(remote_contact.s)
					remote_contact.len = strlen(remote_contact.s);
			}
			extra_headers.s= (char*)row_vals[extra_headers_col].val.string_val;
			if(extra_headers.s)
				extra_headers.len= strlen(extra_headers.s);
			else
				extra_headers.len= 0;

			size= sizeof(ua_pres_t)+ sizeof(str)+ (pres_uri.len+ pres_id.len+
						tuple_id.len)* sizeof(char);

			if(watcher_uri.s)
				size+= sizeof(str)+ to_uri.len + watcher_uri.len+ call_id.len+ to_tag.len+
					from_tag.len+ record_route.len+ contact.len;

			p= (ua_pres_t*)shm_malloc(size);
			if(p== NULL)
			{
				LM_ERR("no more shared memmory");
				goto error;
			}
			memset(p, 0, size);
			size= sizeof(ua_pres_t);

			p->pres_uri= (str*)((char*)p+ size);
			size+= sizeof(str);
			p->pres_uri->s= (char*)p + size;
			memcpy(p->pres_uri->s, pres_uri.s, pres_uri.len);
			p->pres_uri->len= pres_uri.len;
			size+= pres_uri.len;

			if(pres_id.s)
			{
				CONT_COPY(p, p->id, pres_id);
			}

			if(watcher_uri.s && watcher_uri.len)
			{
				p->watcher_uri= (str*)((char*)p+ size);
				size+= sizeof(str);

				p->watcher_uri->s= (char*)p+ size;
				memcpy(p->watcher_uri->s, watcher_uri.s, watcher_uri.len);
				p->watcher_uri->len= watcher_uri.len;
				size+= watcher_uri.len;

				CONT_COPY(p, p->to_uri, to_uri);
				CONT_COPY(p, p->to_tag, to_tag);
				CONT_COPY(p, p->from_tag, from_tag);
				CONT_COPY(p, p->call_id, call_id);

				if(record_route.s && record_route.len)
				{
					CONT_COPY(p, p->record_route, record_route);
				}
				CONT_COPY(p, p->contact, contact);

				p->cseq= row_vals[cseq_col].val.int_val;

				p->remote_contact.s= (char*)shm_malloc(remote_contact.len);
				if(p->remote_contact.s== NULL)
				{
					LM_ERR("No more shared memory\n");
					goto error;
				}
				memcpy(p->remote_contact.s, remote_contact.s, remote_contact.len);
				p->remote_contact.len= remote_contact.len;

				p->version= row_vals[version_col].val.int_val;
			}

			LM_DBG("size= %d\n", size);
			p->event= row_vals[event_col].val.int_val;
			p->expires= row_vals[expires_col].val.int_val;
			p->desired_expires= row_vals[desired_expires_col].val.int_val;
			p->flag|=	row_vals[flag_col].val.int_val;

			memset(&p->etag, 0, sizeof(str));
			if(etag.s && etag.len)
			{
				/* alloc separately */
				p->etag.s= (char*)shm_malloc(etag.len);
				if(p->etag.s==  NULL)
				{
					LM_ERR("no more share memory\n");
					goto error;
				}
				memcpy(p->etag.s, etag.s, etag.len);
				p->etag.len= etag.len;
			}

			memset(&p->extra_headers, 0, sizeof(str));
			if(extra_headers.s && extra_headers.len)
			{
				/* alloc separately */
				p->extra_headers.s= (char*)shm_malloc(extra_headers.len);
				if(p->extra_headers.s==  NULL)
				{
					LM_ERR("no more share memory\n");
					goto error;
				}
				memcpy(p->extra_headers.s, extra_headers.s, extra_headers.len);
				p->extra_headers.len= extra_headers.len;
			}

			print_ua_pres(p);
			insert_htable(p);
		} /* end for(all rows)*/

		if (DB_CAPABILITY(pua_dbf, DB_CAP_FETCH)) {
			if(pua_dbf.fetch_result(pua_db, &res, no_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	pua_dbf.free_result(pua_db, res);
	res = NULL;

	if(pua_dbf.delete(pua_db, 0, 0 , 0, 0) < 0)
	{
		LM_ERR("while deleting information from db\n");
		goto error;
	}

	return 0;

error:
	if(res)
		pua_dbf.free_result(pua_db, res);

	if(p)
	{
		if(p->remote_contact.s) shm_free(p->remote_contact.s);
		if(p->extra_headers.s) shm_free(p->extra_headers.s);
		if(p->etag.s) shm_free(p->etag.s);
		shm_free(p);
	}
	return -1;
}
コード例 #13
0
ファイル: pdt.c プロジェクト: Distrotech/opensips
static int pdt_load_db(void)
{
	db_key_t db_cols[3] = {&sdomain_column, &prefix_column, &domain_column};
	str p, d, sdomain;
	db_res_t* db_res = NULL;
	int i, ret;
	pdt_tree_t *_ptree_new = NULL;
	pdt_tree_t *old_tree = NULL;
	int no_rows = 10;

	if(db_con==NULL)
	{
		LM_ERR("no db connection\n");
		return -1;
	}

	if (pdt_dbf.use_table(db_con, &db_table) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	if (DB_CAPABILITY(pdt_dbf, DB_CAP_FETCH)) {
		if(pdt_dbf.query(db_con,0,0,0,db_cols,0,3,&sdomain_column,0) < 0)
		{
			LM_ERR("Error while querying db\n");
			return -1;
		}
		no_rows = estimate_available_rows( 64+16+64, 3);
		if (no_rows==0) no_rows = 10;
		if(pdt_dbf.fetch_result(db_con, &db_res, no_rows)<0)
		{
			LM_ERR("Error while fetching result\n");
			if (db_res)
				pdt_dbf.free_result(db_con, db_res);
			goto error;
		} else {
			if(RES_ROW_N(db_res)==0)
			{
				return 0;
			}
		}
	} else {
		if((ret=pdt_dbf.query(db_con, NULL, NULL, NULL, db_cols,
				0, 3, &sdomain_column, &db_res))!=0
			|| RES_ROW_N(db_res)<=0 )
		{
			pdt_dbf.free_result(db_con, db_res);
			if( ret==0)
			{
				return 0;
			} else {
				goto error;
			}
		}
	}

	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			/* check for NULL values ?!?! */
			sdomain.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
			sdomain.len = strlen(sdomain.s);

			p.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val);
			p.len = strlen(p.s);

			d.s = (char*)(RES_ROWS(db_res)[i].values[2].val.string_val);
			d.len = strlen(d.s);

			if(p.s==NULL || d.s==NULL || sdomain.s==NULL ||
					p.len<=0 || d.len<=0 || sdomain.len<=0)
			{
				LM_ERR("Error - bad values in db\n");
				continue;
			}

			if(pdt_check_domain!=0 && _ptree_new!=NULL
					&& pdt_check_pd(_ptree_new, &sdomain, &p, &d)==1)
			{
				LM_ERR("sdomain [%.*s]: prefix [%.*s] or domain <%.*s> "
					"duplicated\n", sdomain.len, sdomain.s, p.len, p.s,
					d.len, d.s);
				continue;
			}

			if(pdt_add_to_tree(&_ptree_new, &sdomain, &p, &d)<0)
			{
				LM_ERR("Error adding info to tree\n");
				goto error;
			}
	 	}
		if (DB_CAPABILITY(pdt_dbf, DB_CAP_FETCH)) {
			if(pdt_dbf.fetch_result(db_con, &db_res, no_rows)<0) {
				LM_ERR("Error while fetching!\n");
				if (db_res)
					pdt_dbf.free_result(db_con, db_res);
				goto error;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(db_res)>0);
	pdt_dbf.free_result(db_con, db_res);


	/* block all readers */
	lock_start_write( pdt_lock );

	old_tree = *_ptree;
	*_ptree = _ptree_new;

	lock_stop_write( pdt_lock );

	/* free old data */
	if (old_tree!=NULL)
		pdt_free_tree(old_tree);

	return 0;

error:
	pdt_dbf.free_result(db_con, db_res);
	if (_ptree_new!=NULL)
		pdt_free_tree(_ptree_new);
	return -1;
}
コード例 #14
0
ファイル: mtree_mod.c プロジェクト: mehulsbhatt/voip-foip
static int mt_load_db(str *tname)
{
	db_key_t db_cols[3] = {&tprefix_column, &tvalue_column};
	str tprefix, tvalue;
	db1_res_t* db_res = NULL;
	int i, ret;
	m_tree_t new_tree; 
	m_tree_t *old_tree = NULL; 
	mt_node_t *bk_head = NULL; 

	if(db_con==NULL)
	{
		LM_ERR("no db connection\n");
		return -1;
	}
	LM_ERR("attempting to load [%.*s]\n", tname->len, tname->s);
	old_tree = mt_get_tree(tname);
	if(old_tree==NULL)
	{
		LM_ERR("tree definition not found [%.*s]\n", tname->len, tname->s);
		return -1;
	}
	memcpy(&new_tree, old_tree, sizeof(m_tree_t));
	new_tree.head = 0;
	new_tree.next = 0;

	if (mt_dbf.use_table(db_con, &old_tree->dbtable) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) {
		if(mt_dbf.query(db_con, 0, 0, 0, db_cols, 0, 2, 0, 0) < 0)
		{
			LM_ERR("Error while querying db\n");
			return -1;
		}
		if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0)
		{
			LM_ERR("Error while fetching result\n");
			if (db_res)
				mt_dbf.free_result(db_con, db_res);
			goto error;
		} else {
			if(RES_ROW_N(db_res)==0)
			{
				return 0;
			}
		}
	} else {
		if((ret=mt_dbf.query(db_con, NULL, NULL, NULL, db_cols,
				0, 2, 0, &db_res))!=0
			|| RES_ROW_N(db_res)<=0 )
		{
			mt_dbf.free_result(db_con, db_res);
			if( ret==0)
			{
				return 0;
			} else {
				goto error;
			}
		}
	}

	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			/* check for NULL values ?!?! */
			tprefix.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
			tprefix.len = strlen(tprefix.s);
			
			tvalue.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val);
			tvalue.len = strlen(tvalue.s);

			if(tprefix.s==NULL || tvalue.s==NULL
					|| tprefix.len<=0 || tvalue.len<=0)
			{
				LM_ERR("Error - bad values in db\n");
				continue;
			}
		
			if(mt_add_to_tree(&new_tree, &tprefix, &tvalue)<0)
			{
				LM_ERR("Error adding info to tree\n");
				goto error;
			}
	 	}
		if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) {
			if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) {
				LM_ERR("Error while fetching!\n");
				if (db_res)
					mt_dbf.free_result(db_con, db_res);
				goto error;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(db_res)>0);
	mt_dbf.free_result(db_con, db_res);


	/* block all readers */
	lock_get( mt_lock );
	mt_reload_flag = 1;
	lock_release( mt_lock );

	while (mt_tree_refcnt) {
		sleep_us(10);
	}

	bk_head = old_tree->head;
	old_tree->head = new_tree.head;

	mt_reload_flag = 0;

	/* free old data */
	if (bk_head!=NULL)
		mt_free_node(bk_head, new_tree.type);

	return 0;

error:
	mt_dbf.free_result(db_con, db_res);
	if (new_tree.head!=NULL)
		mt_free_node(new_tree.head, new_tree.type);
	return -1;
}
コード例 #15
0
ファイル: dp_db.c プロジェクト: adubovikov/kamailio
/*load rules from DB*/
int dp_load_db(void)
{
	int i, nr_rows;
	db1_res_t * res = 0;
	db_val_t * values;
	db_row_t * rows;
	db_key_t query_cols[DP_TABLE_COL_NO] = {
		&dpid_column,	&pr_column,
		&match_op_column,	&match_exp_column,	&match_len_column,
		&subst_exp_column,	&repl_exp_column,	&attrs_column };

	db_key_t order = &pr_column;

	dpl_node_t *rule;

	LM_DBG("init\n");
	if( (*crt_idx) != (*next_idx)){
		LM_WARN("a load command already generated, aborting reload...\n");
		return 0;
	}

	if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){
		LM_ERR("error in use_table %.*s\n", dp_table_name.len, dp_table_name.s);
		return -1;
	}

	if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
					DP_TABLE_COL_NO, order, 0) < 0){
			LM_ERR("failed to query database!\n");
			return -1;
		}
		if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) {
			LM_ERR("failed to fetch\n");
			if (res)
				dp_dbf.free_result(dp_db_handle, res);
			return -1;
		}
	} else {
		/*select the whole table and all the columns*/
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
					DP_TABLE_COL_NO, order, &res) < 0){
			LM_ERR("failed to query database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	*next_idx = ((*crt_idx) == 0)? 1:0;
	destroy_hash(*next_idx);

	if(nr_rows == 0){
		LM_WARN("no data in the db\n");
		goto end;
	}

	do {
		for(i=0; i<RES_ROW_N(res); i++){
			rows 	= RES_ROWS(res);

			values = ROW_VALUES(rows+i);

			if((rule = build_rule(values)) ==0 )
				goto err2;

			if(add_rule2hash(rule , *next_idx) != 0)
				goto err2;

		}
		if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
			if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) {
				LM_ERR("failure while fetching!\n");
				if (res)
					dp_dbf.free_result(dp_db_handle, res);
				return -1;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(res)>0);


end:
	/*update data*/
	*crt_idx = *next_idx;
	list_hash(*crt_idx);
	dp_dbf.free_result(dp_db_handle, res);
	return 0;

err2:
	if(rule)	destroy_rule(rule);
	destroy_hash(*next_idx);
	dp_dbf.free_result(dp_db_handle, res);
	*next_idx = *crt_idx; 
	return -1;
}
コード例 #16
0
ファイル: sca_db_handler.c プロジェクト: AndreiPlesa/opensips
static int load_sca_info_from_db(void)
{
	db_res_t * res = NULL;
	db_val_t * values;
	db_row_t * rows;
	int i, j, nr_rows;
	unsigned int valid_record;
	unsigned int n_result_cols = 0;
	unsigned int shared_line_col, watchers_col;
	unsigned int app_shared_entity_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_state_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_info_uri_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_info_appearance_uri_col[MAX_APPEARANCE_INDEX];
	unsigned int app_b2bl_key_col[MAX_APPEARANCE_INDEX];
	db_key_t q_cols[SCA_TABLE_TOTAL_COL_NO];

	str shared_line, watchers_csv;
	//str_lst_t *watchers;
	//unsigned int size, watcher_size, watchers_no;
	//unsigned int size;
	unsigned int hash_index;
	//char *p;
	b2b_sca_record_t *record;
	b2b_sca_call_t *call;
	unsigned int shared_entity, appearance_index, call_state;
	str call_info_uri, call_info_apperance_uri, b2bl_key;
	b2bl_cb_ctx_t *cb_params;

	if(use_sca_table()) return -1;

	q_cols[shared_line_col = n_result_cols++] = &shared_line_column;
	q_cols[watchers_col = n_result_cols++] = &watchers_column;

	for (i=0; i<MAX_APPEARANCE_INDEX; i++) {
		q_cols[app_shared_entity_col[i]	= n_result_cols++] = &app_shared_entity_column[i];
		q_cols[app_call_state_col[i] = n_result_cols++] = &app_call_state_column[i];
		q_cols[app_call_info_uri_col[i] = n_result_cols++] = &app_call_info_uri_column[i];
		q_cols[app_call_info_appearance_uri_col[i] = n_result_cols++] =
						&app_call_info_appearance_uri_column[i];
		q_cols[app_b2bl_key_col[i] = n_result_cols++] = &app_b2bl_key_column[i];
	}

	/* select the whole tabel and all the columns */
	if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) {
		if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0,
				SCA_TABLE_TOTAL_COL_NO, 0, 0) < 0) {
			LM_ERR("Error while querying (fetch) database\n");
			return -1;
		}
		if(sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0){
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0,
				SCA_TABLE_TOTAL_COL_NO, 0, &res) < 0) {
			LM_ERR("Error while querying database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	do {
		LM_DBG("loading [%i] records from db\n", nr_rows);
		rows = RES_ROWS(res);
		/* for every row/record */
		for(i=0; i<nr_rows; i++){
			values = ROW_VALUES(rows + i);
			if (VAL_NULL(values+shared_line_col) || VAL_NULL(values+watchers_col)) {
				LM_ERR("columns [%.*s] or/and [%.*s] cannot be null -> skipping\n",
					shared_line_column.len, shared_line_column.s,
					watchers_column.len, watchers_column.s);
				continue;
			}
			shared_line.s = (char*)values[shared_line_col].val.string_val;
			shared_line.len = strlen(shared_line.s);

			watchers_csv.s = (char*)values[watchers_col].val.string_val;
			watchers_csv.len = strlen(watchers_csv.s);

			record = restore_record(&shared_line, &watchers_csv);
			if (record == NULL)
				goto error;
			hash_index = core_hash(&shared_line, NULL, b2b_sca_hsize);

			j = 0;
			while (j < MAX_APPEARANCE_INDEX) {
				if(	VAL_NULL(values + app_shared_entity_col[j]) ||
					VAL_NULL(values + app_call_state_col[j]) ||
					VAL_NULL(values + app_call_info_uri_col[j]) ||
					VAL_NULL(values + app_call_info_appearance_uri_col[j]) ||
					VAL_NULL(values + app_b2bl_key_col[j]) ) {
					goto cont;
				}
				appearance_index = j + 1;
				/* 1 - get shared_entity */
				shared_entity = values[app_shared_entity_col[j]].val.int_val;
				if (shared_entity!=0 && shared_entity!=1) {
					LM_ERR("Unexpected shared_entity [%d] "
						"for shared_line [%.*s]\n",
						shared_entity, shared_line.len, shared_line.s);
					goto cont;
				}
				/* 2 - get call_state */
				call_state = values[app_call_state_col[j]].val.int_val;
				if (call_state == IDLE_STATE) {
					LM_DBG("empty call[%d]\n", appearance_index);
					goto cont;
				}
				if (call_state > MAX_INDEX_STATE) {
					LM_ERR("Unexpected call_state [%d] for shared_line [%.*s]\n",
						call_state, shared_line.len, shared_line.s);
					goto cont;
				}
				/* 3 - get call_info_uri */
				call_info_uri.s =
					(char*)values[app_call_info_uri_col[j]].val.string_val;
				if (call_info_uri.s)
					call_info_uri.len = strlen(call_info_uri.s);
				else {
					LM_ERR("Missing call_info_uri for shared_line [%.*s][%d]\n",
						shared_line.len, shared_line.s, appearance_index);
					goto cont;
				}
				LM_DBG("call_info_uri=[%.*s]\n",
					call_info_uri.len, call_info_uri.s);
				/* 4 - get call_info_apperance_uri */
				call_info_apperance_uri.s =
					(char*)
					values[app_call_info_appearance_uri_col[j]].val.string_val;
				if (call_info_apperance_uri.s)
					call_info_apperance_uri.len =
						strlen(call_info_apperance_uri.s);
				else {
					LM_ERR("Missing call_info_apperance_uri for "
						"shared_line [%.*s][%d]\n",
						shared_line.len, shared_line.s, appearance_index);
					goto cont;
				}
				LM_DBG("call_info_apperance_uri=[%.*s]\n",
					call_info_apperance_uri.len, call_info_apperance_uri.s);
				/* 5 - get b2bl_key */
				b2bl_key.s = (char*)values[app_b2bl_key_col[j]].val.string_val;
				if (b2bl_key.s) {
					b2bl_key.len = strlen(b2bl_key.s);
					if (b2bl_key.len > B2BL_MAX_KEY_LEN) {
						LM_ERR("buffer overflow on b2bl_key [%.*s]"
							" for shared_line [%.*s][%d]\n",
							b2bl_key.len, b2bl_key.s,
							shared_line.len, shared_line.s,
							appearance_index);
						goto cont;
					}
					LM_DBG("b2bl_key=[%.*s]\n", b2bl_key.len, b2bl_key.s);
				} else {
					LM_ERR("Missing b2bl_key for shared_line [%.*s][1]\n",
						shared_line.len, shared_line.s);
					goto cont;
				}
				/* restore the call */
				call = restore_call(record, appearance_index,
					shared_entity, call_state,
					&call_info_uri, &call_info_apperance_uri);
				if (call == NULL) {
					goto error;
				}
				/* update record */
				if (0!=b2b_sca_update_call_record_key(call, &b2bl_key)) {
					LM_ERR("Unable to update b2bl_key [%.*s]\n",
						b2bl_key.len, b2bl_key.s);
					shm_free(call);
					call = NULL;
					record->call[appearance_index-1] = NULL;
					goto cont;
				}
				/* Prepare b2b_logic callback params. */
				cb_params = build_cb_params(hash_index,
							&shared_line, appearance_index);
				if (cb_params == NULL) {
					LM_ERR("Unable to build cb_params\n");
					goto error;
				}
				/* re-register callbacks */
				if(b2bl_api.register_cb(&b2bl_key, &sca_logic_notify, cb_params,
					B2B_RE_INVITE_CB|B2B_CONFIRMED_CB|B2B_DESTROY_CB) != 0){
					LM_ERR("Unable register b2b cb\n");
					shm_free(call);
					call = NULL;
					record->call[appearance_index-1] = NULL;
					goto cont;
				}
cont:
				j++;
			}

			valid_record = j = 0;
			while (j < MAX_APPEARANCE_INDEX) {
				if (record->call[j]) {
					valid_record = 1;
					goto check_valid_record;
				}
				j++;
			}
check_valid_record:
			if (valid_record) {
				b2b_sca_print_record(record);
				insert_record(hash_index, record);
			} else {
				LM_DBG("removing the record from db!\n");
				delete_sca_info_from_db(record);
			}
			LM_DBG("Done\n");
		}

		/* any more data to be fetched ?*/
		if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) {
			if (sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0) {
				LM_ERR("fetching more rows failed\n");
				goto error;
			}
			nr_rows = RES_ROW_N(res);
		} else {
			nr_rows = 0;
		}
	}while (nr_rows>0);

	sca_dbf.free_result(sca_db_handle, res);
	return 0;
error:
	sca_dbf.free_result(sca_db_handle, res);
	return -1;
}
コード例 #17
0
ファイル: ht_db.c プロジェクト: kiryu/kamailio
/**
 * load content of a db table in hash table
 */
int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
{
	db_key_t db_cols[5] = {&ht_db_name_column, &ht_db_ktype_column,
		&ht_db_vtype_column, &ht_db_value_column, &ht_db_expires_column};
	db_key_t db_ord = &ht_db_name_column;
	db1_res_t* db_res = NULL;
	str kname;
	str pname;
	str hname;
	str kvalue;
	int ktype;
	int vtype;
	int last_ktype;
	int n;
	int_str val;
	int_str expires;
	int i;
	int ret;
	int cnt;
	int now;
	int ncols;

	if(ht_db_con==NULL)
	{
		LM_ERR("no db connection\n");
		return -1;
	}

	if (ht_dbf.use_table(ht_db_con, dbtable) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	LM_DBG("=============== loading hash table [%.*s] from database [%.*s]\n",
			ht->name.len, ht->name.s, dbtable->len, dbtable->s);
	cnt = 0;
	ncols = 4;
	if(ht->htexpire > 0 && ht_db_expires_flag!=0)
		ncols = 5;

	if (DB_CAPABILITY(ht_dbf, DB_CAP_FETCH)) {
		if(ht_dbf.query(ht_db_con,0,0,0,db_cols,0,ncols,db_ord,0) < 0)
		{
			LM_ERR("Error while querying db\n");
			return -1;
		}
		if(ht_dbf.fetch_result(ht_db_con, &db_res, ht_fetch_rows)<0)
		{
			LM_ERR("Error while fetching result\n");
			if (db_res)
				ht_dbf.free_result(ht_db_con, db_res);
			goto error;
		} else {
			if(RES_ROW_N(db_res)==0)
			{
				LM_DBG("Nothing to be loaded in hash table\n");
				return 0;
			}
		}
	} else {
		if((ret=ht_dbf.query(ht_db_con, NULL, NULL, NULL, db_cols,
				0, ncols, db_ord, &db_res))!=0
			|| RES_ROW_N(db_res)<=0 )
		{
			if( ret==0)
			{
				ht_dbf.free_result(ht_db_con, db_res);
				return 0;
			} else {
				goto error;
			}
		}
	}

	pname.len = 0;
	pname.s = "";
	n = 0;
	last_ktype = 0;
	now = (int)time(NULL);
	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			/* not NULL values enforced in table definition ?!?! */
			kname.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
			if(kname.s==NULL) {
				LM_ERR("null key in row %d\n", i);
				goto error;
			}
			kname.len = strlen(kname.s);

			expires.n = 0;
			if(ht->htexpire > 0 && ht_db_expires_flag!=0) {
				expires.n = RES_ROWS(db_res)[i].values[4].val.int_val;
				if (expires.n > 0 && expires.n < now) {
					LM_DBG("skipping expired entry [%.*s] (%d)\n", kname.len,
							kname.s, expires.n-now);
					continue;
				}
			}

			cnt++;
			ktype = RES_ROWS(db_res)[i].values[1].val.int_val;
			if(last_ktype==1)
			{
				if(pname.len>0
						&& (pname.len!=kname.len
							|| strncmp(pname.s, kname.s, pname.len)!=0))
				{
					/* new key name, last was an array => add its size */
					snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s%.*s",
						pname.len, pname.s, ht_array_size_suffix.len,
						ht_array_size_suffix.s);
					hname.s = ht_name_buf;
					hname.len = strlen(ht_name_buf);
					val.n = n;

					if(ht_set_cell(ht, &hname, 0, &val, mode))
					{
						LM_ERR("error adding array size to hash table.\n");
						goto error;
					}
					pname.len = 0;
					pname.s = "";
					n = 0;
				}
			}
			last_ktype = ktype;
			pname = kname;
			if(ktype==1)
			{
				snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s[%d]",
						kname.len, kname.s, n);
				hname.s = ht_name_buf;
				hname.len = strlen(ht_name_buf);
				n++;
			} else {
				hname = kname;
			}
			vtype = RES_ROWS(db_res)[i].values[2].val.int_val;
			kvalue.s = (char*)(RES_ROWS(db_res)[i].values[3].val.string_val);
			if(kvalue.s==NULL) {
				LM_ERR("null value in row %d\n", i);
				goto error;
			}
			kvalue.len = strlen(kvalue.s);

			/* add to hash */
			if(vtype==1)
				str2sint(&kvalue, &val.n);
			else
				val.s = kvalue;
				
			if(ht_set_cell(ht, &hname, (vtype)?0:AVP_VAL_STR, &val, mode))
			{
				LM_ERR("error adding to hash table\n");
				goto error;
			}

			/* set expiry */
			if (ht->htexpire > 0 && expires.n > 0) {
				expires.n -= now;
				if(ht_set_cell_expire(ht, &hname, 0, &expires)) {
					LM_ERR("error setting expires to hash entry [%*.s]\n", hname.len, hname.s);
					goto error;
				}
			}
	 	}
		if (DB_CAPABILITY(ht_dbf, DB_CAP_FETCH)) {
			if(ht_dbf.fetch_result(ht_db_con, &db_res, ht_fetch_rows)<0) {
				LM_ERR("Error while fetching!\n");
				goto error;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(db_res)>0);

	if(last_ktype==1)
	{
		snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s%.*s",
			pname.len, pname.s, ht_array_size_suffix.len,
			ht_array_size_suffix.s);
		hname.s = ht_name_buf;
		hname.len = strlen(ht_name_buf);
		val.n = n;
		if(ht_set_cell(ht, &hname, 0, &val, mode))
		{
			LM_ERR("error adding array size to hash table.\n");
			goto error;
		}
	}

	ht_dbf.free_result(ht_db_con, db_res);
	LM_DBG("loaded %d values in hash table\n", cnt);

	return 0;
error:
	ht_dbf.free_result(ht_db_con, db_res);
	return -1;

}