udomain.c

来自「性能优秀的SIP Proxy」· C语言 代码 · 共 816 行 · 第 1/2 页

C
816
字号
	}	if (ul_dbf.query(_c, 0, 0, 0, columns, 0, (use_domain) ? (14) : (13), 0,				&res) < 0) {		LOG(L_ERR, "preload_udomain(): Error while doing db_query\n");		return -1;	}	if (RES_ROW_N(res) == 0) {		DBG("preload_udomain(): Table is empty\n");		ul_dbf.free_result(_c, res);		return 0;	}	lock_udomain(_d);	for(i = 0; i < RES_ROW_N(res); i++) {		row = RES_ROWS(res) + i;		user.s = (char*)VAL_STRING(ROW_VALUES(row));		if (VAL_NULL(ROW_VALUES(row)) || user.s==0 || user.s[0]==0) {			LOG(L_CRIT, "ERROR:usrloc:preload_udomain: empty username "				"record in table %s...skipping\n",_d->name->s);			continue;		}		user.len = strlen(user.s);		ci = dbrow2info( ROW_VALUES(row)+1, &contact);		if (ci==0) {			LOG(L_ERR, "ERROR:usrloc:preload_udomain: skipping record for "				"%.*s in table %s\n", user.len, user.s, _d->name->s);			continue;		}		if (use_domain) {			domain = (char*)VAL_STRING(ROW_VALUES(row) + 13);			if (VAL_NULL(ROW_VALUES(row)+12) || domain==0 || domain[0]==0) {				LOG(L_CRIT, "ERROR:usrloc:preload_udomain: empty domain "				"record for user %.*s...skipping\n", user.len, user.s);				continue;			}			/* user.s cannot be NULL - checked previosly */			user.len = snprintf(uri, MAX_URI_SIZE, "%.*s@%s",				user.len, user.s, domain);			user.s = uri;			if (user.s[user.len]!=0) {				LOG(L_CRIT,"ERROR:usrloc:preload_udomain: URI '%.*s@%s' "					"longer than %d\n", user.len, user.s, domain,MAX_URI_SIZE);				continue;			}		}				if (get_urecord(_d, &user, &r) > 0) {			if (mem_insert_urecord(_d, &user, &r) < 0) {				LOG(L_ERR, "preload_udomain(): Can't create a record\n");				goto error;			}		}		if ( (c=mem_insert_ucontact(r, &contact, ci)) < 0) {			LOG(L_ERR, "preload_udomain(): Error while inserting contact\n");			goto error1;		}		/* We have to do this, because insert_ucontact sets state to CS_NEW		 * and we have the contact in the database already */		c->state = CS_SYNC;	}	ul_dbf.free_result(_c, res);	unlock_udomain(_d);	return 0;error1:	free_ucontact(c);error:	ul_dbf.free_result(_c, res);	unlock_udomain(_d);	return -1;}/* * loads from DB all contacts for an AOR */urecord_t* db_load_urecord(db_con_t* _c, udomain_t* _d, str *_aor){	ucontact_info_t *ci;	db_key_t columns[12];	db_key_t keys[2];	db_val_t vals[2];	db_res_t* res;	str contact;	char *domain;	int i;	urecord_t* r;	ucontact_t* c;	keys[0] = user_col.s;	vals[0].type = DB_STR;	vals[0].nul = 0;	if (use_domain) {		keys[1] = domain_col.s;		vals[1].type = DB_STR;		vals[1].nul = 0;		domain = q_memchr(_aor->s, '@', _aor->len);		if (domain==0) {			LOG(L_CRIT,"BUG:usrloc:db_load_urecord: AOR has no @ while "				"use_domain is enabled\n");			return 0;		}		vals[0].val.str_val.s   = _aor->s;		vals[0].val.str_val.len = domain - _aor->s;		vals[1].val.str_val.s   = domain+1;		vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1;	} else {		vals[0].val.str_val = *_aor;	}	columns[0] = contact_col.s;	columns[1] = expires_col.s;	columns[2] = q_col.s;	columns[3] = callid_col.s;	columns[4] = cseq_col.s;	columns[5] = flags_col.s;	columns[6] = user_agent_col.s;	columns[7] = received_col.s;	columns[8] = path_col.s;	columns[9] = sock_col.s;	columns[10] = methods_col.s;	columns[11] = last_mod_col.s;	if (ul_dbf.use_table(_c, _d->name->s) < 0) {		LOG(L_ERR, "ERROR:usrloc:db_load_urecord: failed to use_table\n");		return 0;	}	if (ul_dbf.query(_c, keys, 0, vals, columns, (use_domain)?2:1, 12, 0,				&res) < 0) {		LOG(L_ERR, "ERROR:usrloc:db_load_urecord: db_query failed\n");		return 0;	}	if (RES_ROW_N(res) == 0) {		DBG("DEBUG:usrloc:db_load_urecord: aor not found in DB\n");		ul_dbf.free_result(_c, res);		return 0;	}	r = 0;	for(i = 0; i < RES_ROW_N(res); i++) {		ci = dbrow2info(  ROW_VALUES(RES_ROWS(res) + i), &contact);		if (ci==0) {			LOG(L_ERR, "ERROR:usrloc:db_load_urecord: skipping record for "				"%.*s in table %s\n", _aor->len, _aor->s, _d->name->s);			continue;		}				if ( r==0 )			get_static_urecord( _d, _aor, &r);		if ( (c=mem_insert_ucontact(r, &contact, ci)) < 0) {			LOG(L_ERR, "ERROR:usrloc:db_load_urecord: mem_insert failed\n");			free_urecord(r);			ul_dbf.free_result(_c, res);			return 0;		}		/* We have to do this, because insert_ucontact sets state to CS_NEW		 * and we have the contact in the database already */		c->state = CS_SYNC;	}	ul_dbf.free_result(_c, res);	return r;}int db_timer_udomain(udomain_t* _d){	db_key_t keys[1];	db_op_t  ops[1];	db_val_t vals[1];	keys[0] = expires_col.s;	ops[0] = "<";	vals[0].type = DB_DATETIME;	vals[0].nul = 0;	vals[0].val.time_val = act_time + 1;	if (ul_dbf.use_table(ul_dbh, _d->name->s) < 0) {		LOG(L_ERR, "ERROR:usrloc: db_timer_udomain: use_table failed\n");		return -1;	}	if (ul_dbf.delete(ul_dbh, keys, ops, vals, 1) < 0) {		LOG(L_ERR, "ERROR:usrloc:db_timer_udomain: failed to delete from "			"table %s\n",_d->name->s);		return -1;	}	return 0;}/* performs a dummy query just to see if DB is ok */int testdb_udomain(db_con_t* con, udomain_t* d){	db_key_t key[1], col[1];	db_val_t val[1];	db_res_t* res;	if (ul_dbf.use_table(con, d->name->s) < 0) {		LOG(L_ERR, "ERROR:usrloc:testdb_udomain: failed to change table\n");		return -1;	}	key[0] = user_col.s;	col[0] = user_col.s;	VAL_TYPE(val) = DB_STRING;	VAL_NULL(val) = 0;	VAL_STRING(val) = "dummy_user";		if (ul_dbf.query( con, key, 0, val, col, 1, 1, 0, &res) < 0) {		LOG(L_ERR, "ERROR:usrloc:testdb_udomain: failure in db_query\n");		return -1;	}	ul_dbf.free_result( con, res);	return 0;}/* * Insert a new record into domain */int mem_insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r){	int sl;		if (new_urecord(_d->name, _aor, _r) < 0) {		LOG(L_ERR, "insert_urecord(): Error while creating urecord\n");		return -1;	}	sl = hash_func(_d, (unsigned char*)_aor->s, _aor->len);	slot_add(&_d->table[sl], *_r);	udomain_add(_d, *_r);	update_stat( _d->users, 1);	return 0;}/* * Remove a record from domain */void mem_delete_urecord(udomain_t* _d, struct urecord* _r){	if (_r->watchers == 0) {		udomain_remove(_d, _r);		slot_rem(_r->slot, _r);		free_urecord(_r);		update_stat( _d->users, -1);	}}int mem_timer_udomain(udomain_t* _d){	struct urecord* ptr, *t;	lock_udomain(_d);	ptr = _d->d_ll.first;	while(ptr) {		if (timer_urecord(ptr) < 0) {			LOG(L_ERR, "timer_udomain(): Error in timer_urecord\n");			unlock_udomain(_d);			return -1;		}				/* Remove the entire record if it is empty */		if (ptr->contacts == 0) {			t = ptr;			ptr = ptr->d_ll.next;			mem_delete_urecord(_d, t);		} else {			ptr = ptr->d_ll.next;		}	}		unlock_udomain(_d);	return 0;}/* * Get lock */void lock_udomain(udomain_t* _d){	if (db_mode!=DB_ONLY)		lock_get(&_d->lock);}/* * Release lock */void unlock_udomain(udomain_t* _d){	if (db_mode!=DB_ONLY)		lock_release(&_d->lock);}/* * Create and insert a new record */int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r){	if (db_mode!=DB_ONLY) {		if (mem_insert_urecord(_d, _aor, _r) < 0) {			LOG(L_ERR, "insert_urecord(): Error while inserting record\n");			return -1;		}	} else {		get_static_urecord( _d, _aor, _r);	}	return 0;}/* * Obtain a urecord pointer if the urecord exists in domain */int get_urecord(udomain_t* _d, str* _aor, struct urecord** _r){	int sl, i;	urecord_t* r;	if (db_mode!=DB_ONLY) {		/* search in cache */		sl = hash_func(_d, (unsigned char*)_aor->s, _aor->len);		r = _d->table[sl].first;		for(i = 0; i < _d->table[sl].n; i++) {			if((r->aor.len==_aor->len) && !memcmp(r->aor.s,_aor->s,_aor->len)){				*_r = r;				return 0;			}			r = r->s_ll.next;		}	} else {		/* search in DB */		r = db_load_urecord( ul_dbh, _d, _aor);		if (r) {			*_r = r;			return 0;		}	}	return 1;   /* Nothing found */}/* * Delete a urecord from domain */int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r){	struct ucontact* c, *t;	if (db_mode==DB_ONLY) {		if (_r==0)			get_static_urecord( _d, _aor, &_r);		if (db_delete_urecord(_r)<0) {			LOG(L_ERR, "ERROR:usrloc:delete_urecord: DB delete failed\n");			return -1;		}		free_urecord(_r);		return 0;	}	if (_r==0) {		if (get_urecord(_d, _aor, &_r) > 0) {			return 0;		}	}	c = _r->contacts;	while(c) {		t = c;		c = c->next;		if (delete_ucontact(_r, t) < 0) {			LOG(L_ERR, "delete_urecord(): Error while deleting contact\n");			return -1;		}	}	release_urecord(_r);	return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?