This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
tutorials:faq:main [2013/04/05 22:51] miconda [Media Streams] |
tutorials:faq:main [2018/01/12 16:32] miconda [Configuration File Processing] |
||
---|---|---|---|
Line 44: | Line 44: | ||
!!! Yes. | !!! Yes. | ||
- | |||
- | ??? What transport layer protocols are implemented in Kamailio? | ||
- | |||
- | !!! At network layer, Kamailio supports both IPv4 and IPv6. | ||
- | |||
- | At transport layer, Kamailio support UDP, TCP, TLS and SCTP. Transmission can be done in asynchronous mode (configuration option), inclusive for TCP and TLS. | ||
- | |||
- | Kamailio can be used to bridge between any combinations of these protocols, e.g., receiving SIP packets on UDP over IPv4 and sending out on TLS over IPv6. | ||
- | |||
- | ??? Does Kamailio have support for WebSockets? | ||
- | |||
- | !!! Yes, but only in development version at this time (Oct 2012), to become stable release 3.4.0. Releases 3.3.x or earlier do not have support for websockets. | ||
??? Is it possible to reload Kamailio configuration file? | ??? Is it possible to reload Kamailio configuration file? | ||
Line 73: | Line 61: | ||
!!! No. There is no official development pushed in this direction, Linux/Unix being the de facto for running servers. But it might not be big effort to make it compile using the Linux-like environments for Windows (such as cygwin). | !!! No. There is no official development pushed in this direction, Linux/Unix being the de facto for running servers. But it might not be big effort to make it compile using the Linux-like environments for Windows (such as cygwin). | ||
+ | |||
+ | =?==== Transport Layers ===== | ||
+ | |||
+ | ??? What transport layer protocols are implemented in Kamailio? | ||
+ | |||
+ | !!! At network layer, Kamailio supports both IPv4 and IPv6. | ||
+ | |||
+ | At transport layer, Kamailio support UDP, TCP, TLS and SCTP. Transmission can be done in asynchronous mode (configuration option), inclusive for TCP and TLS. | ||
+ | |||
+ | Kamailio can be used to bridge between any combinations of these protocols, e.g., receiving SIP packets on UDP over IPv4 and sending out on TLS over IPv6. | ||
+ | |||
+ | Starting with version 4.0.0, Kamailio supports WebSocket transport protocol, allowing modern web browsers to call between them directly through Kamailio. | ||
+ | |||
+ | ??? Does Kamailio have support for WebSockets? | ||
+ | |||
+ | !!! Yes, starting with version 4.0.0. It supports WebSockets over TCP (WS) and over TLS (WSS), on both IPv4 and IPv6. | ||
+ | |||
+ | ??? Can Kamailio do gatewaying between transport layers? | ||
+ | |||
+ | !!! Yes. You can use Kamailio to receive SIP message on one transport and send out on a different transport. For example, receive TLS on IPv6 and send out UDP on IPv4. | ||
+ | |||
+ | ??? Can Kamailio be used to call from web browsers (webrtc) to classic SIP phones? | ||
+ | |||
+ | !!! Yes, from signaling point of view. Remember that Kamailio is SIP packet router, not handling media plane at all. Simply, Kamailio can do gatewaying from WebSocket to UDP, TCP, TLS or SCTP for all SIP messages. | ||
+ | |||
+ | However, note that media plane (RTP streams) requires special secure encoding of the RTP packets, which may not be supported by the old SIP phones. | ||
=?==== Modules ===== | =?==== Modules ===== | ||
Line 83: | Line 97: | ||
!!! Inside the source tree, there are three directories: | !!! Inside the source tree, there are three directories: | ||
* modules/ | * modules/ | ||
- | * modules_k/ | + | * modules_k/ |
- | * modules_s/ | + | * modules_s/ |
Each module is located in its own sub-folder. The documentation for modules that are bundled in Kamailio packages is available at: | Each module is located in its own sub-folder. The documentation for modules that are bundled in Kamailio packages is available at: | ||
Line 91: | Line 105: | ||
??? Which modules are compiled by default? | ??? Which modules are compiled by default? | ||
- | !!! The modules that have the same dependencies as the core of Kamailio. Those that are not compiled by default are kept in the variable ' | + | !!! The modules that have the same dependencies as the core of Kamailio. Those that are not compiled by default are kept in the variable ' |
+ | |||
+ | < | ||
+ | make printvar v=exclude_modules | ||
+ | </ | ||
??? How can I compile and install a module that is excluded by default? | ??? How can I compile and install a module that is excluded by default? | ||
Line 102: | Line 120: | ||
make install | make install | ||
</ | </ | ||
+ | |||
+ | ??? I use 'make all', but I can't get the db_mysql.so. How can I get this? | ||
+ | |||
+ | !!! The module is not compiled by default, because depends on libmysqlclient. Use following commands to get in compiled and installed: | ||
+ | |||
+ | < | ||
+ | make modules include_modules=" | ||
+ | |||
+ | make install include_modules=" | ||
+ | </ | ||
+ | |||
+ | ??? How to compile only one module? | ||
+ | |||
+ | !!! First be sure that the core compiles fine with the command: | ||
+ | |||
+ | < | ||
+ | make | ||
+ | </ | ||
+ | |||
+ | To compile a single module, use: | ||
+ | |||
+ | < | ||
+ | make modules modules=modules/ | ||
+ | </ | ||
+ | |||
+ | Replace modname with the real name of the module you want to compile -- for example, compiling only tls module: | ||
+ | |||
+ | < | ||
+ | make modules modules=modules/ | ||
+ | </ | ||
+ | |||
=?==== SIP Message Processing ===== | =?==== SIP Message Processing ===== | ||
Line 140: | Line 189: | ||
</ | </ | ||
+ | |||
+ | ??? How to set different header values for each destination of a SIP request? | ||
+ | |||
+ | !!! Set the value of the header inside a **branch_route**. | ||
+ | |||
+ | All the operations done over a SIP message inside the **request_route** (including from the sub-routes executed from request_route) will be common to all outgoing branches. If you want to do updates only for specific destinations, | ||
+ | |||
+ | Example: | ||
+ | |||
+ | * add X-VBox header only when sending to voicemail server | ||
+ | * add X-Peer-ID header when sending somewhere else | ||
+ | |||
+ | < | ||
+ | request_route { | ||
+ | ... | ||
+ | if(is_method(" | ||
+ | t_on_branch(" | ||
+ | t_on_failure(" | ||
+ | } | ||
+ | t_relay(); | ||
+ | exit; | ||
+ | } | ||
+ | |||
+ | branch_route[SETHEADERS] { | ||
+ | | ||
+ | | ||
+ | } else { | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | failure_route[REROUTE] { | ||
+ | if (t_is_canceled()) { | ||
+ | exit; | ||
+ | } | ||
+ | if (t_check_status(" | ||
+ | $du = $null; | ||
+ | $ru = " | ||
+ | t_on_failure(" | ||
+ | exit; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ??? How to remove a single header field when a header appears multiple times? | ||
+ | |||
+ | !!! SIP allows that certain header fields may appear multiple times in a SIP message. This header fields (e.g. Via, Route, Record-Route, | ||
+ | |||
+ | The remove_hf() function from textops module always removes all header fields with a certain name, thus it can not be used in this case. | ||
+ | |||
+ | To address a certain header (regardless if headers are in a single line or in separate lines) use the @hf_value select. The trick is to load the textopsx module (this select used to be in ser's textops module). Note, header names must use ' | ||
+ | |||
+ | For example, incoming message: | ||
+ | < | ||
+ | Record-Route: | ||
+ | Record-Route: | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | Dump all headers: | ||
+ | < | ||
+ | xlog(" | ||
+ | </ | ||
+ | |||
+ | Dump the first header (< | ||
+ | < | ||
+ | xlog(" | ||
+ | </ | ||
+ | |||
+ | Dump the second last header (< | ||
+ | < | ||
+ | xlog(" | ||
+ | </ | ||
+ | |||
+ | Remove the last header (< | ||
+ | < | ||
+ | remove_hf_value(" | ||
+ | #or in above case: | ||
+ | remove_hf_value(" | ||
+ | </ | ||
+ | |||
+ | ??? Why the SIP requests are replied with "483 Too Many Hops" or "513 Message Too Large"? | ||
+ | |||
+ | !!! In both cases, the reason is probably an error in request routing script which caused an infinite loop. | ||
+ | |||
+ | You can easily verify whether this happens by watching SIP traffic on loopback interface, for example using ngrep: | ||
+ | |||
+ | < | ||
+ | ngrep -d lo -qt -W byline port 5060 | ||
+ | </ | ||
+ | |||
+ | |||
+ | A typical reason for misrouting is a failure to match local domain correctly. If a server fails to recognize a request for itself, it will try to forward it to current URI in believe it would forward them to a foreign domain. | ||
+ | |||
+ | Alas, it forwards the request to itself again. This continues to happen until value of the max_forwards header field reaches zero or the request grows too big. | ||
+ | |||
+ | The solution: make sure that domain matching is correctly configured. | ||
+ | |||
+ | A quick way to achieve that is to introduce a config option to kamailio.cfg: | ||
+ | |||
+ | < | ||
+ | alias=domainname | ||
+ | </ | ||
+ | |||
+ | where domainname has to be replaced with name of domain, which you wish to serve by Kamailio and which appears in request-URIs. | ||
+ | |||
+ | |||
+ | ??? I send SIP requests to Kamailio, but nothing happens, why? | ||
+ | |||
+ | !!! Check if you have a firewall rule dropping traffic on SIP port (5060). Note that network sniffing tools have hooks in kernel before the firewall, so even if you see the SIP packets with ngrep or wireshark, they may be dropped by the firewall. | ||
+ | |||
+ | If you have the pike module loaded, double check to see if you don't block valid trusted traffic with it. | ||
+ | |||
+ | You can increase the debug parameter value to 3 in the configuration file, restart kamailio and watch syslog messages to see if there is any text printed by kamailio. For each SIP packet received on the networks, Kamailio is printing at least few debug messages. | ||
=?==== Media Streams ===== | =?==== Media Streams ===== | ||
Line 161: | Line 324: | ||
??? What are the minimum knowledge requirements before starting with Kamailio? | ??? What are the minimum knowledge requirements before starting with Kamailio? | ||
- | !!! To be familiar with Linux and understand Session Initiation Protocol (SIP - RFC3261). | + | !!! To be familiar with Linux or UNIX (FreeBSD, OpenBSD, OS/X) and understand Session Initiation Protocol (SIP - RFC3261). |
??? Any step-by-step guide to install Kamailio? | ??? Any step-by-step guide to install Kamailio? | ||
Line 200: | Line 363: | ||
!!! Use the bug tracker available at: | !!! Use the bug tracker available at: | ||
- | * http://sip-router.org/tracker | + | * https://github.com/kamailio/ |
??? Where can I buy commercial support? | ??? Where can I buy commercial support? | ||
Line 221: | Line 384: | ||
!!! Yes. | !!! Yes. | ||
+ | |||
+ | |||
+ | ??? How to avoid reverse DNS for **src_ip** comparison? | ||
+ | |||
+ | !!! Do not enclose the IP address between quotes. Use like: | ||
+ | |||
+ | < | ||
+ | if(src_ip==1.2.3.4) { ... | ||
+ | </ | ||
+ | |||
+ | The next example results in reverse DNS operation, because src_ip is compared with a string: | ||
+ | |||
+ | < | ||
+ | if(src_ip==" | ||
+ | </ | ||
=?==== Instant Messaging and Presence ===== | =?==== Instant Messaging and Presence ===== | ||
Line 266: | Line 444: | ||
??? Can Kamailio be used with phones connecting from behind NAT? | ??? Can Kamailio be used with phones connecting from behind NAT? | ||
- | Yes, Kamailio supports the so called " | + | !!! Yes, Kamailio supports the so called " |
+ | |||
+ | Read the comments at top of default configuration file shipped with Kamailio, to enable NAT traversal logic there, one has to enable the define WITH_NAT: | ||
+ | |||
+ | < | ||
+ | #!define WITH_NAT | ||
+ | </ | ||
??? Can Kamailio be installed behind NAT (e.g., like on Amazon EC2)? | ??? Can Kamailio be installed behind NAT (e.g., like on Amazon EC2)? | ||
- | Yes. You have to set the public IP address as advertised attribute to listen parameter: | + | !!! Yes. You have to set the public IP address as advertised attribute to listen parameter: |
+ | < | ||
listen=_localsocket_ advertise _publicaddr_ | listen=_localsocket_ advertise _publicaddr_ | ||
+ | </ | ||
Example: | Example: | ||
+ | < | ||
listen=udp: | listen=udp: | ||
+ | </ | ||
+ | |||
+ | =?==== Configuration File Processing ===== | ||
+ | |||
+ | |||
+ | ??? Can I check the configuration files for syntax errors? | ||
+ | |||
+ | !!! Yes. Use ' | ||
+ | |||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Note that even configuration file is reported to be ok, there might still be troubles starting kamailio with the respective configuration file. For example, the database URL can be syntactically correct, but the access itself is not working due to wrong username or password, causing kamailio to fail starting. | ||
+ | |||
+ | ??? Do I have to delete the AVPs added in the configuration file for a SIP message? | ||
+ | |||
+ | !!! No. The AVPs are automatically deleted when associated SIP transaction is destroyed. | ||
+ | |||
+ | If you want to do it on purpose, you can delete the AVP using assignment to $null, like: | ||
+ | |||
+ | < | ||
+ | $avp(name) = $null; | ||
+ | </ | ||
+ | |||
+ | ??? What is a pseudo-variable? | ||
+ | |||
+ | !!! A pseudo-variable is a special token that is expanded at runtume with a specific value. It can be used inside the parameters of some functions or in configuration file expressions. | ||
+ | |||
+ | A pseudo-variable can refer to the value of an avp, body of a header, part of a SIP message or other variables from system. | ||
+ | |||
+ | For more see: | ||
+ | * http:// | ||
+ | |||
+ | ??? How to iterate through the items in a comma separated string? | ||
+ | |||
+ | !!! If you have a variable holding a string like " | ||
+ | |||
+ | Here is an example: | ||
+ | |||
+ | <code c> | ||
+ | $var(x) = " | ||
+ | $var(i) = 0; | ||
+ | |||
+ | while( $(var(x){s.select, | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ??? How is the function return code evaluated? | ||
+ | |||
+ | !!! Configuration file interpreter evaluates the return code of a function as follow: | ||
+ | |||
+ | * <0 (negative value) - it is evaluated to false | ||
+ | * >0 (positive value) - it is evaluated to true | ||
+ | * =0 (zero) - it is evaluated as exit (stop execution of configuration file) | ||
+ | |||
+ | Example: | ||
+ | |||
+ | <code c> | ||
+ | |||
+ | if(function_returns_one()) { | ||
+ | # it goes here | ||
+ | } else { | ||
+ | # it doesn' | ||
+ | } | ||
+ | ... | ||
+ | if(function_returns_minus_one()) { | ||
+ | # it doesn' | ||
+ | } else { | ||
+ | # it goes here | ||
+ | } | ||
+ | ... | ||
+ | if(function_returns_zero()) { | ||
+ | # it doesn' | ||
+ | } else { | ||
+ | # it doesn' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Note that you can use $rc to get the return code value, like: | ||
+ | |||
+ | <code c> | ||
+ | function(); | ||
+ | xlog(" | ||
+ | </ | ||
+ | |||
+ | However, if return code is 0, the next action after function() is not executed. It can be used only of positive or negative response code. | ||
+ | |||
+ | ??? How is the SIP request retransmission handled? | ||
+ | |||
+ | !!! The next snippet is detecting retransmissions: | ||
+ | |||
+ | <code c> | ||
+ | # handle retransmissions | ||
+ | if (!is_method(" | ||
+ | if(t_precheck_trans()) { | ||
+ | t_check_trans(); | ||
+ | exit; | ||
+ | } | ||
+ | t_check_trans(); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The **ACK** request is skipped because it doesn' | ||
+ | |||
+ | The function **t_precheck_trans()** returns true if the same SIP request is processed at that time by another Kamailio process, so in this case it is a retransmission. The inner **t_check_trans()** has the role of detecting if the SIP transaction was created by the other process, and if yes, send again the last SIP response of the transaction, | ||
+ | |||
+ | If the function **t_precheck_trans()** returns false, the SIP request is not under processing by another Kamailio process, but it can be the case that the request processing was finished, request being sent out in stateful mode, therefore **t_check_trans()** is used to see if a transaction is found in shared memory corresponding to the same request. If such transaction is found in shared memory, then **t_check_trans()** triggers internally the **exit** for configuration file execution. | ||
+ | =?==== Troubleshooting ===== | ||
+ | |||
+ | ??? I get 'out of memory' | ||
+ | |||
+ | !!! Most probably you run out of memory allocated for Kamailio. The application does not use the entire system memory, but up to a configured size. | ||
+ | |||
+ | There are two memory pools used by Kamailio: | ||
+ | * shared memory - shm - common at application level, where most of the data needed for long time is stored (such as location records, least cost routing records, transactions, | ||
+ | * private memory - pkg - allocated per process, used for local storage and temporary operations. The default size is 4MB. | ||
+ | |||
+ | To increase the sizes for memory pools you have to give following command line parameters: | ||
+ | * **-m SIZE** - specify the shared memory size in MB | ||
+ | * **-M SIZE** - specify the private memory size in MB | ||
+ | |||
+ | For example, start Kamailio with 512MB of shared memory and 8MB of private memory: | ||
+ | |||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | =?==== Tools ===== | ||
+ | |||
+ | ??? How to generate HA1 value in command line? | ||
+ | |||
+ | !!! Use following command: | ||
+ | |||
+ | < | ||
+ | echo -n ' | ||
+ | </ | ||
+ | |||
+ | ??? How to generate HA1B value in command line? | ||
+ | |||
+ | !!! Use following command: | ||
+ | |||
+ | < | ||
+ | echo -n ' | ||
+ | </ | ||
+ | |||
+ | ??? Kamctl gives an error regarding opening FIFO file, why? | ||
+ | |||
+ | !!! Kamctl couldn' | ||
+ | |||
+ | Check if your configuration loads the mi_fifo module and configures a fifo name. | ||
+ | |||
+ | Example for the configuration syntax: | ||
+ | < | ||
+ | loadmodule " | ||
+ | |||
+ | modparam(" | ||
+ | </ | ||
+ | |||
+ | Check also the access privileges of the FIFO file in order to be sure that the user running kamctl can read and write to the file. | ||
+ | |||
+ | ??? Kamcmd sometime fails to execute RPC commands with number parameters, why? | ||
+ | |||
+ | !!! There are situations when a **kamcmd** RPC command fails because the parameters that are provided are auto-converted to integer numbers. This happens when the implementation of the RPC commands expects a string parameter (e.g., username). | ||
+ | |||
+ | To prevent **kamcmd** to do the auto-conversion, | ||
+ | |||
+ | Example: | ||
+ | |||
+ | < | ||
+ | # - next command fails | ||
+ | kamcmd uac.reg_refresh 1001 | ||
+ | |||
+ | # use instead | ||
+ | kamcmd uac.reg_refresh s:1001 | ||
+ | </ |