예제 #1
0
파일: domain.c 프로젝트: OPSF/uClinux
/*
 * Reload domain table to new hash table and when done, make new hash table
 * current one.
 */
int reload_domain_table ( void )
{
/*	db_key_t keys[] = {domain_col}; */
	db_val_t vals[1];
	db_key_t cols[1];
	db_res_t* res;
	db_row_t* row;
	db_val_t* val;

	struct domain_list **new_hash_table;
	int i;

	cols[0] = domain_col.s;

	if (domain_dbf.use_table(db_handle, domain_table.s) < 0) {
		LOG(L_ERR, "reload_domain_table(): Error while trying to use domain table\n");
		return -1;
	}

	VAL_TYPE(vals) = DB_STR;
	VAL_NULL(vals) = 0;
    
	if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 1, 0, &res) < 0) {
		LOG(L_ERR, "reload_domain_table(): Error while querying database\n");
		return -1;
	}

	/* Choose new hash table and free its old contents */
	if (*hash_table == hash_table_1) {
		hash_table_free(hash_table_2);
		new_hash_table = hash_table_2;
	} else {
		hash_table_free(hash_table_1);
		new_hash_table = hash_table_1;
	}

	row = RES_ROWS(res);

	DBG("Number of rows in domain table: %d\n", RES_ROW_N(res));
		
	for (i = 0; i < RES_ROW_N(res); i++) {
		val = ROW_VALUES(row + i);
		if ((ROW_N(row) == 1) && (VAL_TYPE(val) == DB_STRING)) {
			
			DBG("Value: %s inserted into domain hash table\n", VAL_STRING(val));

			if (hash_table_install(new_hash_table, (char *)(VAL_STRING(val))) == -1) {
				LOG(L_ERR, "domain_reload(): Hash table problem\n");
				domain_dbf.free_result(db_handle, res);
				return -1;
			}
		} else {
			LOG(L_ERR, "domain_reload(): Database problem\n");
			domain_dbf.free_result(db_handle, res);
			return -1;
		}
	}
	domain_dbf.free_result(db_handle, res);

	*hash_table = new_hash_table;
	
	return 1;
}
예제 #2
0
파일: res.c 프로젝트: AndreiPlesa/opensips
/*
 * Convert data fron db format to internal format
 */
static int convert_row(db_res_t* _res, db_row_t* _r, dmap_t* _d)
{
	unsigned i, n = RES_COL_N(_res);

	ROW_N(_r) = n;

	for (i = 0; i < n; i++) {
		static const str dummy_string = {"", 0};

		db_val_t* v = &ROW_VALUES(_r)[i];
		db_type_t t = RES_TYPES(_res)[i];

		if (_d->ind[i] == -1) {
			/* Initialize the string pointers to a dummy empty
			 * string so that we do not crash when the NULL flag
			 * is set but the module does not check it properly
			 */
			VAL_STRING(v) = dummy_string.s;
			VAL_STR(v) = dummy_string;
			VAL_BLOB(v) = dummy_string;
			VAL_TYPE(v) = t;
			VAL_NULL(v) = 1;
			continue;
		}

		if (_d->ind[i])
			LM_WARN("truncated value in DB\n");

		VAL_TYPE(v) = t;
		switch (t) {
		case DB_INT:
			VAL_INT(v) = *_d->pv[i].i;
			break;

		case DB_BIGINT:
			VAL_BIGINT(v) = *_d->pv[i].i;
			break;

		case DB_BITMAP:
			VAL_BITMAP(v) = *_d->pv[i].i;
			break;

		case DB_DOUBLE:
			VAL_DOUBLE(v) = *_d->pv[i].f;
			break;

		case DB_DATETIME:
			{
				struct tm tm;
				memset(&tm, 0, sizeof(tm));
				OCIDateGetTime(_d->pv[i].o, &tm.tm_hour,
					&tm.tm_min, &tm.tm_sec);
				OCIDateGetDate(_d->pv[i].o, &tm.tm_year,
					&tm.tm_mon, &tm.tm_mday);
				if (tm.tm_mon)
					--tm.tm_mon;
				if (tm.tm_year >= 1900)
					tm.tm_year -= 1900;
				VAL_TIME(v) = mktime(&tm);
			}
			break;

		case DB_STR:
		case DB_BLOB:
		case DB_STRING:
			{
				size_t len = _d->len[i];
				char *pstr = pkg_malloc(len+1);

				if (pstr == NULL)
					return -1;

				memcpy(pstr, _d->pv[i].c, len);
				pstr[len] = '\0';
				VAL_FREE(v) = 1;
				if (t == DB_STR) {
					VAL_STR(v).s = pstr;
					VAL_STR(v).len = len;
				} else if (t == DB_BLOB) {
					VAL_BLOB(v).s = pstr;
					VAL_BLOB(v).len = len;
				} else {
					VAL_STRING(v) = pstr;
				}
			}
			break;

		default:
			LM_ERR("unknown type mapping (%u)\n", t);
			return -2;
		}
	}

	return 0;
}
예제 #3
0
/*!
 * \brief Convert rows from mongodb to db API representation
 * \param _h database connection
 * \param _r database result set
 * \return 0 on success, negative on failure
 */
static int db_mongodb_convert_bson(const db1_con_t* _h, db1_res_t* _r,
		int _row, const bson_t *_rdoc)
{
	static str dummy_string = {"", 0};
	int col;
	db_mongodb_result_t *mgres;
	const char *colname;
	bson_type_t coltype;
	bson_iter_t riter;
	bson_iter_t citer;
	bson_iter_t *piter;
	db_val_t* dval;
	uint32_t i32tmp;
    bson_subtype_t subtype;
	bson_t *cdoc;

	mgres = (db_mongodb_result_t*)RES_PTR(_r);
	if(mgres->nrcols==0) {
		LM_ERR("no fields to convert\n");
		return -1;
	}
	if(mgres->colsdoc==NULL) {
		cdoc = (bson_t*)_rdoc;
	} else {
		cdoc = (bson_t*)mgres->colsdoc;
	}

	if (!bson_iter_init (&citer, cdoc)) {
		LM_ERR("failed to initialize columns iterator\n");
		return -3;
	}
	if(mgres->colsdoc) {
		if (!bson_iter_init (&riter, _rdoc)) {
			LM_ERR("failed to initialize result iterator\n");
			return -3;
		}
	}
	if (db_allocate_row(_r, &(RES_ROWS(_r)[_row])) != 0) {
		LM_ERR("could not allocate row: %d\n", _row);
		return -2;
	}
	col = 0;
	while (bson_iter_next (&citer)) {
		if(col >= RES_COL_N(_r)) {
			LM_ERR("invalid number of columns (%d/%d)\n", col, RES_COL_N(_r));
			return -4;
		}

		colname = bson_iter_key (&citer);
		LM_DBG("looking for field[%d] named: %s\n", col, colname);
		if(mgres->colsdoc) {
			if(!bson_iter_find(&riter, colname)) {
				LM_ERR("field [%s] not found in result iterator\n",
						colname);
				return -4;
			}
			piter = &riter;
		} else {
			piter = &citer;
		}
		coltype = bson_iter_type(piter);

		dval = &(ROW_VALUES(&(RES_ROWS(_r)[_row]))[col]);
		VAL_TYPE(dval) = RES_TYPES(_r)[col];

		switch(coltype) {
			case BSON_TYPE_BOOL:
				VAL_INT(dval) = (int)bson_iter_bool (piter);
				break;
			case BSON_TYPE_INT32:
				VAL_INT(dval) = bson_iter_int32 (piter);
				break;
			case BSON_TYPE_TIMESTAMP:
				bson_iter_timestamp (piter,
						(uint32_t*)&VAL_INT(dval), &i32tmp);
				break;

			case BSON_TYPE_INT64:
				VAL_BIGINT(dval) = bson_iter_int64 (piter);
				break;

			case BSON_TYPE_DOUBLE:
				VAL_DOUBLE(dval) = bson_iter_double (piter);
				break;

			case BSON_TYPE_DATE_TIME:
				VAL_TIME(dval) = (time_t)(bson_iter_date_time (piter)/1000);
				break;

			case BSON_TYPE_BINARY:
				bson_iter_binary (piter, &subtype,
                  (uint32_t*)&VAL_BLOB(dval).len, (const uint8_t**)&VAL_BLOB(dval).s);
				break;

			case BSON_TYPE_UTF8:
				VAL_STRING(dval) = (char*)bson_iter_utf8 (piter, &i32tmp);
				break;

			case BSON_TYPE_OID:
				break;

			case BSON_TYPE_NULL:
				memset(dval, 0, sizeof(db_val_t));
				/* Initialize the string pointers to a dummy empty
				 * string so that we do not crash when the NULL flag
				 * is set but the module does not check it properly
				 */
				VAL_STRING(dval) = dummy_string.s;
				VAL_STR(dval) = dummy_string;
				VAL_BLOB(dval) = dummy_string;
				VAL_TYPE(dval) = RES_TYPES(_r)[col];
				VAL_NULL(dval) = 1;
				break;

#if 0
			case BSON_TYPE_EOD:
			case BSON_TYPE_DOCUMENT:
			case BSON_TYPE_ARRAY:
			case BSON_TYPE_UNDEFINED:
			case BSON_TYPE_REGEX:
			case BSON_TYPE_DBPOINTER:
			case BSON_TYPE_CODE:
			case BSON_TYPE_SYMBOL:
			case BSON_TYPE_CODEWSCOPE:
			case BSON_TYPE_MAXKEY:
			case BSON_TYPE_MINKEY:
#endif

			default:
				LM_WARN("unhandled data type column (%.*s) type id (%d), "
						"use DB1_STRING as default\n", RES_NAMES(_r)[col]->len,
						RES_NAMES(_r)[col]->s, coltype);
				RES_TYPES(_r)[col] = DB1_STRING;
				break;
		}

		LM_DBG("RES_NAMES(%p)[%d]=[%.*s] (%d)\n", RES_NAMES(_r)[col], col,
				RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype);
		col++;
	}
	return 0;
}
예제 #4
0
파일: dp_db.c 프로젝트: NormB/opensips
/*compile the expressions, and if ok, build the rule */
dpl_node_t * build_rule(db_val_t * values)
{
	tmrec_t *parsed_timerec;
	pcre * match_comp, *subst_comp;
	struct subst_expr * repl_comp;
	dpl_node_t * new_rule;
	str match_exp, subst_exp, repl_exp, attrs, timerec;
	int matchop;
	int namecount;

	matchop = VAL_INT(values+2);

	if((matchop != REGEX_OP) && (matchop!=EQUAL_OP)){
		LM_ERR("invalid value for match operator\n");
		return NULL;
	}

	parsed_timerec = 0;
	match_comp = subst_comp = 0;
	repl_comp = 0;
	new_rule = 0;

	GET_STR_VALUE(match_exp, values, 3, 0);
	if(matchop == REGEX_OP){

		LM_DBG("Compiling %.*s expression with flag: %d\n",
				match_exp.len, match_exp.s, VAL_INT(values+4));

		match_comp = wrap_pcre_compile(match_exp.s, VAL_INT(values+4));

		if(!match_comp){
			LM_ERR("failed to compile match expression \"%.*s\"\n",
				match_exp.len, match_exp.s);
			goto err;
		}
	}

	LM_DBG("building subst rule\n");
	GET_STR_VALUE(subst_exp, values, 5, 1);
	if(!VAL_NULL(values+5) && subst_exp.s && subst_exp.len){
		/* subst regexp */
		subst_comp = wrap_pcre_compile(subst_exp.s, VAL_INT(values+4));
		if(subst_comp == NULL){
			LM_ERR("failed to compile subst expression \"%.*s\"\n",
					subst_exp.len, subst_exp.s);
			goto err;
		}
	}

	/* replace exp */
	GET_STR_VALUE(repl_exp, values, 6, 1);
	if(!VAL_NULL(values+6) && repl_exp.len && repl_exp.s){
		repl_comp = repl_exp_parse(repl_exp);
		if(!repl_comp){
			LM_ERR("failed to compile replacing expression \"%.*s\"\n",
				repl_exp.len, repl_exp.s);
			goto err;
		}
	}

	pcre_fullinfo(
		subst_comp, /* the compiled pattern */
		NULL, /* no extra data - we didn't study the pattern */
		PCRE_INFO_CAPTURECOUNT, /* number of named substrings */
		&namecount); /* where to put the answer */

	LM_DBG("references:%d , max:%d\n",namecount,
		repl_comp?repl_comp->max_pmatch:0);

	if ( (repl_comp!=NULL) && (namecount<repl_comp->max_pmatch) &&
	(repl_comp->max_pmatch!=0) ){
		LM_ERR("repl_exp uses a non existing subexpression\n");
			goto err;
	}

	new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t));
	if(!new_rule){
		LM_ERR("out of shm memory(new_rule)\n");
		goto err;
	}
	memset(new_rule, 0, sizeof(dpl_node_t));

	if(str_to_shm(match_exp, &new_rule->match_exp)!=0)
		goto err;

	if (subst_comp)
		if(str_to_shm(subst_exp, &new_rule->subst_exp)!=0)
			goto err;
	if (repl_comp)
		if(str_to_shm(repl_exp, &new_rule->repl_exp)!=0)
			goto err;

	/*set the rest of the rule fields*/
	new_rule->dpid          =	VAL_INT(values);
	new_rule->pr            =	VAL_INT(values+1);
	new_rule->match_flags   =	VAL_INT(values+4);
	new_rule->matchop       =	matchop;

	/* attributes */
	GET_STR_VALUE(attrs, values, 7, 1);
	if( !VAL_NULL(values+7) && attrs.len && attrs.s) {
		if(str_to_shm(attrs, &new_rule->attrs)!=0)
			goto err;
		LM_DBG("attrs are %.*s\n",
			new_rule->attrs.len, new_rule->attrs.s);
	}

	/* Retrieve and Parse Timerec Matching Pattern */
	GET_STR_VALUE(timerec, values, 8, 1);
	if( !VAL_NULL(values+8) && timerec.len && timerec.s) {
		parsed_timerec = parse_time_def(timerec.s);
		if(!parsed_timerec) {
			LM_ERR("failed to parse timerec pattern %.*s\n",
				timerec.len, timerec.s);
			goto err;
		}

		if(str_to_shm(timerec, &new_rule->timerec) != 0)
			goto err;

		new_rule->parsed_timerec = parsed_timerec;

		LM_DBG("timerecs are %.*s\n",
			new_rule->timerec.len, new_rule->timerec.s);
	}

	if (match_comp)
		new_rule->match_comp = match_comp;

	if (subst_comp)
		new_rule->subst_comp = subst_comp;

	if (repl_comp)
		new_rule->repl_comp  = repl_comp;

	return new_rule;

