– Kamailio SIP Server –

New in v3.0.0

Release of 3.0.0: January 11, 2010

IMPORTANT: Source code for Kamailio 3.0 is hosted on GIT repository at http://sip-router.org

IMPORTANT: SVN trunk on SourceForge.net is updated only for branches 1.5 or lower.

Being far from a complete listing of the new features, this page tries to give a fair overview of astonishing number of new functionalities and improvements available in Kamailio (OpenSER) 3.0.0.

This is first release based on http://sip-router.org project, meaning that you can have all Kamailio (OpenSER) and SIP Express Router (SER) extensions and functionalities mixed in same configuration file.

!!! New in core

Transport layer

UDP
  • mili-second base retransmission
  • integration with internal DNS cache system and auto black-listing
  • fallback to TCP, TLS or SCTP if the UDP packet is too big
  • management of UDP cfg parameters at runtime via RPC control interface

Example config to fallback to TCP is size of SIP request is bigger than 1024 bytes:

udp_mtu = 1024
udp_mtu_try_proto = TCP
TCP
  • asynchronous TCP sending
  • many new parameters to tune TCP connection behaviour
  • TCP keepalive support
  • TCP CRLF ping support
  • support many pooling methods: none, poll, epoll_lt, epoll_et, sigio_rt, select, kqueue, /dev/poll
  • TCP file descriptions cache - speed improvement in TCP sending
  • management of TCP cfg parameters at runtime via RPC control interface
$sercmd> core.tcp_options
{
	connect_timeout: 10
	send_timeout: 10
	connection_lifetime: 120
	max_connections(soft): 2048
	no_connect: 0
	fd_cache: 1
	async: 1
	connect_wait: 1
	conn_wq_max: 32768
	wq_max: 10485760
	defer_accept: 0
	delayed_ack: 1
	syncnt: 0
	linger2: 0
	keepalive: 1
	keepidle: 0
	keepintvl: 0
	keepcnt: 0
	crlf_ping: 1
	accept_aliases: 0
	alias_flags: 1
	new_conn_alias_flags: 2
}
TLS
  • completely new TLS architecture
  • TLS hooks in core and functionality provided by TLS module
  • no more re-compilation of all sources to enable TLS, just load tls module
  • dedicated config file to deal easily within multi-homed environment
  • management of TLS cfg parameters at runtime via RPC control interface

Sample config file for TLS:

[server:default]
method = TLSv1
verify_certificate = no
require_certificate = no
private_key = kamailio_key.pem
certificate = kamailio_cert.pem
ca_list = kamailio_ca.pem
 
[client:default]
verify_certificate = yes
require_certificate = yes
 
[server:10.0.0.10:5061]
method = SSLv23
verify_certificate = yes
require_certificate = no
private_key = privatenet_key.pem
certificate = privatenet_cert.pem
verify_depth = 3
ca_list = privatenet_ca.pem
 
[client:10.0.0.11:5061]
verify_certificate = no
certificate = peer_11_client.pem
private_key = peer_11_key.pem
ca_list = peer_11_ca.pem
SCTP
  • completely new SCTP architecture
  • advancced SCTP implementation
  • multi-homing and multi-streaming (connections association)
  • macros for sctp statistics
  • blacklist support at the sctp level. If sctp_send_retries are used, the blacklist will work only for send (using SCTP_SEND_FAILED notifications). If sctp_send_retries is not used (default), there are 2 possible blacklist reasons: SEND or CONNECT (assoc. failed to be opened).
  • connection reuse & connection tracking
  • management of SCTP cfg parameters at runtime via RPC control interface
$sercmd core.sctp_info
{
     opened_connections: 4
     tracked_connections: 0
     total_connections: 40010
}
 
