Sfoglia il codice sorgente

Merge branch 'master' of ssh://git.sip-router.org/sip-router

* 'master' of ssh://git.sip-router.org/sip-router: (31 commits)
  app_lua: several tm functions added to Lua api
  tm: added export structure for extra API
  app_lua: added several core functions to sr package
  app_lua: helper function to return error code
  app_lua: fixed name of module in modparam examples
  app_lua: added registrar API to Lua
  registrar(k): exported inter-module API
  usrloc(k): db modes defines moved in usrloc.h
  usrloc(k)API function get_udomain()
  usrloc(k): preload parameter exported
  usrloc(k): new parameter 'preload'
  sqlops: added LF to end of debug message
  app_lua: sr.maxfwd mentioned as available submodule
  maxfwd(k): added inter-module API structure
  auth_db(k): added new file api.h
  app_lua: typo in register parameter
  app_lua: added functions from auth_db api
  auth_db(k): close db handle only for second param fixup
  app_lua: note about submodule sr.auth
  app_lua: exported functions from AUTH API to Lua
  ...
Jan Janak 15 anni fa
parent
commit
1b209e395c
44 ha cambiato i file con 2373 aggiunte e 226 eliminazioni
  1. 14 5
      modules/app_lua/README
  2. 18 0
      modules/app_lua/app_lua_api.c
  3. 2 0
      modules/app_lua/app_lua_api.h
  4. 1033 67
      modules/app_lua/app_lua_exp.c
  5. 421 6
      modules/app_lua/app_lua_sr.c
  6. 44 2
      modules/app_lua/doc/app_lua_admin.xml
  7. 3 0
      modules/auth/api.c
  8. 41 3
      modules/auth/api.h
  9. 137 64
      modules/auth/auth_mod.c
  10. 17 6
      modules/tm/tm.c
  11. 19 0
      modules/tm/tm_load.c
  12. 41 0
      modules/tm/tm_load.h
  13. 63 0
      modules_k/auth_db/api.h
  14. 3 1
      modules_k/auth_db/authdb_mod.c
  15. 67 29
      modules_k/auth_db/authorize.c
  16. 6 0
      modules_k/auth_db/authorize.h
  17. 62 0
      modules_k/maxfwd/api.h
  18. 33 3
      modules_k/maxfwd/maxfwd.c
  19. 79 0
      modules_k/registrar/api.c
  20. 72 0
      modules_k/registrar/api.h
  21. 5 5
      modules_k/registrar/lookup.c
  22. 2 1
      modules_k/registrar/lookup.h
  23. 25 4
      modules_k/registrar/reg_mod.c
  24. 2 2
      modules_k/registrar/save.c
  25. 2 1
      modules_k/registrar/save.h
  26. 2 0
      modules_k/rr/api.c
  27. 19 9
      modules_k/rr/api.h
  28. 1 3
      modules_k/rr/loose.c
  29. 1 3
      modules_k/rr/loose.h
  30. 13 2
      modules_k/rr/rr_mod.c
  31. 2 2
      modules_k/sqlops/sql_api.c
  32. 2 2
      modules_k/sqlops/sql_api.h
  33. 1 1
      modules_k/sqlops/sqlops.c
  34. 18 0
      modules_k/usrloc/README
  35. 24 0
      modules_k/usrloc/dlist.c
  36. 9 0
      modules_k/usrloc/dlist.h
  37. 23 0
      modules_k/usrloc/doc/usrloc_admin.xml
  38. 1 0
      modules_k/usrloc/ucontact.c
  39. 1 0
      modules_k/usrloc/udomain.c
  40. 36 0
      modules_k/usrloc/ul_mod.c
  41. 0 5
      modules_k/usrloc/ul_mod.h
  42. 1 0
      modules_k/usrloc/urecord.c
  43. 1 0
      modules_k/usrloc/usrloc.c
  44. 7 0
      modules_k/usrloc/usrloc.h

+ 14 - 5
modules/app_lua/README

@@ -10,7 +10,7 @@ Daniel-Constantin Mierla
 
 
    <[email protected]>
    <[email protected]>
 
 
-   Copyright © 2010 Daniel-Constantin Mierla (asipto.com)
+   Copyright © 2010 Daniel-Constantin Mierla (asipto.com)
      __________________________________________________________________
      __________________________________________________________________
 
 
    Table of Contents
    Table of Contents
@@ -116,27 +116,36 @@ Chapter 1. Admin Guide
    use lua_run(function, params) to execute a function from the script at
    use lua_run(function, params) to execute a function from the script at
    runtime.
    runtime.
 
 
-   Default value is "null".
+   Default value is “null�.
 
 
    Example 1.1. Set load parameter
    Example 1.1. Set load parameter
 ...
 ...
-modparam("lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
+modparam("app_lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
 ...
 ...
 
 
 3.2. register (string)
 3.2. register (string)
 
 
    Use this function to register optional SIP Router submodules to Lua.
    Use this function to register optional SIP Router submodules to Lua.
    Available submodules are:
    Available submodules are:
+     * auth - register functions from auth module under 'sr.auth'.
+     * auth_db - register functions from auth_db module under
+       'sr.auth_db'.
+     * maxfwd - register functions from maxfwd module under 'sr.maxfwd'.
+     * registrar - register functions from registrar module under
+       'sr.registrar'.
+     * rr - register functions from rr module under 'sr.rr'.
+     * sqlops - register functions from sqlops module under 'sr.sqlops'.
      * sl - register functions from sl module under 'sr.sl'.
      * sl - register functions from sl module under 'sr.sl'.
+     * tm - register functions from tm module under 'sr.tm'.
 
 
    Note that 'sr', 'sr.hdr' and 'sr.pv' modules are always registered to
    Note that 'sr', 'sr.hdr' and 'sr.pv' modules are always registered to
    Lua.
    Lua.
 
 
-   Default value is "null".
+   Default value is “null�.
 
 
    Example 1.2. Set register parameter
    Example 1.2. Set register parameter
 ...
 ...
-modparam("lua", "register", "sr")
+modparam("app_lua", "register", "sl")
 ...
 ...
 
 
 4. Exported Functions
 4. Exported Functions

+ 18 - 0
modules/app_lua/app_lua_api.c

@@ -271,6 +271,24 @@ int lua_sr_initialized(void)
 	return 1;
 	return 1;
 }
 }
 
 
+/**
+ *
+ */
+int app_lua_return_int(lua_State *L, int v)
+{
+	lua_pushinteger(L, v);
+	return 1;
+}
+
+/**
+ *
+ */
+int app_lua_return_error(lua_State *L)
+{
+	lua_pushinteger(L, -1);
+	return 1;
+}
+
 /**
 /**
  *
  *
  */
  */

+ 2 - 0
modules/app_lua/app_lua_api.h

@@ -60,6 +60,8 @@ int app_lua_run(struct sip_msg *msg, char *func, char *p1, char *p2,
 int app_lua_return_boolean(lua_State *L, int b);
 int app_lua_return_boolean(lua_State *L, int b);
 int app_lua_return_false(lua_State *L);
 int app_lua_return_false(lua_State *L);
 int app_lua_return_true(lua_State *L);
 int app_lua_return_true(lua_State *L);
+int app_lua_return_int(lua_State *L, int v);
+int app_lua_return_error(lua_State *L);
 
 
 void app_lua_dump_stack(lua_State *L);
 void app_lua_dump_stack(lua_State *L);
 
 

+ 1033 - 67
modules/app_lua/app_lua_exp.c

@@ -28,15 +28,28 @@
 
 
 #include "../../sr_module.h"
 #include "../../sr_module.h"
 #include "../../dprint.h"
 #include "../../dprint.h"
+#include "../../route.h"
 #include "../../ut.h"
 #include "../../ut.h"
 
 
 #include "../../modules/sl/sl.h"
 #include "../../modules/sl/sl.h"
 #include "../../modules/tm/tm_load.h"
 #include "../../modules/tm/tm_load.h"
+#include "../../modules_k/sqlops/sql_api.h"
+#include "../../modules_k/rr/api.h"
+#include "../../modules/auth/api.h"
+#include "../../modules_k/auth_db/api.h"
+#include "../../modules_k/maxfwd/api.h"
+#include "../../modules_k/registrar/api.h"
 
 
 #include "app_lua_api.h"
 #include "app_lua_api.h"
 
 
-#define SR_LUA_EXP_MOD_SL	(1<<0)
-#define SR_LUA_EXP_MOD_TM	(1<<1)
+#define SR_LUA_EXP_MOD_SL         (1<<0)
+#define SR_LUA_EXP_MOD_TM         (1<<1)
+#define SR_LUA_EXP_MOD_SQLOPS     (1<<2)
+#define SR_LUA_EXP_MOD_RR         (1<<3)
+#define SR_LUA_EXP_MOD_AUTH       (1<<4)
+#define SR_LUA_EXP_MOD_AUTH_DB    (1<<5)
+#define SR_LUA_EXP_MOD_MAXFWD     (1<<6)
+#define SR_LUA_EXP_MOD_REGISTRAR  (1<<7)
 
 
 /**
 /**
  *
  *
@@ -44,14 +57,45 @@
 static unsigned int _sr_lua_exp_reg_mods = 0;
 static unsigned int _sr_lua_exp_reg_mods = 0;
 
 
 /**
 /**
- *
+ * auth
+ */
+static auth_api_s_t _lua_authb;
+
+/**
+ * auth_db
+ */
+static auth_db_api_t _lua_auth_dbb;
+
+/**
+ * maxfwd
+ */
+static maxfwd_api_t _lua_maxfwdb;
+
+/**
+ * registrar
+ */
+static registrar_api_t _lua_registrarb;
+
+/**
+ * rr
+ */
+static rr_api_t _lua_rrb;
+
+/**
+ * sqlops
+ */
+static sqlops_api_t _lua_sqlopsb;
+
+/**
+ * sl
  */
  */
 static sl_api_t _lua_slb;
 static sl_api_t _lua_slb;
 
 
 /**
 /**
  * tm
  * tm
  */
  */
-static tm_api_t _lua_tmb;
+static tm_api_t  _lua_tmb;
+static tm_xapi_t _lua_xtmb;
 
 
 /**
 /**
  *
  *
@@ -68,27 +112,26 @@ static int lua_sr_sl_send_reply (lua_State *L)
 	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL))
 	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL))
 	{
 	{
 		LM_WARN("weird: sl function executed but module not registered\n");
 		LM_WARN("weird: sl function executed but module not registered\n");
-		return app_lua_return_false(L);
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
 	}
 	}
 
 
 	code = lua_tointeger(L, -2);
 	code = lua_tointeger(L, -2);
 
 
 	if(code<100 || code>=800)
 	if(code<100 || code>=800)
-		return app_lua_return_false(L);
+		return app_lua_return_error(L);
 	
 	
 	txt.s = (char*)lua_tostring(L, -1);
 	txt.s = (char*)lua_tostring(L, -1);
-	if(txt.s!=NULL && env_L->msg!=NULL)
-	{
-		txt.len = strlen(txt.s);
-		ret = _lua_slb.freply(env_L->msg, code, &txt);
-		if(ret<0)
-		{
-			LM_WARN("sl send_reply returned false\n");
-			return app_lua_return_false(L);
-		}
-		return app_lua_return_true(L);
-	}
-	return app_lua_return_false(L);
+	if(txt.s==NULL || env_L->msg==NULL)
+		return app_lua_return_error(L);
+
+	txt.len = strlen(txt.s);
+	ret = _lua_slb.freply(env_L->msg, code, &txt);
+	return app_lua_return_int(L, ret);
 }
 }
 
 
 /**
 /**
@@ -107,6 +150,11 @@ static int lua_sr_sl_get_reply_totag (lua_State *L)
 		LM_WARN("weird: sl function executed but module not registered\n");
 		LM_WARN("weird: sl function executed but module not registered\n");
 		return app_lua_return_false(L);
 		return app_lua_return_false(L);
 	}
 	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
 	ret = _lua_slb.get_reply_totag(env_L->msg, &txt);
 	ret = _lua_slb.get_reply_totag(env_L->msg, &txt);
 	if(ret<0)
 	if(ret<0)
 	{
 	{
@@ -141,27 +189,26 @@ static int lua_sr_tm_t_reply(lua_State *L)
 	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
 	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
 	{
 	{
 		LM_WARN("weird: tm function executed but module not registered\n");
 		LM_WARN("weird: tm function executed but module not registered\n");
-		return app_lua_return_false(L);
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
 	}
 	}
 
 
 	code = lua_tointeger(L, -2);
 	code = lua_tointeger(L, -2);
 
 
 	if(code<100 || code>=800)
 	if(code<100 || code>=800)
-		return app_lua_return_false(L);
+		return app_lua_return_error(L);
 
 
 	txt = (char*)lua_tostring(L, -1);
 	txt = (char*)lua_tostring(L, -1);
 	if(txt!=NULL && env_L->msg!=NULL)
 	if(txt!=NULL && env_L->msg!=NULL)
 	{
 	{
 		ret = _lua_tmb.t_reply(env_L->msg, code, txt);
 		ret = _lua_tmb.t_reply(env_L->msg, code, txt);
-		if(ret<0)
-		{
-			LM_WARN("tm t_reply returned false\n");
-			/* shall push FALSE to Lua ?!? */
-			return app_lua_return_false(L);
-		}
-		return app_lua_return_true(L);
+		return app_lua_return_int(L, ret);
 	}
 	}