err:
	if(parsed_timerec)	shm_free(parsed_timerec);
	if(match_comp)		wrap_pcre_free(match_comp);
	if(subst_comp)		wrap_pcre_free(subst_comp);
	if(repl_comp)		repl_expr_free(repl_comp);
	if(new_rule)		destroy_rule(new_rule);
	return NULL;
}
예제 #5
0
int load_handles(db_func_t * dbf, db1_con_t * dbh) {
	static char query[UL_DB_QUERY_LEN];
	db1_res_t * res;
	db_row_t * row;
	ul_db_handle_list_t * element;
	int i, id, query_len;
	str tmp;

	if(!dbf || !dbh){
		LM_ERR("NULL parameter passed \n");
		return -1;
	}

	query_len = 25 + id_col.len + reg_table.len;

	if(query_len > UL_DB_QUERY_LEN) {
		LM_ERR("weird: query larger than %i bytes.\n", UL_DB_QUERY_LEN);
		return -1;
	}

	memset(query, 0, UL_DB_QUERY_LEN);

	if (sprintf(query,
	        "SELECT DISTINCT "
	        "%.*s "
	        "FROM "
	        "%.*s",
	        id_col.len, id_col.s,
	        reg_table.len, reg_table.s) < 0) {
		LM_ERR("could not print query\n");
		return -1;
	}
	tmp.s = query;
	tmp.len = strlen(query);

	if (dbf->raw_query (dbh, &tmp, &res) < 0) {
		LM_ERR("in database query.\n");
		return -1;
	}

	if (RES_ROW_N (res) == 0) {
		dbf->free_result (dbh, res);
		LM_DBG ("no data found\n");
		return 1;
	}

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

		if((element = allocate_handle_list()) == NULL) {
			LM_ERR("couldnt allocate handle.\n");
			goto errout;
		}

		if (VAL_NULL (ROW_VALUES(row) + 0)) {
			LM_ERR("Weird: Empty ID-Field\n");
			goto errout;
		}

		id = VAL_INT (ROW_VALUES(row) + 0);
		if(load_data(dbf, dbh, element->handle, id) < 0){
			LM_ERR("couldn't load handle data.\n");
			goto errout;
		}
		element->next = db_handles;
		db_handles = element;
	}
	dbf->free_result (dbh, res);
	return 0;
errout:
	dbf->free_result (dbh, res);
	return -1;
}
예제 #6
0
int uac_reg_db_refresh(str *pl_uuid)
{
	db1_con_t *reg_db_con = NULL;
	db_func_t reg_dbf;
	reg_uac_t reg;
	db_key_t db_cols[10] = {
		&l_uuid_column,
		&l_username_column,
		&l_domain_column,
		&r_username_column,
		&r_domain_column,
		&realm_column,
		&auth_username_column,
		&auth_password_column,
		&auth_proxy_column,
		&expires_column
	};
	db_key_t db_keys[1] = {&l_uuid_column};
	db_val_t db_vals[1];

	db1_res_t* db_res = NULL;
	int i, ret;

	/* binding to db module */
	if(reg_db_url.s==NULL)
	{
		LM_ERR("no db url\n");
		return -1;
	}

	if(db_bind_mod(&reg_db_url, &reg_dbf))
	{
		LM_ERR("database module not found\n");
		return -1;
	}

	if (!DB_CAPABILITY(reg_dbf, DB_CAP_ALL))
	{
		LM_ERR("database module does not "
		    "implement all functions needed by the module\n");
		return -1;
	}

	/* open a connection with the database */
	reg_db_con = reg_dbf.init(&reg_db_url);
	if(reg_db_con==NULL)
	{
		LM_ERR("failed to connect to the database\n");
		return -1;
	}
	if (reg_dbf.use_table(reg_db_con, &reg_db_table) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	db_vals[0].type = DB1_STR;
	db_vals[0].nul = 0;
	db_vals[0].val.str_val.s = pl_uuid->s;
	db_vals[0].val.str_val.len = pl_uuid->len;

	if((ret=reg_dbf.query(reg_db_con, db_keys, NULL, db_vals, db_cols,
			1 /*nr keys*/, 10 /*nr cols*/, 0, &db_res))!=0
		|| RES_ROW_N(db_res)<=0 )
	{
		reg_dbf.free_result(reg_db_con, db_res);
		if( ret==0)
		{
			return 0;
		} else {
			goto error;
		}
	}

	memset(&reg, 0, sizeof(reg_uac_t));;
	i = 0;
	/* check for NULL values ?!?! */
	reg_db_set_attr(l_uuid, 0);
	reg_db_set_attr(l_username, 1);
	reg_db_set_attr(l_domain, 2);
	reg_db_set_attr(r_username, 3);
	reg_db_set_attr(r_domain, 4);
	/* realm may be empty */
	if(!VAL_NULL(&RES_ROWS(db_res)[i].values[5])) {
		reg.realm.s = (char*)(RES_ROWS(db_res)[i].values[5].val.string_val);
		reg.realm.len = strlen(reg.realm.s);
	}
	reg_db_set_attr(auth_username, 6);
	reg_db_set_attr(auth_password, 7);
	reg_db_set_attr(auth_proxy, 8);
	reg.expires = (unsigned int)RES_ROWS(db_res)[i].values[9].val.int_val;
	reg.h_uuid = reg_compute_hash(&reg.l_uuid);
	reg.h_user = reg_compute_hash(&reg.l_username);

	lock_get(_reg_htable_gc_lock);
	if(reg_ht_get_byuuid(pl_uuid)!=NULL)
	{
		if(reg_ht_update_password(&reg)<0)
		{
			lock_release(_reg_htable_gc_lock);
			LM_ERR("Error updating reg to htable\n");
			goto error;
		}
	} else {
		if(reg_ht_add(&reg)<0)
		{
			lock_release(_reg_htable_gc_lock);
			LM_ERR("Error adding reg to htable\n");
			goto error;
		}
	}
	lock_release(_reg_htable_gc_lock);

	reg_dbf.free_result(reg_db_con, db_res);
	reg_dbf.close(reg_db_con);

	return 0;

error:
	if (reg_db_con) {
		reg_dbf.free_result(reg_db_con, db_res);
		reg_dbf.close(reg_db_con);
	}
	return -1;
}
예제 #7
0
/*
 * Insert a row into specified table
 * h: structure representing database connection
 * k: key names
 * v: values of the keys
 * n: number of key=value pairs
 */
int flat_db_insert(db_con_t* h, db_key_t* k, db_val_t* v, int n)
{
	FILE* f;
	int i;
	char delims[4], *s;
	size_t len;

	f = CON_FILE(h);
	if (!f) {
		LOG(L_CRIT, "BUG: flat_db_insert: Uninitialized connection\n");
		return -1;
	}

	if (local_timestamp < *flat_rotate) {
		flat_rotate_logs();
		local_timestamp = *flat_rotate;
	}

	for(i = 0; i < n; i++) {

		if (!VAL_NULL(v + i)) {   // TODO: how to distinguish NULL from empty
			switch(VAL_TYPE(v + i)) {
				case DB_INT:
					fprintf(f, "%d", VAL_INT(v + i));
					break;

				case DB_FLOAT:
					fprintf(f, "%f", VAL_FLOAT(v + i));
					break;

				case DB_DOUBLE:
					fprintf(f, "%f", VAL_DOUBLE(v + i));
					break;

				case DB_STRING: {
					s = (char*) VAL_STRING(v + i);
					delims[0] = flat_delimiter[0];
					delims[1] = flat_record_delimiter[0];
					delims[2] = flat_escape[0];
					delims[3] = '\0';
					while (*s) {
						len = strcspn(s, delims);
						fprintf(f, "%.*s", (int)len, s);
						s+= len;
						if (*s) {
							fprintf(f, "%c%c", flat_escape[0], *s);
							s++;
						}
					}
					break;
				}
				case DB_STR:
				case DB_BLOB:
					if (VAL_TYPE(v + i) == DB_STR) {
						s = VAL_STR(v + i).s;
						len = VAL_STR(v + i).len;
					}
					else {
						s = VAL_BLOB(v + i).s;
						len = VAL_BLOB(v + i).len;
					}
					while (len > 0) {
						char *c;
						for (c = s; len > 0 && *c != flat_delimiter[0] && *c != flat_record_delimiter[0] && *c != flat_escape[0]; c++, len--);
						fprintf(f, "%.*s", (int)(c-s), s);
						s = c;
						if (len > 0) {
							fprintf(f, "%c%c", flat_escape[0], *s);
							s++;
							len--;
						}
					}
					break;

				case DB_DATETIME:
					fprintf(f, "%u", (unsigned int)VAL_TIME(v + i));
					break;

				case DB_BITMAP:
					fprintf(f, "%u", VAL_BITMAP(v + i));
					break;
			}
		}
		if (i < (n - 1)) {
			fprintf(f, "%c", flat_delimiter[0]);
		}
	}

	fprintf(f, "%c", flat_record_delimiter[0]);

	if (flat_flush) {
		fflush(f);
	}

	return 0;
}
예제 #8
0
파일: km_dbase.c 프로젝트: kiryu/kamailio
/*!
 * \brief SQL REPLACE implementation
 * \param _h structure representing database connection
 * \param _k key names
 * \param _v values of the keys
 * \param _n number of key=value pairs
 * \param _un number of keys to build the unique key, starting from first
 * \param _m mode - first update, then insert, or first insert, then update
 * \return 0 on success, negative on failure
 */
int db_postgres_replace(const db1_con_t* _h, const db_key_t* _k,
		const db_val_t* _v, const int _n, const int _un, const int _m)
{
	unsigned int pos = 0;
	int i;

	if(_un > _n)
	{
		LM_ERR("number of columns for unique key is too high\n");
		return -1;
	}

	if(_un > 0)
	{
		for(i=0; i<_un; i++)
		{
			if(!VAL_NULL(&_v[i]))
			{
				switch(VAL_TYPE(&_v[i]))
				{
					case DB1_INT:
						pos += VAL_UINT(&_v[i]);
						break;
					case DB1_STR:
						pos += get_hash1_raw((VAL_STR(&_v[i])).s,
									(VAL_STR(&_v[i])).len);
						break;
					case DB1_STRING:
						pos += get_hash1_raw(VAL_STRING(&_v[i]),
									strlen(VAL_STRING(&_v[i])));
						break;
					default:
						break;
				}
			}
		}
		pos &= (_pg_lock_size-1);
		lock_set_get(_pg_lock_set, pos);
		if(db_postgres_update(_h, _k, 0, _v, _k + _un,
						_v + _un, _un, _n -_un)< 0)
		{
			LM_ERR("update failed\n");
			lock_set_release(_pg_lock_set, pos);
			return -1;
		}

		if (db_postgres_affected_rows(_h) <= 0)
		{
			if(db_postgres_insert(_h, _k, _v, _n)< 0)
			{
				LM_ERR("insert failed\n");
				lock_set_release(_pg_lock_set, pos);
				return -1;
			}
			LM_DBG("inserted new record in database table\n");
		} else {
			LM_DBG("updated record in database table\n");
		}
		lock_set_release(_pg_lock_set, pos);
	} else {
		if(db_postgres_insert(_h, _k, _v, _n)< 0)
		{
			LM_ERR("direct insert failed\n");
			return -1;
		}
		LM_DBG("directly inserted new record in database table\n");
	}
	return 0;
}
예제 #9
0
void dialog_update_db(unsigned int ticks, void * param)
{
	static db_ps_t my_ps_update = NULL;
	static db_ps_t my_ps_insert = NULL;
	static db_ps_t my_ps_update_vp = NULL;
	int index;
	db_val_t values[DIALOG_TABLE_TOTAL_COL_NO];
	struct dlg_entry entry;
	struct dlg_cell  * cell; 
	unsigned char on_shutdown;
	int callee_leg,ins_done=0;
	static query_list_t *ins_list = NULL;

	db_key_t insert_keys[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,
			&from_sock_column,	&to_sock_column,		&start_time_column,
			&from_route_column,	&to_route_column, 	&from_contact_column,
			&to_contact_column, &mangled_fu_column, &mangled_tu_column,
			/*update chunk */
			&state_column,		&timeout_column,		&from_cseq_column,
			&to_cseq_column,	&from_ping_cseq_column, &to_ping_cseq_column,
			&vars_column,		&profiles_column,		&sflags_column, &flags_column};

	if (dialog_db_handle==0 || use_dialog_table()!=0)
		return;

	on_shutdown = (ticks==0);

	/*save the current dialogs information*/
	VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = 
	VAL_TYPE(values+16) = VAL_TYPE(values+17) = VAL_TYPE(values+20) =
	VAL_TYPE(values+21) = VAL_TYPE(values+24) = VAL_TYPE(values+25)= DB_INT;

	VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = 
	VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
	VAL_TYPE(values+8) = VAL_TYPE(values+10) = VAL_TYPE(values+11) = 
	VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+14) =
	VAL_TYPE(values+15) = VAL_TYPE(values+18) = VAL_TYPE(values+19) = 
	VAL_TYPE(values+22) = VAL_TYPE(values+23) = DB_STR;

	for(index = 0; index< d_table->size; index++){

		/* lock the whole entry */
		entry = (d_table->entries)[index];
		dlg_lock( d_table, &entry);

		for(cell = entry.first; cell != NULL; cell = cell->next){

			callee_leg = callee_idx(cell);

			if( (cell->flags & DLG_FLAG_NEW) != 0 ) {

				if ( cell->state == DLG_STATE_DELETED ) {
					/* don't need to insert dialogs already terminated */
					continue;
				}
				LM_DBG("inserting new dialog %p\n",cell);

				SET_INT_VALUE(values, cell->h_entry);
				SET_INT_VALUE(values+1, cell->h_id);
				SET_STR_VALUE(values+2, cell->callid);
				SET_STR_VALUE(values+3, cell->from_uri);

				SET_STR_VALUE(values+4, cell->legs[DLG_CALLER_LEG].tag);
				SET_STR_VALUE(values+5, cell->to_uri);
				SET_STR_VALUE(values+6, cell->legs[callee_leg].tag);

				SET_STR_VALUE(values+7,
					cell->legs[DLG_CALLER_LEG].bind_addr->sock_str);
				if (cell->legs[callee_leg].bind_addr) {
					SET_STR_VALUE(values+8, 
						cell->legs[callee_leg].bind_addr->sock_str);
				} else {
					VAL_NULL(values+8) = 1;
				}

				SET_INT_VALUE(values+9,  cell->start_ts);

				SET_STR_VALUE(values+10, cell->legs[DLG_CALLER_LEG].route_set);
				SET_STR_VALUE(values+11,
					cell->legs[callee_leg].route_set);
				SET_STR_VALUE(values+12, cell->legs[DLG_CALLER_LEG].contact);
				SET_STR_VALUE(values+13,
					cell->legs[callee_leg].contact);


				SET_STR_VALUE(values+14,cell->legs[callee_leg].from_uri);
				SET_STR_VALUE(values+15,cell->legs[callee_leg].to_uri);

				SET_INT_VALUE(values+16, cell->state);
				SET_INT_VALUE(values+17, (unsigned int)((unsigned int)time(0)
					+ cell->tl.timeout - get_ticks()) );

				SET_STR_VALUE(values+18, cell->legs[DLG_CALLER_LEG].r_cseq);
				SET_STR_VALUE(values+19, cell->legs[callee_leg].r_cseq);

				SET_INT_VALUE(values+20, cell->legs[DLG_CALLER_LEG].last_gen_cseq);
				SET_INT_VALUE(values+21, cell->legs[callee_leg].last_gen_cseq);

				set_final_update_cols(values+22, cell, on_shutdown);
				SET_INT_VALUE(values+25, cell->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED));

				CON_PS_REFERENCE(dialog_db_handle) = &my_ps_insert;
				if (con_set_inslist(&dialog_dbf,dialog_db_handle,
				&ins_list,insert_keys,DIALOG_TABLE_TOTAL_COL_NO) < 0 )
					CON_RESET_INSLIST(dialog_db_handle);

				if((dialog_dbf.insert(dialog_db_handle, insert_keys, 
				values, DIALOG_TABLE_TOTAL_COL_NO)) !=0){
					LM_ERR("could not add another dialog to db\n");
					goto error;
				}

				if (ins_done==0)
					ins_done=1;

				/* dialog saved */
				run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

				cell->flags &= ~(DLG_FLAG_NEW |DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);

			} else if ( (cell->flags & DLG_FLAG_CHANGED)!=0 || on_shutdown ){
				LM_DBG("updating existing dialog %p\n",cell);

				SET_INT_VALUE(values, cell->h_entry);
				SET_INT_VALUE(values+1, cell->h_id);

				SET_INT_VALUE(values+16, cell->state);
				SET_INT_VALUE(values+17, (unsigned int)((unsigned int)time(0)
					 + cell->tl.timeout - get_ticks()) );
				SET_STR_VALUE(values+18, cell->legs[DLG_CALLER_LEG].r_cseq);
				SET_STR_VALUE(values+19, cell->legs[callee_leg].r_cseq);
				SET_INT_VALUE(values+20, cell->legs[DLG_CALLER_LEG].last_gen_cseq);
				SET_INT_VALUE(values+21, cell->legs[callee_leg].last_gen_cseq);

				set_final_update_cols(values+22, cell, 1);
				SET_INT_VALUE(values+25, cell->flags);

				CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update;

				if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
				(values), (insert_keys+16), (values+16), 2, 10)) !=0) {
					LM_ERR("could not update database info\n");
					goto error;
				}

				/* dialog saved */
				run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

				cell->flags &= ~(DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);
			} else if (cell->flags & DLG_FLAG_VP_CHANGED) {

				SET_INT_VALUE(values, cell->h_entry);
				SET_INT_VALUE(values+1, cell->h_id);

				set_final_update_cols(values+22, cell, 0);

				CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update_vp;

				if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
				(values), (insert_keys+22), (values+22), 2, 3)) !=0) {
					LM_ERR("could not update database info\n");
					goto error;
				}

				run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

				cell->flags &= ~DLG_FLAG_VP_CHANGED;
			}
		}
		dlg_unlock( d_table, &entry);

	}

	if (ins_done) {
		LM_DBG("dlg timer attempting to flush rows to DB\n");
		/* flush everything to DB
		 * so that next-time timer fires
		 * we are sure that DB updates will be succesful */
		if (ql_flush_rows(&dialog_dbf,dialog_db_handle,ins_list) < 0)
			LM_ERR("failed to flush rows to DB\n");
	}

	return;

