domain.c

Go to the documentation of this file.
00001 /* 
00002  * $Id: domain.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * Domain table related functions
00005  *
00006  * Copyright (C) 2002-2003 Juha Heinanen
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * --------
00026  *  2004-06-07  updated to the new DB api, moved reload_table here, created 
00027  *               domain_db_{init.bind,ver,close} (andrei)
00028  *  2004-09-06  is_uri_host_local() can now be called also from
00029  *              failure route (juhe)
00030  */
00031 
00032 #include "domain_mod.h"
00033 #include "hash.h"
00034 #include "../../db/db.h"
00035 #include "../../parser/parse_uri.h"
00036 #include "../../parser/parse_from.h"
00037 #include "../../ut.h"
00038 #include "../../dset.h"
00039 #include "../../route.h"
00040 #include "../../pvar.h"
00041 #include "../../str.h"
00042 
00043 static db_con_t* db_handle=0;
00044 static db_func_t domain_dbf;
00045 
00046 /* helper db functions*/
00047 
00048 int domain_db_bind(const str* db_url)
00049 {
00050    if (db_bind_mod(db_url, &domain_dbf )) {
00051            LM_ERR("Cannot bind to database module!");
00052       return -1;
00053    }
00054    return 0;
00055 }
00056 
00057 
00058 
00059 int domain_db_init(const str* db_url)
00060 {  
00061    if (domain_dbf.init==0){
00062       LM_ERR("Unbound database module\n");
00063       goto error;
00064    }
00065    db_handle=domain_dbf.init(db_url);
00066    if (db_handle==0){
00067       LM_ERR("Cannot initialize database connection\n");
00068       goto error;
00069    }
00070    return 0;
00071 error:
00072    return -1;
00073 }
00074 
00075 
00076 void domain_db_close(void)
00077 {
00078    if (db_handle && domain_dbf.close){
00079       domain_dbf.close(db_handle);
00080       db_handle=0;
00081    }
00082 }
00083 
00084 
00085 
00086 int domain_db_ver(str* name, int version)
00087 {
00088    if (db_handle==0){
00089       LM_ERR("null database handler\n");
00090       return -1;
00091    }
00092    return db_check_table_version(&domain_dbf, db_handle, name, version);
00093 }
00094 
00095 
00096 
00097 /*
00098  * Check if domain is local
00099  */
00100 int is_domain_local(str* _host)
00101 {
00102    if (db_mode == 0) {
00103       db_key_t keys[1];
00104       db_val_t vals[1];
00105       db_key_t cols[1]; 
00106       db_res_t* res = NULL;
00107 
00108       keys[0] = &domain_col;
00109       cols[0] = &domain_col;
00110       
00111       if (domain_dbf.use_table(db_handle, &domain_table) < 0) {
00112          LM_ERR("Error while trying to use domain table\n");
00113          return -1;
00114       }
00115 
00116       VAL_TYPE(vals) = DB_STR;
00117       VAL_NULL(vals) = 0;
00118       
00119       VAL_STR(vals).s = _host->s;
00120       VAL_STR(vals).len = _host->len;
00121 
00122       if (domain_dbf.query(db_handle, keys, 0, vals, cols, 1, 1, 0, &res) < 0
00123             ) {
00124          LM_ERR("Error while querying database\n");
00125          return -1;
00126       }
00127 
00128       if (RES_ROW_N(res) == 0) {
00129          LM_DBG("Realm '%.*s' is not local\n", 
00130                 _host->len, ZSW(_host->s));
00131          domain_dbf.free_result(db_handle, res);
00132          return -1;
00133       } else {
00134          LM_DBG("Realm '%.*s' is local\n", 
00135                 _host->len, ZSW(_host->s));
00136          domain_dbf.free_result(db_handle, res);
00137          return 1;
00138       }
00139    } else {
00140       return hash_table_lookup (_host);
00141    }
00142          
00143 }
00144 
00145 /*
00146  * Check if host in From uri is local
00147  */
00148 int is_from_local(struct sip_msg* _msg, char* _s1, char* _s2)
00149 {
00150    struct sip_uri *puri;
00151 
00152    if ((puri=parse_from_uri(_msg))==NULL) {
00153       LM_ERR("Error while parsing From header\n");
00154       return -2;
00155    }
00156 
00157    return is_domain_local(&(puri->host));
00158 
00159 }
00160 
00161 /*
00162  * Check if host in Request URI is local
00163  */
00164 int is_uri_host_local(struct sip_msg* _msg, char* _s1, char* _s2)
00165 {
00166    str branch;
00167    qvalue_t q;
00168    struct sip_uri puri;
00169 
00170    if ( route_type&(REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE) ) {
00171       if (parse_sip_msg_uri(_msg) < 0) {
00172          LM_ERR("Error while parsing R-URI\n");
00173          return -1;
00174       }
00175       return is_domain_local(&(_msg->parsed_uri.host));
00176    } else if (route_type == FAILURE_ROUTE) {
00177          branch.s = get_branch(0, &branch.len, &q, 0, 0, 0, 0);
00178          if (branch.s) {
00179             if (parse_uri(branch.s, branch.len, &puri) < 0) {
00180                LM_ERR("Error while parsing branch URI\n");
00181                return -1;
00182             }
00183             return is_domain_local(&(puri.host));
00184          } else {
00185             LM_ERR("Branch is missing, error in script\n");
00186             return -1;
00187          }
00188    } else {
00189       LM_ERR("Unsupported route type\n");
00190       return -1;
00191    }
00192 }
00193 
00194 
00195 /*
00196  * Check if domain given as value of pseudo variable parameter is local
00197  */
00198 int w_is_domain_local(struct sip_msg* _msg, char* _sp, char* _s2)
00199 {
00200     pv_spec_t *sp;
00201     pv_value_t pv_val;
00202 
00203     sp = (pv_spec_t *)_sp;
00204 
00205     if (sp && (pv_get_spec_value(_msg, sp, &pv_val) == 0)) {
00206    if (pv_val.flags & PV_VAL_STR) {
00207        if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
00208       LM_DBG("Missing domain name\n");
00209       return -1;
00210        }
00211        return is_domain_local(&(pv_val.rs));
00212    } else {
00213       LM_DBG("Pseudo variable value is not string\n");
00214       return -1;
00215    }
00216     } else {
00217    LM_DBG("Cannot get pseudo variable value\n");
00218    return -1;
00219     }
00220 }
00221 
00222 
00223 /*
00224  * Reload domain table to new hash table and when done, make new hash table
00225  * current one.
00226  */
00227 int reload_domain_table ( void )
00228 {
00229    db_val_t vals[1];
00230    db_key_t cols[1];
00231    db_res_t* res = NULL;
00232    db_row_t* row;
00233    db_val_t* val;
00234 
00235    struct domain_list **new_hash_table;
00236    int i;
00237 
00238    cols[0] = &domain_col;
00239 
00240    if (domain_dbf.use_table(db_handle, &domain_table) < 0) {
00241       LM_ERR("Error while trying to use domain table\n");
00242       return -1;
00243    }
00244 
00245    VAL_TYPE(vals) = DB_STR;
00246    VAL_NULL(vals) = 0;
00247 
00248    if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 1, 0, &res) < 0) {
00249       LM_ERR("Error while querying database\n");
00250       return -1;
00251    }
00252 
00253    /* Choose new hash table and free its old contents */
00254    if (*hash_table == hash_table_1) {
00255       hash_table_free(hash_table_2);
00256       new_hash_table = hash_table_2;
00257    } else {
00258       hash_table_free(hash_table_1);
00259       new_hash_table = hash_table_1;
00260    }
00261 
00262    row = RES_ROWS(res);
00263 
00264    LM_DBG("Number of rows in domain table: %d\n", RES_ROW_N(res));
00265       
00266    for (i = 0; i < RES_ROW_N(res); i++) {
00267       val = ROW_VALUES(row + i);
00268       if ((ROW_N(row) == 1) && (VAL_TYPE(val) == DB_STRING)) {
00269          
00270          LM_DBG("Value: %s inserted into domain hash table\n",VAL_STRING(val));
00271 
00272          if (hash_table_install(new_hash_table,(char*)VAL_STRING(val))==-1){
00273             LM_ERR("Hash table problem\n");
00274             domain_dbf.free_result(db_handle, res);
00275             return -1;
00276          }
00277       } else {
00278          LM_ERR("Database problem\n");
00279          domain_dbf.free_result(db_handle, res);
00280          return -1;
00281       }
00282    }
00283    domain_dbf.free_result(db_handle, res);
00284 
00285    *hash_table = new_hash_table;
00286    
00287    return 1;
00288 }
00289 

Generated on Tue May 22 16:00:27 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6