– Kamailio SIP Server –

Table of Contents

OpenSER Core CookBook

This page is dedicated to OpenSER core interaction with the configuration script (openser.cfg). These parameters, keywords, and functions are exported by OpenSER's core for use in configuration file.

This list is not complete yet. It will eventually, and with your help, that will happen sooner.

Please contribute only to the items you are sure you know what they mean.

Thank you!

IMPORTANT: This document is only valid for OpenSER development version (v1.2.0)

Core Keywords

Keywords specific to SIP messages which can be used mainly in 'if' expressions.

af

The address family of the received SIP message. It is INET if the message was received over IPv4 or INET6 if the message was received over IPv6.

Exampe of usage:

  if(af==INET6) {
      log("Message received over IPv6 link\n");
  };

dst_ip

The IP of the local interface where the SIP message was received. When the proxy listens on many network interfaces, makes possible to detect which was the one that received the packet.

Example of usage:

 if(dst_ip==127.0.0.1) {
    log("message received on loopback interface\n");
 };

dst_port

The local port where the SIP packet was received. When OpenSER is listening on many ports, it is useful to learn which was the one that received the SIP packet.

Example of usage:

 if(dst_port==5061)
 {
     log("message was received on port 5061\n");
 };

from_uri

This script variable is a reference to the URI of 'From' header. It can be used to test 'From'- header URI value.

Example of usage:

  if(is_method("INVITE") && from_uri=~".*@openser.org")
  {
      log("the caller is from openser.org\n");
  };

method

The variable is a reference to the SIP method of the message.

Example of usage:

  if(method=="REGISTER")
  {
     log("this SIP request is a REGISTER message\n");
  };

msg:len

The variable is a reference to the size of the message. It can be used in 'if' constructs to test message's size.

Example of usage:

  if(msg:len>2048)
  {
      sl_send_reply("413", "message too large");
      exit;
  };

retcode

It represents the value returned by last function executed (similar to $? from bash – if you wish, you can use also $? in OpenSER config, both names 'retcode' and '$?' are supported). If tested after a call of a route, it is the value retuned by that route.

Example of usage:

 route {
     route(1);
     if(retcode==1)
     {
         log("The request is an INVITE\n");
     };
 }

 
 route[1] {
     if(is_method("INVITE"))
         return(1);
     return(2);
 }

proto

This variable can be used to test the transport protocol of the SIP message.

Example of usage:

  if(proto==UDP)
  {
      log("SIP message received over UDP\n");
  };

status

If used in onreply_route, this variable is a referece to the status code of the reply. If it used in a standard route block, the variable is a reference to the status of the last reply sent out for the current request.

Example of usage:

  if(status=="200")
  {
      log("this is a 200 OK reply\n");
  };

src_ip

Reference to source IP address of the SIP message.

Example of usage:

  if(src_ip==127.0.0.1)
  {
      log("the message was sent from localhost!\n");
  };

src_port

Reference to source port of the SIP message (from which port the message was sent by previous hop).

Example of usage:

  if(src_port==5061)
  {
      log("message sent from port 5061\n");
  }

to_uri

This variable can be used to test the value of URI from To header.

Example of usage:

if(to_uri=~"sip:.+@openser.org")
{
    log("this is a request for openser.org users\n");
};

uri

This variable can be used to test the value of the request URI.

Example of usage:

  if(uri=~"sip:.+@openser.org")
  {
      log("this is a request for openser.org users\n");
  };

Core Values

Values that can be used in 'if' expressions to check against Core Keywords

INET

This keyword can be used to test whether the SIP packet was received over an IPv4 connection.

Example of usage:

  if(af==INET)
  {
      log("the SIP message was received over IPv4\n");
  };

INET6

This keyword can be used to test whether the SIP packet was received over an IPv6 connection.

Example of usage:

if(af==INET6)
{
    log("the SIP message was received over IPv6\n");
};

TCP

