4 * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com)
5 * Copyright (C) 2004 Voice Sistem SRL
7 * This file is part of a module for Kamailio, a free SIP server.
9 * Kamailio is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version
14 * Kamailio is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "../../core/sr_module.h"
29 #include "../../lib/srdb1/db.h"
30 #include "../../core/dprint.h"
31 #include "../../core/error.h"
32 #include "../../core/mem/mem.h"
33 #include "../../core/ut.h"
34 #include "../../core/mod_fix.h"
35 #include "../../core/kemi.h"
43 /* Module destroy function prototype */
44 static void destroy(void);
47 /* Module child-init function prototype */
48 static int child_init(int rank);
51 /* Module initialization function prototype */
52 static int mod_init(void);
55 static int lookup_fixup(void** param, int param_no);
56 static int find_fixup(void** param, int param_no);
58 static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2);
59 static int w_alias_db_lookup2(struct sip_msg* _msg, char* _table, char* flags);
60 static int w_alias_db_find3(struct sip_msg* _msg, char* _table, char* _in,
62 static int w_alias_db_find4(struct sip_msg* _msg, char* _table, char* _in,
63 char* _out, char* flags);
66 /* Module parameter variables */
67 static str db_url = str_init(DEFAULT_RODB_URL);
68 str user_column = str_init("username");
69 str domain_column = str_init("domain");
70 str alias_user_column = str_init("alias_username");
71 str alias_domain_column = str_init("alias_domain");
72 str domain_prefix = {NULL, 0};
73 int alias_db_use_domain = 0;
74 int ald_append_branches = 0;
76 db1_con_t* db_handle; /* Database connection handle */
77 db_func_t adbf; /* DB functions */
79 /* Exported functions */
80 static cmd_export_t cmds[] = {
81 {"alias_db_lookup", (cmd_function)w_alias_db_lookup1, 1, lookup_fixup, 0,
82 REQUEST_ROUTE|FAILURE_ROUTE},
83 {"alias_db_lookup", (cmd_function)w_alias_db_lookup2, 2, lookup_fixup, 0,
84 REQUEST_ROUTE|FAILURE_ROUTE},
85 {"alias_db_find", (cmd_function)w_alias_db_find3, 3, find_fixup, 0,
86 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
87 {"alias_db_find", (cmd_function)w_alias_db_find4, 4, find_fixup, 0,
88 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
89 {"bind_alias_db", (cmd_function)bind_alias_db, 1, 0, 0,
95 /* Exported parameters */
96 static param_export_t params[] = {
97 {"db_url", PARAM_STR, &db_url },
98 {"user_column", PARAM_STR, &user_column },
99 {"domain_column", PARAM_STR, &domain_column },
100 {"alias_user_column", PARAM_STR, &alias_user_column },
101 {"alias_domain_column", PARAM_STR, &alias_domain_column },
102 {"use_domain", INT_PARAM, &alias_db_use_domain },
103 {"domain_prefix", PARAM_STR, &domain_prefix },
104 {"append_branches", INT_PARAM, &ald_append_branches },
109 /* Module interface */
110 struct module_exports exports = {
112 DEFAULT_DLFLAGS,/* dlopen flags */
113 cmds, /* Exported functions */
114 params, /* exported params */
115 0, /*·exported·RPC·methods·*/
116 0, /* exported pseudo-variables */
117 0, /* response·function */
118 mod_init, /* initialization·module */
119 child_init, /* per-child·init·function */
120 destroy /* destroy function */
124 static int alias_flags_fixup(void** param)
132 if(alias_db_use_domain) {
133 flags |= ALIAS_DOMAIN_FLAG;
141 flags &= ~ALIAS_DOMAIN_FLAG;
145 flags |= ALIAS_REVERSE_FLAG;
149 flags |= ALIAS_DOMAIN_FLAG;
152 LM_ERR("unsupported flag '%c'\n",*c);
158 *param = (void*)(unsigned long)flags;
163 static int lookup_fixup(void** param, int param_no)
167 /* string or pseudo-var - table name */
168 return fixup_spve_null(param, 1);
169 } else if (param_no==2) {
170 /* string - flags ? */
171 return alias_flags_fixup(param);
173 LM_CRIT(" invalid number of params %d \n",param_no);
179 static int find_fixup(void** param, int param_no)
185 /* string or pseudo-var - table name */
186 return fixup_spve_null(param, 1);
187 } else if(param_no==2) {
188 /* pseudo-var - source URI */
189 return fixup_pvar_null(param, 1);
190 } else if(param_no==3) {
191 /* pvar (AVP or VAR) - destination URI */
192 if (fixup_pvar_null(param, 1))
194 sp = (pv_spec_t*)*param;
195 if (sp->type!=PVT_AVP && sp->type!=PVT_SCRIPTVAR)
197 LM_ERR("PV type %d (param 3) cannot be written\n", sp->type);
202 } else if (param_no==4) {
203 /* string - flags ? */
204 return alias_flags_fixup(param);
206 LM_CRIT(" invalid number of params %d \n",param_no);
215 static int child_init(int rank)
217 if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
218 return 0; /* do nothing for the main process */
220 db_handle = adbf.init(&db_url);
223 LM_ERR("unable to connect database\n");
234 static int mod_init(void)
236 /* Find a database module */
237 if (db_bind_mod(&db_url, &adbf))
239 LM_ERR("unable to bind database module\n");
242 if (!DB_CAPABILITY(adbf, DB_CAP_QUERY))
244 LM_CRIT("database modules does not "
245 "provide all functions needed by alias_db module\n");
256 static void destroy(void)
259 adbf.close(db_handle);
264 static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2)
270 if(alias_db_use_domain) {
271 flags |= ALIAS_DOMAIN_FLAG;
274 if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
275 LM_ERR("invalid table parameter\n");
279 return alias_db_lookup_ex(_msg, table_s, flags);
282 static int w_alias_db_lookup2(struct sip_msg* _msg, char* _table, char* flags)
286 if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
287 LM_ERR("invalid table parameter\n");
291 return alias_db_lookup_ex(_msg, table_s, (unsigned long)flags);
294 static int w_alias_db_find3(struct sip_msg* _msg, char* _table, char* _in,
301 if(alias_db_use_domain) {
302 flags |= ALIAS_DOMAIN_FLAG;
305 if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
306 LM_ERR("invalid table parameter\n");
310 return alias_db_find(_msg, table_s, _in, _out, (char*)flags);
313 static int w_alias_db_find4(struct sip_msg* _msg, char* _table, char* _in,
314 char* _out, char* flags)
318 if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
319 LM_ERR("invalid table parameter\n");
323 return alias_db_find(_msg, table_s, _in, _out, flags);
326 int bind_alias_db(struct alias_db_binds *pxb)
329 LM_WARN("bind_alias_db: Cannot load alias_db API into a NULL pointer\n");
333 pxb->alias_db_lookup = alias_db_lookup;
334 pxb->alias_db_lookup_ex = alias_db_lookup_ex;
335 pxb->alias_db_find = alias_db_find;
342 static int ki_alias_db_lookup(sip_msg_t* msg, str* stable)
347 if(alias_db_use_domain) {
348 flags |= ALIAS_DOMAIN_FLAG;
351 return alias_db_lookup_ex(msg, *stable, flags);
357 static int ki_alias_db_lookup_ex(sip_msg_t* msg, str* stable, str* sflags)
363 if(alias_db_use_domain) {
364 flags |= ALIAS_DOMAIN_FLAG;
366 for(i=0; i<sflags->len; i++) {
367 switch (sflags->s[i])
371 flags &= ~ALIAS_DOMAIN_FLAG;
375 flags |= ALIAS_REVERSE_FLAG;
379 flags |= ALIAS_DOMAIN_FLAG;
382 LM_ERR("unsupported flag '%c' - ignoring\n", sflags->s[i]);
387 return alias_db_lookup_ex(msg, *stable, flags);
393 /* clang-format off */
394 static sr_kemi_t sr_kemi_alias_db_exports[] = {
395 { str_init("alias_db"), str_init("lookup"),
396 SR_KEMIP_INT, ki_alias_db_lookup,
397 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
398 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
400 { str_init("alias_db"), str_init("lookup_ex"),
401 SR_KEMIP_INT, ki_alias_db_lookup_ex,
402 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
403 SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
406 { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
408 /* clang-format on */
413 int mod_register(char *path, int *dlflags, void *p1, void *p2)
415 sr_kemi_modules_add(sr_kemi_alias_db_exports);