error:
	dlg_unlock( d_table, &entry);
}
예제 #10
0
/**
 * Does not copy strings
 */
int bdb_str2val(db_type_t _t, db_val_t* _v, char* _s, int _l)
{

	static str dummy_string = {"", 0};

	if(!_s)
	{
		memset(_v, 0, sizeof(db_val_t));
		/* Initialize the string pointers to a dummy empty
		 * string so that we do not crash when the NULL flag
		 * is set but the module does not check it properly
		 */
		VAL_STRING(_v) = dummy_string.s;
		VAL_STR(_v) = dummy_string;
		VAL_BLOB(_v) = dummy_string;
		VAL_TYPE(_v) = _t;
		VAL_NULL(_v) = 1;
		return 0;
	}
	VAL_NULL(_v) = 0;

	switch(_t) {
	case DB_INT:
		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
			LM_ERR("Error while converting INT value from string\n");
			return -2;
		} else {
			VAL_TYPE(_v) = DB_INT;
			return 0;
		}
		break;

	case DB_BIGINT:
		if (db_str2bigint(_s, &VAL_BIGINT(_v)) < 0) {
			LM_ERR("Error while converting BIGINT value from string\n");
			return -2;
		} else {
			VAL_TYPE(_v) = DB_BIGINT;
			return 0;
		}
		break;


	case DB_BITMAP:
		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
			LM_ERR("Error while converting BITMAP value from string\n");
			return -3;
		} else {
			VAL_TYPE(_v) = DB_BITMAP;
			return 0;
		}
		break;

	case DB_DOUBLE:
		if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) {
			LM_ERR("Error while converting DOUBLE value from string\n");
			return -4;
		} else {
			VAL_TYPE(_v) = DB_DOUBLE;
			return 0;
		}
		break;

	case DB_STRING:
		if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) )
			VAL_NULL(_v) = 1;
		else
		{
			VAL_STRING(_v) = _s;
			VAL_TYPE(_v) = DB_STRING;
			VAL_FREE(_v) = 1;
		}


		return 0;

	case DB_STR:

		if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) )
			VAL_NULL(_v) = 1;
		else
		{

			VAL_STR(_v).s = (char*)_s;
			VAL_STR(_v).len = _l;
			VAL_TYPE(_v) = DB_STR;
			VAL_FREE(_v) = 1;
		}


		return 0;

	case DB_DATETIME:
		if( *_s == '\'')
			_s++;
		if (db_str2time(_s, &VAL_TIME(_v)) < 0) {
			LM_ERR("Error converting datetime\n");
			return -5;
		} else {
			VAL_TYPE(_v) = DB_DATETIME;
			return 0;
		}
		break;

	case DB_BLOB:
		VAL_BLOB(_v).s = _s;
		VAL_BLOB(_v).len = _l;
		VAL_TYPE(_v) = DB_BLOB;
		VAL_FREE(_v) = 1;
		LM_DBG("got blob len %d\n", _l);
		return 0;
	}

	return -6;
}
예제 #11
0
파일: domain.c 프로젝트: 4N7HR4X/kamailio
/*
 * Reload domain table to new hash table and when done, make new hash table
 * current one.
 */
int reload_tables ( void )
{
    db_key_t cols[4];
    db1_res_t* res = NULL;
    db_row_t* row;
    struct domain_list **new_hash_table;
    int i;
    short type;
    str did, domain, name, value;
    int_str val;

    /* Choose new hash table and free its old contents */
    if (*hash_table == hash_table_1) {
	hash_table_free(hash_table_2);
	new_hash_table = hash_table_2;
    } else {
	hash_table_free(hash_table_1);
	new_hash_table = hash_table_1;
    }

    cols[0] = &did_col;
    cols[1] = &name_col;
    cols[2] = &type_col;
    cols[3] = &value_col;

    if (domain_db_init(&d_db_url) < 0) {
	LM_ERR("unable to open database connection\n");
	return -1;
    }

    if (domain_dbf.use_table(db_handle, &domain_attrs_table) < 0) {
	LM_ERR("error while trying to use domain_attrs table\n");
	goto err;
    }

    if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 4, 0, &res) < 0) {
	LM_ERR("error while querying database\n");
	goto err;
    }

    row = RES_ROWS(res);

    LM_DBG("number of rows in domain_attrs table: %d\n", RES_ROW_N(res));
    
    for (i = 0; i < RES_ROW_N(res); i++) {

	row = RES_ROWS(res) + i;

	if ((VAL_NULL(ROW_VALUES(row)) == 1) ||
	    (VAL_TYPE(ROW_VALUES(row)) != DB1_STRING)) {
	    LM_ERR("did at row <%u> is null or not string\n", i);
	    goto err;
	}
	did.s = (char *)VAL_STRING(ROW_VALUES(row));
	did.len = strlen(did.s);
	if (did.len == 0) {
	    LM_ERR("did at row <%u> is empty string\n", i);
	    goto err;
	}

	if ((VAL_NULL(ROW_VALUES(row) + 1) == 1) ||
	    (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_STRING)) {
	    LM_ERR("name at row <%u> is null or not string\n", i);
	    goto err;
	}
	name.s = (char *)VAL_STRING(ROW_VALUES(row) + 1);
	name.len = strlen(name.s);
	if (name.len == 0) {
	    LM_ERR("name at row <%u> is empty string\n", i);
	    goto err;
	}

	if ((VAL_NULL(ROW_VALUES(row) + 2) == 1) ||
	    ((VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT) &&
	     (VAL_TYPE(ROW_VALUES(row) + 2) != DB1_BIGINT))) {
	    LM_ERR("type at row <%u> is null or not int\n", i);
	    goto err;
	}
	if(VAL_TYPE(ROW_VALUES(row) + 2) == DB1_BIGINT) {
		type = (int)VAL_BIGINT(ROW_VALUES(row) + 2);
	} else {
		type = (int)VAL_INT(ROW_VALUES(row) + 2);
	}
	if ((type != 0) && (type != 2)) {
	    LM_ERR("unknown type <%d> at row <%u>\n", type, i);
	    goto err;
	}

	if ((VAL_NULL(ROW_VALUES(row) + 3) == 1) ||
	    (VAL_TYPE(ROW_VALUES(row) + 3) != DB1_STRING)) {
	    LM_ERR("value at row <%u> is null or not string\n", i);
	    goto err;
	}
	value.s = (char *)VAL_STRING(ROW_VALUES(row) + 3);
	value.len = strlen(value.s);

	if (type == 0) {
	    if (str2sint(&value, &(val.n)) == -1) {
		LM_ERR("value at row <%u> is invalid int\n", i);
		goto err;
	    }
	} else {
	    val.s = value;
	}

	if (type == 0) 
	    LM_DBG("inserting <did/name/type/value> = <%s/%s/%d/%d> into attribute list\n", did.s, name.s, type, val.n);
	else
	    LM_DBG("inserting <did/name/type/value> = <%s/%s/%d/%s> into attribute list\n", did.s, name.s, type, val.s.s);
		
	if (hash_table_attr_install(new_hash_table, &did, &name, type,
				    &val) == -1) {
	    LM_ERR("could not install attribute into hash table\n");
	    goto err;
	}
    }

    domain_dbf.free_result(db_handle, res);
    res = NULL;

    cols[0] = &domain_col;
    cols[1] = &did_col;
    
    if (domain_dbf.use_table(db_handle, &domain_table) < 0) {
	LM_ERR("error while trying to use domain table\n");
	goto err;
    }

    if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 2, 0, &res) < 0) {
	LM_ERR("error while querying database\n");
	goto err;
    }

    row = RES_ROWS(res);

    LM_DBG("number of rows in domain table: %d\n", RES_ROW_N(res));
		
    for (i = 0; i < RES_ROW_N(res); i++) {
	
	row = RES_ROWS(res) + i;

	if ((VAL_NULL(ROW_VALUES(row)) == 1) ||
	    (VAL_TYPE(ROW_VALUES(row)) != DB1_STRING)) {
	    LM_ERR("domain at row <%u> is null or not string\n", i);
	    goto err;
	}
	domain.s = (char *)VAL_STRING(ROW_VALUES(row));
	domain.len = strlen(domain.s);
	if (domain.len == 0) {
	    LM_ERR("domain at row <%u> is empty string\n", i);
	    goto err;
	}

	if ((VAL_NULL(ROW_VALUES(row) + 1) != 1) &&
	    (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_STRING)) {
	    LM_ERR("did at row <%u> is not null or string\n", i);
	    goto err;
	}
	if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
	    did.s = domain.s;
	    did.len = domain.len;
	} else {
	    did.s = (char *)VAL_STRING(ROW_VALUES(row) + 1);
	    did.len = strlen(did.s);
	    if (did.len == 0) {
		LM_ERR("did at row <%u> is empty string\n", i);
		goto err;
	    }
	}

	LM_DBG("inserting <did/domain> = <%s/%s> into hash table\n",
	       did.s, domain.s);

	if (hash_table_install(new_hash_table, &did, &domain) == -1) {
	    LM_ERR("could not install domain into hash table\n");
	    domain_dbf.free_result(db_handle, res);
	    goto err;
	}
    }

    domain_dbf.free_result(db_handle, res);
    res = NULL;
    
    *hash_table = new_hash_table;

    domain_db_close();
    return 1;

 err:
    domain_dbf.free_result(db_handle, res);
    res = NULL;
    domain_db_close();
    return -1;
}
예제 #12
0
/*
 * Used when converting result from a query
 */