This keyword can be used to test the value of 'proto' and check whether the SIP packet was received over TCP or not.

Example of usage:

if(proto==TCP)
{
    log("the SIP message was received over TCP\n");
};

UDP

This keyword can be used to test the value of 'proto' and check whether the SIP packet was received over UDP or not.

Example of usage:

if(proto==UDP)
{
    log("the SIP message was received over UDP\n");
};

max_len

This keyword is set to the maximum size of an UDP packet. It can be used to test message's size.

Example of usage:

  if(msg:len>max_len)
  {
      sl_send_reply("413", "message too large to be forwarded over UDP without fragmentation");
      exit;
  }

myself

It is a reference to the list of local IP addresses, hostnames and aliases that has been set in OpenSER configuration file. This lists contain the domains served by OpenSER.

The variable can be used to test if the host part of an URI is in the list. The usefulness of this test is to select the messages that has to be processed locally or has to be forwarded to another server.

See “alias” to add hostnames,IP addresses and aliases to the list.

Example of usage:

  if(uri==myself) {
      log("the request is for local processing\n");
  };

Core parameters

Global parameters that can be set in configuration file.

advertised_address

It can be an IP address or string and represents the address advertised in Via header and other destination lumps (e.g RR header). If empty or not set (default value) the socket address from where the request will be sent is used.