$ sercmd core.sctp_options
{
     sctp_socket_rcvbuf: 54784
     sctp_socket_sndbuf: 54784
     sctp_autoclose: 180
     sctp_send_ttl: 32000
     sctp_send_retries: 0
     sctp_srto_initial: 3000
     sctp_srto_max: 60000
     sctp_srto_min: 1000
     sctp_asocmaxrxt: 10
     sctp_init_max_attempts: 8
     sctp_init_max_timeo: 60000
     sctp_hbinterval: 30000
     sctp_pathmaxrxt: 5
     sctp_sack_delay: 200
     sctp_sack_freq: 0
     sctp_max_burst: 4
}

Memory manager

  • new Doug Lea (DL) malloc manager
  • new lockless malloc (LL) manager
  • print memory status summary in debug mode

Locking and synchronisation

  • arch specific optimisations via likely and unlikely defines
  • support for non-blocking lock attempt via lock_try()
  • membar system

Timers

  • 3 level hierarchical timing wheel
    • G. Varghese, T. Lauck, Hashed and Hierarchical Timing Wheels: Efficient Data Structures for Implementing a Timer Facility, 1996
  • support for dynamic adding timers
  • one shot and periodic timers
  • “fast” and “slow” timers

DNS

Select framework

  • new system of config variables
  • over one hundred classes of selects
  • fine access to attributes of header by header index and attributes name (e.g., Via, Auth headers)
  • access to SIP message parts and environment attributes
  • supported by Pseudo-Variables framework via PV module
if(@cseg.method == "INVITE")
{
  ...
}
 
if($sel(cseg.method) == "INVITE")
{
  ...
}

Library framework

  • internal library support – better modularity and less code duplication – shared code among several module can be organised now as a library
    • DB interface became libsrdb1 library
    • new (alternative) DB interface via libsrdb2 library with support for prepared statements
    • Management Interface (MI) became libmi library
    • several Kamailio 1.5 core extensions are now in libkcore library - slimmer core
  • libraries are located in “lib/”
  • ensure smaller footprint to core - the core is less exposed to bugs and no longer under the threat of becoming fat

RPC Interface

  • scanner-like command interface to Kamailio
  • alternative to exiting Management Interface (MI)

CFG framework

  • ability to get and set global or module parameters values at runtime
  • get and set internal variables on-the-fly
  • can be controlled via RPC interface
  • eliminate Kamailio restarts whenever possible

CFG Include support

  • config language supports include file
include_file "name_of_file"
  • can be used in any part of config file, for example:
    • you can include a file defining global parameters
    • you can include a file defining module loading and its parameter
    • you can include a file defining routing rules
  • error reporting prints name of file and line number
  • included file may include another file

Example:

- file kamailio-sanity.cfg:

if (!mf_process_maxfwd_header("10")) {
  sl_send_reply("483","Too Many Hops");
  exit;
}
if ( msg:len >= 8192 ) {
  sl_send_reply("513", "Message too big");
  exit;
}
if ( is_method("NOTIFY") && uri==myself
  && $hdr(Event) =~ "keep-alive" )
{
  sl_send_reply("200", "OK - keepalive");
  exit;
}

Now, at the top of main route block in each config, I include the 'kamailio-sanity.cfg' file:

- file kamailio.cfg:

...
route {
 include_file "kamailio-sanity.cfg"
 ...
}
...

CFG Define support

Control in C-style what parts of the config file are executed. The parts in non-defined zones are not loaded, ensuring lower memory usage and faster execution.

Available directives:

  • #!define NAME - define a keyword
  • #!ifdef NAME - check if a keyword is defined
  • #!ifndef - check if a keyword is not defined
  • #!else - swtich to false branch of ifdef/ifndef region
  • #!endif - end ifdef/ifndef region

Among benefits:

  • easy way to enable/disable features (e.g., see default cfg for 3.0.0 – controlling support of nat traversal, presence, etc…)
  • switch control for parts where conditional statements were not possible (e.g., global parameters, module settings)
  • faster by not using conditional statements inside routing blocks when switching between running environments

Example: how to make config to be used in two environments, say testbed and production, controlled just by one define to switch between the two modes:

...
 
#!define TESTBED_MODE
 
#!ifdef TESTBED_MODE
  debug=5
  log_stderror=yes
  listen=192.168.1.1