int bdb_val2str(db_val_t* _v, char* _s, int* _len)
{
	int l;

	if (VAL_NULL(_v))
	{
		*_len = snprintf(_s, *_len, "NULL");
		return 0;
	}

	switch(VAL_TYPE(_v)) {
	case DB_INT:
		if (db_int2str(VAL_INT(_v), _s, _len) < 0) {
			LM_ERR("Error while converting int to string\n");
			return -2;
		} else {
			LM_DBG("Converted int to string\n");
			return 0;
		}
		break;

	case DB_BIGINT:
		if (db_bigint2str(VAL_BIGINT(_v), _s, _len) < 0) {
			LM_ERR("Error while converting bigint to string\n");
			return -2;
		} else {
			LM_DBG("Converted bigint to string\n");
			return 0;
		}
		break;

	case DB_BITMAP:
		if (db_int2str(VAL_INT(_v), _s, _len) < 0) {
			LM_ERR("Error while converting bitmap to string\n");
			return -3;
		} else {
			LM_DBG("Converted bitmap to string\n");
			return 0;
		}
		break;

	case DB_DOUBLE:
		if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
			LM_ERR("Error while converting double to string\n");
			return -3;
		} else {
			LM_DBG("Converted double to string\n");
			return 0;
		}
		break;

	case DB_STRING:
		l = strlen(VAL_STRING(_v));
		if (*_len < l )
		{	LM_ERR("Destination buffer too short for string\n");
			return -4;
		}
		else
		{	LM_DBG("Converted string to string\n");
			strncpy(_s, VAL_STRING(_v) , l);
			_s[l] = 0;
			*_len = l+1; /* count the 0 also */
			return 0;
		}
		break;

	case DB_STR:
		l = VAL_STR(_v).len;
		if (*_len < l)
		{
			LM_ERR("Destination buffer too short for str\n");
			return -5;
		}
		else
		{
			LM_DBG("Converted str to string\n");
			strncpy(_s, VAL_STR(_v).s , l);
			*_len = l;
			return 0;
		}
		break;

	case DB_DATETIME:
		if (bdb_time2str(VAL_TIME(_v), _s, _len) < 0) {
			LM_ERR("Error while converting time_t to string\n");
			return -6;
		} else {
			LM_DBG("Converted time_t to string\n");
			return 0;
		}
		break;

	case DB_BLOB:
		l = VAL_BLOB(_v).len;
		if (*_len < l)
		{
			LM_ERR("Destination buffer too short for blob\n");
			return -7;
		}
		else
		{
			strncpy(_s, VAL_BLOB(_v).s , l);
			LM_DBG("Converting BLOB [%.*s]\n", l,_s);
			*_len = l;
			return 0;
		}
		break;

	default:
		LM_DBG("Unknown data type\n");
		return -8;
	}
}
예제 #13
0
/*!
 * \brief Get all contacts from the database, in partitions if wanted
 * \see get_all_ucontacts
 * \param buf target buffer
 * \param len length of buffer
 * \param flags contact flags
 * \param part_idx part index
 * \param part_max maximal part
 * \param GAU options
 * \return 0 on success, positive if buffer size was not sufficient, negative on failure
 */
static inline int get_all_db_ucontacts(void *buf, int len, unsigned int flags,
								unsigned int part_idx, unsigned int part_max,
								int options)
{
	struct socket_info *sock;
	unsigned int dbflags;
	db1_res_t* res = NULL;
	db_row_t *row;
	dlist_t *dom;
	str now;
	char now_s[25];
	int port, proto;
	char *p;
	str addr;
	str recv;
	str path;
	str ruid;
	str host;
	unsigned int aorhash;
	int i;
	void *cp;
	int shortage, needed;
	db_key_t keys1[4]; /* where */
	db_val_t vals1[4];
	db_op_t  ops1[4];
	db_key_t keys2[6]; /* select */
	int n[2] = {2,6}; /* number of dynamic values used on key1/key2 */

	cp = buf;
	shortage = 0;
	/* Reserve space for terminating 0000 */
	len -= sizeof(addr.len);

	/* get the current time in DB format */
	now.len = 25;
	now.s = now_s;
	if (db_time2str( time(0), now.s, &now.len)!=0) {
		LM_ERR("failed to print now time\n");
		return -1;
	}
	aorhash = 0;

	/* select fields */
	keys2[0] = &received_col;
	keys2[1] = &contact_col;
	keys2[2] = &sock_col;
	keys2[3] = &cflags_col;
	keys2[4] = &path_col;
	keys2[5] = &ruid_col;

	/* where fields */
	keys1[0] = &expires_col;
	ops1[0] = OP_GT;
	vals1[0].type = DB1_STR;
	vals1[0].nul = 0;
	vals1[0].val.str_val = now;

	keys1[1] = &partition_col;
	ops1[1] = OP_EQ;
	vals1[1].type = DB1_INT;
	vals1[1].nul = 0;
	if(_ul_max_partition>0)
		vals1[1].val.int_val = part_idx;
	else
		vals1[1].val.int_val = 0;

	if (flags & nat_bflag) {
		keys1[n[0]] = &keepalive_col;
		ops1[n[0]] = OP_EQ;
		vals1[n[0]].type = DB1_INT;
		vals1[n[0]].nul = 0;
		vals1[n[0]].val.int_val = 1;
		n[0]++;
	}
	if(options&GAU_OPT_SERVER_ID) {
		keys1[n[0]] = &srv_id_col;
		ops1[n[0]] = OP_EQ;
		vals1[n[0]].type = DB1_INT;
		vals1[n[0]].nul = 0;
		vals1[n[0]].val.int_val = server_id;
		n[0]++;
	}

	/* TODO: use part_idx and part_max on keys1 */

	for (dom = root; dom!=NULL ; dom=dom->next) {
		if (ul_dbf.use_table(ul_dbh, dom->d->name) < 0) {
			LM_ERR("sql use_table failed\n");
			return -1;
		}
		if (ul_dbf.query(ul_dbh, keys1, ops1, vals1, keys2,
							n[0], n[1], NULL, &res) <0 ) {
			LM_ERR("query error\n");
			return -1;
		}
		if( RES_ROW_N(res)==0 ) {
			ul_dbf.free_result(ul_dbh, res);
			continue;
		}

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


			/* received */
			recv.s = (char*)VAL_STRING(ROW_VALUES(row));
			if ( VAL_NULL(ROW_VALUES(row)) || recv.s==0 || recv.s[0]==0 ) {
				recv.s = NULL;
				recv.len = 0;
			}
			else {
				recv.len = strlen(recv.s);
			}

			/* contact */
			addr.s = (char*)VAL_STRING(ROW_VALUES(row)+1);
			if (VAL_NULL(ROW_VALUES(row)+1) || addr.s==0 || addr.s[0]==0) {
				LM_ERR("empty contact -> skipping\n");
				continue;
			}
			else {
				addr.len = strlen(addr.s);
			}

			/* path */
			path.s = (char*)VAL_STRING(ROW_VALUES(row)+4);
			if (VAL_NULL(ROW_VALUES(row)+4) || path.s==0 || path.s[0]==0){
				path.s = NULL;
				path.len = 0;
			} else {
				path.len = strlen(path.s);
			}

			/* ruid */
			ruid.s = (char*)VAL_STRING(ROW_VALUES(row)+5);
			if (VAL_NULL(ROW_VALUES(row)+5) || ruid.s==0 || ruid.s[0]==0){
				ruid.s = NULL;
				ruid.len = 0;
			} else {
				ruid.len = strlen(ruid.s);
			}

			needed = (int)(sizeof(addr.len) + addr.len
					+ sizeof(recv.len) + recv.len
					+ sizeof(sock) + sizeof(dbflags)
					+ sizeof(path.len) + path.len
					+ sizeof(ruid.len) + ruid.len
					+ sizeof(aorhash));
			if (len < needed) {
				shortage += needed ;
				continue;
			}

			/* write contact */
			memcpy(cp, &addr.len, sizeof(addr.len));
			cp = (char*)cp + sizeof(addr.len);
			memcpy(cp, addr.s, addr.len);
			cp = (char*)cp + addr.len;

			/* write received */
			memcpy(cp, &recv.len, sizeof(recv.len));
			cp = (char*)cp + sizeof(recv.len);
			/* copy received only if exist */
			if(recv.len){
				memcpy(cp, recv.s, recv.len);
				cp = (char*)cp + recv.len;
			}

			/* sock */
			p  = (char*)VAL_STRING(ROW_VALUES(row) + 2);
			if (VAL_NULL(ROW_VALUES(row)+2) || p==0 || p[0]==0){
				sock = 0;
			} else {
				if (parse_phostport( p, &host.s, &host.len,
				&port, &proto)!=0) {
					LM_ERR("bad socket <%s>...set to 0\n", p);
					sock = 0;
				} else {
					sock = grep_sock_info( &host, (unsigned short)port, proto);
					if (sock==0) {
						LM_DBG("non-local socket <%s>...set to 0\n", p);
					}
				}
			}

			/* flags */
			dbflags = VAL_BITMAP(ROW_VALUES(row) + 3);

			/* write sock and flags */
			memcpy(cp, &sock, sizeof(sock));
			cp = (char*)cp + sizeof(sock);
			memcpy(cp, &dbflags, sizeof(dbflags));
			cp = (char*)cp + sizeof(dbflags);

			/* write path */
			memcpy(cp, &path.len, sizeof(path.len));
			cp = (char*)cp + sizeof(path.len);
			/* copy path only if exist */
			if(path.len){
				memcpy(cp, path.s, path.len);
				cp = (char*)cp + path.len;
			}

			/* write ruid */
			memcpy(cp, &ruid.len, sizeof(ruid.len));
			cp = (char*)cp + sizeof(ruid.len);
			/* copy ruid only if exist */
			if(ruid.len){
				memcpy(cp, ruid.s, ruid.len);
				cp = (char*)cp + ruid.len;
			}
			/* aorhash not used for db-only records, but it is added
			 * (as 0) to match the struct used for mem records */
			memcpy(cp, &aorhash, sizeof(aorhash));
			cp = (char*)cp + sizeof(aorhash);

			len -= needed;
		} /* row cycle */

		ul_dbf.free_result(ul_dbh, res);
	} /* domain cycle */

	/* len < 0 is possible, if size of the buffer < sizeof(c->c.len) */
	if (len >= 0)
		memset(cp, 0, sizeof(addr.len));

	/* Shouldn't happen */
	if (shortage > 0 && len > shortage) {
		abort();
	}

	shortage -= len;

	return shortage > 0 ? shortage : 0;
}
예제 #14
0
/*
 * Reload addr table to new hash table and when done, make new hash table
 * current one.
 */