WARNING: 
- don't set it unless you know what you are doing (e.g. nat traversal)
- you can set anything here, no check is made (e.g. foo.bar will be accepted even if foo.bar doesn't exist)

Example of usage:

  advertised_address="openser.org"

advertised_port

The port advertised in Via header and other destination lumps (e.g. RR). If empty or not set (default value) the port from where the message will be sent is used. Same warnings as for 'advertised_address'.

Example of usage:

  advertised_port=5080

alias

Parameter to set alias hostnames for the server. It can be set many times, each value being added in a list to match the hostname when 'myself' is checked.

It is necessary to include the port (the port value used in the “port=” or “listen=” defintions) in the alias definition otherwise the loose_route() function will not work as expected for local forwards

Example of usage:

  alias="other.domain.com:5060"
  alias="another.domain.com:5060"

check_via

Check if the address in top most via of replies is local. Default value is 0 (check disabled).

Example of usage:

  check_via=1 

children

Number of children to fork (one for each interface, protocol and port). Default value is 8, maximum value can be 32.

Example of usage:

  children=16

chroot

The value must be a valid path in the system. If set, OpenSER will chroot (change root directory) to its value.

Example of usage:

  chroot=/other/fakeroot

debug

Set the debug level. Higher values make SER to print more debug messages.

Examples of usage:

  debug=3 -- print only important messages (like errors or more critical situations) 
  - recommended for running proxy as daemon
  debug=9 -- print a lot of debug messages - use it only when doing debugging sessions

The 'debug' parameter is usually used in concordance with 'log_stderror' parameter.

For more see: http://www.voice-system.ro/docs/ser-syslog/

disable_core_dump

Can be 'yes' or 'no'. By default core dump limits are set to unlimited or a high enough value. Set this config variable to 'yes' to disable core dump-ing (will set core limits to 0).

Default value is 'no'.

Example of usage:

  disable_core_dump=yes

disable_tcp

Global parameter to disable TCP support in the SIP server. Default value is 'no'.

Example of usage:

  disable_tcp=yes

disable_tls

dns

This parameter controls if the SIP server should attempt to lookup its own domain name in DNS. If this parameter is set to yes and the domain name is not in DNS a warning is printed on syslog and a “received=” field is added to the via header.

Default is no.

dns_retr_time

Time in seconds before retrying a dns request. Default value is system specific, depends also on the '/etc/resolv.conf' content (usually 5s).

Example of usage:

  dns_retr_time=3

dns_retr_no

Number of dns retransmissions before giving up. Default value is system specific, depends also on the '/etc/resolv.conf' content (usually 4).

Example of usage:

  dns_retr_no=3

dns_server_no

How many dns servers from the ones defined in '/etc/resolv.conf' will be used. Default value is to use all of them.

Example of usage:

  dns_server_no=2

dns_try_ipv6

Can be 'yes' or 'no'. If it is set to 'yes' and a DNS lookup fails, it will retry it for ipv6 (AAAA record). Default value is 'yes'.

Example of usage:

  dns_try_ipv6=no

dns_use_search_list

Can be 'yes' or 'no'. If set to 'no', the search list in '/etc/resolv.conf' will be ignored (⇒ fewer lookups ⇒ gives up faster). Default value is 'yes'.

HINT: even if you don't have a search list defined, setting this option to 'no' will still be “faster”, because an empty search list is in fact search “” (so even if the search list is empty/missing there will still be 2 dns queries, eg. foo+'.' and foo+“”+'.')

Example of usage:

  dns_use_search_list=no

fifo

Global paramter to set the path to FIFO file. Default value is NULL. If not set, the FIFO server is not started.

Example of usage:

  fifo="/tmp/openser_fifo"

The FIFO server offers an additional interface to the server besides listening to the line interfaces for SIP messages. The FIFO file can be used to inject e.g. SIP messages directly in to the SIP proxy with an external application. Openserctl uses this interface and therefore needs the FIFO file to be set.

fifo_dir

Set the directory where to create the FIFO files to reply to a FIFO command. Default value is “/tmp/”.

Example of usage:

  fifo_dir="/var/tmp/"

fifo_mode sock_mode file_mode

Set permissions for unix sockets and fifo file created by OpenSER. Default value is '0660'.

Example of usage:

  sock_mode=0600

fifo_user sock_user

Set the user id to be used to create the fifo file or unix socket file (the owner of the file).

Example of usage:

  fifo_user=root

fifo_group sock_group

Set the group id to be used to create the fifo file or the unix socket file.

Example of usage:

  fifo_group=wheel

fifo_db_url

fork

If set to 'yes' the proxy will fork and run in daemon mode - one process will be created for each network interface the proxy listens to and for each protocol (TCP/UDP), multiplied with the value of 'children' parameter.

When set to 'no', the proxy will stay bound to the terminal and runs as single process. First interface is used for listening to.

Default value is 'yes'.

Example of usage:

  fork=no

group gid

The group id to run OpenSER.

Example of usage:

group="openser"

listen

Set the network addresses the SIP server should listen to. It can be an IP address, hostname or network iterface id or combination of protocol:address:port (e.g., udp:10.10.10.10:5060). This parameter can be set multiple times in same configuration file, the server listening on all addresses specified.

Example of usage:

  listen=10.10.10.10
  listen=eth1:5062
  listen=udp:10.10.10.10:5064

If you omit this directive then the SIP server will listen on all interfaces. On start the SIP server reports all the interfaces that it is listening on.

log_facility

If OpenSER logs to syslog, you can control the facility for logging. Very useful when you want to divert all OpenSER logs to a different log file. See man page syslog(3) for more details.

For more see: http://www.voice-system.ro/docs/ser-syslog/

Example of usage:

  log_facility=LOG_LOCAL0

log_name

Set the id to be printed in syslog. The value must be a string and has effect only when OpenSER runs in daemon mode (fork=yes), after daemonize. Default value is argv[0].

Example of usage:

  log_name="openser-5070"

log_stderror

With this parameter you can make OpenSER to write log and debug messages to standard error. Possible values are:

- “yes” - write the messages to standard error

- “no” - write the messages to syslog

Default value is “no”.

For more see: http://www.voice-system.ro/docs/ser-syslog/

Example of usage:

  log_stderror=yes

maxbuffer

The size in bytes not to be exceeded during the auto-probing procedure of descovering the maximum buffer size for receiving UDP messages. Default value is 262144.

Example of usage:

  maxbuffer=65536

memlog mem_log

Log level to print memory debug info. It has be less than the value of 'debug' parameter if you want memory info to be logged.

Example of usage:

  memlog=2

mcast_loopback

It can be 'yes' or 'no'. If set to 'yes', multicast datagram are sent over loopback. Default value is 'no'.

Example of usage:

  mcast_loopback=yes

mcast_ttl

Set the value for multicast ttl. Default value is OS specific (usually 1).

Example of usage:

  mcast_ttl=32

mhomed

Set the server to try to locate outbound interface on multihomed host. By default is not (0) - it is rather time consuming.

Example of usage:

  mhomed=1

mpath

Set the module search path. This can be used to simplify the loadmodule parameter

Example of usage:

  mpath="/usr/local/lib/openser/modules"
  loadmodule "mysql.so"
  loadmodule "uri.so"
  loadmodule "uri_db.so"
  loadmodule "sl.so"
  loadmodule "tm.so"
  ...

open_files_limit

If set and bigger than the current open file limit, OpenSER will try to increase its open file limit to this number. Note: OpenSER must be started as root to be able to increase a limit past the hard limit (which, for open files, is 1024 on most systems).

Example of usage:

  open_files_limit=2048

port

The port the SIP server listens to. The default value for it is 5060.

Example of usage:

  port=5080

reply_to_via

If it is set to 1, any local reply is sent to the address advertised in top most Via of the request. Default value is 0 (off).

Example of usage:

  reply_to_via=0

rev_dns

This parameter controls if the SIP server shold attempt to lookup its own IP address in DNS. If this parameter is set to yes and the IP address is not in DNS a warning is printed on syslog and a “received=” field is added to the via header.

Default is no.

server_header

The body of Server header field generated by OpenSER when it sends a request as UAS. It defaults to “OpenSer (<version> (<arch>/<os>))”.

Example of usage:

   server_header="My Company SIP Proxy"

Please note that OpenSER will only write My Company SIP Proxy. into the header. To add a valid Server: Header, use server_header=“Server: My Company SIP Proxy”, this will add Server: My Company SIP Proxy I just trapped into this Problem with OpenSER 1.1.0 and Sipura Clients, Softphones work correctly.

server_signature

This parameter controls the “Server” header in any locally generated message.

Example of usage:

   server_signature=no

If it is enabled (default=yes) a header is generated as in the following example:

   Server: OpenSer (0.9.5 (i386/linux))

sip_warning

Can be 0 or 1. If set to 1 (default value) a 'Warning' header is added to each rely generated by OpenSER. The header contains several details that help troubleshooting using the network traffic dumps.

Example of usage:

  sip_warning=0

tcp_children

Number of childr processes to be created for TCP connections.

Example of usage:

  tcp_children=4

tcp_accept_aliases

tcp_send_timeout

Time in seconds after a TCP connection will be closed if it is not available for writing in this interval (and OpenSER wants to send something on it).

Example of usage:

  tcp_send_timeout=3

tcp_connect_timeout

Time in seconds before an ongoing attempt to connect will be aborted.

Example of usage:

  tcp_connect_timeout=5

tls_ca_list

tls_certificate

tls_ciphers_list

tls_domain

tls_handshake_timeout

tls_log

tls_method

tls_port_no

tls_private_key

tls_require_certificate

tls_send_timeout

tls_verify

tos

The TOS (Type Of Service) to be used for the sent IP packages (both TCP and UDP).

Example of usage:

  tos=IPTOS_LOWDELAY
  tos=0x10
  tos=IPTOS_RELIABILITY

unix_sock

The name of the socket the unixsock server should listen on.

Example of usage:

  unix_sock="/tmp/openser.sock"

unix_sock_children

The number of children that will listen on the unix domain socket. Default value is 1.

Example of usage:

  unix_sock_children=2

unix_tx_timeout

Timeout (in miliseconds) used when sending replies through unix sockets.

Example of usage:

  unix_tx_timeout=2000

user uid

The user id to run OpenSER (OpenSER will suid to it).

Example of usage:

  user="openser"

user_agent_header

The body of User-Agent header field generated by OpenSER when it sends a request as UAC. It defaults to “OpenSer (<version> (<arch>/<os>))”.

Example of usage:

   user_agent_header="My Company SIP Proxy"

wdir

The working directory used by OpenSER at runtime. You might find it usefull when come to generating core files :)

