avpops.c
来自「性能优秀的SIP Proxy」· C语言 代码 · 共 1,264 行 · 第 1/3 页
C
1,264 行
/* * $Id: avpops.c,v 1.23 2006/07/05 14:33:07 miconda Exp $ * * Copyright (C) 2004 Voice Sistem SRL * * This file is part of Open SIP Express Router. * * AVPOPS OpenSER-module 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. * * AVPOPS OpenSER-module 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. * * For any questions about this software and its license, please contact * Voice Sistem at following e-mail address: * office@voice-sistem.ro * * * History: * --------- * 2004-10-04 first version (ramona) * 2004-11-15 added support for db schemes for avp_db_load (ramona) * 2004-11-17 aligned to new AVP core global aliases (ramona) * 2005-01-30 "fm" (fast match) operator added (ramona) * 2005-01-30 avp_copy (copy/move operation) added (ramona) */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h> /* for regex */#include <regex.h>#include "../../mem/shm_mem.h"#include "../../mem/mem.h"#include "../../parser/parse_hname2.h"#include "../../sr_module.h"#include "../../str.h"#include "../../dprint.h"#include "../../error.h"#include "../../ut.h"#include "avpops_parse.h"#include "avpops_impl.h"#include "avpops_db.h"MODULE_VERSION/* modules param variables */static char *DB_URL = 0; /* database url */static char *DB_TABLE = 0; /* table */static int use_domain = 0; /* if domain should be use for avp matching */static char *db_columns[6] = {"uuid","attribute","value", "type","username","domain"};static int avpops_init(void);static int avpops_child_init(int rank);static int register_galiases( modparam_t type, void* val);static int fixup_db_load_avp(void** param, int param_no);static int fixup_db_delete_avp(void** param, int param_no);static int fixup_db_store_avp(void** param, int param_no);static int fixup_db_query_avp(void** param, int param_no);static int fixup_write_avp(void** param, int param_no);static int fixup_delete_avp(void** param, int param_no);static int fixup_copy_avp(void** param, int param_no);static int fixup_printf(void** param, int param_no);static int fixup_pushto_avp(void** param, int param_no);static int fixup_check_avp(void** param, int param_no);static int fixup_op_avp(void** param, int param_no);static int fixup_subst(void** param, int param_no);static int fixup_is_avp_set(void** param, int param_no);static int w_print_avps(struct sip_msg* msg, char* foo, char *bar);static int w_dbload_avps(struct sip_msg* msg, char* source, char* param);static int w_dbdelete_avps(struct sip_msg* msg, char* source, char* param);static int w_dbstore_avps(struct sip_msg* msg, char* source, char* param);static int w_dbquery1_avps(struct sip_msg* msg, char* query, char* param);static int w_dbquery2_avps(struct sip_msg* msg, char* query, char* dest);static int w_write_avps(struct sip_msg* msg, char* source, char* param);static int w_delete_avps(struct sip_msg* msg, char* param, char *foo);static int w_copy_avps(struct sip_msg* msg, char* param, char *check);static int w_printf(struct sip_msg* msg, char* dest, char *format);static int w_pushto_avps(struct sip_msg* msg, char* destination, char *param);static int w_check_avps(struct sip_msg* msg, char* param, char *check);static int w_op_avps(struct sip_msg* msg, char* param, char *op);static int w_subst(struct sip_msg* msg, char* src, char *subst);static int w_is_avp_set(struct sip_msg* msg, char* param, char *foo);/* * Exported functions */static cmd_export_t cmds[] = { {"avp_print", w_print_avps, 0, 0, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_db_load", w_dbload_avps, 2, fixup_db_load_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_db_delete", w_dbdelete_avps, 2, fixup_db_delete_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_db_store", w_dbstore_avps, 2, fixup_db_store_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_db_query", w_dbquery1_avps, 1, fixup_db_query_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_db_query", w_dbquery2_avps, 2, fixup_db_query_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_write", w_write_avps, 2, fixup_write_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_delete", w_delete_avps, 1, fixup_delete_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_copy", w_copy_avps, 2, fixup_copy_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_printf", w_printf, 2, fixup_printf, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_pushto", w_pushto_avps, 2, fixup_pushto_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_check", w_check_avps, 2, fixup_check_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_op", w_op_avps, 2, fixup_op_avp, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"avp_subst", w_subst, 2, fixup_subst, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"is_avp_set", w_is_avp_set, 1, fixup_is_avp_set, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {0, 0, 0, 0, 0}};/* * Exported parameters */static param_export_t params[] = { {"db_url", STR_PARAM, &DB_URL }, {"avp_url", STR_PARAM, &DB_URL }, {"avp_table", STR_PARAM, &DB_TABLE }, {"avp_aliases", STR_PARAM|USE_FUNC_PARAM, (void*)register_galiases }, {"use_domain", INT_PARAM, &use_domain }, {"uuid_column", STR_PARAM, &db_columns[0] }, {"attribute_column", STR_PARAM, &db_columns[1] }, {"value_column", STR_PARAM, &db_columns[2] }, {"type_column", STR_PARAM, &db_columns[3] }, {"username_column", STR_PARAM, &db_columns[4] }, {"domain_column", STR_PARAM, &db_columns[5] }, {"db_scheme", STR_PARAM|USE_FUNC_PARAM, (void*)avp_add_db_scheme }, {0, 0, 0}};struct module_exports exports = { "avpops", cmds, /* Exported functions */ params, /* Exported parameters */ 0, /* exported statistics */ avpops_init, /* Module initialization function */ (response_function) 0, (destroy_function) 0, (child_init_function) avpops_child_init /* per-child init function */};static int register_galiases( modparam_t type, void* val){ if (val!=0 && ((char*)val)[0]!=0) { if ( add_avp_galias_str((char*)val)!=0 ) return -1; } return 0;}static int avpops_init(void){ LOG(L_INFO,"AVPops - initializing\n"); /* if DB_URL defined -> bind to a DB module */ if (DB_URL!=0) { /* check AVP_TABLE param */ if (DB_TABLE==0) { LOG(L_CRIT,"ERROR:avpops_init: \"AVP_DB\" present but " "\"AVP_TABLE\" found empty\n"); goto error; } /* bind to the DB module */ if (avpops_db_bind(DB_URL)<0) goto error; } init_store_avps( db_columns ); return 0;error: return -1;}static int avpops_child_init(int rank){ /* init DB only if enabled */ if (DB_URL==0) return 0; /* skip main process and TCP manager process */ if (rank==PROC_MAIN || rank==PROC_TCP_MAIN) return 0; /* init DB connection */ return avpops_db_init(DB_URL, DB_TABLE, db_columns);}static int fixup_db_avp(void** param, int param_no, int allow_scheme){ struct fis_param *sp; struct db_param *dbp; int flags; int flags0; char *s; char *p; flags=0; flags0=0; if (DB_URL==0) { LOG(L_ERR,"ERROR:avpops:fixup_db_avp: you have to config a db url " "for using avp_db_xxx functions\n"); return E_UNSPEC; } s = (char*)*param; if (param_no==1) { /* prepare the fis_param structure */ sp = (struct fis_param*)pkg_malloc(sizeof(struct fis_param)); if (sp==0) { LOG(L_ERR,"ERROR:avpops:fixup_db_avp: no more pkg mem!\n"); return E_OUT_OF_MEM; } memset( sp, 0, sizeof(struct fis_param)); if ( (p=strchr(s,'/'))!=0) { *(p++) = 0; /* check for extra flags/params */ if (!strcasecmp("domain",p)) { flags|=AVPOPS_FLAG_DOMAIN0; } else if (!strcasecmp("username",p)) { flags|=AVPOPS_FLAG_USER0; } else if (!strcasecmp("uri",p)) { flags|=AVPOPS_FLAG_URI0; } else if (!strcasecmp("uuid",p)) { flags|=AVPOPS_FLAG_UUID0; } else { LOG(L_ERR,"ERROR:avpops:fixup_db_avp: unknow flag " "<%s>\n",p); return E_UNSPEC; } } if (*s!='$') { /* is a constant string -> use it as uuid*/ sp->opd = ((flags==0)?AVPOPS_FLAG_UUID0:flags)|AVPOPS_VAL_STR; sp->sval.p.val.s = (char*)pkg_malloc(strlen(s)+1); if (sp->sval.p.val.s==0) { LOG(L_ERR,"ERROR:avpops:fixup_db_avp: no more pkg mem!!\n"); return E_OUT_OF_MEM; } sp->sval.p.val.len = strlen(s); strcpy(sp->sval.p.val.s,s); } else { /* is a variable $xxxxx */ p = xl_parse_spec(s, &sp->sval, XL_THROW_ERROR|XL_DISABLE_MULTI|XL_DISABLE_COLORS); if (p==0 || sp->sval.type==XL_NULL || sp->sval.type==XL_EMPTY) { LOG(L_ERR,"ERROR:avops:fixup_db_avp: bad param 1; " "expected : $pseudo-variable or int/str value\n"); return E_UNSPEC; } if(sp->sval.type==XL_RURI || sp->sval.type==XL_FROM || sp->sval.type==XL_TO || sp->sval.type==XL_OURI) { sp->opd = ((flags==0)?AVPOPS_FLAG_URI0:flags)|AVPOPS_VAL_PVAR; } else { sp->opd = ((flags==0)?AVPOPS_FLAG_UUID0:flags)|AVPOPS_VAL_PVAR; } } *param=(void*)sp; } else if (param_no==2) { /* compose the db_param structure */ dbp = (struct db_param*)pkg_malloc(sizeof(struct db_param)); if (dbp==0) { LOG(L_ERR,"ERROR:avpops:fixup_db_avp: no more pkg mem!!!\n"); return E_OUT_OF_MEM; } memset( dbp, 0, sizeof(struct db_param)); if ( parse_avp_db( s, dbp, allow_scheme)!=0 ) { LOG(L_ERR,"ERROR:avpops:fixup_db_avp: parse failed\n"); return E_UNSPEC; } *param=(void*)dbp; } return 0;}static int fixup_db_load_avp(void** param, int param_no){ return fixup_db_avp( param, param_no, 1/*allow scheme*/);}static int fixup_db_delete_avp(void** param, int param_no){ return fixup_db_avp( param, param_no, 0/*no scheme*/);}static int fixup_db_store_avp(void** param, int param_no){ return fixup_db_avp( param, param_no, 0/*no scheme*/);}static int fixup_db_query_avp(void** param, int param_no){ xl_elem_t *model = NULL; avpname_list_t *anlist = NULL; char *s; s = (char*)(*param); if (param_no==1) { if(s==NULL) { LOG(L_ERR, "ERROR:avpops:fixup_db_query_avp: null format in P%d\n", param_no); return E_UNSPEC; } if(xl_parse_format(s, &model, XL_DISABLE_COLORS|XL_THROW_ERROR)<0) { LOG(L_ERR, "ERROR:avpops:fixup_db_query_avp: wrong format[%s]\n", s); return E_UNSPEC; } *param = (void*)model; return 0; } else if(param_no==2) { if(s==NULL) { LOG(L_ERR, "ERROR:avpops:fixup_db_query_avp: null format in P%d\n", param_no); return E_UNSPEC; } anlist = parse_avpname_list(s); if(anlist==NULL) { LOG(L_ERR, "ERROR:avpops:fixup_db_query_avp: bad format in P%d [%s]\n", param_no, s); return E_UNSPEC; } *param = (void*)anlist; return 0; } return 0;}static int fixup_write_avp(void** param, int param_no){ struct fis_param *ap; int flags; char *s; char *p; flags=0; s = (char*)*param; ap = 0 ; if (param_no==1) /* source */ { /* flags */ if ( (p=strchr(s,'/'))!=0) { *(p++) = '\0'; if (!strcasecmp("username",p)) { flags|=AVPOPS_FLAG_USER0; } else if(!strcasecmp("domain", p)) { flags|=AVPOPS_FLAG_DOMAIN0; } else { LOG(L_ERR,"ERROR:avpops:fixup_write_avp: flag \"%s\"" " unknown!\n", p); return E_UNSPEC; } } if ( *s=='$' ) { /* is variable */ ap = avpops_parse_pvar(s, XL_THROW_ERROR|XL_DISABLE_COLORS); if (ap==0) { LOG(L_ERR,"ERROR:avpops:fixup_write_avp: unable to get"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?