3 * Copyright (C) 2001-2003 FhG Fokus
5 * This file is part of ser, a free SIP server.
7 * ser is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version
12 * For a license to use the ser software under conditions
13 * other than those described here, or to purchase support for this
14 * software, please contact iptel.org by e-mail at the following addresses:
17 * ser is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * 2003-03-10 switched to new module_exports format: updated find_export,
30 * find_export_param, find_module (andrei)
31 * 2003-03-19 replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
32 * 2003-03-19 Support for flags in find_export (janakj)
33 * 2003-03-29 cleaning pkg_mallocs introduced (jiri)
34 * 2003-04-24 module version checking introduced (jiri)
35 * 2004-09-19 compile flags are checked too (andrei)
36 * 2005-01-07 removed find_module-overloading problems, added
38 * 2006-02-07 added fix_flag (andrei)
39 * 2008-02-29 store all the reponse callbacks in their own array (andrei)
40 * 2008-11-17 support dual module interface: ser & kamailio (andrei)
41 * 2008-11-26 added fparam_free_contents() and fix_param_types (andrei)
46 * \brief SIP-router core ::
51 #include "sr_module.h"
58 #include "route_struct.h"
62 #include "rpc_lookup.h"
63 #include "sr_compat.h"
73 struct sr_module* modules=0;
76 extern struct module_exports exec_exports;
79 extern struct module_exports tm_exports;
83 extern struct module_exports maxfwd_exports;
87 extern struct module_exports auth_exports;
91 extern struct module_exports rr_exports;
95 extern struct module_exports usrloc_exports;
99 extern struct module_exports sl_exports;
103 int mod_response_cbk_no=0;
104 response_function* mod_response_cbks=0;
107 /* initializes statically built (compiled in) modules*/
108 int register_builtin_modules()
114 ret=register_module(MODULE_INTERFACE_VER, &tm_exports,"built-in", 0);
115 if (ret<0) return ret;
119 ret=register_module(MODULE_INTERFACE_VER, &exec_exports,"built-in", 0);
120 if (ret<0) return ret;
124 ret=register_module(MODULE_INTERFACE_VER, &maxfwd_exports, "built-in", 0);
125 if (ret<0) return ret;
129 ret=register_module(MODULE_INTERFACE_VER, &auth_exports, "built-in", 0);
130 if (ret<0) return ret;
134 ret=register_module(MODULE_INTERFACE_VER, &rr_exports, "built-in", 0);
135 if (ret<0) return ret;
139 ret=register_module(MODULE_INTERFACE_VER, &usrloc_exports, "built-in", 0);
140 if (ret<0) return ret;
144 ret=register_module(MODULE_INTERFACE_VER, &sl_exports, "built-in", 0);
145 if (ret<0) return ret;
153 /** convert cmd exports to current format.
154 * @param ver - module interface versions (0 == ser, 1 == kam).
155 * @param src - null terminated array of cmd exports
156 * (either ser_cmd_export_t or kam_cmd_export_t, depending
158 * @param mod - pointer to module exports structure.
159 * @return - pkg_malloc'ed null terminated sr_cmd_export_v31_t array with
160 * the converted cmd exports or 0 on error.
162 static sr31_cmd_export_t* sr_cmd_exports_convert(unsigned ver,
163 void* src, void* mod)
166 ser_cmd_export_t* ser_cmd;
167 kam_cmd_export_t* kam_cmd;
168 sr31_cmd_export_t* ret;
174 /* count the number of elements */
177 for (; ser_cmd[n].name; n++);
178 } else if (ver == 1) {
180 for (; kam_cmd[n].name; n++);
181 } else goto error; /* unknown interface version */
182 /* alloc & init new array */
183 ret = pkg_malloc(sizeof(*ret)*(n+1));
184 memset(ret, 0, sizeof(*ret)*(n+1));
186 for (i=0; i < n; i++) {
188 ret[i].name = ser_cmd[i].name;
189 ret[i].function = ser_cmd[i].function;
190 ret[i].param_no = ser_cmd[i].param_no;
191 ret[i].fixup = ser_cmd[i].fixup;
192 ret[i].free_fixup = 0; /* no present in ser <= 2.1 */
193 ret[i].flags = ser_cmd[i].flags;
195 ret[i].name = kam_cmd[i].name;
196 ret[i].function = kam_cmd[i].function;
197 ret[i].param_no = kam_cmd[i].param_no;
198 ret[i].fixup = kam_cmd[i].fixup;
199 ret[i].free_fixup = kam_cmd[i].free_fixup;
200 ret[i].flags = kam_cmd[i].flags;
202 /* 3.1+ specific stuff */
203 ret[i].fixup_flags = 0;
204 ret[i].module_exports = mod;
213 /* registers a module, register_f= module register functions
214 * returns <0 on error, 0 on success */
215 static int register_module(unsigned ver, union module_exports_u* e,
216 char* path, void* handle)
219 struct sr_module* mod;
223 /* add module to the list */
224 if ((mod=pkg_malloc(sizeof(struct sr_module)))==0){
225 LOG(L_ERR, "load_module: memory allocation failure\n");
229 memset(mod,0, sizeof(struct sr_module));
232 mod->orig_mod_interface_ver=ver;
233 /* convert exports to sr31 format */
236 mod->exports.name = e->v0.name;
238 mod->exports.cmds = sr_cmd_exports_convert(ver, e->v0.cmds, mod);
239 if (mod->exports.cmds == 0) {
240 ERR("failed to convert module command exports to 3.1 format"
241 " for module \"%s\" (%s), interface version %d\n",
242 mod->exports.name, mod->path, ver);
247 mod->exports.params = e->v0.params;
248 mod->exports.init_f = e->v0.init_f;
249 mod->exports.response_f = e->v0.response_f;
250 mod->exports.destroy_f = e->v0.destroy_f;
251 mod->exports.onbreak_f = e->v0.onbreak_f;
252 mod->exports.init_child_f = e->v0.init_child_f;
253 mod->exports.dlflags = 0; /* not used in ser <= 3.0 */
254 mod->exports.rpc_methods = e->v0.rpc_methods;
255 /* the rest are 0, not used in ser */
256 } else if (ver == 1) {
257 /* kamailio <= 3.0 */
258 mod->exports.name = e->v1.name;
260 mod->exports.cmds = sr_cmd_exports_convert(ver, e->v1.cmds, mod);
261 if (mod->exports.cmds == 0) {
262 ERR("failed to convert module command exports to 3.1 format"
263 " for module \"%s\" (%s), interface version %d\n",
264 mod->exports.name, mod->path, ver);
269 mod->exports.params = e->v1.params;
270 mod->exports.init_f = e->v1.init_f;
271 mod->exports.response_f = e->v1.response_f;
272 mod->exports.destroy_f = e->v1.destroy_f;
273 mod->exports.onbreak_f = 0; /* not used in k <= 3.0 */
274 mod->exports.init_child_f = e->v1.init_child_f;
275 mod->exports.dlflags = e->v1.dlflags;
276 mod->exports.rpc_methods = 0; /* not used in k <= 3.0 */
277 mod->exports.stats = e->v1.stats;
278 mod->exports.mi_cmds = e->v1.mi_cmds;
279 mod->exports.items = e->v1.items;
280 mod->exports.procs = e->v1.procs;
282 ERR("unsupported module interface version %d\n", ver);
287 if (mod->exports.items) {
288 /* register module pseudo-variables for kamailio modules */
289 LM_DBG("register PV from: %s\n", mod->exports.name);
290 if (register_pvars_mod(mod->exports.name, mod->exports.items)!=0) {
291 LM_ERR("failed to register pseudo-variables for module %s (%s)\n",
292 mod->exports.name, path);
297 if (mod->exports.rpc_methods){
298 /* register rpcs for ser modules */
299 i=rpc_register_array(mod->exports.rpc_methods);
301 ERR("failed to register RPCs for module %s (%s)\n",
302 mod->exports.name, path);
306 ERR("%d duplicate RPCs name detected while registering RPCs"
307 " declared in module %s (%s)\n",
308 i, mod->exports.name, path);
312 /* i==0 => success */
315 /* link module in the list */
326 /* define it to null */
330 static inline int version_control(void *handle, char *path)
336 m_ver=(char **)dlsym(handle, DLSYM_PREFIX "module_version");
337 if ((error=(char *)dlerror())!=0) {
338 LOG(L_ERR, "ERROR: no version info in module <%s>: %s\n",
342 m_flags=(char **)dlsym(handle, DLSYM_PREFIX "module_flags");
343 if ((error=(char *)dlerror())!=0) {
344 LOG(L_ERR, "ERROR: no compile flags info in module <%s>: %s\n",
348 if (!m_ver || !(*m_ver)) {
349 LOG(L_ERR, "ERROR: no version in module <%s>\n", path );
352 if (!m_flags || !(*m_flags)) {
353 LOG(L_ERR, "ERROR: no compile flags in module <%s>\n", path );
357 if (strcmp(SER_FULL_VERSION, *m_ver)==0){
358 if (strcmp(SER_COMPILE_FLAGS, *m_flags)==0)
361 LOG(L_ERR, "ERROR: module compile flags mismatch for %s "
362 " \ncore: %s \nmodule: %s\n",
363 path, SER_COMPILE_FLAGS, *m_flags);
367 LOG(L_ERR, "ERROR: module version mismatch for %s; "
368 "core: %s; module: %s\n", path, SER_FULL_VERSION, *m_ver );
372 /** load a sr module.
373 * tries to load the module specified by mod_path.
374 * If mod_path is 'modname' or 'modname.so' then
375 * <MODS_DIR>/<modname>.so will be tried and if this fails
376 * <MODS_DIR>/<modname>/<modname>.so
377 * If mod_path contain a '/' it is assumed to be the
378 * path to the module and tried first. If fails and mod_path is not
379 * absolute path (not starting with '/') then will try:
380 * <MODS_DIR>/mod_path
381 * @param modname - path or module name
382 * @return 0 on success , <0 on error
384 int load_module(char* mod_path)
388 mod_register_function mr;
389 union module_exports_u* exp;
390 unsigned* mod_if_ver;
392 struct stat stat_buf;
406 #define RTLD_NOW DL_LAZY
411 modname.len = strlen(mod_path);
412 if(modname.len>3 && strcmp(modname.s+modname.len-3, ".so")==0) {
416 if (!strchr(path, '/'))
418 if((path_type&2) || path[0] != '/') {
419 /* module name was given, we try to construct the path */
420 mdir=mods_dir; /* search path */
422 nxt_mdir=strchr(mdir, ':');
423 if (nxt_mdir) mdir_len=(int)(nxt_mdir-mdir);
424 else mdir_len=strlen(mdir);
427 /* try path <MODS_DIR>/<modname>.so */
428 path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
429 modname.len + 3 /* ".so" */ + 1);
430 if (path==0) goto error;
431 memcpy(path, mdir, mdir_len);
433 if (len != 0 && path[len - 1] != '/'){
438 strcat(path, modname.s);
442 if (stat(path, &stat_buf) == -1) {
443 DBG("load_module: module file not found <%s>\n", path);
446 /* try path <MODS_DIR>/<modname>/<modname>.so */
447 path = (char*)pkg_malloc(
448 mdir_len + 1 /* "/" */ +
449 modname.len + 1 /* "/" */ +
450 modname.len + 3 /* ".so" */ + 1);
451 if (path==0) goto error;
452 memcpy(path, mdir, mdir_len);
454 if (len != 0 && path[len - 1] != '/') {
459 strncat(path, modname.s, modname.len);
461 strcat(path, modname.s);
465 if (stat(path, &stat_buf) == -1) {
466 DBG("load_module: module file not found <%s>\n", path);
472 /* try mod_path - S compat */
474 if (stat(path, &stat_buf) == -1) {
475 DBG("load_module: module file not found <%s>\n", path);
480 /* try path <MODS_DIR>/mod_path - K compat */
481 path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
482 strlen(mod_path) + 1);
483 if (path==0) goto error;
484 memcpy(path, mdir, mdir_len);
486 if (len != 0 && path[len - 1] != '/'){
491 strcat(path, mod_path);
493 if (stat(path, &stat_buf) == -1) {
494 DBG("load_module: module file not found <%s>\n", path);
500 mdir=nxt_mdir?nxt_mdir+1:0;
501 }while(path==0 && mdir);
503 LOG(L_ERR, "ERROR: load_module: could not find module <%.*s> in"
504 " <%s>\n", modname.len, modname.s, mods_dir);
508 DBG("load_module: trying to load <%s>\n", path);
513 handle=dlopen(path, dlflags); /* resolve all symbols now */
515 LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
520 for(t=modules;t; t=t->next){
521 if (t->handle==handle){
522 LOG(L_WARN, "WARNING: load_module: attempting to load the same"
523 " module twice (%s)\n", path);
527 /* version control */
528 if (!version_control(handle, path)) {
531 mod_if_ver = (unsigned *)dlsym(handle,
532 DLSYM_PREFIX "module_interface_ver");
533 if ( (error =(char*)dlerror())!=0 ){
534 LOG(L_ERR, "ERROR: no module interface version in module <%s>\n",
538 /* launch register */
539 mr = (mod_register_function)dlsym(handle, DLSYM_PREFIX "mod_register");
540 if (((error =(char*)dlerror())==0) && mr) {
541 /* no error call it */
543 if (mr(path, &dlflags, 0, 0)!=0) {
544 LOG(L_ERR, "ERROR: load_module: %s: mod_register failed\n", path);
547 if (new_dlflags!=dlflags && new_dlflags!=0) {
548 /* we have to reload the module */
552 if (retries>0) goto reload;
553 LOG(L_ERR, "ERROR: load_module: %s: cannot agree"
554 " on the dlflags\n", path);
558 exp = (union module_exports_u*)dlsym(handle, DLSYM_PREFIX "exports");
559 if ( (error =(char*)dlerror())!=0 ){
560 LOG(L_ERR, "ERROR: load_module: %s\n", error);
563 /* hack to allow for kamailio style dlflags inside exports */
564 if (*mod_if_ver == 1) {
565 new_dlflags = exp->v1.dlflags;
566 if (new_dlflags!=dlflags && new_dlflags!=DEFAULT_DLFLAGS) {
567 /* we have to reload the module */
569 WARN("%s: exports dlflags interface is deprecated and it will not"
570 "be supported in newer versions; consider using"
571 " mod_register() instead", path);
574 if (retries>0) goto reload;
575 LOG(L_ERR, "ERROR: load_module: %s: cannot agree"
576 " on the dlflags\n", path);
580 if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
587 if (path && path!=mod_path)
594 /* searches the module list for function name in module mod and returns
595 * a pointer to the "name" function record union or 0 if not found
596 * sets also *mod_if_ver to the original module interface version.
597 * mod==0 is a wildcard matching all modules
598 * flags parameter is OR value of all flags that must match
600 sr31_cmd_export_t* find_mod_export_record(char* mod, char* name,
601 int param_no, int flags,
602 unsigned* mod_if_ver)
605 sr31_cmd_export_t* cmd;
607 for(t=modules;t;t=t->next){
608 if (mod!=0 && (strcmp(t->exports.name, mod) !=0))
611 for(cmd=&t->exports.cmds[0]; cmd->name; cmd++) {
612 if((strcmp(name, cmd->name) == 0) &&
613 ((cmd->param_no == param_no) ||
614 (cmd->param_no==VAR_PARAM_NO)) &&
615 ((cmd->flags & flags) == flags)
617 DBG("find_export_record: found <%s> in module %s [%s]\n",
618 name, t->exports.name, t->path);
619 *mod_if_ver=t->orig_mod_interface_ver;
624 DBG("find_export_record: <%s> not found \n", name);
630 /* searches the module list for function name and returns
631 * a pointer to the "name" function record union or 0 if not found
632 * sets also *mod_if_ver to the module interface version (needed to know
633 * which member of the union should be accessed v0 or v1)
634 * mod==0 is a wildcard matching all modules
635 * flags parameter is OR value of all flags that must match
637 sr31_cmd_export_t* find_export_record(char* name,
638 int param_no, int flags,
639 unsigned* mod_if_ver)
641 return find_mod_export_record(0, name, param_no, flags, mod_if_ver);
646 cmd_function find_export(char* name, int param_no, int flags)
648 sr31_cmd_export_t* cmd;
651 cmd = find_export_record(name, param_no, flags, &mver);
652 return cmd?cmd->function:0;
656 rpc_export_t* find_rpc_export(char* name, int flags)
658 return rpc_lookup((char*)name, strlen(name));
663 * searches the module list and returns pointer to "name" function in module
666 * flags parameter is OR value of all flags that must match
668 cmd_function find_mod_export(char* mod, char* name, int param_no, int flags)
670 sr31_cmd_export_t* cmd;
673 cmd=find_mod_export_record(mod, name, param_no, flags, &mver);
675 return cmd->function;
677 DBG("find_mod_export: <%s> in module <%s> not found\n", name, mod);
682 struct sr_module* find_module_by_name(char* mod) {
685 for(t = modules; t; t = t->next) {
686 if (strcmp(mod, t->exports.name) == 0) {
690 DBG("find_module_by_name: module <%s> not found\n", mod);
695 void* find_param_export(struct sr_module* mod, char* name,
696 modparam_t type_mask, modparam_t *param_type)
698 param_export_t* param;
702 for(param = mod->exports.params ;param && param->name ; param++) {
703 if ((strcmp(name, param->name) == 0) &&
704 ((param->type & PARAM_TYPE_MASK(type_mask)) != 0)) {
705 DBG("find_param_export: found <%s> in module %s [%s]\n",
706 name, mod->exports.name, mod->path);
707 *param_type = param->type;
708 return param->param_pointer;
711 DBG("find_param_export: parameter <%s> not found in module <%s>\n",
712 name, mod->exports.name);
717 void destroy_modules()
719 struct sr_module* t, *foo;
724 if (t->exports.destroy_f){
725 t->exports.destroy_f();
731 if (mod_response_cbks){
732 pkg_free(mod_response_cbks);
737 #ifdef NO_REVERSE_INIT
740 * Initialize all loaded modules, the initialization
741 * is done *AFTER* the configuration file is parsed
743 int init_modules(void)
747 for(t = modules; t; t = t->next) {
748 if (t->exports.init_f)
749 if (t->exports.init_f() != 0) {
750 LOG(L_ERR, "init_modules(): Error while"
751 " initializing module %s\n", t->exports.name);
754 if (t->exports.response_f)
755 mod_response_cbk_no++;
757 mod_response_cbks=pkg_malloc(mod_response_cbk_no *
758 sizeof(response_function));
759 if (mod_response_cbks==0){
760 LOG(L_ERR, "init_modules(): memory allocation failure"
761 " for %d response_f callbacks\n", mod_response_cbk_no);
764 for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next) {
765 if (t->exports.response_f) {
766 mod_response_cbks[i]=t->exports.response_f;
776 * per-child initialization
778 int init_child(int rank)
784 case PROC_MAIN: type = "PROC_MAIN"; break;
785 case PROC_TIMER: type = "PROC_TIMER"; break;
786 case PROC_FIFO: type = "PROC_FIFO"; break;
787 case PROC_TCP_MAIN: type = "PROC_TCP_MAIN"; break;
788 default: type = "CHILD"; break;
790 DBG("init_child: initializing %s with rank %d\n", type, rank);
793 for(t = modules; t; t = t->next) {
794 if (t->exports.init_child_f) {
795 if ((t->exports.init_child_f(rank)) < 0) {
796 LOG(L_ERR, "init_child(): Initialization of child"
797 " %d failed\n", rank);
808 /* recursive module child initialization; (recursion is used to
809 process the module linear list in the same order in
810 which modules are loaded in config file
813 static int init_mod_child( struct sr_module* m, int rank )
816 /* iterate through the list; if error occurs,
817 propagate it up the stack
819 if (init_mod_child(m->next, rank)!=0) return -1;
820 if (m->exports.init_child_f) {
821 DBG("DEBUG: init_mod_child (%d): %s\n", rank, m->exports.name);
822 if (m->exports.init_child_f(rank)<0) {
823 LOG(L_ERR, "init_mod_child(): Error while"
824 " initializing module %s (%s)\n",
825 m->exports.name, m->path);
828 /* module correctly initialized */
832 /* no init function -- proceed with success */
842 * per-child initialization
844 int init_child(int rank)
846 return init_mod_child(modules, rank);
851 /* recursive module initialization; (recursion is used to
852 process the module linear list in the same order in
853 which modules are loaded in config file
856 static int init_mod( struct sr_module* m )
859 /* iterate through the list; if error occurs,
860 propagate it up the stack
862 if (init_mod(m->next)!=0) return -1;
863 if (m->exports.init_f) {
864 DBG("DEBUG: init_mod: %s\n", m->exports.name);
865 if (m->exports.init_f()!=0) {
866 LOG(L_ERR, "init_mod(): Error while initializing"
868 m->exports.name, m->path);
871 /* module correctly initialized */
875 /* no init function -- proceed with success */
884 * Initialize all loaded modules, the initialization
885 * is done *AFTER* the configuration file is parsed
887 int init_modules(void)
892 i = init_mod(modules);
896 for(t = modules; t; t = t->next)
897 if (t->exports.response_f)
898 mod_response_cbk_no++;
899 mod_response_cbks=pkg_malloc(mod_response_cbk_no *
900 sizeof(response_function));
901 if (mod_response_cbks==0){
902 LOG(L_ERR, "init_modules(): memory allocation failure"
903 " for %d response_f callbacks\n", mod_response_cbk_no);
906 for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next)
907 if (t->exports.response_f) {
908 mod_response_cbks[i]=t->exports.response_f;
918 action_u_t *fixup_get_param(void **cur_param, int cur_param_no,
919 int required_param_no)
922 /* cur_param points to a->u.string, get pointer to a */
923 a = (void*) ((char *)cur_param - ((char *)&a2.u.string-(char *)&a2));
924 return a + required_param_no - cur_param_no;
927 int fixup_get_param_count(void **cur_param, int cur_param_no)
930 a = fixup_get_param(cur_param, cur_param_no, 0);
939 /** get a pointer to a parameter internal type.
941 * @return pointer to the parameter internal type.
943 action_param_type* fixup_get_param_ptype(void** param)
946 a = (void*)((char*)param - (char*)&(((action_u_t*)(0))->u.string));
951 /** get a parameter internal type.
952 * @see fixup_get_param_ptype().
953 * @return paramter internal type.
955 action_param_type fixup_get_param_type(void** param)
957 return *fixup_get_param_ptype(param);
962 /* fixes flag params (resolves possible named flags)
963 * use PARAM_USE_FUNC|PARAM_STRING as a param. type and create
964 * a wrapper function that does just:
965 * return fix_flag(type, val, "my_module", "my_param", &flag_var)
966 * see also param_func_t.
968 int fix_flag( modparam_t type, void* val,
969 char* mod_name, char* param_name, int* flag)
977 if ((type & PARAM_STRING)==0){
978 LOG(L_CRIT, "BUG: %s: fix_flag(%s): bad parameter type\n",
979 mod_name, param_name);
985 /* try to see if it's a number */
986 num = str2s(s, len, &err);
988 /* see if it's in the name:<no> format */
991 f= str2s(p+1, strlen(p+1), &err);
993 LOG(L_ERR, "ERROR: %s: invalid %s format:"
994 " \"%s\"", mod_name, param_name, s);
999 if ((num=get_flag_no(s, len))<0){
1000 /* not declared yet, declare it */
1001 num=register_flag(s, f);
1004 LOG(L_ERR, "ERROR: %s: bad %s %s\n", mod_name, param_name, s);
1006 } else if ((f>0) && (num!=f)){
1007 LOG(L_ERR, "WARNING: %s: flag %s already defined"
1008 " as %d (and not %d), using %s:%d\n",
1009 mod_name, s, num, f, s, num);
1017 * Common function parameter fixups
1020 /** Generic parameter fixup function.
1021 * Creates a fparam_t structure.
1022 * @param type contains allowed parameter types
1023 * @param param is the parameter that will be fixed-up
1027 * 1 if the param doesn't match the specified type
1030 int fix_param(int type, void** param)
1037 p = (fparam_t*)pkg_malloc(sizeof(fparam_t));
1039 ERR("No memory left\n");
1040 return E_OUT_OF_MEM;
1042 memset(p, 0, sizeof(fparam_t));
1047 ERR("Invalid type value\n");
1050 p->v.asciiz = *param;
1053 p->v.str.s = (char*)*param;
1054 p->v.str.len = strlen(p->v.str.s);
1058 s.s = (char*)*param;
1059 s.len = strlen(s.s);
1060 err = str2int(&s, &num);
1068 p->fixed = (void*)(long)num;
1071 if ((p->v.regex = pkg_malloc(sizeof(regex_t))) == 0) {
1072 ERR("No memory left\n");
1075 if (regcomp(p->v.regex, *param,
1076 REG_EXTENDED|REG_ICASE|REG_NEWLINE)) {
1077 pkg_free(p->v.regex);
1079 /* not a valid regex */
1082 p->fixed = p->v.regex;
1085 name.s = (char*)*param;
1086 name.len = strlen(name.s);
1088 if (!name.len || name.s[0] != '$') {
1089 /* Not an AVP identifier */
1094 if (parse_avp_ident(&name, &p->v.avp) < 0) {
1095 /* invalid avp identifier (=> no match) */
1101 name.s = (char*)*param;
1102 name.len = strlen(name.s);
1104 if (!name.len || name.s[0] != '@') {
1105 /* Not a select identifier */
1108 if (parse_select(&name.s, &p->v.select) < 0) {
1109 ERR("Error while parsing select identifier\n");
1116 s.len = strlen(s.s);
1117 p->v.subst = subst_parser(&s);
1119 ERR("Error while parsing regex substitution\n");
1125 name.s = (char*)*param;
1126 name.len = strlen(name.s);
1128 if (!name.len || name.s[0] != '$'){
1129 /* not a pvs identifier */
1132 p->v.pvs=pkg_malloc(sizeof(pv_spec_t));
1134 ERR("out of memory while parsing pv_spec_t\n");
1137 if (pv_parse_spec2(&name, p->v.pvs, 1)==0){
1138 /* not a valid pvs identifier (but it might be an avp) */
1143 p->fixed = p->v.pvs;
1146 name.s = (char*)*param;
1147 name.len = strlen(name.s);
1148 if (pv_parse_format(&name, &p->v.pve)<0){
1149 ERR("bad PVE format: \"%.*s\"\n", name.len, name.s);
1170 /** fparam_t free function.
1171 * Frees the "content" of a fparam, but not the fparam itself.
1172 * Assumes pkg_malloc'ed content.
1173 * @param fp - fparam to be freed
1176 void fparam_free_contents(fparam_t* fp)
1183 case FPARAM_STRING: /* asciiz string, not str */
1190 regfree(fp->v.regex);
1191 pkg_free(fp->v.regex);
1196 free_avp_name(&fp->v.avp.flags, &fp->v.avp.name);
1200 free_select(fp->v.select);
1206 subst_expr_free(fp->v.subst);
1212 pv_spec_free(fp->v.pvs);
1218 pv_elem_free_all(fp->v.pve);
1231 /** fix a param to one of the given types (mask).
1233 * @param types - bitmap of the allowed types (e.g. FPARAM_INT|FPARAM_STR)
1234 * @param param - value/result
1235 * @return - 0 on success, -1 on error, 1 if param doesn't
1236 * match any of the types
1238 int fix_param_types(int types, void** param)
1243 if (fixup_get_param_type(param) == STRING_RVE_ST &&
1244 (types & (FPARAM_INT|FPARAM_STR|FPARAM_STRING))) {
1245 /* if called with a RVE already converted to string =>
1246 don't try AVP, PVAR or SELECT (to avoid double
1247 deref., e.g.: $foo="$bar"; f($foo) ) */
1248 types &= ~ (FPARAM_AVP|FPARAM_PVS|FPARAM_SELECT|FPARAM_PVE);
1250 for (t=types & ~(types-1); types; types&=(types-1), t=types & ~(types-1)){
1251 if ((ret=fix_param(t, param))<=0) return ret;
1259 * Fixup variable string, the parameter can be
1260 * AVP, SELECT, or ordinary string. AVP and select
1261 * identifiers will be resolved to their values during
1264 * The parameter value will be converted to fparam structure
1265 * This function returns -1 on an error
1267 int fixup_var_str_12(void** param, int param_no)
1270 if (fixup_get_param_type(param) != STRING_RVE_ST) {
1271 /* if called with a RVE already converted to string =>
1272 don't try AVP, PVAR or SELECT (to avoid double
1273 deref., e.g.: $foo="$bar"; f($foo) ) */
1274 if ((sr_cfg_compat!=SR_COMPAT_SER) &&
1275 ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
1276 if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
1277 if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
1279 if ((ret = fix_param(FPARAM_STR, param)) <= 0) return ret;
1280 ERR("Error while fixing parameter, AVP, SELECT, and str conversions"
1285 /* Same as fixup_var_str_12 but applies to the 1st parameter only */
1286 int fixup_var_str_1(void** param, int param_no)
1288 if (param_no == 1) return fixup_var_str_12(param, param_no);
1292 /* Same as fixup_var_str_12 but applies to the 2nd parameter only */
1293 int fixup_var_str_2(void** param, int param_no)
1295 if (param_no == 2) return fixup_var_str_12(param, param_no);
1301 * Fixup variable integer, the parameter can be
1302 * AVP, SELECT, or ordinary integer. AVP and select
1303 * identifiers will be resolved to their values and
1304 * converted to int if necessary during runtime
1306 * The parameter value will be converted to fparam structure
1307 * This function returns -1 on an error
1309 int fixup_var_int_12(void** param, int param_no)
1312 if (fixup_get_param_type(param) != STRING_RVE_ST) {
1313 /* if called with a RVE already converted to string =>
1314 don't try AVP, PVAR or SELECT (to avoid double
1315 deref., e.g.: $foo="$bar"; f($foo) ) */
1316 if ((sr_cfg_compat!=SR_COMPAT_SER) &&
1317 ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
1318 if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
1319 if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
1321 if ((ret = fix_param(FPARAM_INT, param)) <= 0) return ret;
1322 ERR("Error while fixing parameter, AVP, SELECT, and int conversions"
1327 /* Same as fixup_var_int_12 but applies to the 1st parameter only */
1328 int fixup_var_int_1(void** param, int param_no)
1330 if (param_no == 1) return fixup_var_int_12(param, param_no);
1334 /* Same as fixup_var_int_12 but applies to the 2nd parameter only */
1335 int fixup_var_int_2(void** param, int param_no)
1337 if (param_no == 2) return fixup_var_int_12(param, param_no);
1343 * The parameter must be a regular expression which must compile, the
1344 * parameter will be converted to compiled regex
1346 int fixup_regex_12(void** param, int param_no)
1350 if ((ret = fix_param(FPARAM_REGEX, param)) <= 0) return ret;
1351 ERR("Error while compiling regex in function parameter\n");
1355 /* Same as fixup_regex_12 but applies to the 1st parameter only */
1356 int fixup_regex_1(void** param, int param_no)
1358 if (param_no == 1) return fixup_regex_12(param, param_no);
1362 /* Same as fixup_regex_12 but applies to the 2nd parameter only */
1363 int fixup_regex_2(void** param, int param_no)
1365 if (param_no == 2) return fixup_regex_12(param, param_no);
1370 * The string parameter will be converted to integer
1372 int fixup_int_12(void** param, int param_no)
1376 if ((ret = fix_param(FPARAM_INT, param)) <= 0) return ret;
1377 ERR("Cannot function parameter to integer\n");
1382 /* Same as fixup_int_12 but applies to the 1st parameter only */
1383 int fixup_int_1(void** param, int param_no)
1385 if (param_no == 1) return fixup_int_12(param, param_no);
1389 /* Same as fixup_int_12 but applies to the 2nd parameter only */
1390 int fixup_int_2(void** param, int param_no)
1392 if (param_no == 2) return fixup_int_12(param, param_no);
1397 * Parse the parameter as static string, do not resolve
1398 * AVPs or selects, convert the parameter to str structure
1400 int fixup_str_12(void** param, int param_no)
1404 if ((ret = fix_param(FPARAM_STR, param)) <= 0) return ret;
1405 ERR("Cannot function parameter to string\n");
1409 /* Same as fixup_str_12 but applies to the 1st parameter only */
1410 int fixup_str_1(void** param, int param_no)
1412 if (param_no == 1) return fixup_str_12(param, param_no);
1416 /* Same as fixup_str_12 but applies to the 2nd parameter only */
1417 int fixup_str_2(void** param, int param_no)
1419 if (param_no == 2) return fixup_str_12(param, param_no);
1425 #define PV_PRINT_BUF_SIZE 1024
1426 #define PV_PRINT_BUF_NO 3
1427 /** Get the function parameter value as string.
1428 * @return 0 - Success
1429 * -1 - Cannot get value
1431 int get_str_fparam(str* dst, struct sip_msg* msg, fparam_t* param)
1437 static int buf_itr = 0; /* ugly hack needed for PVE */
1438 static char pve_buf[PV_PRINT_BUF_NO][PV_PRINT_BUF_SIZE];
1440 switch(param->type) {
1446 dst->s = param->v.asciiz;
1447 dst->len = strlen(param->v.asciiz);
1450 *dst = param->v.str;
1453 avp = search_first_avp(param->v.avp.flags, param->v.avp.name,
1455 if (unlikely(!avp)) {
1456 DBG("Could not find AVP from function parameter '%s'\n",
1460 if (likely(avp->flags & AVP_VAL_STR)) {
1463 /* The caller does not know of what type the AVP will be so
1464 * convert int AVPs into string here
1466 dst->s = int2str(val.n, &dst->len);
1470 ret = run_select(dst, param->v.select, msg);
1471 if (unlikely(ret < 0 || ret > 0)) return -1;
1474 if (likely((pv_get_spec_value(msg, param->v.pvs, &pv_val)==0) &&
1475 ((pv_val.flags&(PV_VAL_NULL|PV_VAL_STR))==PV_VAL_STR))){
1478 ERR("Could not convert PV to str\n");
1483 dst->s=pve_buf[buf_itr];
1484 dst->len=PV_PRINT_BUF_SIZE;
1485 buf_itr = (buf_itr+1)%PV_PRINT_BUF_NO;
1486 if (unlikely(pv_printf(msg, param->v.pve, dst->s, &dst->len)!=0)){
1487 ERR("Could not convert the PV-formated string to str\n");
1497 /** Get the function parameter value as integer.
1498 * @return 0 - Success
1499 * -1 - Cannot get value
1501 int get_int_fparam(int* dst, struct sip_msg* msg, fparam_t* param)
1509 switch(param->type) {
1519 avp = search_first_avp(param->v.avp.flags, param->v.avp.name,
1521 if (unlikely(!avp)) {
1522 DBG("Could not find AVP from function parameter '%s'\n",
1526 if (avp->flags & AVP_VAL_STR) {
1527 if (str2int(&val.s, (unsigned int*)dst) < 0) {
1528 ERR("Could not convert AVP string value to int\n");
1536 ret = run_select(&tmp, param->v.select, msg);
1537 if (unlikely(ret < 0 || ret > 0)) return -1;
1538 if (unlikely(str2int(&tmp, (unsigned int*)dst) < 0)) {
1539 ERR("Could not convert select result to int\n");
1544 if (likely((pv_get_spec_value(msg, param->v.pvs, &pv_val)==0) &&
1545 ((pv_val.flags&(PV_VAL_NULL|PV_VAL_INT))==PV_VAL_INT))){
1548 ERR("Could not convert PV to int\n");
1559 * Retrieve the compiled RegExp.
1560 * @return: 0 for success, negative on error.
1562 int get_regex_fparam(regex_t *dst, struct sip_msg* msg, fparam_t* param)
1564 switch (param->type) {
1566 *dst = *param->v.regex;
1569 ERR("unexpected parameter type (%d), instead of regexp.\n",
1577 /** returns true if a fixup is a fparam_t* one.
1578 * Used to automatically detect fparam fixups that can be used with non
1580 * @param f - function pointer
1581 * @return 1 for fparam fixups, 0 for others.
1583 int is_fparam_rve_fixup(fixup_function f)
1585 if (f == fixup_var_str_12 ||
1586 f == fixup_var_str_1 ||
1587 f == fixup_var_str_2 ||
1588 f == fixup_var_int_12 ||
1589 f == fixup_var_int_1 ||
1590 f == fixup_var_int_2 ||
1591 f == fixup_int_12 ||
1594 f == fixup_str_12 ||