#!else
  debug=2
  log_stderror=no
  listen=10.0.0.1
#!endif
 
...
 
#!ifdef TESTBED_MODE
modparam("acc|auth_db|usrloc", "db_url",
	"mysql://openser:openserrw@localhost/openser_testbed")
#!else
modparam("acc|auth_db|usrloc", "db_url",
	"mysql://openser:openserrw@10.0.0.2/openser_production")
#!endif
 
...
 
#!ifdef TESTBED_MODE
route[DEBUG] {
  xlog("SCRIPT: SIP $rm from: $fu to: $ru - srcip: $si"\n);
}
#!endif
 
...
 
route {
#!ifdef TESTBED_MODE
  route(DEBUG);
#!endif
 
  ...
}
 
...

onsend_route

  • executed just before sending the SIP message to the network
  • shows the final content (headers and body updated)
  • more flexibility in handling DNS blacklists and filters
  • you can drop requestss just to be sent using own logic in onsend_route
  • details of destination are available and can be used in route via
    • cfg keywords
      • snd_ip
      • snd_port
      • snd_proto
      • snd_af
    • pseudo-variables
      • $snd(ip)
      • $snd(port)
      • $snd(proto)
      • $snd(af)
  • you can access the content of the buffer to be sent to network via:
    • $snd(buf)
    • $snd(len)
onsend_route {
  if(isflagset(2) && $snd(ip)=="10.10.10.10") {
    drop;
  }
}

event_route

  • framework exported by core to execute a set of actions when a specific event happens
  • no longer needed to extend cfg file grammar for each new type of event that needs to execute a route block in cfg
  • an event route can be triggered by core or any of the modules
  • implemented event routes
    • event_route[htable:mod-init] - executed by htable module after module has been initialised
    • event_route[tm:local-request] - executed by tm modules when a local SIP request is generated (former local_route in 1.5.x)
event_route[htable:mod-init] {
  $shv(start_time) = $Tf;
  sql_query("insert into restarts (start_time) values ('$Tf')");
}

Names for route blocks and flags

  • route blocks can have string name
    • you can still use integer IDs (backward compatible) in cfg file
    • no more limitation of number of routing blocks
    • easier to write and maintain routing logic by having meaningful names
  • SIP message (transaction) flags can have string name
    • easy to spot and understand the meaning of the flag
    • note: name for flags cannot be used for branch or script flags
...
flags
  FLAG_ONE   : 1,
  FLAG_TWO   : 2;
 
...
 
route {
  ...
  if($rU=~"^\+[1-9][0-9]+$")
  {
     # route to gateway
     $du = "sip:10.0.0.11";
     route(RELAY);
  }
  ...
  if(isflagset(FLAG_ONE))
  {
     ...
  }
  ...
}
 
route[RELAY] {
   t_relay();
   exit;
}

switch statement

  • support for regular expression matching for string
  • optimisation for integer matching
  • break can be used inside actions of a case block (previously was allowed only at the end of block)
switch($rU) {
  case /"^123":
    if($fU=="345") {
      break;
    } else {
      ...
    }
  break;
  case /"^456":
    ...
  break;
}

while statement

  • you can use break to jump out of while loop (not possible in previous versions)
$var(i) = 0;
while($var(i)<10) {
  if($var(i)==5 && $rU=="123")
     break;
  $var(i) = $var(i) + 1;
}

</code>

Config file interpreter

type casts operators

  • (int) - cast to integer
  • (str) - cast to string
$var(expires) = (int)$hdr(expires);

new comparison operators

  • eq, ne for string comparisons
  • ieq, ine for integer comparisons
