User Tools

Site Tools


devel:config-engines

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
devel:config-engines [2016/05/03 13:47]
miconda [To-Do]
devel:config-engines [2017/11/20 14:31]
miconda
Line 1: Line 1:
 ====== Configuration File Engines ====== ====== Configuration File Engines ======
  
-Kamailio implements from scratch the interpreter for its configuration file scripting language(used inside kamailio.cfg).+Kamailio implements from scratch the interpreter for its configuration file native scripting language (used inside kamailio.cfg).
  
 Starting with v5.0.0, the routing blocks can be written in some other (well known) scripting languages and run via their embedded interpreters inside Kamailio. Known to work: Starting with v5.0.0, the routing blocks can be written in some other (well known) scripting languages and run via their embedded interpreters inside Kamailio. Known to work:
  
 +  * JavaScript - implemented by app_jsdt module, as "jsdt" config engine
   * Lua - implemented by app_lua module, as "lua" config engine   * Lua - implemented by app_lua module, as "lua" config engine
   * Python - implemented by app_python module, as "python" config engine   * Python - implemented by app_python module, as "python" config engine
Line 34: Line 35:
     * an extended set of data types, expressions and statements already available     * an extended set of data types, expressions and statements already available
     * a large set of extensions and libraries already available     * a large set of extensions and libraries already available
-  * reload the SIP routing logic without restarting Kamailio+    * good documentation about language itself and its extensions 
 +  * reload the SIP routing logic without restarting Kamailio (implemented for Lua)
  
 Internally, the support for implementing routing logic in an embedded language is codenamed **KEMI** - Kamailio EMbedded Interface. Internally, the support for implementing routing logic in an embedded language is codenamed **KEMI** - Kamailio EMbedded Interface.
Line 40: Line 42:
 ===== Exporting Functions To KEMI ===== ===== Exporting Functions To KEMI =====
  
-The current implementation relies on the ability of Lua to allow hash tables with custom indexThis is like an object that can have methods defined on the fly. Kamailio registers an empty object with custom index function implemented in Kamailio codewhenever a member of that object is accessed, the index function is executed and Kamailio will resolve it to one of its functions, corresponding by name.+Because Kamailio needs to load modules in order to export useful functions to KEMI, statical wrappers to C functions implemented in other modules cannot be used, because they will introduce dependencies on each embedded interpreter for all modules. 
 + 
 +The implementation relies on defining a set of generic functions that are exported to each embedded interpreter, which are associated at startup with a Kamailio C functionsThe lookup at runtime is by an integer index, therefore very fast. 
 + 
 +Currently the association table size is 1024 (it means that there can be maximum 1024 Kamailio C functions exported to the interpreter by configuration file). The number can be increasedbut it should be fairly enough as all kamailio.cfg functions are around 1000 and it is no real use case to load all the modules at the same time for use in production. Also, many functions may not be exported to an embedded languageas they have native alternative in the embedded language.
  
 Each existing component of Kamailio (e.g., module), can export new functions to KEMI in the following way: Each existing component of Kamailio (e.g., module), can export new functions to KEMI in the following way:
Line 124: Line 130:
  
   * **sr** - provided by the old way of exporting functions to Lua (https://www.kamailio.org/wiki/embeddedapi/devel/lua)   * **sr** - provided by the old way of exporting functions to Lua (https://www.kamailio.org/wiki/embeddedapi/devel/lua)
-  * **KSR** - provided via KEMI interface (not many functions exported at this moment, but expected to take over all **sr** module). The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...).+  * **KSR** - provided via KEMI interface. The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...). 
 ==== Lua Embedded Config Example ==== ==== Lua Embedded Config Example ====
  
Line 262: Line 269:
  
   * **Router** - provided by the old way of exporting functions to Python (https://www.kamailio.org/wiki/embeddedapi/devel/python)   * **Router** - provided by the old way of exporting functions to Python (https://www.kamailio.org/wiki/embeddedapi/devel/python)
-  * **KSR** - provided via KEMI interface (not many functions exported at this moment, but expected to take over all **Router** module). The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...).+  * **KSR** - provided via KEMI. The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...).
  
  
Line 382: Line 389:
 </code> </code>
  