int reload_address_table(void)
{
	db_key_t cols[5];
	db1_res_t* res = NULL;
	db_row_t* row;
	db_val_t* val;

	struct addr_list **new_hash_table;
	struct subnet *new_subnet_table;
	struct domain_name_list **new_domain_name_table;
	int i;
	unsigned int gid;
	unsigned int port;
	unsigned int mask;
	str ips;
	ip_addr_t *ipa;
	char *tagv;

	cols[0] = &grp_col;
	cols[1] = &ip_addr_col;
	cols[2] = &mask_col;
	cols[3] = &port_col;
	cols[4] = &tag_col;

	if (perm_dbf.use_table(db_handle, &address_table) < 0) {
		LM_ERR("failed to use table\n");
		return -1;
	}

	if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 5, 0, &res) < 0) {
		LM_ERR("failed to query database\n");
		return -1;
	}

	/* Choose new hash table and free its old contents */
	if (*addr_hash_table == addr_hash_table_1) {
		empty_addr_hash_table(addr_hash_table_2);
		new_hash_table = addr_hash_table_2;
	} else {
		empty_addr_hash_table(addr_hash_table_1);
		new_hash_table = addr_hash_table_1;
	}

	/* Choose new subnet table */
	if (*subnet_table == subnet_table_1) {
		empty_subnet_table(subnet_table_2);
		new_subnet_table = subnet_table_2;
	} else {
		empty_subnet_table(subnet_table_1);
		new_subnet_table = subnet_table_1;
	}

	/* Choose new domain name table */
	if (*domain_list_table == domain_list_table_1) {
		empty_domain_name_table(domain_list_table_2);
		new_domain_name_table = domain_list_table_2;
	} else {
		empty_domain_name_table(domain_list_table_1);
		new_domain_name_table = domain_list_table_1;
	}


	row = RES_ROWS(res);

	LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res));

	for (i = 0; i < RES_ROW_N(res); i++) {
		val = ROW_VALUES(row + i);
		/* basic checks to db values */
		if (ROW_N(row + i) != 5)
		{
			LM_DBG("failure during checks of db address table: Colums %d - expected 5\n", ROW_N(row + i));
			goto dberror;
		}
		if ((VAL_TYPE(val) != DB1_INT) || VAL_NULL(val) || (VAL_INT(val) <= 0))
		{
			LM_DBG("failure during checks of database value 1 (group) in address table\n");
			goto dberror;
		}
		if ((VAL_TYPE(val + 1) != DB1_STRING) && (VAL_TYPE(val + 1) != DB1_STR))
		{
			LM_DBG("failure during checks of database value 2 (IP address) in address table - not a string value\n");
			goto dberror;
		}
		if (VAL_NULL(val + 1))
		{
			LM_DBG("failure during checks of database value 2 (IP address) in address table - NULL value not permitted\n");
			goto dberror;
		}
		if ((VAL_TYPE(val + 2) != DB1_INT) || VAL_NULL(val + 2))
		{
			LM_DBG("failure during checks of database value 3 (subnet size/CIDR) in address table\n");
			goto dberror;
		}
		if ((VAL_TYPE(val + 3) != DB1_INT) || VAL_NULL(val + 3))
		{
			LM_DBG("failure during checks of database value 4 (port) in address table\n");
			goto dberror;
		}
		gid = VAL_UINT(val);
		ips.s = (char *)VAL_STRING(val + 1);
		ips.len = strlen(ips.s);
		mask = VAL_UINT(val + 2);
		port = VAL_UINT(val + 3);
		tagv = VAL_NULL(val + 4)?NULL:(char *)VAL_STRING(val + 4);
		ipa = strtoipX(&ips);
		if ( ipa==NULL )
		{
			LM_DBG("Domain name: %.*s\n", ips.len, ips.s);
			//	goto dberror;
		} else {
			if(ipa->af == AF_INET6) {
				if((int)mask<0 || mask>128) {
					LM_DBG("failure during IP mask check for v6\n");
					goto dberror;
				}
			} else {
				if((int)mask<0 || mask>32) {
					LM_DBG("failure during IP mask check for v4\n");
					goto dberror;
				}
			}
		}

		if ( ipa ) {
			if ( (ipa->af==AF_INET6 && mask==128) || (ipa->af==AF_INET && mask==32) ) {
				if (addr_hash_table_insert(new_hash_table, gid, ipa, port, tagv)
						== -1) {
					LM_ERR("hash table problem\n");
					perm_dbf.free_result(db_handle, res);
					return -1;
				}
				LM_DBG("Tuple <%u, %s, %u> inserted into address hash table\n",
						gid, ips.s, port);
			} else {
				if (subnet_table_insert(new_subnet_table, gid, ipa, mask,
							port, tagv)
						== -1) {
					LM_ERR("subnet table problem\n");
					perm_dbf.free_result(db_handle, res);
					return -1;
				}
				LM_DBG("Tuple <%u, %s, %u, %u> inserted into subnet table\n",
						gid, ips.s, port, mask);
			}
		} else {
			if (domain_name_table_insert(new_domain_name_table, gid, &ips,
						port, tagv)
					== -1) {
				LM_ERR("domain name table problem\n");
				perm_dbf.free_result(db_handle, res);
				return -1;
			}
			LM_DBG("Tuple <%u, %s, %u> inserted into domain name table\n",
					gid, ips.s, port);
		}
	}

	perm_dbf.free_result(db_handle, res);

	*addr_hash_table = new_hash_table;
	*subnet_table = new_subnet_table;
	*domain_list_table = new_domain_name_table;

	LM_DBG("address table reloaded successfully.\n");

	return 1;

dberror:
	LM_ERR("database problem - invalid record\n");
	perm_dbf.free_result(db_handle, res);
	return -1;
}
예제 #15
0
파일: group.c 프로젝트: GeorgeShaw/opensips
/*
 * Check if username in specified header field is in a table
 */
int db_is_user_in(struct sip_msg* _msg, char* _hf, char* _grp)
{
	static db_ps_t my_ps = NULL;
	db_key_t keys[3];
	db_val_t vals[3];
	db_key_t col[1];
	db_res_t* res = NULL;

	keys[0] = &user_column;
	keys[1] = &group_column;
	keys[2] = &domain_column;
	col[0]  = &group_column;

	str hf_s = { NULL, 0 };
	str grp_s = { NULL, 0 };

	if(_hf ==  NULL || fixup_get_svalue(_msg, (gparam_p)_hf, &hf_s) != 0) {
		LM_ERR("Invalid parameter URI\n");
		return -1;
	}

	if(_grp == NULL || fixup_get_svalue(_msg, (gparam_p)_grp, &grp_s) != 0) {
		LM_ERR("Invalid parameter grp\n");
		return -1;
	}

	if ( get_username_domain( _msg, &hf_s, &(VAL_STR(vals)),
	&(VAL_STR(vals+2)))!=0) {
		LM_ERR("failed to get username@domain\n");
		return -1;
	}

	if (VAL_STR(vals).s==NULL || VAL_STR(vals).len==0 ) {
		LM_DBG("no username part\n");
		return -1;
	}

	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB_STR;
	VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0;

	VAL_STR(vals + 1) = *(&grp_s);

	group_dbf.use_table(group_dbh, &table);
	CON_PS_REFERENCE(group_dbh) = &my_ps;

	if (group_dbf.query(group_dbh, keys, 0, vals, col, (use_domain) ? (3): (2),
				1, 0, &res) < 0) {
		LM_ERR("failed to query database\n");
		return -5;
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("user is not in group '%.*s'\n",
		    (grp_s.len), ZSW((grp_s.s)));
		group_dbf.free_result(group_dbh, res);
		return -6;
	} else {
		LM_DBG("user is in group '%.*s'\n",
			(grp_s.len), ZSW((grp_s.s)));
		group_dbf.free_result(group_dbh, res);
		return 1;
	}
}
예제 #16
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;
}
예제 #17
0
int uac_reg_load_db(void)
{
	db1_con_t *reg_db_con = NULL;
	db_func_t reg_dbf;
	reg_uac_t reg;
	db_key_t db_cols[10] = {
		&l_uuid_column,
		&l_username_column,
		&l_domain_column,
		&r_username_column,
		&r_domain_column,
		&realm_column,
		&auth_username_column,
		&auth_password_column,
		&auth_proxy_column,
		&expires_column
	};
	db1_res_t* db_res = NULL;
	int i, ret;

	/* binding to db module */
	if(reg_db_url.s==NULL)
	{
		LM_ERR("no db url\n");
		return -1;
	}

	if(db_bind_mod(&reg_db_url, &reg_dbf))
	{
		LM_ERR("database module not found\n");
		return -1;
	}

	if (!DB_CAPABILITY(reg_dbf, DB_CAP_ALL))
	{
		LM_ERR("database module does not "
		    "implement all functions needed by the module\n");
		return -1;
	}

	/* open a connection with the database */
	reg_db_con = reg_dbf.init(&reg_db_url);
	if(reg_db_con==NULL)
	{
		LM_ERR("failed to connect to the database\n");
		return -1;
	}
	if (reg_dbf.use_table(reg_db_con, &reg_db_table) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

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

	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			memset(&reg, 0, sizeof(reg_uac_t));;
			/* check for NULL values ?!?! */
			reg_db_set_attr(l_uuid, 0);
			reg_db_set_attr(l_username, 1);
			reg_db_set_attr(l_domain, 2);
			reg_db_set_attr(r_username, 3);
			reg_db_set_attr(r_domain, 4);
			/* realm may be empty */
			if(!VAL_NULL(&RES_ROWS(db_res)[i].values[5])) {
				reg.realm.s = (char*)(RES_ROWS(db_res)[i].values[5].val.string_val);
				reg.realm.len = strlen(reg.realm.s);
			}
			reg_db_set_attr(auth_username, 6);
			reg_db_set_attr(auth_password, 7);
			reg_db_set_attr(auth_proxy, 8);
			reg.expires
				= (unsigned int)RES_ROWS(db_res)[i].values[9].val.int_val;
			
			if(reg_ht_add(&reg)<0)
			{
				LM_ERR("Error adding reg to htable\n");
				goto error;
			}
	 	}
		if (DB_CAPABILITY(reg_dbf, DB_CAP_FETCH)) {
			if(reg_dbf.fetch_result(reg_db_con, &db_res, reg_fetch_rows)<0) {
				LM_ERR("Error while fetching!\n");
				if (db_res)
					reg_dbf.free_result(reg_db_con, db_res);
				goto error;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(db_res)>0);
	reg_dbf.free_result(reg_db_con, db_res);
	reg_dbf.close(reg_db_con);

done:
	return 0;

error:
	if (reg_db_con) {
		reg_dbf.free_result(reg_db_con, db_res);
		reg_dbf.close(reg_db_con);
	}
	return -1;
}
예제 #18
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;
}
예제 #19
0
/*
 * Release memory used by row
 */
inline int db_free_row(db_row_t* _r)
{
	int col;
	db_val_t* _val;

	if (!_r) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	/*
	 * Loop thru each columm, then check to determine if the storage pointed to
	 * by db_val_t structure must be freed. This is required for all data types
	 * which use a pointer to a buffer like DB1_STRING, DB1_STR and DB1_BLOB and
	 * the database module copied them during the assignment.
	 * If this is not done, a memory leak will happen.
	 * Don't try to free the static dummy string (as indicated from the NULL value),
	 * as this is not valid.
	 */
	for (col = 0; col < ROW_N(_r); col++) {
		_val = &(ROW_VALUES(_r)[col]);
		switch (VAL_TYPE(_val)) {
			case DB1_STRING:
				if ( (!VAL_NULL(_val)) && VAL_FREE(_val)) {
					LM_DBG("free VAL_STRING[%d] '%s' at %p\n", col,
							(char *)VAL_STRING(_val),
							(char *)VAL_STRING(_val));
					pkg_free((char *)VAL_STRING(_val));
					VAL_STRING(_val) = NULL;
				}
				break;
			case DB1_STR:
				if ( (!VAL_NULL(_val)) && VAL_FREE(_val)) {
					LM_DBG("free VAL_STR[%d] '%.*s' at %p\n", col,
							VAL_STR(_val).len,
							VAL_STR(_val).s, VAL_STR(_val).s);
					pkg_free(VAL_STR(_val).s);
					VAL_STR(_val).s = NULL;
				}
				break;
			case DB1_BLOB:
				if ( (!VAL_NULL(_val)) && VAL_FREE(_val)) {
					LM_DBG("free VAL_BLOB[%d] at %p\n", col, VAL_BLOB(_val).s);
					pkg_free(VAL_BLOB(_val).s);
					VAL_BLOB(_val).s = NULL;
				}
				break;
			default:
				break;
		}
	}
	/* now as we freed all, set number of colums to zero again */
	ROW_N(_r) = 0;

	if (ROW_VALUES(_r)) {
		LM_DBG("freeing row values at %p\n", ROW_VALUES(_r));
		pkg_free(ROW_VALUES(_r));
		ROW_VALUES(_r) = NULL;
	}
	return 0;
}
예제 #20
0
int update_dialog_dbinfo(struct dlg_cell * cell)
{
	static db_ps_t my_ps_insert = NULL;
	static db_ps_t my_ps_update = NULL;
	static db_ps_t my_ps_update_vp = NULL;
	struct dlg_entry entry;
	db_val_t values[DIALOG_TABLE_TOTAL_COL_NO];
	int callee_leg;

	db_key_t insert_keys[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,
			&from_sock_column,   &to_sock_column,
			&start_time_column,  &mangled_fu_column,  &mangled_tu_column,
			
			&state_column,       &timeout_column,
			&from_cseq_column,   &to_cseq_column,     &from_ping_cseq_column,
			&to_ping_cseq_column,&flags_column,
			&vars_column,        &profiles_column,    &sflags_column,
			&from_route_column,
			&to_route_column,    &from_contact_column,&to_contact_column};

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

	callee_leg= callee_idx(cell);

	if((cell->flags & DLG_FLAG_NEW) != 0){
		/* save all the current dialogs information*/
		VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = 
		VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+16) =
		VAL_TYPE(values+17) = VAL_TYPE(values+18) = 
		VAL_TYPE(values+21) = DB_INT;

		VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = 
		VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
		VAL_TYPE(values+8) = VAL_TYPE(values+10) = VAL_TYPE(values+11) =
		VAL_TYPE(values+14) = VAL_TYPE(values+15) = 
		VAL_TYPE(values+19) = VAL_TYPE(values+20) = VAL_TYPE(values+22) =
		VAL_TYPE(values+23) = VAL_TYPE(values+24) =
		VAL_TYPE(values+25) = DB_STR;

		/* lock the entry */
		entry = (d_table->entries)[cell->h_entry];
		dlg_lock( d_table, &entry);

		SET_INT_VALUE(values, cell->h_entry);
		SET_INT_VALUE(values+1, cell->h_id);
		SET_STR_VALUE(values+2, cell->callid);

		SET_STR_VALUE(values+3, cell->from_uri);
		SET_STR_VALUE(values+4, cell->legs[DLG_CALLER_LEG].tag);
		SET_STR_VALUE(values+5, cell->to_uri);
		SET_STR_VALUE(values+6, cell->legs[callee_leg].tag);

		SET_STR_VALUE(values+7, cell->legs[DLG_CALLER_LEG].bind_addr->sock_str);
		if (cell->legs[callee_leg].bind_addr) {
			SET_STR_VALUE(values+8, 
				cell->legs[callee_leg].bind_addr->sock_str);
		} else {
			VAL_NULL(values+8) = 1;
		}

		SET_INT_VALUE(values+9, cell->start_ts);

		SET_STR_VALUE(values+10,cell->legs[callee_leg].from_uri);
		SET_STR_VALUE(values+11,cell->legs[callee_leg].to_uri);

		SET_INT_VALUE(values+12, cell->state);
		SET_INT_VALUE(values+13, (unsigned int)( (unsigned int)time(0) +
			 cell->tl.timeout - get_ticks()) );

		SET_STR_VALUE(values+14, cell->legs[DLG_CALLER_LEG].r_cseq);
		SET_STR_VALUE(values+15, cell->legs[callee_leg].r_cseq);
		SET_INT_VALUE(values+16,cell->legs[DLG_CALLER_LEG].last_gen_cseq);
		SET_INT_VALUE(values+17,cell->legs[callee_leg].last_gen_cseq);
		SET_INT_VALUE(values+18, cell->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED));
		set_final_update_cols(values+19, cell, 0);
		SET_STR_VALUE(values+22, cell->legs[DLG_CALLER_LEG].route_set);
		SET_STR_VALUE(values+23, cell->legs[callee_leg].route_set);
		SET_STR_VALUE(values+24, cell->legs[DLG_CALLER_LEG].contact);
		SET_STR_VALUE(values+25, cell->legs[callee_leg].contact);

		CON_PS_REFERENCE(dialog_db_handle) = &my_ps_insert;

		if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, 
								DIALOG_TABLE_TOTAL_COL_NO)) !=0){
			LM_ERR("could not add another dialog to db\n");
			goto error;
		}

		/* dialog saved */
		run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

		cell->flags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);

	} else if((cell->flags & DLG_FLAG_CHANGED) != 0) {
		/* save only dialog's state and timeout */
		VAL_TYPE(values) = VAL_TYPE(values+1) = 
		VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+16) =
		VAL_TYPE(values+17) = VAL_TYPE(values+18) =
		VAL_TYPE(values+21) =DB_INT;

		VAL_TYPE(values+14) = VAL_TYPE(values+15) =
		VAL_TYPE(values+19) = VAL_TYPE(values+20) = DB_STR;

		/* lock the entry */
		entry = (d_table->entries)[cell->h_entry];
		dlg_lock( d_table, &entry);

		SET_INT_VALUE(values, cell->h_entry);
		SET_INT_VALUE(values+1, cell->h_id);
		SET_INT_VALUE(values+12, cell->state);
		SET_INT_VALUE(values+13, (unsigned int)( (unsigned int)time(0) +
				 cell->tl.timeout - get_ticks()) );

		SET_STR_VALUE(values+14, cell->legs[DLG_CALLER_LEG].r_cseq);
		SET_STR_VALUE(values+15, cell->legs[callee_leg].r_cseq);
		SET_INT_VALUE(values+16,cell->legs[DLG_CALLER_LEG].last_gen_cseq);
		SET_INT_VALUE(values+17,cell->legs[callee_leg].last_gen_cseq);
		SET_INT_VALUE(values+18, cell->flags);
		set_final_update_cols(values+19, cell, 1);

		CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update;

		if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
						(values), (insert_keys+12), (values+12), 2, 10)) !=0){
			LM_ERR("could not update database info\n");
			goto error;
		}

		/* dialog saved */
		run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

		cell->flags &= ~(DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);
	} else if (cell->flags & DLG_FLAG_VP_CHANGED) {
		cell->flags |= DLG_FLAG_VP_CHANGED;
		VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+21) = DB_INT;
		VAL_TYPE(values+19) = VAL_TYPE(values+20) = DB_STR;

		/* lock the entry */
		entry = (d_table->entries)[cell->h_entry];
		dlg_lock( d_table, &entry);

		SET_INT_VALUE(values, cell->h_entry);
		SET_INT_VALUE(values+1, cell->h_id);

		set_final_update_cols(values+19, cell, 0);

		CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update_vp;

		if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
						(values), (insert_keys+19), (values+19), 2, 3)) !=0){
			LM_ERR("could not update database info\n");
			goto error;
		}

		run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

		cell->flags &= ~DLG_FLAG_VP_CHANGED;
	} else {
		return 0;
	}

	dlg_unlock( d_table, &entry);
	return 0;

