carrierroute.c

Go to the documentation of this file.
00001 /*
00002  * $Id: carrierroute.c 5633 2009-02-25 12:05:28Z henningw $
00003  *
00004  * Copyright (C) 2007-2008 1&1 Internet AG
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 /**
00024  * \file carrierroute.c
00025  * \brief Contains the functions exported by the module.
00026  * \ingroup carrierroute
00027  * - Module; \ref carrierroute
00028  */
00029 
00030 /*!
00031  * \defgroup carrierroute CARRIERROUTE :: The Kamailio carrierroute Module
00032  * The module provides routing, balancing and blacklisting capabilities.
00033  * It reads routing entries from a database source or from a config file
00034  * at Kamailio startup. It can uses one routing tree (for one carrier),
00035  * or if needed for every user a different routing tree (unique for each carrier)
00036  * for number prefix based routing. It supports several routing domains, e.g.
00037  * for failback routes or different routing rules for VoIP and PSTN targets.
00038  */
00039 
00040 #include "../../sr_module.h"
00041 #include "../../str.h"
00042 #include "../../mem/mem.h"
00043 #include "carrierroute.h"
00044 #include "cr_fixup.h"
00045 #include "cr_map.h"
00046 #include "cr_fifo.h"
00047 #include "cr_data.h"
00048 #include "cr_func.h"
00049 #include "db_carrierroute.h"
00050 #include <sys/stat.h>
00051 
00052 MODULE_VERSION
00053 
00054 str carrierroute_db_url = str_init(DEFAULT_RODB_URL);
00055 str subscriber_table = str_init("subscriber");
00056 
00057 static str subscriber_username_col = str_init("username");
00058 static str subscriber_domain_col = str_init("domain");
00059 static str cr_preferred_carrier_col = str_init("cr_preferred_carrier");
00060 
00061 str * subscriber_columns[SUBSCRIBER_COLUMN_NUM] = {
00062    &subscriber_username_col,
00063    &subscriber_domain_col,
00064    &cr_preferred_carrier_col
00065 };
00066 
00067 char * config_source = "file";
00068 char * config_file = CFG_DIR"carrierroute.conf";
00069 
00070 str default_tree = str_init("default");
00071 const str CR_EMPTY_PREFIX = str_init("null");
00072 
00073 int mode = 0;
00074 int use_domain = 0;
00075 int fallback_default = 1;
00076 int cr_fetch_rows = 2000;
00077 int cr_match_mode = 10;
00078 
00079 
00080 /************* Declaration of Interface Functions **************************/
00081 static int mod_init(void);
00082 static int child_init(int);
00083 static int mi_child_init(void);
00084 static void mod_destroy(void);
00085 
00086 
00087 /************* Module Exports **********************************************/
00088 static cmd_export_t cmds[]={
00089    {"cr_user_carrier", (cmd_function)cr_load_user_carrier,  3, cr_load_user_carrier_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE },
00090    {"cr_route",        (cmd_function)cr_route,              5, cr_route_fixup,             0, REQUEST_ROUTE | FAILURE_ROUTE },
00091    {"cr_route",        (cmd_function)cr_route,              6, cr_route_fixup,             0, REQUEST_ROUTE | FAILURE_ROUTE },
00092    {"cr_prime_route",  (cmd_function)cr_route,              5, cr_route_fixup,             0, REQUEST_ROUTE | FAILURE_ROUTE },
00093    {"cr_prime_route",  (cmd_function)cr_route,              6, cr_route_fixup,             0, REQUEST_ROUTE | FAILURE_ROUTE },
00094    {"cr_next_domain",  (cmd_function)cr_load_next_domain,   6, cr_load_next_domain_fixup,  0, REQUEST_ROUTE | FAILURE_ROUTE },
00095    {0, 0, 0, 0, 0, 0}
00096 };
00097 
00098 static param_export_t params[]= {
00099    carrierroute_DB_URL
00100    carrierroute_DB_TABLE
00101    carrierfailureroute_DB_TABLE
00102    carrier_name_DB_TABLE
00103    domain_name_DB_TABLE
00104    carrierroute_DB_COLS
00105    carrierfailureroute_DB_COLS
00106    carrier_name_DB_COLS
00107    domain_name_DB_COLS
00108    {"subscriber_table",       STR_PARAM, &subscriber_table.s },
00109    {"subscriber_user_col",    STR_PARAM, &subscriber_username_col.s },
00110    {"subscriber_domain_col",  STR_PARAM, &subscriber_domain_col.s },
00111    {"subscriber_carrier_col", STR_PARAM, &cr_preferred_carrier_col.s },
00112    {"config_source",          STR_PARAM, &config_source },
00113    {"default_tree",           STR_PARAM, &default_tree.s },
00114    {"config_file",            STR_PARAM, &config_file },
00115    {"use_domain",             INT_PARAM, &use_domain },
00116    {"fallback_default",       INT_PARAM, &fallback_default },
00117    {"fetch_rows",             INT_PARAM, &cr_fetch_rows },
00118    {"match_mode",             INT_PARAM, &cr_match_mode },
00119    {0,0,0}
00120 };
00121 
00122 static mi_export_t mi_cmds[] = {
00123    { "cr_reload_routes",   reload_fifo,     MI_NO_INPUT_FLAG, 0,  mi_child_init },
00124    { "cr_dump_routes",     dump_fifo,       MI_NO_INPUT_FLAG, 0,  0 },
00125    { "cr_replace_host",    replace_host,    0,                0,  0 },
00126    { "cr_deactivate_host", deactivate_host, 0,                0,  0 },
00127    { "cr_activate_host",   activate_host,   0,                0,  0 },
00128    { "cr_add_host",        add_host,        0,                0,  0 },
00129    { "cr_delete_host",     delete_host,     0,                0,  0 },
00130    { 0, 0, 0, 0, 0}
00131 };
00132 
00133 struct module_exports exports = {
00134    "carrierroute",
00135    DEFAULT_DLFLAGS, /* dlopen flags */
00136    cmds,       /* Exported functions */
00137    params,     /* Export parameters */
00138    0,          /* exported statistics */
00139    mi_cmds,    /* exported MI functions */
00140    0,          /* exported pseudo-variables */
00141    0,          /* extra processes */
00142    mod_init,   /* Module initialization function */
00143    0,          /* Response function */
00144    mod_destroy,/* Destroy function */
00145    child_init  /* Child initialization function */
00146 };
00147 
00148 
00149 /************* Interface Functions *****************************************/
00150 
00151 /**
00152  * Initialises the module, i.e. it binds the necessary API functions
00153  * and registers the fifo commands
00154  *
00155  * @return 0 on success, -1 on failure
00156  */
00157 static int mod_init(void) {
00158    struct stat fs;
00159 
00160    subscriber_table.len = strlen(subscriber_table.s);
00161    subscriber_username_col.len = strlen(subscriber_username_col.s);
00162    subscriber_domain_col.len = strlen(subscriber_domain_col.s);
00163    cr_preferred_carrier_col.len = strlen(cr_preferred_carrier_col.s);
00164    default_tree.len = strlen(default_tree.s);
00165 
00166    carrierroute_db_vars();
00167 
00168    if (cr_match_mode != 10 && cr_match_mode != 128) {
00169       LM_ERR("invalid matching mode %d specific, please use 10 or 128", cr_match_mode);
00170       return -1;
00171    }
00172 
00173    if (strcmp(config_source, "db") == 0) {
00174       mode = CARRIERROUTE_MODE_DB;
00175 
00176       LM_INFO("use database as configuration source");
00177       if(carrierroute_db_init() < 0){
00178          return -1;
00179       }
00180       // FIXME, move data initialization into child process
00181       if(carrierroute_db_open() < 0){
00182          return -1;
00183       }
00184    }
00185    else if (strcmp(config_source, "file") == 0) {
00186       mode = CARRIERROUTE_MODE_FILE;
00187 
00188       LM_INFO("use file as configuration source");
00189       if(stat(config_file, &fs) != 0){
00190          LM_ERR("can't stat config file\n");
00191          return -1;
00192       }
00193       if(fs.st_mode & S_IWOTH){
00194          LM_WARN("insecure file permissions, routing data is world writeable");
00195       }
00196       if( !( fs.st_mode & S_IWOTH) &&
00197          !((fs.st_mode & S_IWGRP) && (fs.st_gid == getegid())) &&
00198          !((fs.st_mode & S_IWUSR) && (fs.st_uid == geteuid())) ) {
00199             LM_ERR("config file %s not writable\n", config_file);
00200             return -1;
00201       }
00202    }
00203    else {
00204       LM_ERR("invalid config_source parameter: %s\n", config_source);
00205       return -1;
00206    }
00207 
00208    if (init_route_data() < 0) {
00209       LM_ERR("could not init route data\n");
00210       return -1;
00211    }
00212 
00213    if (reload_route_data() == -1) {
00214       LM_ERR("could not prepare route data\n");
00215       return -1;
00216    }
00217 
00218    if(mode == CARRIERROUTE_MODE_DB){
00219       carrierroute_db_close();
00220    }
00221    return 0;
00222 }
00223 
00224 
00225 static int child_init(int rank) {
00226    if(mode == CARRIERROUTE_MODE_DB){
00227       return carrierroute_db_open();
00228    }
00229    return 0;
00230 }
00231 
00232 
00233 static int mi_child_init(void) {
00234    if(mode == CARRIERROUTE_MODE_DB){
00235       return carrierroute_db_open();
00236    }
00237    return 0;
00238 }
00239 
00240 
00241 static void mod_destroy(void) {
00242    if(mode == CARRIERROUTE_MODE_DB){
00243       carrierroute_db_close();
00244    }
00245    destroy_route_data();
00246 }

Generated on Thu May 17 12:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6