if($ua eq "Snom") {
   ...
}
  • they are almost equivalent to = = or !=, but they force the conversion of their operands (eq to string and ieq to int), allowing among other things better type checking on startup and more optimisations.
  • non equiv. examples: 0 = = “” (true) is not equivalent to 0 eq “” (false: it evaluates to “0” eq “”). “a” ieq “b” (true: (int)“a” is 0 and (int)“b” is 0) is not equivalent to “a” = = “b” (false).
  • note: internally = = and != are converted on startup to eq/ne/ieq/ine whenever possible (both operand types can be safely determined at start time and they are the same).
  • try to guess what the user wanted when operators that support multiple types are used on different typed operands. In general convert the right operand to the type of the left operand and then perform the operation. Exception: the left operand is undef. This applies to the following operators: +, == and !=.
  • expression evaluation changes: auto-convert to interger or string in function of the operators:
       int(undef)==0,  int("")==0, int("123")==123, int("abc")==0
       str(undef)=="", str(123)=="123".
new script operators
  • defined expr - returns true if expr is defined, and false if not. Note: only a standalone avp or pvar can be undefined, everything else is defined.
  • strlen(expr) - returns the length of expr evaluated as string.
  • strempty(expr) - returns true if expr evaluates to the empty string (equivalent to expr==“”)
if (defined $v && !strempty($v))
   $len=strlen($v);

Module search path

    loadpath "/usr/local/lib/kamailio/modules:/usr/local/lib/kamailio/modules_k"
 
    loadmodule "db_mysql.so"
    loadmodule "uri"

Dual module interfaces

  • modules can implement any of the interfaces specific so far to:
    • kamailio
    • ser
  • core can deal at the same time with modules implementing different interfaces
  • straightforward migration and run on the same Kamailio instance of modules developed so far for:
    • Kamailio (OpenSER)
    • SIP Express Router (SER)
    • OpenIMSCore

Script compatibility mode

  • option to offer best compatibility with expected behaviour had by older versions
  • as now we integrate functionalities from Kamailio and SER all together, this directive offer the possibility to choose between. For example:
    • in Kamailio, processing of failure route uses selected reply code from branches of the last step of serial forking
    • in SER, processing of failure route uses selected reply code from all branches, offering the option to drop replies for branches of the last step of serial forking via a module function
  • you can choose between ser compatible, kamailio compatible and max compatibility (compatible with both as much as possible), using:
      #!SER
      #!KAMAILIO
      #!OPENSER
      #!ALL
      #!MAXCOMPAT

where #!KAMAILIO is equivalent with #!OPENSER and #!ALL with #!MAXCOMPAT

IMPORTANT - set #!KAMAILIO as first line in your config file if you update from 1.5.x or older version of Kamailio (OpenSER), otherwise you may experience new behaviour for some old functions.

#!KAMAILIO
...

extended avps

  • XAVP
    • new class of variables
    • structure-like access to variables bind to SIP transactions
    • ability to store more value types, not only integer and string
    • simplify addressing by using only string name for attributes
    • possibility to optimise the search by creating lists of xavp lists
    • availability in config file for xavp with string or integer value (expression interpreter supports only these values) via PV module
    • availability in stateful processing, during the lifetime of transaction
  • Kamailio must be compiled with define WITH_XAVP set
$xavp(sf=>uri)="sip:10.10.10.10";
$xavp(sf[0]=>fr_timer)=10;
$xavp(sf[0]=>fr_inv_timer)=15;
$xavp(sf[0]=>headers)="X-CustomerID: 1234\r\n";
 
$xavp(sf=>uri)="sip:10.10.10.11";
$xavp(sf[0]=>fr_timer)=20;
$xavp(sf[0]=>fr_inv_timer)=35;
 
$xavp(sf=>uri)="sip:10.10.10.12";
$xavp(sf[0]=>fr_timer)=10;
$xavp(sf[0]=>fr_inv_timer)=15;
$xavp(sf[0]=>headers)="X-CustomerID: pw45\r\n";
 
xlog("uri attribute in first sf xavp: $xavp(sf=>uri)\n");

New cfg file elements

Custom cfg file parameters

  • along with predefined global parameters, you can define your own in global parameters section and use later in routing blocks
Format: group.id = value 'desc' description
  • you can get access to them via
    • pseudo-variables: $sel(cfg_get.group.id)
    • selects: @cfg_get.group.id