error:
	dlg_unlock( d_table, &entry);
	return -1;
}
예제 #21
0
파일: dp_db.c 프로젝트: NormB/opensips
/*load rules from DB*/
int dp_load_db(dp_connection_list_p dp_conn)
{
	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_flags_column,
		&subst_exp_column,	&repl_exp_column,	&attrs_column,	&timerec_column };
	db_key_t order = &pr_column;
	/* disabled condition */
	db_key_t cond_cols[1] = { &disabled_column };
	db_val_t cond_val[1];

	dpl_node_t *rule;
	int no_rows = 10;


	lock_start_write( dp_conn->ref_lock );

	if( dp_conn->crt_index != dp_conn->next_index){
		LM_WARN("a load command already generated, aborting reload...\n");
		lock_stop_write( dp_conn->ref_lock );
		return 0;
	}

	dp_conn->next_index = dp_conn->crt_index == 0 ? 1 : 0;

	lock_stop_write( dp_conn->ref_lock );

	if (dp_conn->dp_dbf.use_table(*dp_conn->dp_db_handle, &dp_conn->table_name) < 0){
		LM_ERR("error in use_table\n");
		goto err1;
	}

	VAL_TYPE(cond_val) = DB_INT;
	VAL_NULL(cond_val) = 0;
	VAL_INT(cond_val) = 0;

	if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) {
		if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,cond_cols,
				0,cond_val,query_cols,1,
					DP_TABLE_COL_NO, order, 0) < 0){
			LM_ERR("failed to query database!\n");

			goto err1;
		}
		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_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle,
						&res, no_rows)<0) {
			LM_ERR("failed to fetch\n");
			if (res)
				dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);

			goto err1;
		}
	} else {
		/*select the whole table and all the columns*/
		if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,
				cond_cols,0,cond_val,query_cols,1,
			DP_TABLE_COL_NO, order, &res) < 0){
				LM_ERR("failed to query database\n");

			goto err1;
		}
	}

	nr_rows = RES_ROW_N(res);



	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;
			}

			rule->table_id = i;

			if(add_rule2hash(rule , dp_conn, dp_conn->next_index) != 0) {
				LM_ERR("add_rule2hash failed\n");
				goto err2;
			}
		}


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


end:


	/*update data*/
	lock_start_write( dp_conn->ref_lock );

	destroy_hash(&dp_conn->hash[dp_conn->crt_index]);

	dp_conn->crt_index = dp_conn->next_index;

	lock_stop_write( dp_conn->ref_lock );

	list_hash(dp_conn->hash[dp_conn->crt_index], dp_conn->ref_lock);

	dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);
	return 0;

err1:

	lock_start_write( dp_conn->ref_lock );

	dp_conn->next_index = dp_conn->crt_index;

	lock_stop_write( dp_conn->ref_lock );

	return -1;

err2:
	if(rule)	destroy_rule(rule);
	destroy_hash(&dp_conn->hash[dp_conn->next_index]);
	dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);

	lock_start_write( dp_conn->ref_lock );

	dp_conn->next_index = dp_conn->crt_index;
	/* if lock defined - release the exclusive writing access */

	lock_stop_write( dp_conn->ref_lock );
	return -1;
}
예제 #22
0
파일: trusted.c 프로젝트: kiryu/kamailio
/*
 * Matches from uri against patterns returned from database.  Returns number
 * of matches or -1 if none of the patterns match.
 */
static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r)
{
	int i, tag_avp_type;
	str uri;
	char uri_string[MAX_URI_SIZE+1];
	db_row_t* row;
	db_val_t* val;
	regex_t preg;
	int_str tag_avp, avp_val;
	int count = 0;

	if (IS_SIP(msg)) {
		if (parse_from_header(msg) < 0) return -1;
		uri = get_from(msg)->uri;
		if (uri.len > MAX_URI_SIZE) {
			LM_ERR("message has From URI too large\n");
			return -1;
		}
		memcpy(uri_string, uri.s, uri.len);
		uri_string[uri.len] = (char)0;
	}
	get_tag_avp(&tag_avp, &tag_avp_type);

	row = RES_ROWS(_r);

	for(i = 0; i < RES_ROW_N(_r); i++) {
		val = ROW_VALUES(row + i);
		if ((ROW_N(row + i) == 3) &&
		    (VAL_TYPE(val) == DB1_STRING) && !VAL_NULL(val) &&
		    match_proto(VAL_STRING(val), proto) &&
		    (VAL_NULL(val + 1) ||
		      ((VAL_TYPE(val + 1) == DB1_STRING) && !VAL_NULL(val + 1))) &&
		    (VAL_NULL(val + 2) ||
		      ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))))
		{
			if (!VAL_NULL(val + 1) && IS_SIP(msg)) {
				if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) {
					LM_ERR("invalid regular expression\n");
					continue;
				}
				if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
					regfree(&preg);
					continue;
				}
			    regfree(&preg);
			}
			/* Found a match */
			if (tag_avp.n && !VAL_NULL(val + 2)) {
				avp_val.s.s = (char *)VAL_STRING(val + 2);
				avp_val.s.len = strlen(avp_val.s.s);
				if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, avp_val) != 0) {
					LM_ERR("failed to set of tag_avp failed\n");
					return -1;
				}
			}
			if (!peer_tag_mode) 
				return 1;
			count++;
		}
	}
	if (!count)
		return -1;
	else 
		return count;
}
예제 #23
0
/*
 * Insert a row into specified table
 * h: structure representing database connection
 * k: key names
 * v: values of the keys
 * n: number of key=value pairs
 */
int flat_db_insert(const db_con_t* h, const db_key_t* k, const db_val_t* v,
		const int n)
{
	FILE* f;
	int i;
	int auxl;
	str aux;
	char * begin = flat_iov_buf.s;

	if (local_timestamp < *flat_rotate) {
		flat_rotate_logs();
		local_timestamp = *flat_rotate;
	}

	if ( !h || !CON_TAIL(h) || (f=CON_FILE(h))==NULL ) {
		LM_ERR("uninitialized connection\n");
		return -1;
	}

	if (flat_prepare_iovec(n) < 0) {
		LM_ERR("cannot insert row\n");
		return -1;
	}

	FLAT_LOCK(f);

	for(i = 0; i < n; i++) {
		if (VAL_NULL(v + i)) {
			FLAT_SET_STR(i, "");
			FLAT_SET_LEN(i, 0);
			continue;
		}
		FLAT_SET_STR(i, FLAT_BUF);
		switch(VAL_TYPE(v + i)) {
		case DB_INT:
			/* guess this is 20 */
			FLAT_ALLOC(20);
			FLAT_PRINTF("%d", VAL_INT(v+i), i);
			break;

		case DB_DOUBLE:
			/* guess there are max 20 digits */
			FLAT_ALLOC(40);
			FLAT_PRINTF("%f", VAL_DOUBLE(v+i), i);
			break;

		case DB_BIGINT:
			/* guess there are max 20 digits */
			FLAT_ALLOC(40);
			FLAT_PRINTF("%llu", VAL_BIGINT(v+i), i);
			break;

		case DB_STRING:
			auxl = strlen(VAL_STRING(v + i));
			FLAT_ALLOC(auxl * 4);
			FLAT_COPY(i, VAL_STRING(v + i), auxl);
			break;

		case DB_STR:
			FLAT_ALLOC(VAL_STR(v + i).len * 4);
			FLAT_COPY(i, VAL_STR(v + i).s, VAL_STR(v + i).len);
			break;

		case DB_DATETIME:
			/* guess this is 20 */
			FLAT_ALLOC(20);
			FLAT_PRINTF("%lu", VAL_TIME(v+i), i);
			break;

		case DB_BLOB:
			auxl = VAL_BLOB(v+i).len;
			/* the maximum size is 4l - if all chars were not printable */
			FLAT_ALLOC(4 * auxl);
			FLAT_COPY(i, VAL_BLOB(v+i).s, auxl);
			break;

		case DB_BITMAP:
			/* guess this is 20 */
			FLAT_ALLOC(20);
			FLAT_PRINTF("%u", VAL_BITMAP(v+i), i);
			break;
		}
	}
	/* reorder pointers in case they were altered by (re)allocation */
	if (flat_iov_buf.s != begin && flat_iov_buf.len) {
		FLAT_RESET();
		for (i = 0; i < n; i++) {
			if (!VAL_NULL(v + i)) {
				FLAT_SET_STR(i, FLAT_BUF);
				FLAT_INC(FLAT_GET_LEN(i));
			}
		}
	}

	do {
		auxl = writev(fileno(f), flat_iov, 2 * n);
	} while (auxl < 0 && errno == EINTR);

	if (auxl < 0) {
		LM_ERR("unable to write to file: %s - %d\n", strerror(errno), errno);
		return -1;
	}

	/* XXX does this make sense any more? */
	if (flat_flush && fflush(f) < 0) {
		LM_ERR("cannot flush buffer: %s - %d\n", strerror(errno), errno);
	}
	FLAT_UNLOCK(f);


	return 0;
}
예제 #24
0
파일: trusted.c 프로젝트: kiryu/kamailio
/*
 * Reload trusted table to new hash table and when done, make new hash table
 * current one.
 */
