Table of Contents

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

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
$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

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
$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

Locking and synchronisation

Timers

DNS

Select framework

if(@cseg.method == "INVITE")
{
  ...
}
 
if($sel(cseg.method) == "INVITE")
{
  ...
}

Library framework

RPC Interface

CFG framework

CFG Include support

include_file "name_of_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:

Among benefits:

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

onsend_route {
  if(isflagset(2) && $snd(ip)=="10.10.10.10") {
    drop;
  }
}

event_route

event_route[htable:mod-init] {
  $shv(start_time) = $Tf;
  sql_query("insert into restarts (start_time) values ('$Tf')");
}

Names for route blocks and 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

switch($rU) {
  case /"^123":
    if($fU=="345") {
      break;
    } else {
      ...
    }
  break;
  case /"^456":
    ...
  break;
}

while statement

$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

$var(expires) = (int)$hdr(expires);

new comparison operators

if($ua eq "Snom") {
   ...
}
       int(undef)==0,  int("")==0, int("123")==123, int("abc")==0
       str(undef)=="", str(123)=="123".
new script operators
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

Script compatibility mode

      #!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(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

Format: group.id = value 'desc' description
...
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

drouting

iptrtpproxy

kex

memcached

mi_rpc

pdb

tmx

topoh

xmlrpc

#...
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

htable

  /* print number of items in htable 'a' */
  xlog("htable a has $shtcn(a= >.*) items\n");

imc

...
modparam("imc", "extra_hdrs", "P-Hint: imc\r\n")
...

lcr

msilo

nathelper

presence_xml

$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

registrar

seas

textops

tm

usrloc

utils

userblacklist

!!! New tools

sercmd

siremis

Project resources:

A series of blog posts highlighting the best of new in Kamailio (OpenSER) 3.0.0: