📄 pdt.c
字号:
/** * $Id: pdt.c,v 1.14.2.1 2005/01/21 23:02:51 bogdan Exp $ * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * ser 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: * ------- * 2003-04-07: a structure for both hashes introduced (ramona) * 2003-04-06: db connection closed in mod_init (janakj) * 2004-06-07 updated to the new DB api (andrei) *//* * Prefix-Domains Translation - ser module * Ramona Modroiu <modroiu@fokus.fraunhofer.de> */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include "../../db/db_op.h"#include "../../sr_module.h"#include "../../parser/parse_fline.h"#include "../../db/db.h"#include "../../mem/shm_mem.h"#include "../../mem/mem.h"#include "../../dprint.h"#include "../../fifo_server.h"#include "../../unixsock_server.h"#include "../../parser/parse_uri.h"#include "../../parser/msg_parser.h"#include "../../ut.h"#include "domains.h"MODULE_VERSION#define NR_KEYS 2#define DB_KEY_NAME "domain"#define DB_KEY_CODE "code"int hs_two_pow = 1;/** structure containing the both hashes */double_hash_t *hash = NULL;/** next code to be allocated */code_t *next_code = NULL;/** database connection */static db_con_t *db_con = NULL;static db_func_t pdt_dbf;/** parameters */static char *db_url = "mysql://root@127.0.0.1/pdt";char *db_table = "domains";/** pstn prefix */char *prefix = NULL;code_t prefix_len = 0;code_t code_terminator = 0;code_t start_range = 10;gen_lock_t l;static int prefix2domain(struct sip_msg*, char*, char*);static int mod_init(void);static void mod_destroy(void);static int mod_child_init(int r);static int get_domainprefix_unixsock(str* msg);static cmd_export_t cmds[]={ {"prefix2domain", prefix2domain, 0, 0, REQUEST_ROUTE}, {0, 0, 0, 0, 0}};static param_export_t params[]={ {"db_url", STR_PARAM, &db_url}, {"db_table", STR_PARAM, &db_table}, {"prefix", STR_PARAM, &prefix}, {"terminator", INT_PARAM, &code_terminator}, {"start_range", INT_PARAM, &start_range}, {"hsize_2pow", INT_PARAM, &hs_two_pow}, {0, 0, 0}};struct module_exports exports = { "pdt", cmds, params, mod_init, /* module initialization function */ 0, /* response function */ mod_destroy, /* destroy function */ 0, /* oncancel function */ mod_child_init /* per child init function */}; inline code_t code_valid(code_t code){ code_t tmp; tmp = code; while(tmp) { if(tmp%10==code_terminator) return 0; tmp /= 10; } return 1;}/* the superior interval limit is kept to signal that * there are no more prefixes available */code_t apply_correction(code_t code){ code_t p, tmp, new_code; if(code==MAX_CODE) return MAX_CODE; p = 1; tmp = code; new_code = code; while(tmp) { if(tmp%10==code_terminator) { tmp += 1; if(MAX_CODE-p <= new_code) return MAX_CODE; new_code += p; } if(p>MAX_CODE_10) return MAX_CODE; p *= 10; tmp /= 10; } return new_code;}inline int prefix_valid(){ char *p; if(!prefix) return 1; p=prefix; prefix_len = 0; while(*p!='\0') { prefix_len++; if( *p<'0' || *p>'9' ) { DBG("PDT: prefix_valid: supplied parameter as prefix is not valid\n"); return 0; } p++; } return 1;}/** * init module function */static int mod_init(void){ db_res_t* db_res = NULL; code_t i, code; dc_t* cell; DBG("PDT: initializing...\n"); if(hs_two_pow<0) { LOG(L_ERR, "PDT: mod_init: hash_size_two_pow must be" " positive and less than %d\n", MAX_HSIZE_TWO_POW); return -1; } if(code_terminator>9 || code_terminator<0) { LOG(L_ERR, "PDT: mod_init: code_terminator must be a digit\n"); return -1; } if(!prefix_valid()) return -1; next_code = (code_t*)shm_malloc(sizeof(code_t)); if(!next_code) { LOG(L_ERR, "PDT: mod_init: cannot allocate next_code!\n"); return -1; } if(lock_init(&l) == 0) { shm_free(next_code); LOG(L_ERR, "PDT: mod_init: cannot init the lock\n"); return -1; } if(register_fifo_cmd(get_domainprefix, "get_domainprefix", 0)<0) { LOG(L_ERR, "PDT: mod_init: cannot register fifo command 'get_domaincode'\n"); goto error1; } if(unixsock_register_cmd("get_domainprefix", get_domainprefix_unixsock)<0) { LOG(L_ERR, "PDT: mod_init: cannot register unixsock command 'get_domainprefix'\n"); goto error1; } /* binding to mysql module */ if(bind_dbmod(db_url, &pdt_dbf)) { LOG(L_ERR, "PDT: mod_init: Database module not found\n"); goto error1; } if (!DB_CAPABILITY(pdt_dbf, DB_CAP_ALL)) { LOG(L_ERR, "PDT: mod_init: Database module does not " "implement all functions needed by the module\n"); goto error1; } /* open a connection with the database */ db_con = pdt_dbf.init(db_url); if(!db_con) { LOG(L_ERR, "PDT: mod_init: Error while connecting to database\n"); goto error1; } else { if (pdt_dbf.use_table(db_con, db_table) < 0) { LOG(L_ERR, "PDT: mod_init: Error in use_table\n"); goto error1; } DBG("PDT: mod_init: Database connection opened successfully\n"); } /* init hashes in share memory */ if( (hash = init_double_hash(hs_two_pow)) == NULL) { LOG(L_ERR, "PDT: mod_init: hash could not be allocated\n"); goto error2; } /* loading all information from database */ *next_code = 0; if(pdt_dbf.query(db_con, NULL, NULL, NULL, NULL, 0, 0, "code", &db_res)==0) { for(i=0; i<RES_ROW_N(db_res); i++) { code = RES_ROWS(db_res)[i].values[0].val.int_val; if (!code_valid(code)) { LOG(L_ERR, "PDT: mod_init: existing code contains the terminator\n"); goto error; } if (*next_code < code) *next_code = code; cell=new_cell( (char*)(RES_ROWS(db_res)[i].values[1].val.string_val), code); if(cell == NULL) goto error; if(add_to_double_hash(hash, cell)<0) { LOG(L_ERR, "PDT: mod_init: could not add information from database" " into shared-memory hashes\n"); goto error; } } // clear up here //print_hash(hash->dhash, hash->hash_size); //print_hash(hash->chash, hash->hash_size); (*next_code)++; if (*next_code < start_range) *next_code = start_range; *next_code = apply_correction(*next_code); DBG("PDT: mod_init: next_code:%d\n", *next_code); /* free up the space allocated for response */ if(pdt_dbf.free_result(db_con, db_res)<0) { LOG(L_ERR, "PDT: mod_init: error when freeing" " up the response space\n"); } } else { /* query to database failed */ LOG(L_ERR, "PDT: mod_init: query to database failed\n"); goto error; } pdt_dbf.close(db_con); /* janakj - close the connection */ /* success code */ return 0;error: free_double_hash(hash); hash = 0;error2: pdt_dbf.close(db_con); db_con = 0;error1: shm_free(next_code); next_code = 0; lock_destroy(&l); return -1;}/* each child get a new connection to the database */static int mod_child_init(int r){ DBG("PDT: mod_child_init #%d / pid <%d>\n", r, getpid()); db_con = pdt_dbf.init(db_url); if(!db_con) { LOG(L_ERR,"PDT: child %d: Error while connecting database\n",r); return -1; } else { if (pdt_dbf.use_table(db_con, db_table) < 0) { LOG(L_ERR, "PDT:child %d: Error in use_table\n", r); return -1; } DBG("PDT:child %d: Database connection opened successfully\n",r); } return 0;}/* change the r-uri if it is a PSTN format */static int prefix2domain(struct sip_msg* msg, char* str1, char* str2){ char *host_port; code_t code=0, i; int digit; if(!msg) return -1; /* parse the uri, if not yet */ if(msg->parsed_uri_ok==0) if(parse_sip_msg_uri(msg)<0) { LOG(L_ERR,"PDT:prefix2domain: ERROR while parsing the R-URI\n"); return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -