Hello Kamailio-3 users,
I have two questions regarding usage of variables within the config file (as published in the NEW FEATURES of Kamailio 3.0.0).
The reason why I want to use variables instead of standard configuration lines is the maintainability of my SIP servers. I have a group of about 20 sip servers distributed over a wide area. Especially routing rules might change during operation of the servers and must be adapted on all servers. Therefore I want to use variables, defined at the beginning of each config file. Within the config file / the different routing blocks I want to reference to these variables. That would be much easier for automatic config script adaptation with a linux script (e.g.) than parsing the whole config file for special text phrases.
QUESTION 1: ========== Is it impossible using a variable for requesting a SRC_IP address? With my current configuration I always see an entry in the SYSLOG that looks as follows: "<core> [route.c:1531]: BUG: comp_ip: invalid type for src_ip or dst_ip (20)"
The configuration lines look like:
$var(lst_gwIpRange) = "10.16.48.6[0-2]"; [...] if (src_ip=~$var(lst_gwIpRange)) { [...] }
Is maybe a transformation missing/necessary to avoid the error message (which causes a malfunction)? Can anybody give me a hint?
QUESTION 2: ========== The second problem I found is, that the config variables can be configured within a route block only and not - as expected - e.g. at the top of the config file (in the same way as the custom variables). I can't use the custom variables as they are, because I will use more complex variables, which are a mixture of up to three custom variables. These "complex" variables will be used in more than one routing block. Therefore I have to define these variables in every routing block...... Is an alternative (easier) solution with a single definition available, too?
An example of my problem is as follows:
# custom variables defined on top of the kamailio.cfg file tst.loc_ipaddr = "10.10.1.1" desc "IP addr of the local SIP Server" tst.loc_prefix = "11" desc "prefix of this SRV" tst.distRu1 = "51[0-9].*" desc "variable representing ID1"
# the final variable should look like "sip:1151[0-9].*@10.10.1.1" # and is used in 3 routing blocks
route[] $var(test) = "sip:" + $sel(cfg_get.tst.loc_prefix) + $sel(cfg_get.tst.distRu1) + "@" + $sel(cfg_get.tst.loc_ipaddr); [...]
route[TEST1] $var(test) = "sip:" + $sel(cfg_get.tst.loc_prefix) + $sel(cfg_get.tst.distRu1) + "@" + $sel(cfg_get.tst.loc_ipaddr); [...]
route[TEST2] $var(test) = "sip:" + $sel(cfg_get.tst.loc_prefix) + $sel(cfg_get.tst.distRu1) + "@" + $sel(cfg_get.tst.loc_ipaddr); [...]
Thanks in advance for any hints!
Regards, Klaus Feichtinger
On 02/22/2010 05:47 AM, Klaus Feichtinger wrote:
QUESTION 1:
Is it impossible using a variable for requesting a SRC_IP address? With my current configuration I always see an entry in the SYSLOG that looks as follows: "<core> [route.c:1531]: BUG: comp_ip: invalid type for src_ip or dst_ip (20)"
The configuration lines look like:
$var(lst_gwIpRange) = "10.16.48.6[0-2]"; [...] if (src_ip=~$var(lst_gwIpRange)) { [...] }
The problem is that 'src_ip' is one of the composite types used in the core and cannot be evaluated against a regular expression. The type that 'src_ip' has is just not part of the grammar surrounding the '=~' operator.
Use $si instead. It will have an identical value. For more information, see:
http://www.kamailio.org/dokuwiki/doku.php/pseudovariables:3.0.x
QUESTION 2:
The second problem I found is, that the config variables can be configured within a route block only and not - as expected - e.g. at the top of the config file (in the same way as the custom variables). I can't use the custom variablesas they are, because I will use more complex variables, which are a mixture of up to three custom variables. These "complex" variables will be used in more than one routing block. Therefore I have to define these variables in every routing block...... Is an alternative (easier) solution with a single definition available, too?
This question I cannot answer and will defer to the developers, because I am confused by your use of custom "selects." It was my impression that select namespaces are only defined by modules and the user cannot come up with them on his own, e.g. like 'tst'.
I also am not sure that there is a nice, elegant way to initialise variables in a global namespace right now except shared variables ($shv(...), in the 'pv' module), even though I would agree that such a thing would be immensely useful.
On Monday 22 February 2010, Alex Balashov wrote:
Is it impossible using a variable for requesting a SRC_IP address? With my current configuration I always see an entry in the SYSLOG that looks as follows: "<core> [route.c:1531]: BUG: comp_ip: invalid type for src_ip or dst_ip (20)"
The configuration lines look like:
$var(lst_gwIpRange) = "10.16.48.6[0-2]"; [...] if (src_ip=~$var(lst_gwIpRange)) { [...] }
The problem is that 'src_ip' is one of the composite types used in the core and cannot be evaluated against a regular expression. The type that 'src_ip' has is just not part of the grammar surrounding the '=~' operator.
Klaus,
one thing that is useful with regards to the 'src_ip' variable that you can compare against networks, e.g. src_ip == 192.168.1.0/24 - perhaps this can be used to implement your requirements as well.
QUESTION 2:
The second problem I found is, that the config variables can be configured within a route block only and not - as expected - e.g. at the top of the config file (in the same way as the custom variables). I can't use the custom variablesas they are, because I will use more complex variables, which are a mixture of up to three custom variables. These "complex" variables will be used in more than one routing block. Therefore I have to define these variables in every routing block...... Is an alternative (easier) solution with a single definition available, too?
This question I cannot answer and will defer to the developers, because I am confused by your use of custom "selects." It was my impression that select namespaces are only defined by modules and the user cannot come up with them on his own, e.g. like 'tst'.
Its possible to define them also on your own: http://by-miconda.blogspot.com/2009/12/best-of-new-in-kamailio-300-4-cfg.htm...
I also am not sure that there is a nice, elegant way to initialise variables in a global namespace right now except shared variables ($shv(...), in the 'pv' module), even though I would agree that such a thing would be immensely useful.
With regards to the question of the OP, if you need to access this variable only in one place then perhaps you could just ommit the temporary definition. If you only have the problem of visibility, what about using another type of storage, like Alex suggested, '$shv' or perhaps '$avp'?
Regards,
Henning
On 02/22/2010 06:26 AM, Henning Westerholt wrote:
Its possible to define them also on your own: http://by-miconda.blogspot.com/2009/12/best-of-new-in-kamailio-300-4-cfg.htm...
Aha! Thanks! I missed that one. This is actually very useful.
What would be even more useful is if these values could be used as input to modparams. Are modparam values evaluated for PV spec?
In other words, let's say I want to define a global 'db_url' for all modules, but I do not know which modules I am going to load in advance because I am using preprocessor macros to determine that, so the usual formula
modparam("mod1|mod2|mod3|...", "db_url", "...")
will not work.
Can I do something like this instead?
modparam("usrloc", "db_url", "$sel(cfg_get.db_url)");
With regards to the question of the OP, if you need to access this variable only in one place then perhaps you could just ommit the temporary definition. If you only have the problem of visibility, what about using another type of storage, like Alex suggested, '$shv' or perhaps '$avp'?
If the values need to be loaded from a database and postprocessed somehow, or something like that, then this problem could also be elegantly solved if there existed an additional type of 'route' that was not module or event-specific, e.g. not like route[htable:mod-init], but was tied to Kamailio booting up, like an 'onload_route'. Was there not a little talk of this some time ago?
On Monday 22 February 2010, Alex Balashov wrote:
What would be even more useful is if these values could be used as input to modparams. Are modparam values evaluated for PV spec?
I don't think that modparam evaluates PVs at the moment, i've gave it a short try, and only got a syntax error.
With regards to the question of the OP, if you need to access this variable only in one place then perhaps you could just ommit the temporary definition. If you only have the problem of visibility, what about using another type of storage, like Alex suggested, '$shv' or perhaps '$avp'?
If the values need to be loaded from a database and postprocessed somehow, or something like that, then this problem could also be elegantly solved if there existed an additional type of 'route' that was not module or event-specific, e.g. not like route[htable:mod-init], but was tied to Kamailio booting up, like an 'onload_route'. Was there not a little talk of this some time ago?
You probably could already use the htable specific route as generic startup route, you only need to load the module for this to work. But a generic solution would be indeed better. I think that Daniel extended the routing framework some time ago in a way that it would allow to easier specify functionality like this, but i did not looked into the details so far.
Henning
Thank you for the first tip. The already defined pseudo variable is a good alternative for the "src_ip" keyword. It is working fine.
However, the alternative variables solutions do not offer the same flexibility in definition as $var. Shared variables can not be composed from other variables + text. I fear AVP variables are not really different....
I will use the combined method of 'customer variables' and route-specific '$var-variables'. Although it requires multiple definitions, the given flexibility is the best.
Klaus
On Monday 22 February 2010, Alex Balashov wrote:
What would be even more useful is if these values could be used as input to modparams. Are modparam values evaluated for PV spec?
I don't think that modparam evaluates PVs at the moment, i've gave it a short try, and only got a syntax error.
With regards to the question of the OP, if you need to access this variable only in one place then perhaps you could just ommit the temporary definition. If you only have the problem of visibility, what about using another type of storage, like Alex suggested, '$shv' or perhaps '$avp'?
If the values need to be loaded from a database and postprocessed somehow, or something like that, then this problem could also be elegantly solved if there existed an additional type of 'route' that was not module or event-specific, e.g. not like route[htable:mod-init], but was tied to Kamailio booting up, like an 'onload_route'. Was there not a little talk of this some time ago?
You probably could already use the htable specific route as generic startup route, you only need to load the module for this to work. But a generic solution would be indeed better. I think that Daniel extended the routing framework some time ago in a way that it would allow to easier specify functionality like this, but i did not looked into the details so far.
Henning
On 02/22/2010 12:52 PM, Henning Westerholt wrote:
On Monday 22 February 2010, Alex Balashov wrote:
What would be even more useful is if these values could be used as input to modparams. Are modparam values evaluated for PV spec?
I don't think that modparam evaluates PVs at the moment, i've gave it a short try, and only got a syntax error.
This is true. Most of the pseudo-variables will require a SIP message to be evaluated (not in this particular case).
Module parameters can be evaluated at startup only if the developer did it inside modparam setting function or in mod init. Otherwise is just setting the int/str value.
With regards to the question of the OP, if you need to access this variable only in one place then perhaps you could just ommit the temporary definition. If you only have the problem of visibility, what about using another type of storage, like Alex suggested, '$shv' or perhaps '$avp'?
If the values need to be loaded from a database and postprocessed somehow, or something like that, then this problem could also be elegantly solved if there existed an additional type of 'route' that was not module or event-specific, e.g. not like route[htable:mod-init], but was tied to Kamailio booting up, like an 'onload_route'. Was there not a little talk of this some time ago?
You probably could already use the htable specific route as generic startup route, you only need to load the module for this to work. But a generic solution would be indeed better.
Perhaps the event_route[htable:mod-init] can be moved to a more common used module and perhaps renamed to event-route[config:mod-init]. Right now it does not depend at all on htable module.
However, it is important to know when is needed to execute the event route. The 'mod-init' is executed after all modules were initialized (so htables were defined, data was loaded in cache from db, a.s.o).
We can add new event routes, to hook in different steps of initialization, like child init, modparam, etc.
I think that Daniel extended the routing framework some time ago in a way that it would allow to easier specify functionality like this, but i did not looked into the details so far
Adding an event route is pretty simple, no need to touch the core and config syntax. For example, executing event_route[config:child-init] would be:
static int child_init(int rank) { struct sip_msg *fmsg; struct run_act_ctx ctx; int rtb, rt;
LM_DBG("rank is (%d)\n", rank); if (rank<=0) return 0;
rt = route_get(&event_rt, "config:child-init"); if(rt>=0 && event_rt.rlist[rt]!=NULL) { LM_DBG("executing event_route[config:child-init] (%d)\n", rt); if(faked_msg_init()<0) return -1; fmsg = faked_msg_next(); rtb = get_route_type(); set_route_type(REQUEST_ROUTE); init_run_actions_ctx(&ctx); run_top_route(event_rt.rlist[rt], fmsg, &ctx); if(ctx.run_flags&DROP_R_F) { LM_ERR("exit due to 'drop' in event route\n"); return -1; } set_route_type(rtb); } return 0; }
In this case, a fake SIP message is built and given to event route actions so all functions that are allowed to be executed in 'route' can be used in event route. If you don't need that, you can omit some lines from the snipped above.
Cheers, Daniel
On Wednesday 24 February 2010, Daniel-Constantin Mierla wrote:
[...] In this case, a fake SIP message is built and given to event route actions so all functions that are allowed to be executed in 'route' can be used in event route. If you don't need that, you can omit some lines from the snipped above.
Hi Daniel,
thank you for the code example and the additional informations.
Cheers,
Henning