Example of usage:

   wdir="/usr/local/openser"
   or
   wdir=/usr/openser_wd

Core Functions

Functions exported by core that can be used in route blocks.

add_local_rport()

Add 'rport' parameter to the Via header generated by server (see RFC3581 for its meaning). It affects only the current processed request.

Example of usage:

  add_local_rport()

append_branch()

Similarly to t_fork_to, it extends destination set by a new entry. The difference is that current URI is taken as new entry.

break()

Since v0.10.0-dev3, 'break' can no longer be used to stop the execution of a route. The only place to use is to end a 'case' block in a 'switch' statement. 'return' must be now used instead of old 'break'.

'return' and 'break' have now a similar meaning as in c/shell.

drop()

Stop the execution of the configuration script and alter the implicit action which is done afterwards.

If the function is called in a 'branch_route' then the branch is discarded (implicit action for 'branch_route' is to forward the request).

If the function is called in a 'onreply_route' then any provisional reply is discarded (implicit action for 'onreply_route' is to send the reply upstream according to Via header).

Example of usage:

  onreply_route {
      if(status=="183") {
          drop();
      }
  }

exit()

Stop the execution of the configuration script – it has the same behaviour as return(0). It does not affect the implicit action to be taken after script execution.

route {
  if (route(2)) {
    xlog("L_NOTICE","method $rm is INVITE\n");
  } else {
    xlog("L_NOTICE","method is $rm\n");
  };
}
route[2] {
  if (is_method("INVITE")) {
    return(1);
  } else if (is_method("REGISTER")) {
    return(-1);
  } else if (is_method("MESSAGE")) {
    sl_send_reply("403","IM not allowed");
    exit;
  };
}