-===== Examples =====+===== JavaScript Config KEMI Engine ===== 
 + 
 +The **app_jsdt** module must be loaded and the JavaScript script with routing logic must be set to its **load** parameter. 
 + 
 +Inside the JavaScript script, following functions are relevant: 
 + 
 +  * **ksr_request_route()** - is executed by Kamailio core every time a SIP request is received. If this function is not defined, then Kamailio will write error messages. This is equivalent of request_route {} from kamailio.cfg. 
 +  * **ksr_reply_route()** - is executed by Kamailio core every time a SIP Response (reply) is received. If this function is not defined, then Kamailio will not write error messages. This is equivalent of reply_route {} from kamailio.cfg. 
 +  * **ksr_onsend_route()** - is executed by Kamailio core every time a SIP request (and optionally for a response) is sent out. If this function is not defined, then Kamailio will not write error messages. This is equivalent of onsend_route {} from kamailio.cfg. 
 +  * branch route callback - the name of the Lua function to be executed instead of a branch route has to be provided as parameter to KSR.tm.t_on_branch(...) 
 +  * onreply route callback - the name of the Lua function to be executed instead of an onreply route has to be provided as parameter to KSR.tm.t_on_reply(...) 
 +  * failure route callback - the name of the Lua function to be executed instead of a failure route has to be provided as parameter to KSR.tm.t_on_failure(...) 
 +  * branch failure route callback - the name of the Lua function to be executed instead of an event route for branch failure has to be provided as parameter to KSR.tm.t_on_branch_failure(...) 
 +  * TBD: the options for specific event_route blocks. Meanwhile, should work using hybrid configuration with request_route/reply_route/... in embedded interpreter and the other routing blocks in native kamailio.cfg. 
 + 
 +The following objects are available inside the Lua script: 
 + 
 +  * **KSR** - provided via KEMI interface. The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...). 
 + 
 +===== Basic IP Telephony Config Example =====
  
 Some examples of configuration files using the native, Lua or Python interpreter are available in Kamailio source tree inside the **examples/kemi** folder - online at github: Some examples of configuration files using the native, Lua or Python interpreter are available in Kamailio source tree inside the **examples/kemi** folder - online at github:
  
-  * https://github.com/kamailio/kamailio/tree/master/examples/kemi+  * https://github.com/kamailio/kamailio/tree/master/misc/examples/kemi
  
 The configuration file to start with is **kamailio-basic-kemi.cfg**: The configuration file to start with is **kamailio-basic-kemi.cfg**:
  