int reload_trusted_table(void)
{
	db_key_t cols[4];
	db1_res_t* res = NULL;
	db_row_t* row;
	db_val_t* val;

	struct trusted_list **new_hash_table;
	int i;

	char *pattern, *tag;

	cols[0] = &source_col;
	cols[1] = &proto_col;
	cols[2] = &from_col;
	cols[3] = &tag_col;

	if (db_handle == 0) {
	    LM_ERR("no connection to database\n");
	    return -1;
	}

	if (perm_dbf.use_table(db_handle, &trusted_table) < 0) {
		LM_ERR("failed to use trusted table\n");
		return -1;
	}

	if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 4, 0, &res) < 0) {
		LM_ERR("failed to query database\n");
		return -1;
	}

	/* Choose new hash table and free its old contents */
	if (*hash_table == hash_table_1) {
		empty_hash_table(hash_table_2);
		new_hash_table = hash_table_2;
	} else {
		empty_hash_table(hash_table_1);
		new_hash_table = hash_table_1;
	}

	row = RES_ROWS(res);

	LM_DBG("number of rows in trusted table: %d\n", RES_ROW_N(res));
		
	for (i = 0; i < RES_ROW_N(res); i++) {
	    val = ROW_VALUES(row + i);
	    if ((ROW_N(row + i) == 4) &&
		(VAL_TYPE(val) == DB1_STRING) && !VAL_NULL(val) &&
		(VAL_TYPE(val + 1) == DB1_STRING) && !VAL_NULL(val + 1) &&
		(VAL_NULL(val + 2) ||
		 ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))) &&
		(VAL_NULL(val + 3) ||
		 ((VAL_TYPE(val + 3) == DB1_STRING) && !VAL_NULL(val + 3)))) {
		if (VAL_NULL(val + 2)) {
		    pattern = 0;
		} else {
		    pattern = (char *)VAL_STRING(val + 2);
		}
		if (VAL_NULL(val + 3)) {
		    tag = 0;
		} else {
		    tag = (char *)VAL_STRING(val + 3);
		}
		if (hash_table_insert(new_hash_table,
				      (char *)VAL_STRING(val),
				      (char *)VAL_STRING(val + 1),
				      pattern, tag) == -1) {
		    LM_ERR("hash table problem\n");
		    perm_dbf.free_result(db_handle, res);
		    return -1;
		}
		LM_DBG("tuple <%s, %s, %s, %s> inserted into trusted hash "
		    "table\n", VAL_STRING(val), VAL_STRING(val + 1),
		    pattern, tag);
	    } else {
		LM_ERR("database problem\n");
		perm_dbf.free_result(db_handle, res);
		return -1;
	    }
	}

	perm_dbf.free_result(db_handle, res);

	*hash_table = new_hash_table;

	LM_DBG("trusted table reloaded successfully.\n");
	
	return 1;
}
예제 #25
0
int load_data(db_func_t * dbf, db1_con_t * dbh, ul_db_handle_t * handle, int id){
	db1_res_t *res;
	db_row_t *row;
	db_key_t cols[7];
	db_key_t keys[2];
	db_val_t key_vals[2];
	db_op_t op[2];
	db_key_t order;
	int i, ret = 0;

	if(!dbf || !dbh || !handle){
		LM_ERR("NULL-Pointer in Parameter\n");
		return -1;
	}

	memset(handle, 0, sizeof(ul_db_handle_t));
	
	cols[0] = &num_col;
	cols[1] = &url_col;
	cols[2] = &status_col;
	cols[3] = &failover_time_col;
	cols[4] = &spare_col;
	cols[5] = &error_col;
	cols[6] = &risk_group_col;
	
	order = &num_col;

	keys[0] = &id_col;
	op[0] = OP_EQ;
	key_vals[0].type = DB1_INT;
	key_vals[0].nul = 0;
	key_vals[0].val.int_val = id;
	
	if(dbf->use_table(dbh, &reg_table) < 0){
		LM_ERR("could't use table.\n");
		return -1;
	}
	if(dbf->query(dbh, keys, op, key_vals, cols, 1, 7, order, &res) < 0){
		LM_ERR("error while doing db query.\n");
		return -1;
	}
	if(RES_ROW_N(res) < DB_NUM) {
		LM_ERR("keys have too few location databases\n");
		ret = -1;
		goto ret;
	}

	handle->id = id;
	
	for(i=0; i<DB_NUM; i++) {
		row = RES_ROWS(res) + i;
		handle->db[i].no = (int)VAL_INT(ROW_VALUES(row));
		if(VAL_NULL(ROW_VALUES(row) + 1)){
			LM_ERR("Weird: Empty database URL\n");
			ret = -1;
			goto ret;
		}
		if(strlen((char *)VAL_STRING(ROW_VALUES(row) + 1)) >= (UL_DB_URL_LEN - 1)){
			LM_ERR("weird: very large URL (%d Bytes)\n",
					(int)(strlen((char *)VAL_STRING(ROW_VALUES(row) + 1)) + 1));
			ret = -1;
			goto ret;
		}
		strcpy(handle->db[i].url.s, (char *)VAL_STRING(ROW_VALUES(row) + 1));
		handle->db[i].url.len = strlen(handle->db[i].url.s);
		handle->db[i].status = (int)VAL_INT(ROW_VALUES(row) + 2);
		handle->db[i].failover_time = VAL_TIME (ROW_VALUES(row) + 3);
		handle->db[i].spare = VAL_INT (ROW_VALUES(row) + 4);
		handle->db[i].errors = VAL_INT (ROW_VALUES(row) + 5);
		handle->db[i].rg = VAL_INT (ROW_VALUES(row) + 6);
	}
ret:
	dbf->free_result(dbh, res);
	return ret;
}
예제 #26
0
/* select data from emergency_routing and put in memory
* coluns keys: srid(selectiveRoutingID), resn(routingESN) and npa.
* coluns translate: esgwri 
*/
int get_db_routing(str table_name, rw_lock_t *ref_lock ){
    db_key_t query_cols[] = {&id_col, &srid_col, &resn_col, &npa_col, &esgwri_col};
    db_res_t * res;
    db_val_t * values;
    db_row_t * rows;
    str esgwri;
    str SRID;
    int RESN;
    int NPA;
    int nr_rows, i, size, id;
    struct esrn_routing *esrn_cell, *old_list, *it, *aux, *new_list;
    struct esrn_routing *init_esrn = NULL;

    db_funcs.use_table(db_con, &table_name);

    /* select value from routing table
    *  the keys of routing table: selectiveRoutingID, routingESN, npa
    *  the result of routing lookup: esgwri
    */
    if (db_funcs.query(db_con, 0, 0, 0, query_cols, 0, 5, 0, &res) != 0) {
        LM_ERR("Failure to issue query\n");
        return -1;
    }

    nr_rows = RES_ROW_N(res);
    rows = RES_ROWS(res);

    new_list = NULL;
    LM_DBG("NUMBER OF LINES ROUTING %d \n", nr_rows);

    for (i = 0; i < nr_rows; i++) {
        values = ROW_VALUES(rows + i);

        if (VAL_NULL(values) ||
                (VAL_TYPE(values) != DB_INT)) {
            LM_ERR("Invalid value returned 1\n");
            goto end;
        }

        id = VAL_INT(values);

        if (VAL_NULL(values + 1) ||
                (VAL_TYPE(values + 1) != DB_STR && VAL_TYPE(values + 1) != DB_STRING)) {
            LM_ERR("Invalid translated returned 2\n");
            goto end;
        }

        if (VAL_TYPE(values + 1) == DB_STR) {
            SRID = VAL_STR(values + 1);
        } else {
            SRID.s = (char*) VAL_STRING(values + 1);
            SRID.len = strlen(SRID.s);
        }

        if (VAL_NULL(values + 2) ||
                (VAL_TYPE(values + 2) != DB_INT)) {
            LM_ERR("Invalid translated returned 3\n");
            goto end;
        }

        RESN = VAL_INT(values + 2);

        if (VAL_NULL(values + 3) ||
                (VAL_TYPE(values + 3) != DB_INT)) {
            LM_ERR("Invalid translated returned 4\n");
            goto end;
        }

        NPA = VAL_INT(values + 3);

        if (VAL_NULL(values + 4) ||
                (VAL_TYPE(values + 4) != DB_STR && VAL_TYPE(values + 4) != DB_STRING)) {
            LM_ERR("Invalid translated returned 5\n");
            goto end;
        }

        if (VAL_TYPE(values + 4) == DB_STR) {
            esgwri = VAL_STR(values + 4);
        } else {
            esgwri.s = (char*) VAL_STRING(values + 4);
            esgwri.len = strlen(esgwri.s);
        }

        size = sizeof (struct esrn_routing)+SRID.len + esgwri.len;
        esrn_cell = shm_malloc(size);
        if (!esrn_cell) {
            LM_ERR("no more shm\n");
            goto end;
        }           

        memset(esrn_cell, 0, size);

        esrn_cell->srid.len = SRID.len;
        esrn_cell->srid.s = (char *) (esrn_cell + 1);
        memcpy(esrn_cell->srid.s, SRID.s, SRID.len);
      
        esrn_cell->resn = RESN;
        esrn_cell->npa = NPA;
        esrn_cell->esgwri.len = esgwri.len;
        esrn_cell->esgwri.s = (char *) (esrn_cell + 1) + SRID.len;
        memcpy(esrn_cell->esgwri.s, esgwri.s, esgwri.len);       

        LM_DBG("-SRID %.*s \n", SRID.len, SRID.s);
        LM_DBG("-RESN %d \n", RESN);
        LM_DBG("-NPA %d \n", NPA);
        LM_DBG("-esgwri %.*s \n", esgwri.len, esgwri.s); 


        if (new_list != NULL) {
            new_list->next = esrn_cell;
            new_list = esrn_cell;
        } else {
            new_list = esrn_cell;
            init_esrn = new_list;
        }

    }

    new_list = init_esrn;


    lock_start_write(ref_lock);
    old_list = *db_esrn_esgwri;
    *db_esrn_esgwri = init_esrn;
    lock_stop_write(ref_lock);

    it = old_list;
    while (it) {
        aux = it;
        it = it->next;
        shm_free(aux);
    }

end:
    db_funcs.free_result(db_con, res);

    return 1;

}
예제 #27
0
/*
 * Add key-value to a bson document
 */
