/*
* $Id: domain.c 1506 2007-01-15 10:22:40Z bogdan_iancu $
*
* Domain table related functions
*
* Copyright (C) 2002-2003 Juha Heinanen
*
* This file is part of openser, a free SIP server.
*
* openser is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* openser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* History:
* --------
* 2004-06-07 updated to the new DB api, moved reload_table here, created
* domain_db_{init.bind,ver,close} (andrei)
* 2004-09-06 is_uri_host_local() can now be called also from
* failure route (juhe)
*/
#include "domain_mod.h"
#include "hash.h"
#include "../../db/db.h"
#include "../../parser/parse_uri.h"
#include "../../parser/parse_from.h"
#include "../../ut.h"
#include "../../dset.h"
#include "../../route.h"
#include "../../items.h"
static db_con_t* db_handle=0;
static db_func_t domain_dbf;
/* helper db functions*/
int domain_db_bind(char* db_url)
{
if (bind_dbmod(db_url, &domain_dbf )) {
LOG(L_CRIT, "ERROR: domain_db_bind: cannot bind to database module! "
"Did you forget to load a database module ?\n");
return -1;
}
return 0;
}
int domain_db_init(char* db_url)
{
if (domain_dbf.init==0){
LOG(L_CRIT, "BUG: domain_db_init: unbound database module\n");
goto error;
}
db_handle=domain_dbf.init(db_url);
if (db_handle==0){
LOG(L_CRIT, "ERROR:domain_db_init: cannot initialize database "
"connection\n");
goto error;
}
return 0;
error:
return -1;
}
void domain_db_close()
{
if (db_handle && domain_dbf.close){
domain_dbf.close(db_handle);
db_handle=0;
}
}
int domain_db_ver(str* name)
{
int ver;
if (db_handle==0){
LOG(L_CRIT, "BUG:domain_db_ver: null database handler\n");
return -1;
}
ver=table_version(&domain_dbf, db_handle, name);
return ver;
}
/*
* Check if domain is local
*/
int is_domain_local(str* _host)
{
if (db_mode == 0) {
db_key_t keys[1];
db_val_t vals[1];
db_key_t cols[1];
db_res_t* res = NULL;
keys[0]=domain_col.s;
cols[0]=domain_col.s;
if (domain_dbf.use_table(db_handle, domain_table.s) < 0) {
LOG(L_ERR, "is_local(): Error while trying to use domain table\n");
return -1;
}
VAL_TYPE(vals) = DB_STR;
VAL_NULL(vals) = 0;
VAL_STR(vals).s = _host->s;
VAL_STR(vals).len = _host->len;
if (domain_dbf.query(db_handle, keys, 0, vals, cols, 1, 1, 0, &res) < 0
) {
LOG(L_ERR, "is_local(): Error while querying database\n");
return -1;
}
if (RES_ROW_N(res) == 0) {
DBG("is_local(): Realm '%.*s' is not local\n",
_host->len, ZSW(_host->s));
domain_dbf.free_result(db_handle, res);
return -1;
} else {
DBG("is_local(): Realm '%.*s' is local\n",
_host->len, ZSW(_host->s));
domain_dbf.free_result(db_handle, res);
return 1;
}
} else {
return hash_table_lookup (_host);
}
}
/*
* Check if host in From uri is local
*/
int is_from_local(struct sip_msg* _msg, char* _s1, char* _s2)
{
struct sip_uri *puri;
if ((puri=parse_from_uri(_msg))==NULL) {
LOG(L_ERR, "is_from_local(): Error while parsing From header\n");
return -2;
}
return is_domain_local(&(puri->host));
}
/*
* Check if host in Request URI is local
*/
int is_uri_host_local(struct sip_msg* _msg, char* _s1, char* _s2)
{
str branch;
qvalue_t q;
struct sip_uri puri;
if ((route_type == REQUEST_ROUTE) || (route_type == BRANCH_ROUTE)
|| (route_type == FAILURE_ROUTE)) {
if (parse_sip_msg_uri(_msg) < 0) {
LOG(L_ERR, "is_uri_host_local(): Error while parsing R-URI\n");
return -1;
}
return is_domain_local(&(_msg->parsed_uri.host));
} else if (route_type == FAILURE_ROUTE) {
branch.s = get_branch(0, &branch.len, &q, 0, 0, 0, 0);
if (branch.s) {
if (parse_uri(branch.s, branch.len, &puri) < 0) {
LOG(L_ERR, "is_uri_host_local():"
" Error while parsing branch URI\n");
return -1;
}
return is_domain_local(&(puri.host));
} else {
LOG(L_ERR, "is_uri_host_local(): Branch is missing, "
" error in script\n");
return -1;
}
} else {
LOG(L_ERR, "is_uri_host_local(): Unsupported route type\n");
return -1;
}
}
/*
* Check if domain given as value of pseudo variable parameter is local
*/
int w_is_domain_local(struct sip_msg* _msg, char* _sp, char* _s2)
{
xl_spec_t *sp;
xl_value_t xl_val;
sp = (xl_spec_t *)_sp;
if (sp && (xl_get_spec_value(_msg, sp, &xl_val, 0) == 0)) {
if (xl_val.flags & XL_VAL_STR) {
if (xl_val.rs.len == 0 || xl_val.rs.s == NULL) {
DBG("domain:w_is_domain_local(): Missing domain name\n");
return -1;
}
return is_domain_local(&(xl_val.rs));
} else {
DBG("domain:w_is_domain_local(): pseudo variable value is "
"not string\n");
return -1;
}
} else {
DBG("domain:w_is_domain_local(): cannot get pseudo variable value\n");
return -1;
}
}
/*
* Reload domain table to new hash table and when done, make new hash table
* current one.
*/
int reload_domain_table ( void )
{
db_val_t vals[1];
db_key_t cols[1];
db_res_t* res = NULL;
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;
}
syntax highlighted by Code2HTML, v. 0.9.1