-	return app_lua_return_false(L);
+	return app_lua_return_error(L);
 }
 }
 
 
 /**
 /**
@@ -177,15 +224,188 @@ static int lua_sr_tm_t_relay(lua_State *L)
 	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
 	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
 	{
 	{
 		LM_WARN("weird: tm function executed but module not registered\n");
 		LM_WARN("weird: tm function executed but module not registered\n");
-		return app_lua_return_false(L);
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
 	}
 	}
 	ret = _lua_tmb.t_relay(env_L->msg, NULL, NULL);
 	ret = _lua_tmb.t_relay(env_L->msg, NULL, NULL);
-	if(ret<0)
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_on_failure(lua_State *L)
+{
+	char *name;
+	int i;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
 	{
 	{
-		LM_WARN("tm t_relay returned false\n");
-		return app_lua_return_false(L);
+		LM_WARN("weird: tm function executed but module not registered\n");
+		return app_lua_return_error(L);
 	}
 	}
-	return app_lua_return_true(L);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+
+	name = (char*)lua_tostring(L, -1);
+	if(name==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+
+	i = route_get(&failure_rt, name);
+	if(failure_rt.rlist[i]==0)
+	{
+		LM_WARN("no actions in failure_route[%s]\n", name);
+		return app_lua_return_error(L);
+	}
+
+	_lua_xtmb.t_on_failure((unsigned int)i);
+	return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_on_branch(lua_State *L)
+{
+	char *name;
+	int i;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
+	{
+		LM_WARN("weird: tm function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+
+	name = (char*)lua_tostring(L, -1);
+	if(name==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+
+	i = route_get(&branch_rt, name);
+	if(branch_rt.rlist[i]==0)
+	{
+		LM_WARN("no actions in branch_route[%s]\n", name);
+		return app_lua_return_error(L);
+	}
+
+	_lua_xtmb.t_on_branch((unsigned int)i);
+	return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_on_reply(lua_State *L)
+{
+	char *name;
+	int i;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
+	{
+		LM_WARN("weird: tm function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+
+	name = (char*)lua_tostring(L, -1);
+	if(name==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+
+	i = route_get(&onreply_rt, name);
+	if(onreply_rt.rlist[i]==0)
+	{
+		LM_WARN("no actions in onreply_route[%s]\n", name);
+		return app_lua_return_error(L);
+	}
+
+	_lua_xtmb.t_on_reply((unsigned int)i);
+	return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_check_trans(lua_State *L)
+{
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
+	{
+		LM_WARN("weird: tm function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+
+	ret = _lua_xtmb.t_check_trans(env_L->msg);
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_is_canceled(lua_State *L)
+{
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM))
+	{
+		LM_WARN("weird: tm function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+
+	ret = _lua_xtmb.t_is_canceled(env_L->msg);
+	return app_lua_return_int(L, ret);
 }
 }
 
 
 
 
@@ -193,8 +413,13 @@ static int lua_sr_tm_t_relay(lua_State *L)
  *
  *
  */
  */
 static const luaL_reg _sr_tm_Map [] = {
 static const luaL_reg _sr_tm_Map [] = {
-	{"t_reply", lua_sr_tm_t_reply},
-	{"t_relay", lua_sr_tm_t_relay},
+	{"t_reply",        lua_sr_tm_t_reply},
+	{"t_relay",        lua_sr_tm_t_relay},
+	{"t_on_failure",   lua_sr_tm_t_on_failure},
+	{"t_on_branch",    lua_sr_tm_t_on_branch},
+	{"t_on_reply",     lua_sr_tm_t_on_reply},
+	{"t_check_trans",  lua_sr_tm_t_check_trans},
+	{"t_is_canceled",  lua_sr_tm_t_is_canceled},
 	{NULL, NULL}
 	{NULL, NULL}
 };
 };
 
 
@@ -202,60 +427,801 @@ static const luaL_reg _sr_tm_Map [] = {
 /**
 /**
  *
  *
  */
  */
-int lua_sr_exp_init_mod(void)
+static int lua_sr_sqlops_query(lua_State *L)
 {
 {
-	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL)
+	str scon;
+	str squery;
+	str sres;
+	int ret;
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
 	{
 	{
-		/* bind the SL API */
-		if (sl_load_api(&_lua_slb)!=0) {
-			LM_ERR("cannot bind to SL API\n");
-			return -1;
-		}
-		LM_DBG("loaded sl api\n");
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_error(L);
 	}
 	}
-	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM)
+
+	scon.s = (char*)lua_tostring(L, -3);
+	squery.s = (char*)lua_tostring(L, -2);
+	sres.s = (char*)lua_tostring(L, -1);
+	if(scon.s == NULL || squery.s == NULL || sres.s == NULL)
 	{
 	{
-		/* bind the TM API */
-		if (tm_load_api(&_lua_tmb) == -1)
-		{
-			LM_ERR("cannot bind to TM API\n");
-			return -1;
-		}
-		LM_DBG("loaded tm api\n");
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
 	}
 	}
-	return 0;
+	scon.len = strlen(scon.s);
+	squery.len = strlen(squery.s);
+	sres.len = strlen(sres.s);
+
+	ret = _lua_sqlopsb.query(&scon, &squery, &sres);
+	return app_lua_return_int(L, ret);
 }
 }
 
 
 /**
 /**
  *
  *
  */
  */