int db_mongodb_bson_add(bson_t *doc, const db_key_t _k, const db_val_t *_v, int idx)
{
	int vtype;

	vtype = VAL_TYPE(_v);
	if(VAL_NULL(_v)) {
		if(!bson_append_null(doc, _k->s, _k->len)) {
			LM_ERR("failed to append int to bson doc %.*s = %d [%d]\n",
					_k->len, _k->s, VAL_INT(_v), idx);
			goto error;
		}
		goto done;
	}
	switch(vtype) {
		case DB1_INT:
			if(!bson_append_int32(doc, _k->s, _k->len,
						VAL_INT(_v))) {
				LM_ERR("failed to append int to bson doc %.*s = %d [%d]\n",
						_k->len, _k->s, VAL_INT(_v), idx);
				goto error;
			}
			break;

		case DB1_BIGINT:
			if(!bson_append_int64(doc, _k->s, _k->len,
						VAL_BIGINT(_v ))) {
				LM_ERR("failed to append bigint to bson doc %.*s = %lld [%d]\n",
						_k->len, _k->s, VAL_BIGINT(_v), idx);
				goto error;
			}
			return -1;

		case DB1_DOUBLE:
			if(!bson_append_double(doc, _k->s, _k->len,
						VAL_DOUBLE(_v))) {
				LM_ERR("failed to append double to bson doc %.*s = %f [%d]\n",
						_k->len, _k->s, VAL_DOUBLE(_v), idx);
				goto error;
			}
			break;

		case DB1_STRING:
			if(!bson_append_utf8(doc, _k->s, _k->len,
						VAL_STRING(_v), strlen(VAL_STRING(_v))) ) {
				LM_ERR("failed to append string to bson doc %.*s = %s [%d]\n",
						_k->len, _k->s, VAL_STRING(_v), idx);
				goto error;
			}
			break;

		case DB1_STR:

			if(!bson_append_utf8(doc, _k->s, _k->len,
						VAL_STR(_v).s, VAL_STR(_v).len) ) {
				LM_ERR("failed to append str to bson doc %.*s = %.*s [%d]\n",
						_k->len, _k->s, VAL_STR(_v).len, VAL_STR(_v).s, idx);
				goto error;
			}
			break;

		case DB1_DATETIME:
			if(!bson_append_time_t(doc, _k->s, _k->len,
						VAL_TIME(_v))) {
				LM_ERR("failed to append time to bson doc %.*s = %ld [%d]\n",
						_k->len, _k->s, VAL_TIME(_v), idx);
				goto error;
			}
			break;

		case DB1_BLOB:
			if(!bson_append_binary(doc, _k->s, _k->len,
						BSON_SUBTYPE_BINARY,
						(const uint8_t *)VAL_BLOB(_v).s, VAL_BLOB(_v).len) ) {
				LM_ERR("failed to append blob to bson doc %.*s = [bin] [%d]\n",
						_k->len, _k->s, idx);
				goto error;
			}
			break;

		case DB1_BITMAP:
			if(!bson_append_int32(doc, _k->s, _k->len,
						VAL_INT(_v))) {
				LM_ERR("failed to append bitmap to bson doc %.*s = %d [%d]\n",
						_k->len, _k->s, VAL_INT(_v), idx);
				goto error;
			}
			break;

		default:
			LM_ERR("val type [%d] not supported\n", vtype);
			return -1;
	}

done:
	return 0;
error:
	return -1;
}
예제 #28
0
/* select data from emergency_service_prvider for put in xml to VPC
* coluns key: attribution and nodeIP.
* coluns attributs: OrganizationName, hostId, nenaId, contact, certUri. 
*/
int get_db_provider(str table_name, rw_lock_t *ref_lock ){
    db_key_t query_cols[] = {&id_col, &organizationName_col, &hostId_col, &nenaId_col, &contact_col, &certUri_col, &nodeIP_col, &attribution_col};
    db_res_t * res;
    db_val_t * values;
    db_row_t * rows;
    str OrganizationName;
    str hostId;
    str nenaId;
    str contact;
    str certUri;
    str nodeIP;
    int attribution;
    int nr_rows, i, size, id;
    struct service_provider *provider_cell, *old_list, *it, *aux, *new_list;
    struct service_provider *init_provider = NULL;

    db_funcs.use_table(db_con, &table_name);

    if (db_funcs.query(db_con, 0, 0, 0, query_cols, 0, 8, 0, &res) != 0) {
        LM_ERR("Failure to issue query\n");
        return -1;
    }

    nr_rows = RES_ROW_N(res);
    rows = RES_ROWS(res);
    new_list = NULL;
    LM_DBG("NUMBER OF LINES %d \n", nr_rows);

    for (i = 0; i < nr_rows; i++) {
        values = ROW_VALUES(rows + i);

        if (VAL_NULL(values) ||
                (VAL_TYPE(values) != DB_INT)) {
            LM_ERR("Invalid value returned 1\n");
            goto end;
        }

        id = VAL_INT(values);

        if (VAL_NULL(values + 1) ||
                (VAL_TYPE(values + 1) != DB_STR && VAL_TYPE(values + 1) != DB_STRING)) {
            LM_ERR("Invalid translated returned 2\n");
            goto end;
        }

        if (VAL_TYPE(values + 1) == DB_STR) {
            OrganizationName = VAL_STR(values + 1);
        } else {
            OrganizationName.s = (char*) VAL_STRING(values + 1);
            OrganizationName.len = strlen(OrganizationName.s);
        }

        if (VAL_NULL(values + 2) ||
                (VAL_TYPE(values + 2) != DB_STR && VAL_TYPE(values + 2) != DB_STRING)) {
            LM_ERR("Invalid translated returned 2\n");
            goto end;
        }

        if (VAL_TYPE(values + 2) == DB_STR) {
            hostId = VAL_STR(values + 2);
        } else {
            hostId.s = (char*) VAL_STRING(values + 2);
            hostId.len = strlen(hostId.s);
        }

        if (VAL_NULL(values + 3) ||
                (VAL_TYPE(values + 3) != DB_STR && VAL_TYPE(values + 3) != DB_STRING)) {
            LM_ERR("Invalid translated returned 3\n");
            goto end;
        }

        if (VAL_TYPE(values + 3) == DB_STR) {
            nenaId = VAL_STR(values + 3);
        } else {
            nenaId.s = (char*) VAL_STRING(values + 3);
            nenaId.len = strlen(nenaId.s);
        }

        if (VAL_NULL(values + 4) ||
                (VAL_TYPE(values + 4) != DB_STR && VAL_TYPE(values + 4) != DB_STRING)) {
            LM_ERR("Invalid translated returned 4\n");
            goto end;
        }

        if (VAL_TYPE(values + 4) == DB_STR) {
            contact = VAL_STR(values + 4);
        } else {
            contact.s = (char*) VAL_STRING(values + 4);
            contact.len = strlen(contact.s);
        }        

        if (VAL_NULL(values + 5) ||
                (VAL_TYPE(values + 5) != DB_STR && VAL_TYPE(values + 5) != DB_STRING)) {
            LM_ERR("Invalid translated returned 3\n");
            goto end;
        }

        if (VAL_TYPE(values + 5) == DB_STR) {
            certUri = VAL_STR(values + 5);
        } else {
            certUri.s = (char*) VAL_STRING(values + 5);
            certUri.len = strlen(certUri.s);
        }

        if (VAL_NULL(values + 6) ||
                (VAL_TYPE(values + 6) != DB_STR && VAL_TYPE(values + 6) != DB_STRING)) {
            LM_ERR("Invalid translated returned 6\n");
            goto end;
        }

        if (VAL_TYPE(values + 6) == DB_STR) {
            nodeIP = VAL_STR(values + 6);
        } else {
            nodeIP.s = (char*) VAL_STRING(values + 6);
            nodeIP.len = strlen(nodeIP.s);
        } 

        if (VAL_NULL(values + 7) ||
                (VAL_TYPE(values + 7) != DB_INT)) {
            LM_ERR("Invalid translated returned 7\n");
            goto end;
        }
        attribution = VAL_INT(values + 7);

        if (attribution == 0){
            if (hostId.len == 0 || contact.len == 0) {
                LM_ERR("source_hostname and source_contact are mandatory \n");
                mandatory_parm[0] = '1';
                mandatory_parm[1] = 0;
            } else{
                mandatory_parm[0] = '0';
                mandatory_parm[1] = 0;                
            }
        }       

        size = sizeof (struct service_provider)+ nodeIP.len + OrganizationName.len + hostId.len + nenaId.len + contact.len + certUri.len;
        provider_cell = shm_malloc(size);
        if (!provider_cell) {
            LM_ERR("no more shm\n");
            goto end;
        }

        memset(provider_cell, 0, size);

        provider_cell->nodeIP.len = nodeIP.len;
        provider_cell->nodeIP.s = (char *) (provider_cell + 1);
        memcpy(provider_cell->nodeIP.s, nodeIP.s, nodeIP.len);

        provider_cell->OrganizationName.len = OrganizationName.len;
        provider_cell->OrganizationName.s = (char *) (provider_cell + 1) + nodeIP.len;
        memcpy(provider_cell->OrganizationName.s, OrganizationName.s, OrganizationName.len);

        provider_cell->hostId.len = hostId.len;
        provider_cell->hostId.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len;
        memcpy(provider_cell->hostId.s, hostId.s, hostId.len); 

        provider_cell->nenaId.len = nenaId.len;
        provider_cell->nenaId.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len + hostId.len;
        memcpy(provider_cell->nenaId.s, nenaId.s, nenaId.len);

        provider_cell->contact.len = contact.len;
        provider_cell->contact.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len + hostId.len + nenaId.len;
        memcpy(provider_cell->contact.s, contact.s, contact.len);  

        provider_cell->certUri.len = certUri.len;
        provider_cell->certUri.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len + hostId.len + nenaId.len + contact.len;
        memcpy(provider_cell->certUri.s, certUri.s, certUri.len); 

        provider_cell->attribution = attribution;             
   
        if (new_list != NULL) {
            new_list->next = provider_cell;
            new_list = provider_cell;
        } else {
            new_list = provider_cell;
            init_provider = new_list;
        }       
    }
    
    new_list = init_provider;

    lock_start_write(ref_lock);
    old_list = *db_service_provider;
    *db_service_provider = init_provider;
    lock_stop_write(ref_lock);

    it = old_list;
    while (it) {
        aux = it;
        it = it->next;
        shm_free(aux);
    }

end:
    db_funcs.free_result(db_con, res);

    return 1;
}
예제 #29
0
/*
 * Add key-op-value to a bson filter document
 */
int db_mongodb_bson_filter_add(bson_t *doc, const db_key_t* _k, const db_op_t* _op,
		const db_val_t* _v, int idx)
{
	bson_t mdoc;
	db_key_t tkey;
	const db_val_t *tval;
	int vtype;
	str ocmp;

	tkey = _k[idx];
	tval = _v + idx;
	vtype = VAL_TYPE(tval);

	/* OP_EQ is handled separately */
	if(!strcmp(_op[idx], OP_LT)) {
		ocmp.s = "$lt";
		ocmp.len = 3;
	} else if(!strcmp(_op[idx], OP_LEQ)) {
		ocmp.s = "$lte";
		ocmp.len = 4;
	} else if(!strcmp(_op[idx], OP_GT)) {
		ocmp.s = "$gt";
		ocmp.len = 3;
	} else if(!strcmp(_op[idx], OP_GEQ)) {
		ocmp.s = "$gte";
		ocmp.len = 4;
	} else if(!strcmp(_op[idx], OP_NEQ)
			|| !strcmp(_op[idx], "!=")) {
		ocmp.s = "$ne";
		ocmp.len = 3;
	} else {
		LM_ERR("unsuported match operator: %s\n", _op[idx]);
		goto error;
	}

	if(!bson_append_document_begin(doc, tkey->s, tkey->len, &mdoc)) {
		LM_ERR("failed to append start to bson doc %.*s %s ... [%d]\n",
					tkey->len, tkey->s, ocmp.s, idx);
		goto error;
	}

	if(VAL_NULL(tval)) {
		if(!bson_append_null(&mdoc, ocmp.s, ocmp.len)) {
			LM_ERR("failed to append null to bson doc %.*s %s null [%d]\n",
					tkey->len, tkey->s, ocmp.s, idx);
			goto error;
		}
		goto done;
	}
	switch(vtype) {
		case DB1_INT:
			if(!bson_append_int32(&mdoc, ocmp.s, ocmp.len,
						VAL_INT(tval))) {
				LM_ERR("failed to append int to bson doc %.*s %s %d [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_INT(tval), idx);
				goto error;
			}
			break;

		case DB1_BIGINT:
			if(!bson_append_int64(&mdoc, ocmp.s, ocmp.len,
						VAL_BIGINT(tval ))) {
				LM_ERR("failed to append bigint to bson doc %.*s %s %lld [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_BIGINT(tval), idx);
				goto error;
			}
			return -1;

		case DB1_DOUBLE:
			if(!bson_append_double(&mdoc, ocmp.s, ocmp.len,
						VAL_DOUBLE(tval))) {
				LM_ERR("failed to append double to bson doc %.*s %s %f [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_DOUBLE(tval), idx);
				goto error;
			}
			break;

		case DB1_STRING:
			if(!bson_append_utf8(&mdoc, ocmp.s, ocmp.len,
						VAL_STRING(tval), strlen(VAL_STRING(tval))) ) {
				LM_ERR("failed to append string to bson doc %.*s %s %s [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_STRING(tval), idx);
				goto error;
			}
			break;

		case DB1_STR:

			if(!bson_append_utf8(&mdoc, ocmp.s, ocmp.len,
						VAL_STR(tval).s, VAL_STR(tval).len) ) {
				LM_ERR("failed to append str to bson doc %.*s %s %.*s [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_STR(tval).len, VAL_STR(tval).s, idx);
				goto error;
			}
			break;

		case DB1_DATETIME:
			if(!bson_append_time_t(&mdoc, ocmp.s, ocmp.len,
						VAL_TIME(tval))) {
				LM_ERR("failed to append time to bson doc %.*s %s %ld [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_TIME(tval), idx);
				goto error;
			}
			break;

		case DB1_BLOB:
			if(!bson_append_binary(&mdoc, ocmp.s, ocmp.len,
						BSON_SUBTYPE_BINARY,
						(const uint8_t *)VAL_BLOB(tval).s, VAL_BLOB(tval).len) ) {
				LM_ERR("failed to append blob to bson doc %.*s %s [bin] [%d]\n",
						tkey->len, tkey->s, ocmp.s, idx);
				goto error;
			}
			break;

		case DB1_BITMAP:
			if(!bson_append_int32(&mdoc, ocmp.s, ocmp.len,
						VAL_INT(tval))) {
				LM_ERR("failed to append bitmap to bson doc %.*s %s %d [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_INT(tval), idx);
				goto error;
			}
			break;

		default:
			LM_ERR("val type [%d] not supported\n", vtype);
			goto error;
	}

done:
	if(!bson_append_document_end(doc, &mdoc)) {
		LM_ERR("failed to append end to bson doc %.*s %s ... [%d]\n",
					tkey->len, tkey->s, ocmp.s, idx);
		goto error;
	}
	return 0;
error:
	return -1;
}
예제 #30
0
int fetch_credentials(sip_msg_t *msg, str *user, str* domain, str *table, int flags)
{
	pv_elem_t *cred;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t *col;
	db1_res_t *res = NULL;

	int n, nc;

	if(flags&AUTH_DB_SUBS_SKIP_CREDENTIALS) {
		nc = 1;
	} else {
		nc = credentials_n;
	}
	col = pkg_malloc(sizeof(*col) * (nc+1));
	if (col == NULL) {
		LM_ERR("no more pkg memory\n");
		return -1;
	}

	keys[0] = &user_column;
	keys[1] = &domain_column;

	if(flags&AUTH_DB_SUBS_SKIP_CREDENTIALS) {
		col[0] = &user_column;
	} else {
		for (n = 0, cred=credentials; cred ; n++, cred=cred->next) {
			col[n] = &cred->text;
		}
	}

	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB1_STR;
	VAL_NULL(vals) = VAL_NULL(vals + 1) = 0;

	n = 1;
	VAL_STR(vals) = *user;

	if (domain && domain->len) {
		VAL_STR(vals + 1) = *domain;
		n = 2;
	}

	if (auth_dbf.use_table(auth_db_handle, table) < 0) {
		LM_ERR("failed to use_table\n");
		pkg_free(col);
		return -1;
	}

	if (auth_dbf.query(auth_db_handle, keys, 0, vals, col, n, nc, 0, &res) < 0) {
		LM_ERR("failed to query database\n");
		pkg_free(col);
		if(res)
			auth_dbf.free_result(auth_db_handle, res);
		return -1;
	}
	pkg_free(col);
	if (RES_ROW_N(res) == 0) {
		if(res)
			auth_dbf.free_result(auth_db_handle, res);
		LM_DBG("no result for user \'%.*s%s%.*s\' in [%.*s]\n",
				user->len, user->s, (n==2)?"@":"",
				(n==2)?domain->len:0, (n==2)?domain->s:"",
				table->len, table->s);
		return -2;
	}
	if(flags&AUTH_DB_SUBS_SKIP_CREDENTIALS) {
		/* there is a result and flag to skip loading credentials is set */
		goto done;
	}
	for (cred=credentials, n=0; cred; cred=cred->next, n++) {
		if (db_val2pv_spec(msg, &RES_ROWS(res)[0].values[n], cred->spec) != 0) {
			if(res)
				auth_dbf.free_result(auth_db_handle, res);
			LM_ERR("Failed to convert value for column %.*s\n",
					RES_NAMES(res)[n]->len, RES_NAMES(res)[n]->s);
			return -3;
		}
	}

done:
	if(res)
		auth_dbf.free_result(auth_db_handle, res);
	return 0;
}