...
pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"
...
route[PSTN] {
	# check if PSTN GW IP is defined
	if (strempty($sel(cfg_get.pstn.gw_ip))) {
		xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");
		return;
	}
 
	# route to PSTN dialed numbers starting with '+' or '00'
	if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
		return;
 
	# only local users allowed to call
	if(from_uri!=myself) {
		sl_send_reply("403", "Not Allowed");
		exit;
	}
 
	$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
 
	route(RELAY);
	exit;
}

!!! New modules

auth identity

call_control

cfg_db

cfg_rpc

ctl

  • Control connector for RPC interface
    • support for fifo, unixsock, tcp, udp communication channels
    • can handle many connections at the same even over different transport layers
  • you have to load it to use sercmd command line interface

drouting

iptrtpproxy

kex

  • some of the features implemented previously in Kamailio core
    • functions to manage script and branch flags, add branch or manage destination uri
    • several MI commands
  • do not forget to load it if you upgrade from 1.5.x or older versions

memcached

  • hash table access for the popular memcached server
  • get/set integer or string values from/to memcached server
  • atomic increment or decrement integer values from memcached server
  • key can be static string or dynamic value build from other config variables
  • set expire time for memcached values
  • operations are done via pseudo-variables, therefore memcached values can be used by other modules, can be printed via xlog, a.s.o.

mi_rpc

pdb

  • number portabilitymodule
    • query portability database daemon
    • parallel interrogation of several PDB servers
    • millisecond timeouts
    • management at runtime via control interface (fifo, xmlrpc, udp, tcp …)
  • source of portability daemon available in utils/pdbt/

tmx

  • TM module extensions
  • new pseudo-variable
    • $T_inv(pv)
    • access to pseudo-variables and attributes of INVITE while processing the CANCEL
  • implements several Kamailio 1.5.x specific extensions to TM
    • MI commands
    • statistics
  • do not forget to load it if you upgrade from 1.5.x or older versions of Kamailio

topoh

  • topology hiding module
    • mask callid, via, route, record-route and contact headers
    • protect your infrastructure topology
    • hide the addresses of one party in the call from the other
  • transparent for config file writer
    • config always access the message in clear, so nothing special has to be done when using the module
    • no need to execute special functions in the config, topoh does his job in pre and post config hooks
  • independent of statless/stateful mode
    • very lightweight as it does not do any state machine and storage
  • packets can be routed via different servers configured in the same way
    • therefore native handling of failover cases (standby can encode/decode what active did previously)
  • restarting the server does not affect ongoing calls (e.g., BYE are encoded/decoded properly)

xmlrpc

  • XMLRPC connector for RPC interface
  • offers high-scalability XMLRPC communication with SIP server
    • reuses the transport layer from the core
    • communication can be done therefore via TCP or TLS
    • all TCP/TLS SIP processing workers can handle XMLRPC, therefore the server can process lot of XMLRPC traffic at same time
  • access to XMLRPC packets in a dedicated route of the config file
    • you can authenticate by IP
    • send XMLRPC reply
    • check the content of the message
#...
modparam("xmlrpc", "route", "XMLRPC");
#...
route[XMLRPC]{
	# allow XMLRPC requests only on TLS and only if the client
	# certificate is valid
	if (proto!=TLS){
		xmlrpc_reply("400", "xmlrpc allowed only over TLS");
		return;
	}
	if (@tls.peer.verified!=""){
		xmlrpc_reply("400", "Unauthorized");
		return;
	}
	if (search("^User-Agent:.*xmlrpclib"))
		set_reply_close();
	set_reply_no_connect(); # optional
	dispatch_rpc();
}

!!! New in old modules

carrierroute

  • new function cr_nofallback_route
    • route like existing cr_prime_route function, but uses CRC32 hash
  • new hash function random
    • for random routing distribution