force_rport()

Force_rport() adds the rport parameter to the first Via header. Thus, openser will add the received IP port to the top most via header in the SIP message, even if the client does not indicate support for rport. This enables subsequent SIP messages to return to the proper port later on in a SIP transaction.

The rport parameter is defined in RFC 3581.

Example of usage:

  force_rport();

force_send_socket([proto:]address[:port])

Force OpenSER to send the message from the specified socket (it _must_ be one of the sockets OpenSER listens on). If the protocol doesn't match (e.g. UDP message “forced” to a TCP socket) the closest socket of the same protocol is used.

Example of usage:

  force_send_socket(10.10.10.10:5060);

force_tcp_alias()

force_tcp_alias(port)

adds a tcp port alias for the current connection (if tcp). Usefull if you want to send all the trafic to port_alias through the same connection this request came from [it could help for firewall or nat traversal]. With no parameters adds the port from the message via as the alias. When the “aliased” connection is closed (e.g. it's idle for too much time), all the port aliases are removed.

forward(destination)

Forward the SIP request to the given destination. This has the format of [proto:]host[:port]. Host can be an IP or hostname; supported protocols are UDP, TCP and TLS. (For TLS, you need to compile the TLS support into core). If proto or port are not specified, NAPTR and SRV lookups will be used to determine them (if possible).

If destination parameter is missing, the forward will be done based on RURI.

Example of usage:

  forward("10.0.0.10:5060");
  #or
  forward();

isdsturiset()

Test if the dst_uri field (next hop address) is set.

Example of usage:

  if(isdsturiset()) {
      log("dst_uri is set\n");
  };

isflagset(int)

Test if a flag is set for current processed message (if the flag value is 1). The value of the parameter can be in range of 0..31.

For more see http://www.voice-system.ro/docs/ser-flags/ .

Example of usage:

  if(isflagset(3)) {
      log("flag 3 is set\n");
  };

log([level,] string)

Write text message to standard error terminal or syslog. You can specify the log level as first parameter.

For more see: http://www.voice-system.ro/docs/ser-syslog/

Example of usage:

  log("just some text message\n");

prefix(string)

Add the string parameter in front of username in R-URI.

Example of usage:

  prefix("00");

return(int)

The return() function allows you to return any integer value from a called route() block. You can test the value returned by a route using 'retcode' variable (http://www.openser.org/dokuwiki/doku.php?id=openser_core_cookbook#retcode).

return(0) is same as exit();

In bool expressions:

Negative is FALSE

Positive is TRUE

Example usage:

route {
  if (route(2)) {
    xlog("L_NOTICE","method $rm is INVITE\n");
  } else {
    xlog("L_NOTICE","method $rm is REGISTER\n");
  };
}
route[2] {
  if (is_method("INVITE")) {
    return(1);
  } else if (is_method("REGISTER")) {
    return(-1);
  } else {
    return(0);
  };
}

resetdsturi()

Set the value of dst_uri filed to NULL. dst_uri field is usually set after loose_route() or lookup(“location”) if the contact address is behind a NAT.

Example of usage:

  resetdsturi();

resetflag(int)

Reset a flag for current processed message (set the value to 0). The value of the parameter can be in range of 0..31.

For more see http://www.voice-system.ro/docs/ser-flags/ .

Example of usage:

  resetflag(3);

revert_uri()

Set the R-URI to the value of the R-URI as it was when the request was received by server (undo all changes of R-URI).

Example of usage:

  revert_uri();

rewritehost() sethost()

Rewrite the domain part of the R-URI with the value of function's parameter. Other parts of the R-URI like username, port and URI parameters remain unchanged.

Example of usage:

  rewritehost("1.2.3.4");

rewritehostport() sethostport()

Rewrite the domain part and port of the R-URI with the value of function's parameter. Other parts of the R-URI like username and URI parameters remain unchanged.

Example of usage:

  rewritehostport("1.2.3.4:5080");

rewriteuser(string) setuser(string)

Rewrite the user part of the R-URI with the value of function's parameter.

Example of usage:

  rewriteuser("newuser");

rewriteuserpass() setuserpass()

Rewrite the password part of the R-URI with the value of function's parameter.

Example of usage:

  rewriteuserpass("my_secret_passwd");

rewriteport() setport()

Rewrites/sets the port part of the R-URI with the value of function's parameter.

Example of usage:

  rewriteport(5070);

rewriteuri(str) seturi(str)

Rewrite the request URI.

Example of usage:

  rewriteuri("sip:test@openser.org");

send(destination)

Send the original SIP message to a specific destination. This is definied as [proto:]host[:port]. No changes are applied to received message, no Via header is added. Host can be an IP or hostname; supported protocols are UDP, TCP and TLS. (For TLS, you need to compile the TLS support into core). If proto or port are not specified, NAPTR and SRV lookups will be used to determine them (if possible).

Paramtere is mandatory and has string format.

Example of usage:

 send("udp:10.10.10.10:5070");

set_advertised_address(ip|string)

Same as 'advertised_address' but it affects only the current message. It has priority if 'advertised_address' is also set.

Example of usage:

  set_advertised_address("openser.org");

set_advertised_port(int)

Same as 'advertised_port' but it affects only the current message. It has priority over 'advertised_port'.

Example of usage:

  set_advertised_port(5080);

setdsturi(string)

Explicitely set the dst_uri field to the value of the paramater. The parameter has to be a valid SIP URI.

Example of usage:

  setdsturi("sip:10.10.10.10:5090");

setflag(int)

Set a flag for current processed message. The value of the parameter can be in range of 0..31. The flags are used to mark the message for special processing (e.g., accounting) or to keep some state (e.g., message authenticated).

For more see http://www.voice-system.ro/docs/ser-flags/ .

Example of usage:

  setflag(3);

strip(int)

Strip the first N-th characters from username of R-URI (N is the value of the parameter).

Example of usage:

  strip(3);

strip_tail(int)

Strip the last N-th characters from username of R-URI (N is the value of the parameter).

Example of usage:

strip_tail(3);

Routing Blocks

route

Request routing block. It contains a set of actions to be taken for SIP requests.

The main 'route' block identified by 'route{…}' or 'route[0]{…}' is executed for each SIP request.

The implicit action after execution of the main route block is to drop the SIP request. To send a reply or forward the request, explicit actions must be called inside the route block.

Example of usage:

  route {
       if(is_method("OPTIONS")) {
          # send reply for each options request
          sl_send_reply("200", "ok");
          exit();
       }
       route(1);
  }
  route[1] {
       # forward according to uri
       forward();
  }

branch_route

Request's branch routing block. It contains a set of actions to be taken for each branch of a SIP request. It is executed only by TM module after it was armed via t_on_branch(“branch_route_index”).

Example of usage:

  route {
      lookup("location");
      t_on_branch("1");
      if(!t_relay()) {
          sl_send_reply("500", "relaying failed");
      }
  }
  branch_route[1] {
      if(uri=~"10\.10\.10].10") {
          # discard branches that go to 10.10.10.10
          drop();
      }
  }

failure_route

Failed transaction routing block. It contains a set of actions to be taken each transaction that received only negative replies (>=300) for all branches. The 'failure_route' is executed only by TM module after it was armed via t_on_failure(“failure_route_index”).

Note that in 'failure_route' is processed the request that initiated the transaction, not the reply .

Example of usage:

  route {
      lookup("location");
      t_on_failure("1");
      if(!t_relay()) {
          sl_send_reply("500", "relaying failed");
      }
  }
  failure_route[1] {
      if(is_method("INVITE")) {
           # call failed - relay to voice mail
           t_relay_to_udp("voicemail.server.com","5060");
      }
  }

onreply_route

Reply routing block. It contains a set of actions to be taken for SIP replies.

The main 'onreply_route' identified by 'onreply_route {…}' or 'onreply_route[0] {…}' is executed for all replies received.

Certain 'onreply_route' blocks can be executed by TM module for special replies. For this, the 'onreply_route' must be armed for the SIP requests whose replies should be processed within it, via t_on_reply(“onreply_route_index”).

route {
    lookup("location");
    t_on_reply("1");
    if(!t_relay()) {
        sl_send_reply("500", "relaying failed");
    }
}
onreply_route[1] {
    if(status=~"1[0-9][0-9]") {
         log("provisional response\n");
    }
}

Routing Constructs

Different constructs that help to select specific actions to be executed.

if

IF-ELSE statement

Example of usage:

  if(is_method("INVITE"))
  {
      log("this sip message is an invite\n");
  } else {
      log("this sip message is not an invite\n");
  }

switch

SWITCH statement - it can be used to test the value returned by last function executed ('retcode').

IMPORTANT NOTE: 'break' can be used only to mark the end of a 'case' branch (as it is in shell scripts). If you are trying to use 'break' outside a 'case' block the script will return error – you must use 'return' there.

Example of usage:

  route {
      route(1);
      switch(retcode)
      {
          case -1:
              log("process INVITE requests here\n");
          break;
          case 1:
              log("process REGISTER requests here\n");
          break;
          case 2:
          case 3:
              log("process SUBSCRIBE and NOTIFY requests here\n");
          break;
          default:
              log("process other requests here\n");
     }
  }
  route[1]{
      if(is_method("INVITE"))
      {
          return(-1);
      };
      if(is_method("REGISTER"))
          return(1);
      }
      if(is_method("SUBSCRIBE"))
          return(2);
      }
      if(is_method("NOTIFY"))
          return(3);
      }
      return(-2);
  }

NOTE: take care while using 'return' - 'return(0)' stops the execution of the script.