-int lua_sr_exp_register_mod(char *mname)
+static int lua_sr_sqlops_value(lua_State *L)
 {
 {
-	int len;
+	str sres;
+	int col;
+	int row;
+	sql_val_t *val;
 
 
-	len = strlen(mname);
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
+	{
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_false(L);
+	}
+	sres.s = (char*)lua_tostring(L, -3);
+	row = lua_tointeger(L, -2);
+	col = lua_tointeger(L, -1);
+	if(row<0 || col<0 || sres.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+	sres.len = strlen(sres.s);
+	if(_lua_sqlopsb.value(&sres, row, col, &val)<0)
+		return app_lua_return_false(L);
+	if(val->flags&PV_VAL_NULL)
+	{
+		lua_pushinteger(L, 0);
+		return 1;
+	}
 
 
-	if(len==2 && strcmp(mname, "sl")==0)
+	if(val->flags&PV_VAL_INT)
 	{
 	{
-		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SL;
-		return 0;
-	} else 	if(len==2 && strcmp(mname, "tm")==0) {
-		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_TM;
-		return 0;
+		lua_pushinteger(L, val->value.n);
+		return 1;
 	}
 	}
+	lua_pushlstring(L, val->value.s.s, val->value.s.len);
+	return 1;
+}
 
 
-	return -1;
+/**
+ *
+ */
+static int lua_sr_sqlops_is_null(lua_State *L)
+{
+	str sres;
+	int col;
+	int row;
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
+	{
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_false(L);
+	}
+	sres.s = (char*)lua_tostring(L, -3);
+	row = lua_tointeger(L, -2);
+	col = lua_tointeger(L, -1);
+	if(row<0 || col<0 || sres.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+	sres.len = strlen(sres.s);
+	if(_lua_sqlopsb.is_null(&sres, row, col)==1)
+		return app_lua_return_true(L);
+	return app_lua_return_false(L);
 }
 }
 
 
 /**
 /**
  *
  *
  */
  */
-void lua_sr_exp_openlibs(lua_State *L)
+static int lua_sr_sqlops_column(lua_State *L)
 {
 {
-	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL)
-		luaL_openlib(L, "sr.sl",   _sr_sl_Map,   0);
-	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM)
-		luaL_openlib(L, "sr.tm",   _sr_tm_Map,   0);
+	str sres;
+	int col;
+	str name = {0, 0};
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
+	{
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_false(L);
+	}
+	sres.s = (char*)lua_tostring(L, -2);
+	col = lua_tointeger(L, -1);
+	if(col<0 || sres.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+	sres.len = strlen(sres.s);
+	if(_lua_sqlopsb.column(&sres, col, &name)<0)
+		return app_lua_return_false(L);
+	lua_pushlstring(L, name.s, name.len);
+	return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_nrows(lua_State *L)
+{
+	str sres;
+	int rows;
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
+	{
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_false(L);
+	}
+	sres.s = (char*)lua_tostring(L, -1);
+	if(sres.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+	sres.len = strlen(sres.s);
+	rows = _lua_sqlopsb.nrows(&sres);
+	if(rows<0)
+		return app_lua_return_false(L);
+	lua_pushinteger(L, rows);
+	return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_ncols(lua_State *L)
+{
+	str sres;
+	int cols;
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
+	{
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_false(L);
+	}
+	sres.s = (char*)lua_tostring(L, -1);
+	if(sres.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+	sres.len = strlen(sres.s);
+	cols = _lua_sqlopsb.ncols(&sres);
+	if(cols<0)
+		return app_lua_return_false(L);
+	lua_pushinteger(L, cols);
+	return 1;
 }
 }
 
 
+/**
+ *
+ */
+static int lua_sr_sqlops_reset(lua_State *L)
+{
+	str sres;
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS))
+	{
+		LM_WARN("weird: sqlops function executed but module not registered\n");
+		return app_lua_return_false(L);
+	}
+	sres.s = (char*)lua_tostring(L, -1);
+	if(sres.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+	sres.len = strlen(sres.s);
+	_lua_sqlopsb.reset(&sres);
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static const luaL_reg _sr_sqlops_Map [] = {
+	{"query",   lua_sr_sqlops_query},
+	{"value",   lua_sr_sqlops_value},
+	{"is_null", lua_sr_sqlops_is_null},
+	{"column",  lua_sr_sqlops_column},
+	{"nrows",   lua_sr_sqlops_nrows},
+	{"ncols",   lua_sr_sqlops_ncols},
+	{"reset",   lua_sr_sqlops_reset},
+	{NULL, NULL}
+};
+
+
+/**
+ *
+ */
+static int lua_sr_rr_record_route(lua_State *L)
+{
+	int ret;
+	str sv = {0, 0};
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_RR))
+	{
+		LM_WARN("weird: rr function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)==1)
+	{
+		sv.s = (char*)lua_tostring(L, -1);
+		if(sv.s!=NULL)
+			sv.len = strlen(sv.s);
+	}
+	ret = _lua_rrb.record_route(env_L->msg, (sv.len>0)?&sv:NULL);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_rr_loose_route(lua_State *L)
+{
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_RR))
+	{
+		LM_WARN("weird: rr function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	ret = _lua_rrb.loose_route(env_L->msg);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_reg _sr_rr_Map [] = {
+	{"record_route",    lua_sr_rr_record_route},
+	{"loose_route",     lua_sr_rr_loose_route},
+	{NULL, NULL}
+};
+
+
+static int lua_sr_auth_challenge(lua_State *L, int hftype)
+{
+	int ret;
+	str realm = {0, 0};
+	int flags;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH))
+	{
+		LM_WARN("weird: auth function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)!=2)
+	{
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	realm.s = (char*)lua_tostring(L, -2);
+	flags   = lua_tointeger(L, -1);
+	if(flags<0 || realm.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	realm.len = strlen(realm.s);
+	ret = _lua_authb.auth_challenge(env_L->msg, &realm, flags, hftype);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_www_challenge(lua_State *L)
+{
+	return lua_sr_auth_challenge(L, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_proxy_challenge(lua_State *L)
+{
+	return lua_sr_auth_challenge(L, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_pv_authenticate(lua_State *L, int hftype)
+{
+	int ret;
+	str realm  = {0, 0};
+	str passwd = {0, 0};
+	int flags;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH))
+	{
+		LM_WARN("weird: auth function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)!=3)
+	{
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	realm.s  = (char*)lua_tostring(L, -3);
+	passwd.s = (char*)lua_tostring(L, -2);
+	flags    = lua_tointeger(L, -1);
+	if(flags<0 || realm.s==NULL || passwd.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	realm.len = strlen(realm.s);
+	passwd.len = strlen(passwd.s);
+	ret = _lua_authb.pv_authenticate(env_L->msg, &realm, &passwd, flags,
+			hftype);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_pv_www_authenticate(lua_State *L)
+{
+	return lua_sr_auth_pv_authenticate(L, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_pv_proxy_authenticate(lua_State *L)
+{
+	return lua_sr_auth_pv_authenticate(L, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_consume_credentials(lua_State *L)
+{
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH))
+	{
+		LM_WARN("weird: auth function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	ret = _lua_authb.consume_credentials(env_L->msg);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_reg _sr_auth_Map [] = {
+	{"www_challenge",            lua_sr_auth_www_challenge},
+	{"proxy_challenge",          lua_sr_auth_proxy_challenge},
+	{"pv_www_authenticate",      lua_sr_auth_pv_www_authenticate},
+	{"pv_proxy_authenticate",    lua_sr_auth_pv_proxy_authenticate},
+	{"consume_credentials",      lua_sr_auth_consume_credentials},
+	{NULL, NULL}
+};
+
+
+/**
+ *
+ */
+static int lua_sr_auth_db_authenticate(lua_State *L, hdr_types_t hftype)
+{
+	int ret;
+	str realm = {0, 0};
+	str table = {0, 0};
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH_DB))
+	{
+		LM_WARN("weird: auth function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)!=2)
+	{
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	realm.s  = (char*)lua_tostring(L, -2);
+	table.s  = (char*)lua_tostring(L, -1);
+	if(realm.s==NULL || table.s==NULL)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	realm.len = strlen(realm.s);
+	table.len = strlen(table.s);
+	ret = _lua_auth_dbb.digest_authenticate(env_L->msg, &realm, &table,
+			hftype);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_db_www_authenticate(lua_State *L)
+{
+	return lua_sr_auth_db_authenticate(L, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_db_proxy_authenticate(lua_State *L)
+{
+	return lua_sr_auth_db_authenticate(L, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+static const luaL_reg _sr_auth_db_Map [] = {
+	{"www_authenticate",      lua_sr_auth_db_www_authenticate},
+	{"proxy_authenticate",    lua_sr_auth_db_proxy_authenticate},
+	{NULL, NULL}
+};
+
+
+/**
+ *
+ */
+static int lua_sr_maxfwd_process_maxfwd(lua_State *L)
+{
+	int ret;
+	int limit;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_MAXFWD))
+	{
+		LM_WARN("weird: maxfwd function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)!=1)
+	{
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	limit = lua_tointeger(L, -1);
+	if(limit<0)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	ret = _lua_maxfwdb.process_maxfwd(env_L->msg, limit);
+
+	return app_lua_return_int(L, ret);
+}
+
+
+/**
+ *
+ */
+static const luaL_reg _sr_maxfwd_Map [] = {
+	{"process_maxfwd",      lua_sr_maxfwd_process_maxfwd},
+	{NULL, NULL}
+};
+
+
+/**
+ *
+ */
+static int lua_sr_registrar_save(lua_State *L)
+{
+	int ret;
+	int flags;
+	char *table;
+	sr_lua_env_t *env_L;
+
+	flags = 0;
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_MAXFWD))
+	{
+		LM_WARN("weird: maxfwd function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)==1)
+	{
+		table  = (char*)lua_tostring(L, -1);
+	} else if(lua_gettop(L)==2) {
+		table  = (char*)lua_tostring(L, -2);
+		flags = lua_tointeger(L, -1);
+	} else {
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	if(table==NULL || strlen(table)==0)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	ret = _lua_registrarb.save(env_L->msg, table, flags);
+
+	return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_registrar_lookup(lua_State *L)
+{
+	int ret;
+	char *table;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_MAXFWD))
+	{
+		LM_WARN("weird: maxfwd function executed but module not registered\n");
+		return app_lua_return_error(L);
+	}
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_error(L);
+	}
+	if(lua_gettop(L)!=1)
+	{
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	table  = (char*)lua_tostring(L, -1);
+	if(table==NULL || strlen(table)==0)
+	{
+		LM_WARN("invalid parameters from Lua\n");
+		return app_lua_return_error(L);
+	}
+	ret = _lua_registrarb.lookup(env_L->msg, table);
+
+	return app_lua_return_int(L, ret);
+}
+
+
+/**
+ *
+ */
+static const luaL_reg _sr_registrar_Map [] = {
+	{"save",      lua_sr_registrar_save},
+	{"lookup",    lua_sr_registrar_lookup},
+	{NULL, NULL}
+};
+
+
+/**
+ *
+ */
+int lua_sr_exp_init_mod(void)
+{
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL)
+	{
+		/* bind the SL API */
+		if (sl_load_api(&_lua_slb) < 0) {
+			LM_ERR("cannot bind to SL API\n");
+			return -1;
+		}
+		LM_DBG("loaded sl api\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM)
+	{
+		/* bind the TM API */
+		if (tm_load_api(&_lua_tmb) < 0)
+		{
+			LM_ERR("cannot bind to TM API\n");
+			return -1;
+		}
+		LM_DBG("loaded tm api\n");
+		/* bind the TM XAPI */
+		if (tm_load_xapi(&_lua_xtmb) < 0)
+		{
+			LM_ERR("cannot bind to TM XAPI\n");
+			return -1;
+		}
+		LM_DBG("loaded tm xapi\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS)
+	{
+		/* bind the SQLOPS API */
+		if (sqlops_load_api(&_lua_sqlopsb) < 0)
+		{
+			LM_ERR("cannot bind to SQLOPS API\n");
+			return -1;
+		}
+		LM_DBG("loaded sqlops api\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_RR)
+	{
+		/* bind the RR API */
+		if (rr_load_api(&_lua_rrb) < 0)
+		{
+			LM_ERR("cannot bind to RR API\n");
+			return -1;
+		}
+		LM_DBG("loaded rr api\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH)
+	{
+		/* bind the AUTH API */
+		if (auth_load_api(&_lua_authb) < 0)
+		{
+			LM_ERR("cannot bind to AUTH API\n");
+			return -1;
+		}
+		LM_DBG("loaded auth api\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH_DB)
+	{
+		/* bind the AUTH_DB API */
+		if (auth_db_load_api(&_lua_auth_dbb) < 0)
+		{
+			LM_ERR("cannot bind to AUTH_DB API\n");
+			return -1;
+		}
+		LM_DBG("loaded auth_db api\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_MAXFWD)
+	{
+		/* bind the MAXFWD API */
+		if (maxfwd_load_api(&_lua_maxfwdb) < 0)
+		{
+			LM_ERR("cannot bind to MAXFWD API\n");
+			return -1;
+		}
+		LM_DBG("loaded maxfwd api\n");
+	}
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_REGISTRAR)
+	{
+		/* bind the REGISTRAR API */
+		if (registrar_load_api(&_lua_registrarb) < 0)
+		{
+			LM_ERR("cannot bind to REGISTRAR API\n");
+			return -1;
+		}
+		LM_DBG("loaded registrar api\n");
+	}
+	return 0;
+}
+
+/**
+ *
+ */
+int lua_sr_exp_register_mod(char *mname)
+{
+	int len;
+
+	len = strlen(mname);
+
+	if(len==2 && strcmp(mname, "sl")==0)
+	{
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SL;
+		return 0;
+	} else 	if(len==2 && strcmp(mname, "tm")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_TM;
+		return 0;
+	} else 	if(len==6 && strcmp(mname, "sqlops")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SQLOPS;
+		return 0;
+	} else 	if(len==2 && strcmp(mname, "rr")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_RR;
+		return 0;
+	} else 	if(len==4 && strcmp(mname, "auth")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_AUTH;
+		return 0;
+	} else 	if(len==7 && strcmp(mname, "auth_db")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_AUTH_DB;
+		return 0;
+	} else 	if(len==6 && strcmp(mname, "maxfwd")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_MAXFWD;
+		return 0;
+	} else 	if(len==9 && strcmp(mname, "registrar")==0) {
+		_sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_REGISTRAR;
+		return 0;
+	}
+
+	return -1;
+}
+
+/**
+ *
+ */
+void lua_sr_exp_openlibs(lua_State *L)
+{
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL)
+		luaL_openlib(L, "sr.sl",         _sr_sl_Map,          0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_TM)
+		luaL_openlib(L, "sr.tm",         _sr_tm_Map,          0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SQLOPS)
+		luaL_openlib(L, "sr.sqlops",     _sr_sqlops_Map,      0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_RR)
+		luaL_openlib(L, "sr.rr",         _sr_rr_Map,          0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH)
+		luaL_openlib(L, "sr.auth",       _sr_auth_Map,        0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_AUTH_DB)
+		luaL_openlib(L, "sr.auth_db",    _sr_auth_db_Map,     0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_MAXFWD)
+		luaL_openlib(L, "sr.maxfwd",     _sr_maxfwd_Map,      0);
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_REGISTRAR)
+		luaL_openlib(L, "sr.registrar",  _sr_registrar_Map,   0);
+}
 
 

+ 421 - 6
modules/app_lua/app_lua_sr.c

@@ -34,6 +34,10 @@
 #include "../../mem/mem.h"
 #include "../../mem/mem.h"
 #include "../../data_lump.h"
 #include "../../data_lump.h"
 #include "../../data_lump_rpl.h"
 #include "../../data_lump_rpl.h"
+#include "../../forward.h"
+#include "../../flags.h"
+#include "../../dset.h"
+#include "../../parser/parse_uri.h"
 #include "../../lib/kcore/cmpapi.h"
 #include "../../lib/kcore/cmpapi.h"
 
 
 #include "app_lua_api.h"
 #include "app_lua_api.h"
@@ -271,15 +275,426 @@ error:
 	return 1;
 	return 1;
 }
 }
 
 
+/**
+ *
+ */
+static int lua_sr_is_myself (lua_State *L)
+{
+	str uri;
+	struct sip_uri puri;
+	int ret;
+
+	uri.s = (char*)lua_tostring(L, -1);
+	if(uri.s==NULL)
+	{
+		LM_ERR("invalid uri parameter\n");
+		return app_lua_return_false(L);
+	}
+	uri.len = strlen(uri.s);
+	if(uri.len>4 && (strncmp(uri.s, "sip:", 4)==0
+				|| strncmp(uri.s, "sips:", 5)==0))
+	{
+		if(parse_uri(uri.s, uri.len, &puri)!=0)
+		{
+			LM_ERR("failed to parse uri [%s]\n", uri.s);
+			return app_lua_return_false(L);
+		}
+		ret = check_self(&puri.host, (puri.port.s)?puri.port_no:0,
+				(puri.transport_val.s)?puri.proto:0);
+	} else {
+		ret = check_self(&uri, 0, 0);
+	}
+	if(ret==1)
+		return app_lua_return_true(L);
+	return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setflag (lua_State *L)
+{
+	int flag;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	flag = lua_tointeger(L, -1);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (!flag_in_range(flag))
+	{
+		LM_ERR("invalid flag parameter %d\n", flag);
+		return app_lua_return_false(L);
+	}
+
+	setflag(env_L->msg, flag);
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_resetflag (lua_State *L)
+{
+	int flag;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	flag = lua_tointeger(L, -1);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (!flag_in_range(flag))
+	{
+		LM_ERR("invalid flag parameter %d\n", flag);
+		return app_lua_return_false(L);
+	}
+
+	resetflag(env_L->msg, flag);
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_isflagset (lua_State *L)
+{
+	int flag;
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	flag = lua_tointeger(L, -1);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (!flag_in_range(flag))
+	{
+		LM_ERR("invalid flag parameter %d\n", flag);
+		return app_lua_return_false(L);
+	}
+
+	ret = isflagset(env_L->msg, flag);
+	if(ret>0)
+		return app_lua_return_true(L);
+	return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setbflag (lua_State *L)
+{
+	int flag;
+	int branch;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	if(lua_gettop(L)==1)
+	{
+		flag = lua_tointeger(L, -1);
+		branch = 0;
+	} else if(lua_gettop(L)==2) {
+		flag = lua_tointeger(L, -2);
+		branch = lua_tointeger(L, -1);
+	} else {
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (!flag_in_range(flag))
+	{
+		LM_ERR("invalid flag parameter %d\n", flag);
+		return app_lua_return_false(L);
+	}
+
+	setbflag(branch, flag);
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_resetbflag (lua_State *L)
+{
+	int flag;
+	int branch;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	if(lua_gettop(L)==1)
+	{
+		flag = lua_tointeger(L, -1);
+		branch = 0;
+	} else if(lua_gettop(L)==2) {
+		flag = lua_tointeger(L, -2);
+		branch = lua_tointeger(L, -1);
+	} else {
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (!flag_in_range(flag))
+	{
+		LM_ERR("invalid flag parameter %d\n", flag);
+		return app_lua_return_false(L);
+	}
+
+	resetbflag(branch, flag);
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_isbflagset (lua_State *L)
+{
+	int flag;
+	int branch;
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	if(lua_gettop(L)==1)
+	{
+		flag = lua_tointeger(L, -1);
+		branch = 0;
+	} else if(lua_gettop(L)==2) {
+		flag = lua_tointeger(L, -2);
+		branch = lua_tointeger(L, -1);
+	} else {
+		LM_WARN("invalid number of parameters from Lua\n");
+		return app_lua_return_false(L);
+	}
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (!flag_in_range(flag))
+	{
+		LM_ERR("invalid flag parameter %d\n", flag);
+		return app_lua_return_false(L);
+	}
+
+	ret = isbflagset(branch, flag);
+	if(ret>0)
+		return app_lua_return_true(L);
+	return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_seturi (lua_State *L)
+{
+	struct action  act;
+	struct run_act_ctx h;
+	str uri;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	uri.s = (char*)lua_tostring(L, -1);
+	if(uri.s==NULL)
+	{
+		LM_ERR("invalid uri parameter\n");
+		return app_lua_return_false(L);
+	}
+	uri.len = strlen(uri.s);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	memset(&act, 0, sizeof(act));
+	act.val[0].type = STRING_ST;
+	act.val[0].u.string = uri.s;
+	act.type = SET_URI_T;
+	init_run_actions_ctx(&h);
+	if (do_action(&h, &act, env_L->msg)<0)
+	{
+		LM_ERR("do action failed\n");
+		return app_lua_return_false(L);
+	}
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setuser (lua_State *L)
+{
+	struct action  act;
+	struct run_act_ctx h;
+	str uri;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	uri.s = (char*)lua_tostring(L, -1);
+	if(uri.s==NULL)
+	{
+		LM_ERR("invalid uri parameter\n");
+		return app_lua_return_false(L);
+	}
+	uri.len = strlen(uri.s);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	memset(&act, 0, sizeof(act));
+	act.val[0].type = STRING_ST;
+	act.val[0].u.string = uri.s;
+	act.type = SET_USER_T;
+	init_run_actions_ctx(&h);
+	if (do_action(&h, &act, env_L->msg)<0)
+	{
+		LM_ERR("do action failed\n");
+		return app_lua_return_false(L);
+	}
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_sethost (lua_State *L)
+{
+	struct action  act;
+	struct run_act_ctx h;
+	str uri;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	uri.s = (char*)lua_tostring(L, -1);
+	if(uri.s==NULL)
+	{
+		LM_ERR("invalid uri parameter\n");
+		return app_lua_return_false(L);
+	}
+	uri.len = strlen(uri.s);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	memset(&act, 0, sizeof(act));
+	act.val[0].type = STRING_ST;
+	act.val[0].u.string = uri.s;
+	act.type = SET_HOST_T;
+	init_run_actions_ctx(&h);
+	if (do_action(&h, &act, env_L->msg)<0)
+	{
+		LM_ERR("do action failed\n");
+		return app_lua_return_false(L);
+	}
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setdsturi (lua_State *L)
+{
+	str uri;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	uri.s = (char*)lua_tostring(L, -1);
+	if(uri.s==NULL)
+	{
+		LM_ERR("invalid uri parameter\n");
+		return app_lua_return_false(L);
+	}
+	uri.len = strlen(uri.s);
+
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	if (set_dst_uri(env_L->msg, &uri)<0)
+	{
+		LM_ERR("setting dst uri failed\n");
+		return app_lua_return_false(L);
+	}
+	return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_resetdsturi (lua_State *L)
+{
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+	if(env_L->msg==NULL)
+	{
+		LM_WARN("invalid parameters from Lua env\n");
+		return app_lua_return_false(L);
+	}
+
+	reset_dst_uri(env_L->msg);
+	return app_lua_return_true(L);
+}
+
+
 /**
 /**
  *
  *
  */
  */
 static const luaL_reg _sr_core_Map [] = {
 static const luaL_reg _sr_core_Map [] = {
-	{"probe", lua_sr_probe},
-	{"dbg",   lua_sr_dbg},
-	{"err",   lua_sr_err},
-	{"log",   lua_sr_log},
-	{"modf",  lua_sr_modf},
+	{"probe",        lua_sr_probe},
+	{"dbg",          lua_sr_dbg},
+	{"err",          lua_sr_err},
+	{"log",          lua_sr_log},
+	{"modf",         lua_sr_modf},
+	{"is_myself",    lua_sr_is_myself},
+	{"setflag",      lua_sr_setflag},
+	{"resetflag",    lua_sr_resetflag},
+	{"isflagset",    lua_sr_isflagset},
+	{"setbflag",     lua_sr_setbflag},
+	{"resetbflag",   lua_sr_resetbflag},
+	{"isbflagset",   lua_sr_isbflagset},
+	{"seturi",       lua_sr_seturi},
+	{"setuser",      lua_sr_setuser},
+	{"sethost",      lua_sr_sethost},
+	{"setdsturi",    lua_sr_setdsturi},
+	{"resetdsturi",  lua_sr_resetdsturi},
 	{NULL, NULL}
 	{NULL, NULL}
 };
 };
 
 
@@ -629,7 +1044,7 @@ static int lua_sr_pv_is_null (lua_State *L)
 		return 0;
 		return 0;
 
 
 	pvn.len = strlen(pvn.s);
 	pvn.len = strlen(pvn.s);
-	LM_DBG("pv is null: %s\n", pvn.s);
+	LM_DBG("pv is null test: %s\n", pvn.s);
 	if(pv_parse_spec(&pvn, &pvs)<0)
 	if(pv_parse_spec(&pvn, &pvs)<0)
 	{
 	{
 		LM_ERR("unable to parse pv [%s]\n", pvn.s);
 		LM_ERR("unable to parse pv [%s]\n", pvn.s);

+ 44 - 2
modules/app_lua/doc/app_lua_admin.xml

@@ -96,7 +96,7 @@
 		<title>Set <varname>load</varname> parameter</title>
 		<title>Set <varname>load</varname> parameter</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-modparam("lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
+modparam("app_lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
 ...
 ...
 </programlisting>
 </programlisting>
 	    </example>
 	    </example>
@@ -109,12 +109,54 @@ modparam("lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
 			to Lua. Available submodules are:
 			to Lua. Available submodules are:
 	    </para>
 	    </para>
 	    	<itemizedlist>
 	    	<itemizedlist>
+		    <listitem>
+			<para>
+				<emphasis>auth</emphasis> - register functions from auth module
+				under 'sr.auth'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>auth_db</emphasis> - register functions from auth_db
+				module under 'sr.auth_db'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>maxfwd</emphasis> - register functions from maxfwd
+				module under 'sr.maxfwd'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>registrar</emphasis> - register functions from
+				registrar module under 'sr.registrar'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>rr</emphasis> - register functions from rr module
+				under 'sr.rr'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>sqlops</emphasis> - register functions from sqlops
+				module under 'sr.sqlops'.
+			</para>
+		    </listitem>
 		    <listitem>
 		    <listitem>
 			<para>
 			<para>
 				<emphasis>sl</emphasis> - register functions from sl module
 				<emphasis>sl</emphasis> - register functions from sl module
 				under 'sr.sl'.
 				under 'sr.sl'.
 			</para>
 			</para>
 		    </listitem>
 		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>tm</emphasis> - register functions from tm module
+				under 'sr.tm'.
+			</para>
+		    </listitem>
 	    	</itemizedlist>
 	    	</itemizedlist>
 	    <para>
 	    <para>
 			Note that 'sr', 'sr.hdr' and 'sr.pv' modules are always registered
 			Note that 'sr', 'sr.hdr' and 'sr.pv' modules are always registered
@@ -129,7 +171,7 @@ modparam("lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
 		<title>Set <varname>register</varname> parameter</title>
 		<title>Set <varname>register</varname> parameter</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-modparam("lua", "register", "sr")
+modparam("app_lua", "register", "sl")
 ...
 ...
 </programlisting>
 </programlisting>
 	    </example>
 	    </example>

+ 3 - 0
modules/auth/api.c

@@ -232,5 +232,8 @@ int bind_auth_s(auth_api_s_t* api)
 	api->calc_HA1 = calc_HA1;
 	api->calc_HA1 = calc_HA1;
 	api->calc_response = calc_response;
 	api->calc_response = calc_response;
 	api->check_response = auth_check_response;
 	api->check_response = auth_check_response;
+	api->auth_challenge = auth_challenge;
+	api->pv_authenticate = pv_authenticate;
+	api->consume_credentials = consume_credentials;
 	return 0;
 	return 0;
 }
 }

+ 41 - 3
modules/auth/api.h

@@ -33,6 +33,7 @@
 
 
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
 #include "../../parser/digest/digest.h"
 #include "../../parser/digest/digest.h"
+#include "../../sr_module.h"
 #include "../../usr_avp.h"
 #include "../../usr_avp.h"
 #include "../../parser/hf.h"
 #include "../../parser/hf.h"
 #include "../../str.h"
 #include "../../str.h"
@@ -96,6 +97,19 @@ auth_result_t post_auth(struct sip_msg* msg, struct hdr_field* hdr);
 typedef int (*check_response_t)(dig_cred_t* cred, str* method, char* ha1);
 typedef int (*check_response_t)(dig_cred_t* cred, str* method, char* ha1);
 int auth_check_response(dig_cred_t* cred, str* method, char* ha1);
 int auth_check_response(dig_cred_t* cred, str* method, char* ha1);
 
 
+typedef int (*auth_challenge_f)(struct sip_msg *msg, str *realm, int flags,
+		int hftype);
+int auth_challenge(struct sip_msg *msg, str *realm, int flags,
+		int hftype);
+
+typedef int (*pv_authenticate_f)(struct sip_msg *msg, str *realm, str *passwd,
+		int flags, int hftype);
+int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
+		int flags, int hftype);
+
+typedef int (*consume_credentials_f)(struct sip_msg* msg);
+int consume_credentials(struct sip_msg* msg);
+
 /*
 /*
  * Auth module API
  * Auth module API
  */
  */
@@ -104,13 +118,37 @@ typedef struct auth_api_s {
     post_auth_t post_auth;                /* The function to be called after authentication */
     post_auth_t post_auth;                /* The function to be called after authentication */
     build_challenge_hf_t build_challenge; /* Function to build digest challenge header */
     build_challenge_hf_t build_challenge; /* Function to build digest challenge header */
     struct qp* qop;                       /* qop module parameter */
     struct qp* qop;                       /* qop module parameter */
-	calc_HA1_t      calc_HA1;
-	calc_response_t calc_response;
-	check_response_t check_response;
+	calc_HA1_t         calc_HA1;
+	calc_response_t    calc_response;
+	check_response_t   check_response;
+	auth_challenge_f   auth_challenge;
+	pv_authenticate_f  pv_authenticate;
+	consume_credentials_f consume_credentials;
 } auth_api_s_t;
 } auth_api_s_t;
 
 
 typedef int (*bind_auth_s_t)(auth_api_s_t* api);
 typedef int (*bind_auth_s_t)(auth_api_s_t* api);
 int bind_auth_s(auth_api_s_t* api);
 int bind_auth_s(auth_api_s_t* api);
 
 
+/**
+ * load AUTH module API
+ */
+static inline int auth_load_api(auth_api_s_t* api)
+{
+	bind_auth_s_t bind_auth;
+
+	/* bind to auth module and import the API */
+	bind_auth = (bind_auth_s_t)find_export("bind_auth_s", 0, 0);
+	if (!bind_auth) {
+		LM_ERR("unable to find bind_auth function. Check if you load"
+				" the auth module.\n");
+		return -1;
+	}
+
+	if (bind_auth(api) < 0) {
+		LM_ERR("unable to bind auth module\n");
+		return -1;
+	}
+	return 0;
+}
 
 
 #endif /* API_H */
 #endif /* API_H */

+ 137 - 64
modules/auth/auth_mod.c

@@ -77,7 +77,7 @@ static int mod_init(void);
 /*
 /*
  * Remove used credentials from a SIP message header
  * Remove used credentials from a SIP message header
  */
  */
-int consume_credentials(struct sip_msg* msg, char* s1, char* s2);
+int w_consume_credentials(struct sip_msg* msg, char* s1, char* s2);
 
 
 static int pv_proxy_authenticate(struct sip_msg* msg, char* realm,
 static int pv_proxy_authenticate(struct sip_msg* msg, char* realm,
 		char *passwd, char *flags);
 		char *passwd, char *flags);
@@ -132,7 +132,7 @@ sl_api_t slb;
  * Exported functions
  * Exported functions
  */
  */
 static cmd_export_t cmds[] = {
 static cmd_export_t cmds[] = {
-    {"consume_credentials",    consume_credentials,                  0,
+    {"consume_credentials",    w_consume_credentials,                0,
 			0, REQUEST_ROUTE},
 			0, REQUEST_ROUTE},
     {"www_challenge",          (cmd_function)www_challenge,          2,
     {"www_challenge",          (cmd_function)www_challenge,          2,
 			fixup_auth_challenge, REQUEST_ROUTE},
 			fixup_auth_challenge, REQUEST_ROUTE},
@@ -355,7 +355,7 @@ static void destroy(void)
 /*
 /*
  * Remove used credentials from a SIP message header
  * Remove used credentials from a SIP message header
  */
  */
-int consume_credentials(struct sip_msg* msg, char* s1, char* s2)
+int consume_credentials(struct sip_msg* msg)
 {
 {
     struct hdr_field* h;
     struct hdr_field* h;
     int len;
     int len;
@@ -383,15 +383,20 @@ int consume_credentials(struct sip_msg* msg, char* s1, char* s2)
     return 1;
     return 1;
 }
 }
 
 
+/**
+ *
+ */
+int w_consume_credentials(struct sip_msg* msg, char* s1, char* s2)
+{
+	return consume_credentials(msg);
+}
+
 /**
 /**
  * @brief do WWW-Digest authentication with password taken from cfg var
  * @brief do WWW-Digest authentication with password taken from cfg var
  */
  */
-static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
-		char *p3, int hftype)
+int pv_authenticate(struct sip_msg *msg, str *realm, str *passwd,
+		int flags, int hftype)
 {
 {
-    int flags = 0;
-    str realm  = {0, 0};
-    str passwd = {0, 0};
 	struct hdr_field* h;
 	struct hdr_field* h;
 	auth_body_t* cred;
 	auth_body_t* cred;
 	int ret;
 	int ret;
@@ -403,32 +408,7 @@ static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
 	cred = 0;
 	cred = 0;
 	ret = AUTH_ERROR;
 	ret = AUTH_ERROR;
 
 
-	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
-		LM_ERR("failed to get realm value\n");
-		goto error;
-	}
-
-	if(realm.len==0) {
-		LM_ERR("invalid realm value - empty content\n");
-		goto error;
-	}
-
-	if (get_str_fparam(&passwd, msg, (fparam_t*)p2) < 0) {
-		LM_ERR("failed to get passwd value\n");
-		goto error;
-	}
-
-	if(passwd.len==0) {
-		LM_ERR("invalid password value - empty content\n");
-		goto error;
-	}
-
-	if (get_int_fparam(&flags, msg, (fparam_t*)p3) < 0) {
-		LM_ERR("invalid flags value\n");
-		goto error;
-	}
-
-	switch(pre_auth(msg, &realm, hftype, &h, NULL)) {
+	switch(pre_auth(msg, realm, hftype, &h, NULL)) {
 		case ERROR:
 		case ERROR:
 		case BAD_CREDENTIALS:
 		case BAD_CREDENTIALS:
 			LM_DBG("error or bad credentials\n");
 			LM_DBG("error or bad credentials\n");
@@ -458,12 +438,12 @@ static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
 	/* compute HA1 if needed */
 	/* compute HA1 if needed */
 	if ((flags&1)==0) {
 	if ((flags&1)==0) {
 		/* Plaintext password is stored in PV, calculate HA1 */
 		/* Plaintext password is stored in PV, calculate HA1 */
-		calc_HA1(HA_MD5, &cred->digest.username.whole, &realm,
-				&passwd, 0, 0, ha1);
+		calc_HA1(HA_MD5, &cred->digest.username.whole, realm,
+				passwd, 0, 0, ha1);
 		LM_DBG("HA1 string calculated: %s\n", ha1);
 		LM_DBG("HA1 string calculated: %s\n", ha1);
 	} else {
 	} else {
-		memcpy(ha1, passwd.s, passwd.len);
-		ha1[passwd.len] = '\0';
+		memcpy(ha1, passwd->s, passwd->len);
+		ha1[passwd->len] = '\0';
 	}
 	}
 
 
 	/* Recalculate response, it must be same to authorize successfully */
 	/* Recalculate response, it must be same to authorize successfully */
@@ -496,7 +476,7 @@ end:
 			qop = &auth_qauth;
 			qop = &auth_qauth;
 		}
 		}
 		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
 		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
-				&realm, NULL, NULL, qop, hftype, &hf) < 0) {
+				realm, NULL, NULL, qop, hftype, &hf) < 0) {
 			ERR("Error while creating challenge\n");
 			ERR("Error while creating challenge\n");
 			ret = AUTH_ERROR;
 			ret = AUTH_ERROR;
 		} else {
 		} else {
@@ -510,9 +490,7 @@ end:
 		}
 		}
 	}
 	}
 
 
-error:
 	return ret;
 	return ret;
-
 }
 }
 
 
 /**
 /**
@@ -521,7 +499,38 @@ error:
 static int pv_proxy_authenticate(struct sip_msg *msg, char* realm,
 static int pv_proxy_authenticate(struct sip_msg *msg, char* realm,
 		char *passwd, char *flags)
 		char *passwd, char *flags)
 {
 {
-	return pv_authenticate(msg, realm, passwd, flags, HDR_PROXYAUTH_T);
+    int vflags = 0;
+    str srealm  = {0, 0};
+    str spasswd = {0, 0};
+
+	if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		goto error;
+	}
+
+	if(srealm.len==0) {
+		LM_ERR("invalid realm value - empty content\n");
+		goto error;
+	}
+
+	if (get_str_fparam(&spasswd, msg, (fparam_t*)passwd) < 0) {
+		LM_ERR("failed to get passwd value\n");
+		goto error;
+	}
+
+	if(spasswd.len==0) {
+		LM_ERR("invalid password value - empty content\n");
+		goto error;
+	}
+
+	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
+		LM_ERR("invalid flags value\n");
+		goto error;
+	}
+	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T);
+
+error:
+	return AUTH_ERROR;
 }
 }
 
 
 /**
 /**
@@ -530,7 +539,38 @@ static int pv_proxy_authenticate(struct sip_msg *msg, char* realm,
 static int pv_www_authenticate(struct sip_msg *msg, char* realm,
 static int pv_www_authenticate(struct sip_msg *msg, char* realm,
 		char *passwd, char *flags)
 		char *passwd, char *flags)
 {
 {
-	return pv_authenticate(msg, realm, passwd, flags, HDR_AUTHORIZATION_T);
+    int vflags = 0;
+    str srealm  = {0, 0};
+    str spasswd = {0, 0};
+
+	if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		goto error;
+	}
+
+	if(srealm.len==0) {
+		LM_ERR("invalid realm value - empty content\n");
+		goto error;
+	}
+
+	if (get_str_fparam(&spasswd, msg, (fparam_t*)passwd) < 0) {
+		LM_ERR("failed to get passwd value\n");
+		goto error;
+	}
+
+	if(spasswd.len==0) {
+		LM_ERR("invalid password value - empty content\n");
+		goto error;
+	}
+
+	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
+		LM_ERR("invalid flags value\n");
+		goto error;
+	}
+	return pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T);
+
+error:
+	return AUTH_ERROR;
 }
 }
 
 
 /**
 /**
@@ -581,37 +621,20 @@ static int auth_send_reply(struct sip_msg *msg, int code, char *reason,
 /**
 /**
  *
  *
  */
  */
-static int auth_challenge(struct sip_msg *msg, char *p1, char *p2, int hftype)
+int auth_challenge(struct sip_msg *msg, str *realm, int flags, int hftype)
 {
 {
-    int flags = 0;
-    str realm  = {0, 0};
 	int ret;
 	int ret;
     str hf = {0, 0};
     str hf = {0, 0};
 	struct qp *qop = NULL;
 	struct qp *qop = NULL;
 
 
 	ret = -1;
 	ret = -1;
 
 
-	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
-		LM_ERR("failed to get realm value\n");
-		goto error;
-	}
-
-	if(realm.len==0) {
-		LM_ERR("invalid realm value - empty content\n");
-		goto error;
-	}
-
-	if (get_int_fparam(&flags, msg, (fparam_t*)p2) < 0) {
-		LM_ERR("invalid flags value\n");
-		goto error;
-	}
-	
 	if(flags&2) {
 	if(flags&2) {
 		qop = &auth_qauthint;
 		qop = &auth_qauthint;
 	} else if(flags&1) {
 	} else if(flags&1) {
 		qop = &auth_qauth;
 		qop = &auth_qauth;
 	}
 	}
-	if (get_challenge_hf(msg, 0, &realm, NULL, NULL, qop, hftype, &hf) < 0) {
+	if (get_challenge_hf(msg, 0, realm, NULL, NULL, qop, hftype, &hf) < 0) {
 		ERR("Error while creating challenge\n");
 		ERR("Error while creating challenge\n");
 		ret = -2;
 		ret = -2;
 		goto error;
 		goto error;
@@ -647,7 +670,32 @@ error:
  */
  */
 static int proxy_challenge(struct sip_msg *msg, char* realm, char *flags)
 static int proxy_challenge(struct sip_msg *msg, char* realm, char *flags)
 {
 {
-	return auth_challenge(msg, realm, flags, HDR_PROXYAUTH_T);
+	int vflags = 0;
+	str srealm  = {0, 0};
+
+	if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		goto error;
+	}
+
+	if(srealm.len==0) {
+		LM_ERR("invalid realm value - empty content\n");
+		goto error;
+	}
+
+	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
+		LM_ERR("invalid flags value\n");
+		goto error;
+	}
+
+	return auth_challenge(msg, &srealm, vflags, HDR_PROXYAUTH_T);
+
+error:
+	if(!(vflags&4)) {
+		if(auth_send_reply(msg, 500, "Internal Server Error", 0, 0) <0 )
+			return -4;
+	}
+	return -1;
 }
 }
 
 
 /**
 /**
@@ -655,7 +703,32 @@ static int proxy_challenge(struct sip_msg *msg, char* realm, char *flags)
  */
  */
 static int www_challenge(struct sip_msg *msg, char* realm, char *flags)
 static int www_challenge(struct sip_msg *msg, char* realm, char *flags)
 {
 {
-	return auth_challenge(msg, realm, flags, HDR_AUTHORIZATION_T);
+	int vflags = 0;
+	str srealm  = {0, 0};
+
+	if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		goto error;
+	}
+
+	if(srealm.len==0) {
+		LM_ERR("invalid realm value - empty content\n");
+		goto error;
+	}
+
+	if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) {
+		LM_ERR("invalid flags value\n");
+		goto error;
+	}
+
+	return auth_challenge(msg, &srealm, vflags, HDR_AUTHORIZATION_T);
+
+error:
+	if(!(vflags&4)) {
+		if(auth_send_reply(msg, 500, "Internal Server Error", 0, 0) <0 )
+			return -4;
+	}
+	return -1;
 }
 }
 
 
 /**
 /**

+ 17 - 6
modules/tm/tm.c

@@ -292,12 +292,12 @@ static int t_branch_timeout(struct sip_msg* msg, char*, char*);
 static int t_branch_replied(struct sip_msg* msg, char*, char*);
 static int t_branch_replied(struct sip_msg* msg, char*, char*);
 static int t_any_timeout(struct sip_msg* msg, char*, char*);
 static int t_any_timeout(struct sip_msg* msg, char*, char*);
 static int t_any_replied(struct sip_msg* msg, char*, char*);
 static int t_any_replied(struct sip_msg* msg, char*, char*);
-static int t_is_canceled(struct sip_msg* msg, char*, char*);
+static int w_t_is_canceled(struct sip_msg* msg, char*, char*);
 static int t_is_expired(struct sip_msg* msg, char*, char*);
 static int t_is_expired(struct sip_msg* msg, char*, char*);
 static int t_grep_status(struct sip_msg* msg, char*, char*);
 static int t_grep_status(struct sip_msg* msg, char*, char*);
 static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar);
 static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar);
 static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar);
 static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar);
-static int t_check_trans(struct sip_msg* msg, char* foo, char* bar);
+static int w_t_check_trans(struct sip_msg* msg, char* foo, char* bar);
 
 
 
 
 /* by default the fr timers avps are not set, so that the avps won't be
 /* by default the fr timers avps are not set, so that the avps won't be
@@ -448,7 +448,7 @@ static cmd_export_t cmds[]={
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 	{"t_any_replied",     t_any_replied,            0, 0, 
 	{"t_any_replied",     t_any_replied,            0, 0, 
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
-	{"t_is_canceled",     t_is_canceled,            0, 0,
+	{"t_is_canceled",     w_t_is_canceled,          0, 0,
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 	{"t_is_expired",      t_is_expired,             0, 0,
 	{"t_is_expired",      t_is_expired,             0, 0,
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
@@ -460,7 +460,7 @@ static cmd_export_t cmds[]={
 			FAILURE_ROUTE},
 			FAILURE_ROUTE},
 	{"t_save_lumps",      w_t_save_lumps,           0, 0,
 	{"t_save_lumps",      w_t_save_lumps,           0, 0,
 			REQUEST_ROUTE},
 			REQUEST_ROUTE},
-	{"t_check_trans",	t_check_trans,				0, 0,
+	{"t_check_trans",	  w_t_check_trans,			0, 0,
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|BRANCH_ROUTE },
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|BRANCH_ROUTE },
 
 
 	{"t_load_contacts", t_load_contacts,            0, 0,
 	{"t_load_contacts", t_load_contacts,            0, 0,
@@ -470,6 +470,7 @@ static cmd_export_t cmds[]={
 
 
 	/* not applicable from the script */
 	/* not applicable from the script */
 	{"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},
 	{"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},
+	{"load_xtm",           (cmd_function)load_xtm,          NO_SCRIPT,   0, 0},
 	{0,0,0,0,0}
 	{0,0,0,0,0}
 };
 };
 
 
@@ -1755,7 +1756,7 @@ int t_branch_replied(struct sip_msg* msg, char* foo, char* bar)
 
 
 
 
 /* script function, returns: 1 if the transaction was canceled, -1 if not */
 /* script function, returns: 1 if the transaction was canceled, -1 if not */
-int t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
+int t_is_canceled(struct sip_msg* msg)
 {
 {
 	struct cell *t;
 	struct cell *t;
 	int ret;
 	int ret;
@@ -1773,6 +1774,11 @@ int t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
 	return ret;
 	return ret;
 }
 }
 
 
+static int w_t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
+{
+	return t_is_canceled(msg);
+}
+
 /* script function, returns: 1 if the transaction lifetime interval has already elapsed, -1 if not */
 /* script function, returns: 1 if the transaction lifetime interval has already elapsed, -1 if not */
 int t_is_expired(struct sip_msg* msg, char* foo, char* bar)
 int t_is_expired(struct sip_msg* msg, char* foo, char* bar)
 {
 {
@@ -1937,7 +1943,7 @@ int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt)
  *       reliable: if the ACK  is delayed the proxied transaction might
  *       reliable: if the ACK  is delayed the proxied transaction might
  *       be already deleted when it reaches the proxy (wait_timeout))
  *       be already deleted when it reaches the proxy (wait_timeout))
  */
  */
-static int t_check_trans(struct sip_msg* msg, char* foo, char* bar)
+int t_check_trans(struct sip_msg* msg)
 {
 {
 	struct cell* t;
 	struct cell* t;
 	
 	
@@ -1976,6 +1982,11 @@ static int t_check_trans(struct sip_msg* msg, char* foo, char* bar)
 	return -1;
 	return -1;
 }
 }
 
 
+static int w_t_check_trans(struct sip_msg* msg, char* foo, char* bar)
+{
+	return t_check_trans(msg);
+}
+
 static int hexatoi(str *s, unsigned int* result)
 static int hexatoi(str *s, unsigned int* result)
 {
 {
 	int i, xv, fact;
 	int i, xv, fact;

+ 19 - 0
modules/tm/tm_load.c

@@ -145,3 +145,22 @@ int load_tm( struct tm_binds *tmb)
 #endif
 #endif
 	return 1;
 	return 1;
 }
 }
+
+int load_xtm(tm_xapi_t *xapi)
+{
+	if(xapi==NULL)
+	{
+		LM_ERR("invalid parameter\n");
+		return -1;
+	}
+
+	memset(xapi, 0, sizeof(tm_xapi_t));
+
+	xapi->t_on_failure    = t_on_negative;
+	xapi->t_on_branch     = t_on_branch;
+	xapi->t_on_reply      = t_on_reply;
+	xapi->t_check_trans   = t_check_trans;
+	xapi->t_is_canceled   = t_is_canceled;
+
+	return 0;
+}

+ 41 - 0
modules/tm/tm_load.h

@@ -163,4 +163,45 @@ static inline int tm_load_api(tm_api_t *tmb)
 	return load_tm_api(tmb);
 	return load_tm_api(tmb);
 }
 }
 
 
+/**
+ * eXtra API - not common used in other modules
+ */
+
+typedef void (*t_on_route_f)(unsigned int);
+typedef int (*t_no_param_f)(struct sip_msg *);
+
+int t_check_trans(struct sip_msg* msg);
+int t_is_canceled(struct sip_msg* msg);
+
+typedef struct tm_xbinds {
+	t_on_route_f t_on_failure;
+	t_on_route_f t_on_branch;
+	t_on_route_f t_on_reply;
+	t_no_param_f t_check_trans;
+	t_no_param_f t_is_canceled;
+} tm_xapi_t;
+
+typedef int(*load_xtm_f)( tm_xapi_t *xtmb );
+int load_xtm(tm_xapi_t *xtmb);
+
+static inline int tm_load_xapi(tm_xapi_t *xtmb)
+{
+	load_xtm_f load_xtm;
+
+	/* import the TM auto-loading function */
+	load_xtm = (load_xtm_f)find_export("load_xtm", NO_SCRIPT, 0);
+
+	if (load_tm == NULL) {
+		LOG(L_WARN, "Cannot import load_xtm function from tm module\n");
+		return -1;
+	}
+
+	/* let the auto-loading function load all extra TM stuff */
+	if (load_xtm(xtmb) < 0) {
+		LOG(L_WARN, "Cannot bind xapi from tm module\n");
+		return -1;
+	}
+	return 0;
+}
+
 #endif
 #endif

+ 63 - 0
modules_k/auth_db/api.h

@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Digest Authentication - Database support
+ *
+ * Copyright (C) 2001-2003 FhG Fokus
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio 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
+ *
+ * Kamailio 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
+ */
+
+
+#ifndef _AUTH_DB_API_H_
+#define _AUTH_DB_API_H_
+
+#include "../../sr_module.h"
+#include "../../parser/msg_parser.h"
+
+typedef int (*digest_authenticate_f)(struct sip_msg* msg, str *realm,
+				str *table, hdr_types_t hftype);
+/**
+ * @brief AUTH_DB API structure
+ */
+typedef struct auth_db_api {
+	digest_authenticate_f digest_authenticate;
+} auth_db_api_t;
+
+typedef int (*bind_auth_db_f)(auth_db_api_t* api);
+
+/**
+ * @brief Load the SL API
+ */
+static inline int auth_db_load_api(auth_db_api_t *api)
+{
+	bind_auth_db_f bindauthdb;
+
+	bindauthdb = (bind_auth_db_f)find_export("bind_auth_db", 0, 0);
+	if(bindauthdb == 0) {
+		LM_ERR("cannot find bind_auth_db\n");
+		return -1;
+	}
+	if (bindauthdb(api)==-1)
+	{
+		LM_ERR("cannot bind authdb api\n");
+		return -1;
+	}
+	return 0;
+}
+
+#endif /* _AUTH_DB_API_H_ */

+ 3 - 1
modules_k/auth_db/authdb_mod.c

@@ -117,6 +117,8 @@ static cmd_export_t cmds[] = {
 		REQUEST_ROUTE},
 		REQUEST_ROUTE},
 	{"proxy_authenticate", (cmd_function)proxy_authenticate, 2, auth_fixup, 0,
 	{"proxy_authenticate", (cmd_function)proxy_authenticate, 2, auth_fixup, 0,
 		REQUEST_ROUTE},
 		REQUEST_ROUTE},
+	{"bind_auth_db",       (cmd_function)bind_auth_db,       0, 0, 0,
+		0},
 	{0, 0, 0, 0, 0, 0}
 	{0, 0, 0, 0, 0, 0}
 };
 };
 
 
@@ -253,7 +255,7 @@ static int auth_fixup(void** param, int param_no)
 			auth_dbf.close(dbh);
 			auth_dbf.close(dbh);
 			return -1;
 			return -1;
 		}
 		}
+		auth_dbf.close(dbh);
 	}
 	}
-	auth_dbf.close(dbh);
 	return 0;
 	return 0;
 }
 }

+ 67 - 29
modules_k/auth_db/authorize.c

@@ -45,6 +45,7 @@
 #include "../../mod_fix.h"
 #include "../../mod_fix.h"
 #include "../../mem/mem.h"
 #include "../../mem/mem.h"
 #include "aaa_avps.h"
 #include "aaa_avps.h"
+#include "api.h"
 #include "authdb_mod.h"
 #include "authdb_mod.h"
 
 
 
 
@@ -204,41 +205,20 @@ static int generate_avps(db1_res_t* result)
 /*
 /*
  * Authorize digest credentials
  * Authorize digest credentials
  */
  */
-static inline int digest_authenticate(struct sip_msg* msg, fparam_t* realm,
-									char* tname, hdr_types_t hftype)
+static int digest_authenticate(struct sip_msg* msg, str *realm,
+				str *table, hdr_types_t hftype)
 {
 {
 	char ha1[256];
 	char ha1[256];
 	int res;
 	int res;
 	struct hdr_field* h;
 	struct hdr_field* h;
 	auth_body_t* cred;
 	auth_body_t* cred;
-	str domain, table;
 	db1_res_t* result = NULL;
 	db1_res_t* result = NULL;
 	int ret;
 	int ret;
 
 
 	cred = 0;
 	cred = 0;
 	ret = AUTH_ERROR;
 	ret = AUTH_ERROR;
 
 
-	if(!tname) {
-		LM_ERR("invalid table parameter\n");
-		return AUTH_ERROR;
-	}
-
-	table.s = tname;
-	table.len = strlen(tname);
-
-	if (get_str_fparam(&domain, msg, realm) < 0) {
-		LM_ERR("failed to get realm value\n");
-		goto end;
-	}
-
-	if (domain.len==0)
-	{
-		LM_ERR("invalid realm parameter - empty value\n");
-		goto end;
-	}
-	LM_DBG("realm value [%.*s]\n", domain.len, domain.s);
-
-	ret = auth_api.pre_auth(msg, &domain, hftype, &h, NULL);
+	ret = auth_api.pre_auth(msg, realm, hftype, &h, NULL);
 	switch(ret) {
 	switch(ret) {
 		case ERROR:
 		case ERROR:
 		case BAD_CREDENTIALS:
 		case BAD_CREDENTIALS:
@@ -266,7 +246,7 @@ static inline int digest_authenticate(struct sip_msg* msg, fparam_t* realm,
 
 
 	cred = (auth_body_t*)h->parsed;
 	cred = (auth_body_t*)h->parsed;
 
 
-	res = get_ha1(&cred->digest.username, &domain, &table, ha1, &result);
+	res = get_ha1(&cred->digest.username, realm, table, ha1, &result);
 	if (res < 0) {
 	if (res < 0) {
 		/* Error while accessing the database */
 		/* Error while accessing the database */
 		ret = AUTH_ERROR;
 		ret = AUTH_ERROR;
@@ -310,8 +290,30 @@ end:
  */
  */
 int proxy_authenticate(struct sip_msg* _m, char* _realm, char* _table)
 int proxy_authenticate(struct sip_msg* _m, char* _realm, char* _table)
 {
 {
-	return digest_authenticate(_m, (fparam_t*)_realm, _table,
-			HDR_PROXYAUTH_T);
+	str srealm;
+	str stable;
+
+	if(_table==NULL) {
+		LM_ERR("invalid table parameter\n");
+		return AUTH_ERROR;
+	}
+
+	stable.s   = _table;
+	stable.len = strlen(stable.s);
+
+	if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		return AUTH_ERROR;
+	}
+
+	if (srealm.len==0)
+	{
+		LM_ERR("invalid realm parameter - empty value\n");
+		return AUTH_ERROR;
+	}
+	LM_DBG("realm value [%.*s]\n", srealm.len, srealm.s);
+
+	return digest_authenticate(_m, &srealm, &stable, HDR_PROXYAUTH_T);
 }
 }
 
 
 
 
@@ -320,6 +322,42 @@ int proxy_authenticate(struct sip_msg* _m, char* _realm, char* _table)
  */
  */
 int www_authenticate(struct sip_msg* _m, char* _realm, char* _table)
 int www_authenticate(struct sip_msg* _m, char* _realm, char* _table)
 {
 {
-	return digest_authenticate(_m, (fparam_t*)_realm, _table,
-			HDR_AUTHORIZATION_T);
+	str srealm;
+	str stable;
+
+	if(_table==NULL) {
+		LM_ERR("invalid table parameter\n");
+		return AUTH_ERROR;
+	}
+
+	stable.s   = _table;
+	stable.len = strlen(stable.s);
+
+	if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0) {
+		LM_ERR("failed to get realm value\n");
+		return AUTH_ERROR;
+	}
+
+	if (srealm.len==0)
+	{
+		LM_ERR("invalid realm parameter - empty value\n");
+		return AUTH_ERROR;
+	}
+	LM_DBG("realm value [%.*s]\n", srealm.len, srealm.s);
+
+	return digest_authenticate(_m, &srealm, &stable, HDR_AUTHORIZATION_T);
+}
+
+/**
+ * @brief bind functions to AUTH_DB API structure
+ */
+int bind_auth_db(auth_db_api_t *api)
+{
+	if (!api) {
+		ERR("Invalid parameter value\n");
+		return -1;
+	}
+	api->digest_authenticate = digest_authenticate;
+
+	return 0;
 }
 }

+ 6 - 0
modules_k/auth_db/authorize.h

@@ -28,6 +28,7 @@
 
 
 
 
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
+#include "api.h"
 
 
 int auth_db_init(const str* db_url);
 int auth_db_init(const str* db_url);
 int auth_db_bind(const str* db_url);
 int auth_db_bind(const str* db_url);
@@ -45,4 +46,9 @@ int proxy_authenticate(struct sip_msg* _msg, char* _realm, char* _table);
 int www_authenticate(struct sip_msg* _msg, char* _realm, char* _table);
 int www_authenticate(struct sip_msg* _msg, char* _realm, char* _table);
 
 
 
 
+/*
+ * Bind to AUTH_DB API
+ */
+int bind_auth_db(auth_db_api_t* api);
+
 #endif /* AUTHORIZE_H */
 #endif /* AUTHORIZE_H */

+ 62 - 0
modules_k/maxfwd/api.h

@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001-2003 FhG Fokus
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio 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
+ *
+ * Kamailio 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
+ */
+
+
+#ifndef _MAXFWD_API_H_
+#define _MAXFWD_API_H_
+
+#include "../../sr_module.h"
+#include "../../parser/msg_parser.h"
+
+typedef int (*process_maxfwd_f)(struct sip_msg *msg, int limit);
+
+/**
+ * @brief MAXFWD API structure
+ */
+typedef struct maxfwd_api {
+	process_maxfwd_f process_maxfwd;
+} maxfwd_api_t;
+
+typedef int (*bind_maxfwd_f)(maxfwd_api_t* api);
+
+/**
+ * @brief Load the MAXFWD API
+ */
+static inline int maxfwd_load_api(maxfwd_api_t *api)
+{
+	bind_maxfwd_f bindmaxfwd;
+
+	bindmaxfwd = (bind_maxfwd_f)find_export("bind_maxfwd", 0, 0);
+	if(bindmaxfwd == 0) {
+		LM_ERR("cannot find bind_maxfwd\n");
+		return -1;
+	}
+	if (bindmaxfwd(api)==-1)
+	{
+		LM_ERR("cannot bind maxfwd api\n");
+		return -1;
+	}
+	return 0;
+}
+
+#endif
+

+ 33 - 3
modules_k/maxfwd/maxfwd.c

@@ -45,6 +45,7 @@
 #include "../../ut.h"
 #include "../../ut.h"
 #include "../../mem/mem.h"
 #include "../../mem/mem.h"
 #include "mf_funcs.h"
 #include "mf_funcs.h"
+#include "api.h"
 
 
 MODULE_VERSION
 MODULE_VERSION
 
 
@@ -57,11 +58,15 @@ static int w_process_maxfwd_header(struct sip_msg* msg,char* str,char* str2);
 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo);
 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo);
 static int mod_init(void);
 static int mod_init(void);
 
 
+int bind_maxfwd(maxfwd_api_t *api);
+
 static cmd_export_t cmds[]={
 static cmd_export_t cmds[]={
 	{"mf_process_maxfwd_header", (cmd_function)w_process_maxfwd_header, 1,
 	{"mf_process_maxfwd_header", (cmd_function)w_process_maxfwd_header, 1,
 		fixup_maxfwd_header, 0, REQUEST_ROUTE},
 		fixup_maxfwd_header, 0, REQUEST_ROUTE},
 	{"is_maxfwd_lt", (cmd_function)is_maxfwd_lt, 1,
 	{"is_maxfwd_lt", (cmd_function)is_maxfwd_lt, 1,
 		fixup_maxfwd_header, 0, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
 		fixup_maxfwd_header, 0, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
+	{"bind_maxfwd",  (cmd_function)bind_maxfwd,  0,
+		0, 0, 0},
 	{0,0,0,0,0,0}
 	{0,0,0,0,0,0}
 };
 };
 
 
@@ -131,8 +136,10 @@ static int fixup_maxfwd_header(void** param, int param_no)
 }
 }
 
 
 
 
-
-static int w_process_maxfwd_header(struct sip_msg* msg, char* str1,char* str2)
+/**
+ * process max forward header
+ */
+int process_maxfwd_header(struct sip_msg *msg, int limit)
 {
 {
 	int val;
 	int val;
 	str mf_value;
 	str mf_value;
@@ -141,7 +148,7 @@ static int w_process_maxfwd_header(struct sip_msg* msg, char* str1,char* str2)
 	switch (val) {
 	switch (val) {
 		/* header not found */
 		/* header not found */
 		case -1:
 		case -1:
-			if (add_maxfwd_header( msg, (unsigned int)(unsigned long)str1)!=0)
+			if (add_maxfwd_header(msg, (unsigned int)limit)!=0)
 				goto error;
 				goto error;
 			return 2;
 			return 2;
 		/* error */
 		/* error */
@@ -166,8 +173,18 @@ error:
 	return -2;
 	return -2;
 }
 }
 
 
+/**
+ *
+ */
+static int w_process_maxfwd_header(struct sip_msg* msg, char* str1, char* str2)
+{
+	return process_maxfwd_header(msg, (int)(unsigned long)str1);
+}
 
 
 
 
+/**
+ *
+ */
 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo)
 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo)
 {
 {
 	str mf_value;
 	str mf_value;
@@ -189,3 +206,16 @@ static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo)
 	return 1;
 	return 1;
 }
 }
 
 
+/**
+ * @brief bind functions to MAXFWD API structure
+ */
+int bind_maxfwd(maxfwd_api_t *api)
+{
+	if (!api) {
+		ERR("Invalid parameter value\n");
+		return -1;
+	}
+	api->process_maxfwd = process_maxfwd_header;
+
+	return 0;
+}

+ 79 - 0
modules_k/registrar/api.c

@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * Functions that process REGISTER message 
+ * and store data in usrloc
+ *
+ * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio 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
+ *
+ * Kamailio 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
+ *
+ */
+
+#include <stdio.h>
+
+#include "../../dprint.h"
+
+#include "reg_mod.h"
+#include "lookup.h"
+#include "save.h"
+#include "api.h"
+
+/**
+ *
+ */
+int regapi_save(struct sip_msg *msg, char *table, int flags)
+{
+	udomain_t* d;
+
+	if(ul.get_udomain(table, &d)<0)
+	{
+		LM_ERR("usrloc domain [%s] not found\n", table);
+		return -1;
+	}
+	return save(msg, d, flags);
+}
+
+/**
+ *
+ */
+int regapi_lookup(struct sip_msg *msg, char *table)
+{
+	udomain_t* d;
+
+	if(ul.get_udomain(table, &d)<0)
+	{
+		LM_ERR("usrloc domain [%s] not found\n", table);
+		return -1;
+	}
+	return lookup(msg, d);
+}
+
+/**
+ *
+ */
+int bind_registrar(registrar_api_t* api)
+{
+	if (!api) {
+		ERR("Invalid parameter value\n");
+		return -1;
+	}
+	api->save   = regapi_save;
+	api->lookup = regapi_lookup;
+
+	return 0;
+}

+ 72 - 0
modules_k/registrar/api.h

@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Functions that process REGISTER message 
+ * and store data in usrloc
+ *
+ * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio 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
+ *
+ * Kamailio 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
+ *
+ */
+
+
+#ifndef _REGISTRAR_API_H_
+#define _REGISTRAR_API_H_
+
+#include "../../sr_module.h"
+#include "../../parser/msg_parser.h"
+
+typedef int (*regapi_save_f)(struct sip_msg *msg, char *table, int flags);
+int regapi_save(struct sip_msg *msg, char *table, int flags);
+
+typedef int (*regapi_lookup_f)(struct sip_msg *msg, char *table);
+int regapi_lookup(struct sip_msg *msg, char *table);
+
+/**
+ * @brief REGISTRAR API structure
+ */
+typedef struct registrar_api {
+	regapi_save_f    save;
+	regapi_lookup_f  lookup;
+} registrar_api_t;
+
+typedef int (*bind_registrar_f)(registrar_api_t* api);
+int bind_registrar(registrar_api_t* api);
+
+/**
+ * @brief Load the REGISTRAR API
+ */
+static inline int registrar_load_api(registrar_api_t *api)
+{
+	bind_registrar_f bindregistrar;
+
+	bindregistrar = (bind_registrar_f)find_export("bind_registrar", 0, 0);
+	if(bindregistrar == 0) {
+		LM_ERR("cannot find bind_registrar\n");
+		return -1;
+	}
+	if (bindregistrar(api) < 0)
+	{
+		LM_ERR("cannot bind registrar api\n");
+		return -1;
+	}
+	return 0;
+}
+
+
+#endif

+ 5 - 5
modules_k/registrar/lookup.c

@@ -57,7 +57,7 @@
  *          -2 : found but method not allowed
  *          -2 : found but method not allowed
  *          -3 : error
  *          -3 : error
  */
  */
-int lookup(struct sip_msg* _m, char* _t, char* _s)
+int lookup(struct sip_msg* _m, udomain_t* _d)
 {
 {
 	urecord_t* r;
 	urecord_t* r;
 	str aor, uri;
 	str aor, uri;
@@ -78,11 +78,11 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
 	
 	
 	get_act_time();
 	get_act_time();
 
 
-	ul.lock_udomain((udomain_t*)_t, &aor);
-	res = ul.get_urecord((udomain_t*)_t, &aor, &r);
+	ul.lock_udomain(_d, &aor);
+	res = ul.get_urecord(_d, &aor, &r);
 	if (res > 0) {
 	if (res > 0) {
 		LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
 		LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
-		ul.unlock_udomain((udomain_t*)_t, &aor);
+		ul.unlock_udomain(_d, &aor);
 		return -1;
 		return -1;
 	}
 	}
 
 
@@ -171,7 +171,7 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
 
 
 done:
 done:
 	ul.release_urecord(r);
 	ul.release_urecord(r);
-	ul.unlock_udomain((udomain_t*)_t, &aor);
+	ul.unlock_udomain(_d, &aor);
 	return ret;
 	return ret;
 }
 }
 
 

+ 2 - 1
modules_k/registrar/lookup.h

@@ -33,12 +33,13 @@
 #define LOOKUP_H
 #define LOOKUP_H
 
 
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
+#include "../../modules_k/usrloc/usrloc.h"
 
 
 
 
 /*! \brief
 /*! \brief
  * Lookup a contact in usrloc and rewrite R-URI if found
  * Lookup a contact in usrloc and rewrite R-URI if found
  */
  */
-int lookup(struct sip_msg* _m, char* _t, char* _s);
+int lookup(struct sip_msg* _m, udomain_t* _d);
 
 
 
 
 /*! \brief
 /*! \brief

+ 25 - 4
modules_k/registrar/reg_mod.c

@@ -67,11 +67,12 @@
 #include "../../socket_info.h"
 #include "../../socket_info.h"
 #include "../../pvar.h"
 #include "../../pvar.h"
 #include "../../lib/kcore/km_ut.h"
 #include "../../lib/kcore/km_ut.h"
-#include "../usrloc/ul_mod.h"
+#include "../../modules_k/usrloc/usrloc.h"
 #include "../../modules/sl/sl.h"
 #include "../../modules/sl/sl.h"
 #include "../../mod_fix.h"
 #include "../../mod_fix.h"
 
 
 #include "save.h"
 #include "save.h"
+#include "api.h"
 #include "lookup.h"
 #include "lookup.h"
 #include "regpv.h"
 #include "regpv.h"
 #include "reply.h"
 #include "reply.h"
@@ -86,6 +87,9 @@ usrloc_api_t ul;/*!< Structure containing pointers to usrloc functions*/
 static int  mod_init(void);
 static int  mod_init(void);
 static int  child_init(int);
 static int  child_init(int);
 static void mod_destroy(void);
 static void mod_destroy(void);
+static int w_save(struct sip_msg* _m, char* _d, char* _cflags);
+static int w_lookup(struct sip_msg* _m, char* _d, char* _p2);
+
 /*! \brief Fixup functions */
 /*! \brief Fixup functions */
 static int domain_fixup(void** param, int param_no);
 static int domain_fixup(void** param, int param_no);
 static int save_fixup(void** param, int param_no);
 static int save_fixup(void** param, int param_no);
@@ -150,11 +154,11 @@ static pv_export_t mod_pvs[] = {
  * Exported functions
  * Exported functions
  */
  */
 static cmd_export_t cmds[] = {
 static cmd_export_t cmds[] = {
-	{"save",         (cmd_function)save,         1,    save_fixup, 0,
+	{"save",         (cmd_function)w_save,       1,    save_fixup, 0,
 			REQUEST_ROUTE | ONREPLY_ROUTE },
 			REQUEST_ROUTE | ONREPLY_ROUTE },
-	{"save",         (cmd_function)save,         2,    save_fixup, 0,
+	{"save",         (cmd_function)w_save,       2,    save_fixup, 0,
 			REQUEST_ROUTE | ONREPLY_ROUTE },
 			REQUEST_ROUTE | ONREPLY_ROUTE },
-	{"lookup",       (cmd_function)lookup,       1,  domain_fixup, 0,
+	{"lookup",       (cmd_function)w_lookup,     1,  domain_fixup, 0,
 			REQUEST_ROUTE | FAILURE_ROUTE },
 			REQUEST_ROUTE | FAILURE_ROUTE },
 	{"registered",   (cmd_function)registered,   1,  domain_fixup, 0,
 	{"registered",   (cmd_function)registered,   1,  domain_fixup, 0,
 			REQUEST_ROUTE | FAILURE_ROUTE },
 			REQUEST_ROUTE | FAILURE_ROUTE },
@@ -168,6 +172,8 @@ static cmd_export_t cmds[] = {
 	{"reg_free_contacts", (cmd_function)pv_free_contacts,   1,
 	{"reg_free_contacts", (cmd_function)pv_free_contacts,   1,
 			fixup_str_null, 0,
 			fixup_str_null, 0,
 			REQUEST_ROUTE| FAILURE_ROUTE },
 			REQUEST_ROUTE| FAILURE_ROUTE },
+	{"bind_registrar",  (cmd_function)bind_registrar,  0,
+		0, 0, 0},
 	{0, 0, 0, 0, 0, 0}
 	{0, 0, 0, 0, 0, 0}
 };
 };
 
 
@@ -383,6 +389,21 @@ static int child_init(int rank)
 	return 0;
 	return 0;
 }
 }
 
 
+/*! \brief
+ * Wrapper to save(location)
+ */
+static int w_save(struct sip_msg* _m, char* _d, char* _cflags)
+{
+	return save(_m, (udomain_t*)_d, ((int)(unsigned long)_cflags));
+}
+
+/*! \brief
+ * Wrapper to lookup(location)
+ */
+static int w_lookup(struct sip_msg* _m, char* _d, char* _p2)
+{
+	return lookup(_m, (udomain_t*)_d);
+}
 
 
 /*! \brief
 /*! \brief
  * Convert char* parameter to udomain_t* pointer
  * Convert char* parameter to udomain_t* pointer

+ 2 - 2
modules_k/registrar/save.c

@@ -741,8 +741,8 @@ static inline int add_contacts(struct sip_msg* _m, contact_t* _c,
 /*!\brief
 /*!\brief
  * Process REGISTER request and save it's contacts
  * Process REGISTER request and save it's contacts
  */
  */
-#define is_cflag_set(_name) (((unsigned int)(unsigned long)_cflags)&(_name))
-int save(struct sip_msg* _m, char* _d, char* _cflags)
+#define is_cflag_set(_name) (((unsigned int)_cflags)&(_name))
+int save(struct sip_msg* _m, udomain_t* _d, int _cflags)
 {
 {
 	contact_t* c;
 	contact_t* c;
 	int st, mode;
 	int st, mode;

+ 2 - 1
modules_k/registrar/save.h

@@ -40,12 +40,13 @@
 
 
 
 
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
+#include "../../modules_k/usrloc/usrloc.h"
 
 
 
 
 /*! \brief
 /*! \brief
  * Process REGISTER request and save it's contacts
  * Process REGISTER request and save it's contacts
  */
  */
-int save(struct sip_msg* _m, char* _d, char* _cflags);
+int save(struct sip_msg* _m, udomain_t* _d, int _cflags);
 int unregister(struct sip_msg* _m, char* _d, char* _uri);
 int unregister(struct sip_msg* _m, char* _d, char* _uri);
 
 
 
 

+ 2 - 0
modules_k/rr/api.c

@@ -56,6 +56,8 @@ extern int append_fromtag;
  */
  */
 int load_rr( struct rr_binds *rrb )
 int load_rr( struct rr_binds *rrb )
 {
 {
+	rrb->record_route      = record_route;
+	rrb->loose_route       = loose_route;
 	rrb->add_rr_param      = add_rr_param;
 	rrb->add_rr_param      = add_rr_param;
 	rrb->check_route_param = check_route_param;
 	rrb->check_route_param = check_route_param;
 	rrb->is_direction      = is_direction;
 	rrb->is_direction      = is_direction;

+ 19 - 9
modules_k/rr/api.h

@@ -50,17 +50,20 @@ typedef  int (*add_rr_param_t)(struct sip_msg*, str*);
 typedef  int (*check_route_param_t)(struct sip_msg*, regex_t*);
 typedef  int (*check_route_param_t)(struct sip_msg*, regex_t*);
 typedef  int (*is_direction_t)(struct sip_msg*, int);
 typedef  int (*is_direction_t)(struct sip_msg*, int);
 typedef  int (*get_route_param_t)(struct sip_msg*, str*, str*);
 typedef  int (*get_route_param_t)(struct sip_msg*, str*, str*);
-
+typedef  int (*record_route_f)(struct sip_msg*, str*);
+typedef  int (*loose_route_f)(struct sip_msg*);
 
 
 /*! record-route API export binding */
 /*! record-route API export binding */
-struct rr_binds {
-	add_rr_param_t		add_rr_param;
-	check_route_param_t	check_route_param;
-	is_direction_t			is_direction;
-	get_route_param_t		get_route_param;
-	register_rrcb_t			register_rrcb;
-	int					append_fromtag;
-};
+typedef struct rr_binds {
+	record_route_f       record_route;
+	loose_route_f        loose_route;
+	add_rr_param_t       add_rr_param;
+	check_route_param_t  check_route_param;
+	is_direction_t       is_direction;
+	get_route_param_t    get_route_param;
+	register_rrcb_t      register_rrcb;
+	int                  append_fromtag;
+} rr_api_t;
 
 
 typedef  int (*load_rr_f)( struct rr_binds* );
 typedef  int (*load_rr_f)( struct rr_binds* );
 
 
@@ -92,5 +95,12 @@ inline static int load_rr_api( struct rr_binds *rrb )
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ *
+ */
+inline static int rr_load_api( rr_api_t *rrb )
+{
+	return load_rr_api(rrb);
+}
 
 
 #endif
 #endif

+ 1 - 3
modules_k/rr/loose.c

@@ -900,11 +900,9 @@ done:
 /*!
 /*!
  * \brief Do loose routing as per RFC3261
  * \brief Do loose routing as per RFC3261
  * \param _m SIP message
  * \param _m SIP message
- * \param _s1 unused
- * \param _s2 unused
  * \return -1 on failure, 1 on success
  * \return -1 on failure, 1 on success
  */
  */
-int loose_route(struct sip_msg* _m, char* _s1, char* _s2)
+int loose_route(struct sip_msg* _m)
 {
 {
 	int ret;
 	int ret;
 
 

+ 1 - 3
modules_k/rr/loose.h

@@ -42,11 +42,9 @@
 /*!
 /*!
  * \brief Do loose routing as per RFC3261
  * \brief Do loose routing as per RFC3261
  * \param _m SIP message
  * \param _m SIP message
- * \param _s1 unused
- * \param _s2 unused
  * \return -1 on failure, 1 on success
  * \return -1 on failure, 1 on success
  */
  */
-int loose_route(struct sip_msg* _m, char* _s1, char* _s2);
+int loose_route(struct sip_msg* _m);
 
 
 
 
 /*!
 /*!

+ 13 - 2
modules_k/rr/rr_mod.c

@@ -65,7 +65,8 @@ static int  mod_init(void);static void mod_destroy(void);
 static int direction_fixup(void** param, int param_no);
 static int direction_fixup(void** param, int param_no);
 static int it_list_fixup(void** param, int param_no);
 static int it_list_fixup(void** param, int param_no);
 /* wrapper functions */
 /* wrapper functions */
-static int w_record_route(struct sip_msg *,char *, char *);
+static int w_loose_route(struct sip_msg *, char *, char *);
+static int w_record_route(struct sip_msg *, char *, char *);
 static int w_record_route_preset(struct sip_msg *,char *, char *);
 static int w_record_route_preset(struct sip_msg *,char *, char *);
 static int w_add_rr_param(struct sip_msg *,char *, char *);
 static int w_add_rr_param(struct sip_msg *,char *, char *);
 static int w_check_route_param(struct sip_msg *,char *, char *);
 static int w_check_route_param(struct sip_msg *,char *, char *);
@@ -75,7 +76,7 @@ static int w_is_direction(struct sip_msg *,char *, char *);
  * \brief Exported functions
  * \brief Exported functions
  */
  */
 static cmd_export_t cmds[] = {
 static cmd_export_t cmds[] = {
-	{"loose_route",          (cmd_function)loose_route,			0, 0, 0,
+	{"loose_route",          (cmd_function)w_loose_route,		0, 0, 0,
 			REQUEST_ROUTE},
 			REQUEST_ROUTE},
 	{"record_route",         (cmd_function)w_record_route,		0, 0, 0,
 	{"record_route",         (cmd_function)w_record_route,		0, 0, 0,
 			REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
 			REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
@@ -199,7 +200,17 @@ static int direction_fixup(void** param, int param_no)
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ * wrapper for loose_route(msg)
+ */
+static int w_loose_route(struct sip_msg *msg, char *p1, char *p2)
+{
+	return loose_route(msg);
+}
 
 
+/**
+ * wrapper for record_route(msg, params)
+ */
 static int w_record_route(struct sip_msg *msg, char *key, char *bar)
 static int w_record_route(struct sip_msg *msg, char *key, char *bar)
 {
 {
 	str s;
 	str s;

+ 2 - 2
modules_k/sqlops/sql_api.c

@@ -440,7 +440,7 @@ error:
 /**
 /**
  *
  *
  */
  */
-int sqlops_get_value(str *sres, int i, int j, sql_val_t *val)
+int sqlops_get_value(str *sres, int i, int j, sql_val_t **val)
 {
 {
 	sql_result_t *res = NULL;
 	sql_result_t *res = NULL;
 
 
@@ -460,7 +460,7 @@ int sqlops_get_value(str *sres, int i, int j, sql_val_t *val)
 		LM_ERR("column index out of bounds [%d/%d]\n", j, res->ncols);
 		LM_ERR("column index out of bounds [%d/%d]\n", j, res->ncols);
 		goto error;
 		goto error;
 	}
 	}
-	val = &res->vals[i][j];
+	*val = &res->vals[i][j];
 
 
 	return 0;
 	return 0;
 error:
 error:

+ 2 - 2
modules_k/sqlops/sql_api.h

@@ -81,8 +81,8 @@ void sql_reset_result(sql_result_t *res);
 typedef int (*sqlops_do_query_f)(str *scon, str *squery, str *sres);
 typedef int (*sqlops_do_query_f)(str *scon, str *squery, str *sres);
 int sqlops_do_query(str *scon, str *squery, str *sres);
 int sqlops_do_query(str *scon, str *squery, str *sres);
 
 
-typedef int (*sqlops_get_value_f)(str *sres, int i, int j, sql_val_t *val);
-int sqlops_get_value(str *sres, int i, int j, sql_val_t *val);
+typedef int (*sqlops_get_value_f)(str *sres, int i, int j, sql_val_t **val);
+int sqlops_get_value(str *sres, int i, int j, sql_val_t **val);
 
 
 typedef int (*sqlops_is_null_f)(str *sres, int i, int j);
 typedef int (*sqlops_is_null_f)(str *sres, int i, int j);
 int sqlops_is_null(str *res, int i, int j);
 int sqlops_is_null(str *res, int i, int j);

+ 1 - 1
modules_k/sqlops/sqlops.c

@@ -149,7 +149,7 @@ int sql_res_param(modparam_t type, void *val)
 
 
 	if(val==NULL)
 	if(val==NULL)
 	{
 	{
-		LM_ERR("invalid parameter");
+		LM_ERR("invalid parameter\n");
 		goto error;
 		goto error;
 	}
 	}
 
 

+ 18 - 0
modules_k/usrloc/README

@@ -62,6 +62,7 @@ Bogdan-Andrei Iancu
               3.22. cseq_delay (integer)
               3.22. cseq_delay (integer)
               3.23. fetch_rows (integer)
               3.23. fetch_rows (integer)
               3.24. hash_size (integer)
               3.24. hash_size (integer)
+              3.25. preload (string)
 
 
         4. Exported Functions
         4. Exported Functions
         5. Exported MI Functions
         5. Exported MI Functions
@@ -130,6 +131,7 @@ Bogdan-Andrei Iancu
    1.22. Set cseq_delay parameter
    1.22. Set cseq_delay parameter
    1.23. Set fetch_rows parameter
    1.23. Set fetch_rows parameter
    1.24. Set hash_size parameter
    1.24. Set hash_size parameter
+   1.25. Set preload parameter
 
 
 Chapter 1. Admin Guide
 Chapter 1. Admin Guide
 
 
@@ -170,6 +172,7 @@ Chapter 1. Admin Guide
         3.22. cseq_delay (integer)
         3.22. cseq_delay (integer)
         3.23. fetch_rows (integer)
         3.23. fetch_rows (integer)
         3.24. hash_size (integer)
         3.24. hash_size (integer)
+        3.25. preload (string)
 
 
    4. Exported Functions
    4. Exported Functions
    5. Exported MI Functions
    5. Exported MI Functions
@@ -270,6 +273,7 @@ Chapter 1. Admin Guide
    3.22. cseq_delay (integer)
    3.22. cseq_delay (integer)
    3.23. fetch_rows (integer)
    3.23. fetch_rows (integer)
    3.24. hash_size (integer)
    3.24. hash_size (integer)
+   3.25. preload (string)
 
 
 3.1. nat_bflag (integer)
 3.1. nat_bflag (integer)
 
 
@@ -600,6 +604,20 @@ modparam("usrloc", "fetch_rows", 3000)
 modparam("usrloc", "hash_size", 10)
 modparam("usrloc", "hash_size", 10)
 ...
 ...
 
 
+3.25. preload (string)
+
+   Preload location table given as value. A location table is loaded based
+   on fixup of registrar functions, therefore you need to use this
+   parameter only to load tables that are not used by registrar module
+   directly in configuration file.
+
+   Default value is “NULL”.
+
+   Example 1.25. Set preload parameter
+...
+modparam("usrloc", "preload", "location")
+...
+
 4. Exported Functions
 4. Exported Functions
 
 
    There are no exported functions that could be used in scripts.
    There are no exported functions that could be used in scripts.

+ 24 - 0
modules_k/usrloc/dlist.c

@@ -46,6 +46,7 @@
 #include "../../ip_addr.h"
 #include "../../ip_addr.h"
 #include "../../socket_info.h"
 #include "../../socket_info.h"
 #include "udomain.h"           /* new_udomain, free_udomain */
 #include "udomain.h"           /* new_udomain, free_udomain */
+#include "usrloc.h"
 #include "utime.h"
 #include "utime.h"
 #include "ul_mod.h"
 #include "ul_mod.h"
 
 
@@ -447,6 +448,29 @@ static inline int new_dlist(str* _n, dlist_t** _d)
 	return 0;
 	return 0;
 }
 }
 
 
+/*!
+ * \brief Registers a new domain with usrloc
+ *
+ * Find and return a usrloc domain (location table)
+ * \param _n domain name
+ * \param _d usrloc domain
+ * \return 0 on success, -1 on failure
+ */
+int get_udomain(const char* _n, udomain_t** _d)
+{
+	dlist_t* d;
+	str s;
+
+	s.s = (char*)_n;
+	s.len = strlen(_n);
+
+	if (find_dlist(&s, &d) == 0) {
+		*_d = d->d;
+		return 0;
+	}
+	*_d = NULL;
+	return -1;
+}
 
 
 /*!
 /*!
  * \brief Registers a new domain with usrloc
  * \brief Registers a new domain with usrloc

+ 9 - 0
modules_k/usrloc/dlist.h

@@ -66,6 +66,15 @@ extern dlist_t* root;
 typedef int (*register_udomain_t)(const char* _n, udomain_t** _d);
 typedef int (*register_udomain_t)(const char* _n, udomain_t** _d);
 int register_udomain(const char* _n, udomain_t** _d);
 int register_udomain(const char* _n, udomain_t** _d);
 
 
+/*!
+ * \brief Find and return usrloc domain
+ *
+ * \param _n domain name
+ * \param _d usrloc domain (location table)
+ * \return 0 on success, -1 on failure
+ */
+typedef int (*get_udomain_t)(const char* _n, udomain_t** _d);
+int get_udomain(const char* _n, udomain_t** _d);
 
 
 /*!
 /*!
  * \brief Free all allocated memory for domains
  * \brief Free all allocated memory for domains

+ 23 - 0
modules_k/usrloc/doc/usrloc_admin.xml

@@ -690,6 +690,29 @@ modparam("usrloc", "hash_size", 10)
 		</example>
 		</example>
 	</section>
 	</section>
 
 
+	<section id="preload">
+		<title><varname>preload</varname> (string)</title>
+		<para>
+		Preload location table given as value. A location table is loaded
+		based on fixup of registrar functions, therefore you need to use this
+		parameter only to load tables that are not used by registrar module
+		directly in configuration file.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>NULL</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>preload</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("usrloc", "preload", "location")
+...
+</programlisting>
+		</example>
+	</section>
+
 	</section>
 	</section>
 
 
 	<section>
 	<section>

+ 1 - 0
modules_k/usrloc/ucontact.c

@@ -43,6 +43,7 @@
 #include "../../lib/srdb1/db.h"
 #include "../../lib/srdb1/db.h"
 #include "ul_mod.h"
 #include "ul_mod.h"
 #include "ul_callback.h"
 #include "ul_callback.h"
+#include "usrloc.h"
 #include "urecord.h"
 #include "urecord.h"
 #include "ucontact.h"
 #include "ucontact.h"
 
 

+ 1 - 0
modules_k/usrloc/udomain.c

@@ -45,6 +45,7 @@
 #include "../../ut.h"
 #include "../../ut.h"
 #include "../../lib/kcore/hash_func.h"
 #include "../../lib/kcore/hash_func.h"
 #include "ul_mod.h"            /* usrloc module parameters */
 #include "ul_mod.h"            /* usrloc module parameters */
+#include "usrloc.h"
 #include "utime.h"
 #include "utime.h"
 
 
 
 

+ 36 - 0
modules_k/usrloc/ul_mod.c

@@ -92,6 +92,11 @@ static void timer(unsigned int ticks, void* param); /*!< Timer handler */
 static int child_init(int rank);                    /*!< Per-child init function */
 static int child_init(int rank);                    /*!< Per-child init function */
 static int mi_child_init(void);
 static int mi_child_init(void);
 
 
+#define UL_PRELOAD_SIZE	8
+static char* ul_preload_list[UL_PRELOAD_SIZE];
+static int ul_preload_index = 0;
+static int ul_preload_param(modparam_t type, void* val);
+
 extern int bind_usrloc(usrloc_api_t* api);
 extern int bind_usrloc(usrloc_api_t* api);
 extern int ul_locks_no;
 extern int ul_locks_no;
 /*
 /*
@@ -168,6 +173,7 @@ static param_export_t params[] = {
 	{"fetch_rows",        INT_PARAM, &ul_fetch_rows   },
 	{"fetch_rows",        INT_PARAM, &ul_fetch_rows   },
 	{"hash_size",         INT_PARAM, &ul_hash_size    },
 	{"hash_size",         INT_PARAM, &ul_hash_size    },
 	{"nat_bflag",         INT_PARAM, &nat_bflag       },
 	{"nat_bflag",         INT_PARAM, &nat_bflag       },
+	{"preload",           STR_PARAM|USE_FUNC_PARAM, (void*)ul_preload_param},
 	{0, 0, 0}
 	{0, 0, 0}
 };
 };
 
 
@@ -216,6 +222,9 @@ struct module_exports exports = {
  */
  */
 static int mod_init(void)
 static int mod_init(void)
 {
 {
+	int i;
+	udomain_t* d;
+
 #ifdef STATISTICS
 #ifdef STATISTICS
 	/* register statistics */
 	/* register statistics */
 	if (register_module_stats( exports.name, mod_stats)!=0 ) {
 	if (register_module_stats( exports.name, mod_stats)!=0 ) {
@@ -311,6 +320,12 @@ static int mod_init(void)
 		nat_bflag = 1<<nat_bflag;
 		nat_bflag = 1<<nat_bflag;
 	}
 	}
 
 
+	for(i=0; i<ul_preload_index; i++) {
+		if(register_udomain((const char*)ul_preload_list[i], &d)<0) {
+			LM_ERR("cannot register preloaded table %s\n", ul_preload_list[i]);
+			return -1;
+		}
+	}
 	init_flag = 1;
 	init_flag = 1;
 
 
 	return 0;
 	return 0;
@@ -419,3 +434,24 @@ static void timer(unsigned int ticks, void* param)
 	}
 	}
 }
 }
 
 
+/*! \brief
+ * preload module parameter handler
+ */
+static int ul_preload_param(modparam_t type, void* val)
+{
+	if(val==NULL)
+	{
+		LM_ERR("invalid parameter\n");
+		goto error;
+	}
+	if(ul_preload_index>=UL_PRELOAD_SIZE)
+	{
+		LM_ERR("too many preloaded tables\n");
+		goto error;
+	}
+	ul_preload_list[ul_preload_index] = (char*)val;
+	ul_preload_index++;
+	return 0;
+error:
+	return -1;
+}

+ 0 - 5
modules_k/usrloc/ul_mod.h

@@ -43,11 +43,6 @@
  */
  */
 
 
 
 
-#define NO_DB         0
-#define WRITE_THROUGH 1
-#define WRITE_BACK    2
-#define DB_ONLY       3
-
 #define UL_TABLE_VERSION 1004
 #define UL_TABLE_VERSION 1004
 
 
 extern str user_col;
 extern str user_col;

+ 1 - 0
modules_k/usrloc/urecord.c

@@ -41,6 +41,7 @@
 #include "../../ut.h"
 #include "../../ut.h"
 #include "../../lib/kcore/hash_func.h"
 #include "../../lib/kcore/hash_func.h"
 #include "ul_mod.h"
 #include "ul_mod.h"
+#include "usrloc.h"
 #include "utime.h"
 #include "utime.h"
 #include "ul_callback.h"
 #include "ul_callback.h"
 
 

+ 1 - 0
modules_k/usrloc/usrloc.c

@@ -61,6 +61,7 @@ int bind_usrloc(usrloc_api_t* api)
 	}
 	}
 
 
 	api->register_udomain   = register_udomain;
 	api->register_udomain   = register_udomain;
+	api->get_udomain        = get_udomain;
 	api->get_all_ucontacts  = get_all_ucontacts;
 	api->get_all_ucontacts  = get_all_ucontacts;
 	api->insert_urecord     = insert_urecord;
 	api->insert_urecord     = insert_urecord;
 	api->delete_urecord     = delete_urecord;
 	api->delete_urecord     = delete_urecord;

+ 7 - 0
modules_k/usrloc/usrloc.h

@@ -35,6 +35,12 @@
 #include "ucontact.h"
 #include "ucontact.h"
 #include "ul_callback.h"
 #include "ul_callback.h"
 
 
+/* storage modes */
+#define NO_DB         0
+#define WRITE_THROUGH 1
+#define WRITE_BACK    2
+#define DB_ONLY       3
+
 
 
 /*! usrloc API export structure */
 /*! usrloc API export structure */
 typedef struct usrloc_api {
 typedef struct usrloc_api {
@@ -43,6 +49,7 @@ typedef struct usrloc_api {
 	unsigned int  nat_flag;   /*! nat_flag module parameter */
 	unsigned int  nat_flag;   /*! nat_flag module parameter */
 
 
 	register_udomain_t   register_udomain;
 	register_udomain_t   register_udomain;
+	get_udomain_t        get_udomain;
 	get_all_ucontacts_t  get_all_ucontacts;
 	get_all_ucontacts_t  get_all_ucontacts;
 
 
 	insert_urecord_t     insert_urecord;
 	insert_urecord_t     insert_urecord;