htable

  • ability to count items matching name by a regular expression
    • via PV $shtcn(ht= >regexp)
  • ability to count items matching value by a regular expression
    • via PV $shtcv(ht= >regexp)
  • execute event_route[htable:mod-init] if it is defined, after module has been initialised
  • dump content of a hash table via MI control interface
  • dump content of a hash table via RPC control interface
  /* print number of items in htable 'a' */
  xlog("htable a has $shtcn(a= >.*) items\n");

imc

  • support to specify extra headers to be added to local generated messages
...
modparam("imc", "extra_hdrs", "P-Hint: imc\r\n")
...

lcr

  • added support for independent LCR instances
    • improve virtualization of sip-router
    • for example, different domains can now manage their own least cost routes to their own gateways.
  • replaced gateway aliveness checking with new defunct_gw() function
    • script writer can use to defunct an unresponsive or busy gateway for a desired period of time.
  • for simplicity, removed:
    • gateway group related functions load_gws_from_grp() and from_gw_grp()
    • group parameter from to_gw() function
    • you can use LCR instances as replacement.

msilo

  • check expiration time of REGISTER for m_dump() using contact parameters

nathelper

  • new functions:
    • add_contact_alias()
    • handle_ruri_alias()
    • they provide an alternative to fix_nated_contact() function that also supports re-use of TCP connections.
  • new pseudo variable $rr_count
    • tells the number of Record Routes in received SIP request or reply.
  • new pseudo variable $rr_top_count
    • tells if topmost Record Route in received SIP request or reply is a single or double Record Route.

presence_xml

  • new PV class: $xml(…)
    • handling of xml documents using XPath (evaluate expressions, update content)
  • get input from static string or variables (e.g., body of SIP message)
  • can handle many XML documents at the same time
  • easier routing decisions based on XML content
$xml(x=>doc) = '<?xml version="1.0" encoding="UTF-8"?><proxy><name>Kamailio</name></proxy>';
xlog("content of node b: $xml(x=>xpath:/proxy/name/text())\n");
$xml(x=>xpath:/proxy/name) = "Kamailio 3.0.0";

pv

  • $sel(name)
  • $snd(name)
    • new PV class to get access to destination address and sent request attributes
      • ip - IP address
      • port - port
      • proto - transport protocol
      • af - address family
      • buf - sent request content
      • len - length of sent request content

registrar

  • save(…) returns different code in case of insert, update or delete
    • learn in cfg file what kind of operation save performed
    • for example, dump stored offline messages only when was a new contact inserted, avoiding useless processing when is an update or un-registration

seas

  • not ported yet to sip router core framework

textops

  • new function msg_apply_changes()
    • apply changes done to SIP message so far(e.g., via subst(), append_hf(), remove_hf(), etc…)
    • the original content of SIP message is lost and the new content is processed further (e.g., if a header was removed, after using this function the check for existence of that header will return false; if a new header is added, after using the function, the check for existence of that header will return true)

tm

  • module was overhauled
    • faster and more lightweight timer implementations for retransmissions
    • removed lot of locking by a better design
    • more internal hooks to develop applications on top of module
  • asynchronous message processing support
    • you can park the transaction and resume the processing later
    • meanwhile the SIP worker process can handle new SIP traffic
  • option to decide what replies to drop in serial forking steps
  • load of new functions to access transactions
  • new parameters to tune transaction management

usrloc

  • dump content of user location tables via RPC control interface
    • ul.dump - get full content of location tables
    • ul.dump brief - get the list of online users

utils

  • ability to interpret xcap documents
  • function: xcap_auth_status(watcher_uri, presentity_uri)

userblacklist

  • new function check_user_whitelist
    • check if the user is whitelisted in the userblacklist table

!!! New tools

sercmd

  • command line application (similar to Asterisk cli)
  • connection or one-command mode
  • tab completion
  • execute RPC commands
  • execute MI commands
  • connect to Kamailio via FIFO, unix file sockets, UDP or TCP - you have to load the new ctl module

siremis

  • web2.0 admin interface (mysql, php, apache)
  • added support for XMLRPC communication with Kamailio server