-{{url>https://github.com/kamailio/kamailio/blob/master/examples/kemi/kamailio-basic-kemi.cfg}}+  * https://github.com/kamailio/kamailio/blob/master/misc/examples/kemi/kamailio-basic-kemi.cfg
  
 You can either rename it to kamailio.cfg or use **-f** command line option to point to it. You can either rename it to kamailio.cfg or use **-f** command line option to point to it.
Line 396: Line 422:
 If started without any change and no define in command line, then Kamailio will continue to load the routing blocks in the native language, stored in the file **kamailio-basic-kemi-native.cfg**: If started without any change and no define in command line, then Kamailio will continue to load the routing blocks in the native language, stored in the file **kamailio-basic-kemi-native.cfg**:
  
-{{url>https://github.com/kamailio/kamailio/blob/master/examples/kemi/kamailio-basic-kemi-native.cfg}}+  * https://github.com/kamailio/kamailio/blob/master/misc/examples/kemi/kamailio-basic-kemi-native.cfg
  
 If you define WITH_CFGLUA inside **kamailio-basic-kemi.cfg** or provide the command line parameter **-A WITH_CFGLUA**, then Kamailio will load the routing blocks in the Lua language, stored in the file **kamailio-basic-kemi-lua.lua**: If you define WITH_CFGLUA inside **kamailio-basic-kemi.cfg** or provide the command line parameter **-A WITH_CFGLUA**, then Kamailio will load the routing blocks in the Lua language, stored in the file **kamailio-basic-kemi-lua.lua**:
  
-{{url>https://github.com/kamailio/kamailio/blob/master/examples/kemi/kamailio-basic-kemi-lua.lua}}+  * https://github.com/kamailio/kamailio/blob/master/misc/examples/kemi/kamailio-basic-kemi-lua.lua
  
 +If you define WITH_CFGJSDT inside **kamailio-basic-kemi.cfg** or provide the command line parameter **-A WITH_CFGJSDT**, then Kamailio will load the routing blocks in the JavaScript language, stored in the file **kamailio-basic-kemi-jsdt.js**:
 +
 +  * https://github.com/kamailio/kamailio/blob/master/misc/examples/kemi/kamailio-basic-kemi-jsdt.js
  
 If you define WITH_CFGPYTHON inside **kamailio-basic-kemi.cfg** or provide the command line parameter **-A WITH_CFGPYTHON**, then Kamailio will load the routing blocks in the Python language, stored in the file **kamailio-basic-kemi-python.py**: If you define WITH_CFGPYTHON inside **kamailio-basic-kemi.cfg** or provide the command line parameter **-A WITH_CFGPYTHON**, then Kamailio will load the routing blocks in the Python language, stored in the file **kamailio-basic-kemi-python.py**:
  
-{{url>https://github.com/kamailio/kamailio/blob/master/examples/kemi/kamailio-basic-kemi-python.py}}+  * https://github.com/kamailio/kamailio/blob/master/misc/examples/kemi/kamailio-basic-kemi-python.py
  
-Combining **kamailio-basic-kemi.cfg** with **kamailio-basic-kemi-native.cfg** results more or less in the **kamailio-basic.cfg** from the **etc/** folder in Kamailio source tree. The Lua and Python scripts are offering the same features, but written in another language.+Combining **kamailio-basic-kemi.cfg** with **kamailio-basic-kemi-native.cfg** results more or less in the **kamailio-basic.cfg** from the **etc/** folder in Kamailio source tree. The Lua, JavaScript and Python scripts are offering the same features, but written in another language.
  
 Note that you need to copy these files at the location of the configuration file for your Kamailio configuration and eventually adjust the paths to them inside **kamailio-basic-kemi.cfg**. Note that you need to copy these files at the location of the configuration file for your Kamailio configuration and eventually adjust the paths to them inside **kamailio-basic-kemi.cfg**.
Line 429: Line 458:
 <code c> <code c>
 /usr/local/sbin/kamailio -f /usr/local/etc/kamailio/kamailio-basic-kemi.cfg -M 12 -M 128 - A WITH_CFGPYTHON /usr/local/sbin/kamailio -f /usr/local/etc/kamailio/kamailio-basic-kemi.cfg -M 12 -M 128 - A WITH_CFGPYTHON
 +</code>
 +
 +To start it with JavaScript routing blocks:
 +
 +<code c>
 +/usr/local/sbin/kamailio -f /usr/local/etc/kamailio/kamailio-basic-kemi.cfg -M 12 -M 128 - A WITH_CFGJSDT
 </code> </code>
  
 If you want to print the log messages to the terminal, add the extra parameters **-E -e -ddd** - this will print up to debug level which can be too verbose. Using up to info level can be better, use the extra parameters  **-E -e -dd** . If you want to print the log messages to the terminal, add the extra parameters **-E -e -ddd** - this will print up to debug level which can be too verbose. Using up to info level can be better, use the extra parameters  **-E -e -dd** .
  
-When you have at least log level info, with kamailio-basic-kemi.cfg you will notice that a log message is printed showing the duration in microseconds of executing the main routing blocks, no matter they were in native language, Lua or Python. If the logs were printed to the terminal, they look like:+When you have at least log level info, with kamailio-basic-kemi.cfg you will notice that a log message is printed showing the duration in microseconds of executing the main routing blocks, no matter they were in native language, Lua, JavaScript or Python. If the logs were printed to the terminal, they look like:
  
 <code> <code>
Line 443: Line 478:
   * NAT - for native interpreter   * NAT - for native interpreter
   * LUA - for LUA   * LUA - for LUA
 +  * JSC - for JavaScript
   * PYT - for Python   * PYT - for Python
  
Line 457: Line 493:
 Testing was done for registrations with user authentication, using **sipp** tool with parameters **-m 1000 -r 50** on the same VirtualBox system with Kamailio. Each test for different interpreters was doing 1000 registrations with different caller ids. Each first REGISTER was challenged for authentication, so practically there were 2000 REGISTER requests: first REGISTER being challenged with 401, the follow up was receiving 200ok as the authentication succeeded. Testing was done for registrations with user authentication, using **sipp** tool with parameters **-m 1000 -r 50** on the same VirtualBox system with Kamailio. Each test for different interpreters was doing 1000 registrations with different caller ids. Each first REGISTER was challenged for authentication, so practically there were 2000 REGISTER requests: first REGISTER being challenged with 401, the follow up was receiving 200ok as the authentication succeeded.
  
-The values are in micro-seconds (1 / 1 000 000 of a second) and represents the average execution time, the minimum execution time and the maximum execution time.+The values are in micro-seconds (1 / 1 000 000 of a second) and represents the average execution time, the minimum execution time and the maximum execution time for request_route{...} block (or the equivalent of).
  
 The results were: The results were:
Line 474: Line 510:
 Remarks: Remarks:
  
-  * the avverage was between 300 and 400 micro-seconds, resulting in a capacity of 2500 to over 3000 REGISTERs/second. CPU usage per Kamailio SIP worker process was around 1%. Again, not targeting to measure the capacity, the config runs with 4 SIP workers, increasing that will increase the capacity as database operations were involved to fetch the username and password via **auth_db** module.+  * the average was between 300 and 400 micro-seconds, resulting in a capacity of 2500 to over 3000 REGISTERs/second. CPU usage per Kamailio SIP worker process was around 1%. Again, not targeting to measure the capacity, the config runs with 4 SIP workers, increasing that will increase the capacity as database operations were involved to fetch the username and password via **auth_db** module.
   * the test was run many times, the Native and Lua execution were close to each other, many times Lua being faster, but again, at small difference   * the test was run many times, the Native and Lua execution were close to each other, many times Lua being faster, but again, at small difference
   * no big surprise as Lua is calling directly the C bindings and its interpreter is written also in C. With the config used in the tests, the Lua script doesn't do much of specific Lua operations, it mainly executes the functions exported by Kamailio   * no big surprise as Lua is calling directly the C bindings and its interpreter is written also in C. With the config used in the tests, the Lua script doesn't do much of specific Lua operations, it mainly executes the functions exported by Kamailio
-  * Python is slower comparing to Native and Lua, but not that much as one may expect. can still deal with 2500 REGISTERs/second. Even more, some of its latency comes from the way **app_modules** is designed, to create a Python object from Kamailio's SIP message structure. That involves cloning (and freeing) of each SIP message to be represented in Python. Lua uses the Kamailio core SIP message structure, like the Native interpreter without any overhead. Same approach should be possible for **app_python**, current approach is more object-oriented at expense of using more resources.+  * Python is slower comparing to Native and Lua, but not that much as one may expect. It can still deal with 2500 REGISTERs/second. Even more, some of its latency comes from the way **app_modules** is designed, to create a Python object from Kamailio's SIP message structure. That involves cloning (and freeing) of each SIP message to be represented as an object in Python. Lua uses the Kamailio core SIP message structure, like the Native interpreter without any overhead. Same approach should be possible for **app_python**, current approach is more object-oriented at expense of using more resources.
   * in some tests, the maximum execution time was between 5000 and 10000 micro-second, but for all interpreters, suspecting to be related to other tasks done by guest OS (which was running a web browser as well). The average didn't result in big differences, even in such cases. Also, sometimes the minimum was below 1 micro-second.   * in some tests, the maximum execution time was between 5000 and 10000 micro-second, but for all interpreters, suspecting to be related to other tasks done by guest OS (which was running a web browser as well). The average didn't result in big differences, even in such cases. Also, sometimes the minimum was below 1 micro-second.
  
devel/config-engines.txt · Last modified: 2017/11/20 14:31 by miconda