Securing the Association of the DTLS Certificate With the User’s SIP-URI


imagesThe SIP protocol can be used to establish SRTP security using DTLS protocol. The DTLS extension ([RFC 5764]) is used. It describes a mechanism to transport a fingerprint attribute in SDP. So the fingerprint of the self-signed certificate can be inserted by the user agent (UA) in the SDP and sent over SIP to the proxy over an integrity protected channel (carried over TLS transport protocol). The fingerprint in the SDP looks like this:

a=fingerprint:sha-1 99:41:49:83:4a:97:0e:1f:ef:6d:f7:c9:c7:70:9d:1f:66:79:a8:07

Then after the user has been authenticated, the proxy generates a hash where the certificate’s fingerprint and SIP user ID are among others included in the calculation. The proxy signs the hash using its private key and inserts the signature in a new header field in the SIP message (the Identity header field). This secure the association between the DTLS certificate and the user’s SIP URI. The Identity-Info header field helps the verifier (the receiver of the SIP/SDP message) in the verification of the signature included in the Identity header field.

The certificates are being used as a carriers for the public keys and used to authenticate the counterpart and negotiate the session keys (symmetric keys). Then the session keys are used by SRTP to encrypt/decrypt the media. The offerer sends its fingerprint in the request and the answerer sends its fingerprint in the corresponding response after accepting the offer.

Using SIP Identity and Identity-Info

The solution as i mentioned above is using the SIP Identity ([RFC 4474]) to sign the binding of the fingerprint to the user. This is done by the proxy responsible for that user. The proxy is the holder of the private key of its domain. After the user is successfully authenticated, it is authorized to claim the identity (AOR of the user). The proxy creates the signature of the hash using its private key and inserts it in Identity header field. The proxy also inserts the place where the verifier can acquire the proxy’s certificate (public key) using the Identity-Info header field.


Identity: CyI4+nAkHrH3ntmaxgr01TMxTmtjP7MASwliNRdupRI1vpkXRvZXx1ja9k

Note the part “/cert” in the Identity-Info URL which addresses a certificate.

The Hash Generation

The signature of the hash is added as an Identity header field in the SIP message. The calculation of the hash must contain mainly the AOR of the user and the fingerprint included in the SDP in the body of the message.  According to RFC [4474], the signature/hash is generated from certain components of SIP message, among others:

  • The AoR of the UA sending the message (or addr-spec of the From header field)
  •  The addr-spec component of the Contact header field value.
  • The whole SDP body (the fingerprint is here)
  • …….

Fingerprint Verification

Using the header Identity-Info, the user agent verifies that the fingerprint of the certificate received over the DTLS handshake matches the fingerprint received in the SDP of SIP request/response.


WebSocket as a Transport for SIP


Here I just want to write a few words that summarize the RFC 7118:


  • The WebSocket protocol enables message exchange between clients and servers on top of a persistent TCP connection

  • The connection is optionally secured with TLS

  • The WebSocket handshake is based on HTTP and uses the HTTP GET method with an Upgrade request → HTTP 101 response on success .

  • During the connection handshake, the client and server agree on the application-level protocol on top of Websocket transport (Websocket subprotocol) -In this document it is SIP

  • Websocket messages can be sent in either UTF-8 text frames or binary frames. SIP allows both. UTF-8 is recommended for Javascript and WebSocket API

  • Each SIP message must be carried in a single WebSocket message and the WebSocket message contains only one SIP message → simplifies the SIP message parsing – no need for message boundaries (Content-Length header)

  • “ws” is used for plain websocket connections and “wss” for secure Websocket connections. These are for “via” transport parameter and SIP URI transport parameter

  • The SIP WebSocket server may decide not to add the parameter “received” in the top via header. The Client must accept the responses without this parameter

  • The SIP webSocket client is not manadated to implement support of UDP and TCP.

  • “SIP+D2W” DNS NAPTR service value for plain Websocket connections and “SIPS+D2W” for secure websocket connections.

  • The authentication can be on SIP level or Web level (token/cookie is used) – Appendix A

  • Using GRUU is valuable here (must be implemented on the client and server)

  • The Contact URI provided by SIP UAs is not used for routing requests to those UAs.

  • When SIP WebSocket server behaves as edge outbound proxy (Outbound + Path support), the proxy performs loose routing and remains in the path.

More Information

Regular Expressions For SIP Trunk



The regular expression is a sequence of characters that form a search pattern. See the definition in Wikipedia. It is a huge topic and takes a lot of time to explain. If you didn’t use it, you will get stuck in a nested “If” statements situation. Using regular expressions means professionalism. I am assuming you know about it and i will just apply it to SIP.


Regular Expressions For a SIP Trunk

Usually when a SIP router receives a SIP request which is addressed to a PSTN gateway (i.e. Its Request-URI contains a telephone number), it checks which group the requested user (called party) belongs to. The router also must check if the caller has permission to make this call. So the check can be done on the caller and calle. Any check done by the router is translated into this simple thinking logic:

If (Routing Condition){

  Do Specific Work


This can be in the router’s routing script or internally integrated in the router’s application.


If (The Call Is Addressed To A Local Number){

Do Specific Work


In OpenSIPS SIP router, the previous condition can be treated in the routing scripts in two ways:

  • Using the Script Variables (e.g. the reference to the request’s uri ($ru)) with the regular expression directly:

If ($ru=~sip:[2-9][0-9]{6}@){


The previous regular expression is for any 7 numbers starting by one digit from the range [2-9].

  • Using a function like “pcre_match” in “Regex” module which matches the given string against a given regular expression. The return value is TRUE if it is matched, FALSE otherwise:

If (pcre_match(“$ru”,sip:[2-9][0-9]{6}@){


The variable “$ru” is read/write variable so be aware where in the script you are checking its value. You can use “$ou” which is a reference to the request’s original URI. The module “Regex” is based on the library “PCRE” which is an implementation of regular expression pattern matching where the regular expression parameter will be compiled in PCRE object. So the development libraries of “PCRE” must be installed (“libpcre-dev” or “pcre-devel”).

Note: Use “&&” if you want to concatenate multiple conditions in one “if” statement.

If ((Routing Condition-1) && (Routing Condition-2)){

  Do Specific Work


Examples of Regular Expressions For SIP Trunk

You should test your regular expression before using it to know if you have constructed it correctly. There are many online free services that you can use to do your tests. Use search engines to search for syntax symbols that you can use to construct the regular expression. The following are examples. Note that each one defines a group:

  • Any user on any domain/IP: sip:(.*)@(.*)
  • Any user on certain domain: sip:(.*)
  • Any user on certain IP (  sip:(.*)@198\.18\.250\.10 In regular expression, the “.” is interpreted as “any character” symbol whereas “\.” is just a period (dot).
  • Any user on IP Range ( – sip:(.*)@198\.18\.250.* The symbol “*” is quantifier which means the preceding character is found 0 or more times. Here i left the last part of IP to be anything but you can restrict it.
  • To group a set of SIP URIs that are within a certain domain or certain subdomain, use .*mydomain\.com.* For example these URIs will be matched:;transport=tcp, and SIP/2.0
  • To group a set of SIP URIs that have certain string in the username part of URI and the ports 5060 and 5061 are accepted, use the regular expression .*group1@198\.18\.250.\10:506<01>.* For example these two URIs will be matched sip:serv1group1@;transport=tcp and sips:serv2group1@;tranport=tcp
  • 8-digit number on any domain: sip:[0-9]{8}@(.*) The [0-9] is a range for one number between 0 and 9 and {8} means repeat the preceding number 8 times.
  • 8-digit number starting optionally by 8 on any domain: sip:8?[0-9]{7}@(.*)  The symbol “?” means the repetition is 0 or 1 to the preceding. For example,,, and so on.
  • 4-digit number (could be an extension number) starting by 6 on a certain domain: sip:6[0-9]{3}@(.*)
  • 4-digit number which is not starting by 55 on any domain: sip:(?!55)[0-9]{4}@(.*)

 More Information

Linux Tuning For SIP Routers – Part 4 (Networking)



This is Part  4 of “Linux Tuning For SIP Routers” topic. In Part 1 i have talked about Interrupts and IRQ Tuning. In Part 2 i have talked about File System Tuning, Journaling File System, and Swappiness . In Part 3 i have talked about OOM killer, Private Momory, and Shared Memory Tuning. In this part i will talk about Network tuning.

Network Adapter Settings

To check the setting of your network card, type: “ethtool X” where X is the interface name. The tool “ethtool” is used to read and write the settings of the network card. To update the settings:

  • Find the name of the network interface: # ifconfig
  • Get the current settings: # ethtool X
  • Do your change using ethtool (See the man page: # man ethtool). For example to change the speed to 1000, and the mode to  full duplex: # ethtool -s p4p2 speed 1000 duplex full autoneg off (where p4p2 is my interface name).

Note: Changes must be supported by the network adapter, otherwise it will give an error message “Cannot set new settings: Invalid argument”

To make the changes permanent for p4p2, set the environment variable  ETHTOOL_OPTS:

  • If you are using bash : # vi /etc/sysconfig/network-scripts/ifcfg-p4p1  (note “ifcfg-p4p1” will be different)
  • Add/update this line: ETHTOOL_OPTS=speed 1000 duplex full
  • Restart the network service: # systemctl restart network.service

“txqueuelen” Parameter

The kernel parameter “txqueuelen” is the size of the transmission queue related to the interface. The default value is 1000 frames. The kernel stores the departing frames in this queue (the frames are not loaded onto the NIC’s buffer yet). Tuning this value is important to avoid loosing frames due to the lack of space in the transmission queue. Use high value (long queue) for high speed interfaces (≈> 10 Gb).

To get the current value of txqueuelen: # ifconfig p4p2 where p4p2 is the interface name. The output will look like:

 p4p2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500 ether 0c:54:a5:08:45:a7  txqueuelen 1000  (Ethernet) RX packets 0  bytes 0 (0.0 B) RX errors 0  dropped 0  overruns 0  frame 0 TX packets 0  bytes 0 (0.0 B) TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 device interrupt 19

You can also execute “# ip link” to get the txqueuelen value (qlen 1000).

To temporarily change the value to 3000 (for ≈10 Gb card): # ifconfig  p4p2 txqueuelen 3000

To permanently change it, add/change the command “/sbin/ifconfig p4p2 txqueuelen 3000” in the file “/etc/rc.d/rc.local”. If this file is not exist, do the following if you have Fedora Red Hat:

  • # vi /etc/rc.d/rc.local
  • # chmod a+x /etc/rc.d/rc.local
  • At the top of the file, add the bash interpreter: #!/bin/sh
  • At the end of the file add exit 0
  • Between the previous two lines add the command: /sbin/ifconfig p4p2 txqueuelen 3000
  • Save the file and reboot (The command will be executed at system startup).

“netdev_max_backlog” Parameter

The kernel parameter “netdev_max_backlog” is the maximum size of the receive queue. The received frames will be stored in this queue after taking them from the ring buffer on the NIC. Use high value for high speed cards to prevent loosing packets. In real time application like SIP router, long queue must  be assigned with high speed CPU otherwise the data in the queue will be out of date (old).

To get the current value of netdev_max_backlog: #  /proc/sys/net/core/netdev_max_backlog. The default value is 1000 frames.

To temporarily change the size to 300000 frame:  # echo 300000 > /proc/sys/net/core/netdev_max_backlog

To permanently change the value:

  • Edit the file “/etc/sysctl.conf
  • Add the line: net.core.netdev_max_backlog=300000
  • Load the change which you did:  # sysctl -p


  • Do a test before going to the deployment.
  • To change the ring buffer size on the NIC: # ethtool -g p4p2 where p4p2 is the interface name. This operation must be supported by the NIC.

Kernel Parameters For the Socket Buffer

Usually SIP uses TCP or UDP to carry the SIP signaling messages over the internet (<=> TCP/UDP sockets). The receive buffer (socket receive buffer) holds the received data until it is read by the application. The send buffer (socket transmit buffer) holds the data until it is read by the underling protocol in the network stack.

The default (initial) and maximum size (In  bytes) of the receive socket buffer:

# cat /proc/sys/net/core/rmem_default

# cat /proc/sys/net/core/rmem_max

You can manipulate this value in the application by calling the function “setsockopt” and specify the option name “SO_RCVBUF”  with the socket level set to SOL_SOCKET. When you specify a value for this option, the kernel will doubles this value.  So the doubled value should be less than the maximum (rmem_max).

The default (initial) and maximum size (In bytes) of the send socket buffer:

#  cat /proc/sys/net/core/wmem_default #  cat /proc/sys/net/core/wmem_max

You can manipulate this value in the application by calling the function “setsockopt” with the option name “SO_SNDBUF”. Choose the value which is suitable to he speed of the network card. For example, to set the maximum to 10 MB (10 * 1024 * 1024 Bytes)=10,485,760 for the receive buffer and send buffer:


# echo 10485760 > /proc/sys/net/core/rmem_max

# echo 10485760 > /proc/sys/net/core/wmem_max


  • Edit the file “/etc/sysctl.conf
  • Add the lines:



  • Save the file and reload the changes:  # sysctl -p

To change the defaults:


# echo 10485760 > /proc/sys/net/core/rmem_default

# echo 10485760 > /proc/sys/net/core/wmem_default


  • Edit the file “/etc/sysctl.conf
  • Add the lines:



  • Save the file and reload the changes:  # sysctl -p

Also You need to set the minimum size, initial size, and maximum size for the protocols. To read the current values (Assuming IPv4 and TCP):

# cat /proc/sys/net/ipv4/tcp_rmem

The output look like this: 4096    87380   6291456 (min, initial, max). To read write buffer settings: # cat /proc/sys/net/ipv4/tcp_wmem

You can do the same for UDP (udp_rmem and udp_wmem) To change the values: Temporarily:

# echo 10240 87380 10485760 > /proc/sys/net/ipv4/tcp_rmem

# echo 10240 87380 10485760 > /proc/sys/net/ipv4/tcp_rmem


  • Edit the file “/etc/sysctl.conf
  • Add the lines:

net.ipv4.tcp_rmem= 10240 87380 10485760

net.ipv4.tcp_wmem= 10240 87380 10485760

  • Save the file and reload the changes:  # sysctl -p

TCP Kernel Parameters

  • Disable TCP timestamp (RFC 1321): TCP timestamp feature allows round trip time measurement (<=>  Adding 8 bytes to TCP header). To avoid this overhead we disable this feature:  net.ipv4.tcp_timestamps = 0
  • Enable window scaling: net.ipv4.tcp_window_scaling = 1
  • Disable select acknowledgements (SACK): net.ipv4.tcp_sack = 1
  • Disable cache metrics so the initial conditions of the closed connections will not be saved to be used in near future connections:

net.ipv4.tcp_no_metrics_save = 1

‘1’ means disable caching.

  • Tune the value of “backlog” (maximum queue length of pending connections “Waiting Acknowledgment”):

tcp_max_syn_backlog= 300000

  • Set the value of somaxconn. This is the Max value of the backlog. The default value is 128. If the backlog is greater than somaxconn, it will truncated to it.

Temporarily# echo 300000 > /proc/sys/net/core/somaxconn

Permanently: Add the line: net.core.somaxconn= 300000 in the file /etc/sysctl.conf. Reload the change (# sysctl -p).

  • ” TIME_WAIT” TCP socket state is the state where the socket is closed but waiting to handle the packets which are still in the network. The parameter tcp_max_tw_buckets is the maximum number of sockets in “TIME_WAIT” state. After reaching this number the system will start destroying the socket in this state. To get the default value:

# cat /proc/sys/net/ipv4/tcp_max_tw_buckets.

Increase the value to 2000000 (2 million). Increasing this value leads to requirement of more memory.


# echo 2000000 > /proc/sys/net/ipv4/tcp_max_tw_buckets

Permanently: Add the line: net.ipv4.tcp_max_tw_buckets= 2000000 in the file /etc/sysctl.conf. Reload the change (# sysctl -p).

  • Other TCP parameters that you can change as above:

net.ipv4.tcp_keepalive_time (how often the keepalive packets will be sent to keep the connection alive).

net.ipv4.tcp_keepalive_intvl (time to wait for a reply on each keepalive probe).

net.ipv4.tcp_retries2 (how many times to retry before killing an alive TCP connection).

net.ipv4.tcp_syn_retries (how many times to retransmit the initial SYN packet).

 Number of Open Files

When the SIP router is high loaded, this means it has a lot of open sockets (Each socket is a file). To increase the number of sockets we increase the number of open files (<=> number of file handles). To know the maximum number of file handles on the entire system:

# cat /proc/sys/fs/file-max. The output will be a number:  391884

To get the current usage of file handles: # cat /proc/sys/fs/file-nr. The output will look like: 10112   0       391884 First number (10112) is the total number of allocated file handles. Second number (0) is the currently used file handles (2.4 kkernel) or currently unused file handles (2.6 kernel). Third number (391884) is the maximum number of file handles.

To change the maximum number of open files temporarily:  # echo 65536 > /proc/sys/fs/file-max

To change the maximum number of open files permanently: Add the line “fs.file-max=65536”  in the file “/etc/sysctl.conf”.

SHELL Limits

The maximum number of open files “/proc/sys/fs/file-max” is for the whole system. This number is for all users so if you want to allow specific user (lets say opensips) to open X files where X < file-max, you can use “ulimit” to do that:

  • As root, edit the file: # vi /etc/security/limits.conf
  • Add/Change the following lines:

opensips              soft               nofile                   4096

opensips              hard               nofile                  40000

At the start time, the opensips can open till 4096 files (soft limit). If opensips gets an error message about running out of file handles, then opensips user can execute “ulimit -n New_Number” to increase the number of file handles to New_Number. The New_Number must be less than the hard limit (the second line) and the hard limit must be less than the file-max.

To avoid getting the error message (“out of file handles”), let opensips in its start scripts execute “ulimit -n New_Number”. Choosing the New_Number depends on your test to know how much your opensips needs. You can as root set permanently “soft limit=hard limit = New_Number”  in the file ” # vi /etc/security/limits.conf”.

Do not set the hard limit to a value equal to /proc/sys/fs/file-max, then the entire system might run out of file handles. Remember file-max is for the whole system.


  • Don’t use the numbers in this article. Do your tests on your system.
  • Use network performance testing tools like netperf, pktgen, and mpstat.
  • You always have to check how to optimize your hardware:
    • If the Network Interface Card support Flow Control (e.g e1000 network interface card).
    • Some NIC drivers support interrupt coalescing (multiple interrupts can be coalesced into one kernel interrupts). If your NIC support this, you can activate it as following: # ethtool -C p4p2 where p4p2 is the interface.

 More Information

SIP Stress Testing -Part 1 (Opensipsctl & OpenSIPS-CP)


What is Stress Testing ?

It is the process of putting so great load on the system and measuring its response. It helps to determine the maximum operating capacity of the system. The behaviour of the system will be predictable under high/peak loads.

I will mention some tools which help you in the testing of OpenSIPS SIP server under stress.


Using SIP traffic generator , we can highly load the SIP server and read the statistics. For example under certain high load, the number of dropped packets became unacceptable or the number of SIP transactions that are in use in memory is so large.

Opensipsctl Tool

It is shell script and it is used as management and monitoring tool. It has some options to generate some statistics. This script communicates with OpenSIPS server through either FIFO pipe or unix socket (The control engine is either fifo or unixsocket). The script is present in OpenSIPS sbin directory. Its configuration file opensipsctlrc is stored in OpenSIPS etc directory. Check the name of your fifo file in the configuration file. To display the available commands, type: #./opensipsctl fifo which

Here is a list of commands available in OpenSIPS 1.11.

get_statistics, reset_statistics, uptime, version, pwd, arg, which, ps, kill, debug, cache_store, cache_fetch, cache_remove, event_subscribe, events_list, subscribers_list, list_tcp_conns, help, list_blacklists, t_uac_dlg, t_uac_cancel, t_hash, t_reply, ul_rm, ul_rm_contact, ul_dump, ul_flush, ul_add, ul_show_contact, ul_sync, dlg_list, dlg_list_ctx, dlg_end_dlg, dlg_db_sync, dlg_restore_db, profile_get_size, profile_list_dlgs, profile_get_values, list_all_profiles.

  • For example to execute the command “ps”, type: #./opensipsctl fifo ps. This command display all  processes running by OpenSIPS. The output looks like:

Process::  ID=0 PID=9739 Type=attendant
Process::  ID=1 PID=9747 Type=MI FIFO
Process::  ID=2 PID=9749 Type=SIP receiver udp:
Process::  ID=3 PID=9751 Type=SIP receiver udp:
Process::  ID=4 PID=9753 Type=SIP receiver udp:
Process::  ID=5 PID=9755 Type=SIP receiver udp:
Process::  ID=6 PID=9756 Type=time_keeper
Process::  ID=7 PID=9757 Type=timer: tm-utimer
Process::  ID=8 PID=9760 Type=TCP receiver
Process::  ID=9 PID=9762 Type=TCP receiver
Process::  ID=10 PID=9764 Type=TCP receiver
Process::  ID=11 PID=9765 Type=TCP receiver
Process::  ID=12 PID=9768 Type=TCP main

  • To get the number of simultaneous calls (=dialogs in case no presence), type: #./opensipsctl fifo get_statistics dialog. Both SIP INVITE message (Establishing a Call) and SUBSCRIBE message (subscription to presence service) creates dialog. If the SIP server provides call management + presence,  the number of active dialogs will not be equal to the number of calls. The length of the call affects the memory of the SIP server not the processing because the dialog remains in the memory till one of the end parties (caller or calle) ends the dialog by sending SIP BYE message.
  • To take information about specific command, use “help” command with the name of the command as an argument. For example if you want to take information about  the command “ps”, type: #./opensipsctl fifo help ps. The output looks like:

Help:: lists all processes used by OpenSIPS
Exported by:: core

Note: Current opensipsctl does not support NoSQL databases.

OpenSIPS Control Panel (OpenSIPS-CP)

You can also use OpenSIPS control panel (OpenSIPS-CP) to do the same things. Open the web interface. Click on “System” –> “MI Commands”. Choose a command from the command list and press “Enter”. Dont forget the parameters.

OpenSIPS-CP Statistics Monitor Page

  • There are two tables needed for statistics monitoring in OpenSIPS-CP. Do the following to download the structures of monitored_stats and monitoring_stats tables in mysql opensips database:

#cd /var/www/opensips-cp/

#mysql -Dopensips -p < config/tools/system/smonitor/tables.mysql

  • On the web interface, click on “System” –> “Statistics Monitor”. You will get the following:


For example you can get some real time statistics about transaction module (TM)  by clicking on the corresponding item in the list “Module:tm”. The “inuse_transaction” sub-item gives the number of transactions in use in memory. The transactions should be released quickly and the average value of this number should be stable (transactions created and released quickly). The number of  transactions per second defines the performance of SIP proxy.

Also you can get statistics on the number of TCP/UDP packets which waiting to be processed. By clicking on “Module:net” item, you can see “waiting_udp” and “waiting_tcp” sub-items.

  • Edit the cron_job/get_opensips_stats.php file and check the value of the variable $path_to_smonitor if it is correct according to your opensips-cp.
  • Add a cron job that collects data from the opensips:

# crontab -e

Append the following entry:

* * * * *   root   php /var/www/opensips-cp/cron_job/get_opensips_stats.php > /dev/null


The MI exported functions can be called only if the corresponded modules are loaded.  Otherwise you will get an error message (command not available). For example enabling tracing by calling sip_trace (# ./opensipsctl fifo sip_trace on) will not work if the module “” is not loaded (i.e. configured to be loaded in the configuration file). You will get this error message “500 command ‘sip_trace’ not available”.

Module Not loaded –> No Exported Functions –> Error upon calling “not exist” Function


The Next Part will be about SIPSAK command line tool which is used as a SIP traffic generator to test the performance and the security of the SIP servers or user agents.

SIP & SIPS Uniform Resource Indictor (URI)



SIP or SIPS URI is a logical address. Generally it is not tight to a single physical device. SIP user can register itself and make calls from any device connected to the internet and has SIP client installed and configured. SIP/SIPS URI identifies a communication resource (e.g. user of an online service, a group such as “sales” or “helpdesk” in an organization , mailbox on a messaging system, PSTN number at a gateway service). SIPS is used when SIP messages are protected by TLS across each hop (the communication resource is contacted securely).

Due to the mobility of SIP/SIPS URI, the user needs to periodically register its physical location with its SIP proxy/registrar (sending SIP REGISTER Request periodically). So the SIP/SIPS URI is mapped to its physical location (FQDN/IP Address) after registration. The physical location is kept in Contact header of the SIP REGISTER Request. The mapping between SIP/SIPS URI and the physical location is stored in the database of the SIP router and used when the router wants to forward a call to a user or group.

SIP URIs are used in “To”, “From”, “Contact” SIP Message’s headers, as well as in Request-URI. The general form of SIP URI is sip:user:password@host:port;uri-parameters?headers. The same format is for SIPS but the scheme is SIPS instead of SIP. The userinfo “user:password”  is optional (for example it is not exist in the URI of the proxy. e.g. If the @ sign is present , the user field MUST NOT be empty. The user field can be a telephone number. The password field is not recommended because of security reason (password in clear text). The host portion “host:port” represent where the request has to be sent (e.g. proxy/registrar). The host can be FQDN (recommended) or IP address.

SIP URI Parameters

 URI parameters comes after the portion “host:port” and are separated by semicolon “;“. The parameters are: “cause” RFC 4458, “transport” RFC 3261, “comp”, RFC 3486, “content-type”, RFC 4240, “delay”, RFC 4240, “duration” ,RFC 4240, “local”, RFC 4240, “param[n]”, RFC 4240, “play”, RFC 4240, “repeat”, RFC 4240, “gr” RFC 5627, “lr” RFC 3261, “maddr”, RFC 3261, “method”, RFC 3261, “ob” RFC 5626, “sigcomp-id”, RFC 5049, “target”, RFC 4240,4458, “ttl”, RFC 3261, “user”, RFC 3261, “voicexml”, RFC 4240.

Examples;transport=tcp  #transport is a parameter;maddr=;ttl=15

SIP URI Headers

SIP URI Headers comes after “?“. The format is Header Name = Header Value.

SIP & SIPS URI Examples taken from RFC 3261;transport=tcp;user=phone

Comparison between SIP/SIPS URI is case sensitive for the portion “user:password”. Characters other than reserved, can be written in HEX. Example: These URIs are equivalent:;transport=TCP

 Converting tel URL to SIP URI

The tel URL is specified in RFC 2806. The portion telephone-subscriber of the tel URL is placed into userinfo part of the SIP/SIPS URI. The telephone-subscriber can be local or global phone number.

Thus, tel:+358-555-1234567;postd=pp22



 More Information


SIP Trunking -Definition and Examples


What is SIP Trunking ?


The term “trunk” came from circuit-switched telecommunications. It refers to a dedicated physical line that carries many signals simultaneously. The trunk is used to interconnect routers and switches between two telecommunications systems. The term “trunk” has been used with Session Initiation Protocol (SIP) despite its reference to a physical circuit. SIP trunk is not dedicated. It allows any number of clients to connect to it due to the nature of the Internet Protocol (IP).  SIP trunk is a virtual connection between telecommunications systems. It is more like a service than a connection. This service is based on SIP and delivered by Internet Telephony Service Provider (ITSP) to a large number of clients that connect.

siptrunkWhen requests come to the server which is providing the SIP trunking service, the server applies its rules on these requests. If  a request is formatted based on the server’s pre-defined rules Then a  pre-defined decisions will be made by the server on that request. The decisions are pre-defined processing & routing of the requests. The rules and the decisions define the behaviour of the trunk and they are configured in the configuration file of the provider’s proxy. SIP trunk behaviour is described in a contract between the client who bought this service and the server who is selling this service. The client is another server and it uses the trunk on behalf of end users.

Examples of SIP trunk

First i want to clarify what is called Direct Inward Dialing (DID) or Direct Dial-in (DDI) number:

♣ In PSTN world: It is a globally unique number that can be called directly from the PSTN. Number is in E.164 format (CountryCode+CityCode+SubscriberNumber).

♣  In VOIP world: It is virtual DID. It is the number that your ITSP assigned to you to connect you (as VOIP user) to the PSTN around the world.

SIP Trunk Examples:

  • Interconnection to the PSTN using SIP trunk: This virtual trunk will be between SIP-enabled PBX like Asterisk as trunk client and VOIP service provider (ITSP) as trunk provider. When the PBX registers itself (Sending SIP REGISTER Request periodically) to the ITSP, the ITSP knows the IP address of the PBX so the ITSP can send the inbound calls to that IP address. If the registration is not required, a pre-defined IP address is used by the ITSP. The PBX  is configured to trust the requests coming from ITSP (static peer). The inbound calls are delivered to the PBX by the ITSP. The PBX will route the call depending on the DID number which must be kept in the SIP request. The ITSP’s proxy overwrites the Request-URI with the PBX’s  registered  SIP contact (user direct route learned during PBX registration and involved in the “Contact” header field of the INVITE requests and responses). The user-part of the Request-URI can be replaced by the original DID.


The outbound calls are delivered to ITSP by the PBX. The mapping between the dialed DID and its corresponding SIP User-ID could be:

♥ User-ID = DID number (one to one relationship).

♥ User-ID = Constant prefix + DID or part of DID (one to one relationship).

♥ Set of DIDs is a set of aliases to the same SIP User-ID. The SIP user can have multiple DIDs. These DIDs are stored in the database of the ITSP’s proxy (one to many relationship). OpenSIPS stores aliases in “dbaliases” table. This table requires uniqueness on the “alias_idx” index. So it is ok to have many lines for the same user with different aliases.

♥ Anyway to do the translation and make the routing possible.

Getting the corresponding VOIP user-ID from  the  dialed DID number and the registered device’s location (IP address) from the user-ID are done by the ITSP’s proxy. The needed information are stored in the database of the ITSP’s proxy/registrar. The ITSP’s proxy/registrar see the IP-PBX as a SIP user with multiple DIDs (multiple aliases).

  • Interconnection to other server-based systems (voicemail servers, call centers, application servers): Usually runs over TCP and secured by TLS. The request URI is formatted according to RFC 4458. The requests are terminated in a SIP-based server. I will back explain this later.
  • SIP-based Interconnection between IP-PBXs: I will explain in another article.

OpenSIPS Provisioning for a simple SIP Call

It is very easy to configure and manage OpenSIPS through OpenSIPS-CP.

Add the domains that OpenSIPS is responsible for

Lets add any domain (like just for test). click on System menu –> Domains


Add the users

Now we can add users to that domain. click on “Users” –> “User Management” snapshot9

User1: (username:test1, password:1234, domain:, User2: (username: test2, password:1234, domain:


Register the users and make the call (user2 –> user1)

Now we have two users: user1 and user2 and we want test2 to call test1.  Users must be registered first from SIP clients installed by the users.  Here you can find a list of open source and free SIP clients: List of Free and Open-Source SIP Software.  I recommend Jitsi,  Linphone, and CSipSimple.

Now i am using Jitsi for test1 on my laptop and i have entered the following account information in Jitsi interface:

( SIP id: test1@, password: 1234, Proxy:, Proxy Port: 5060)

And now Click på “Sign in” and the user test1 is now “online”.


I will make test2 register itself from my mobile where i have downloaded CSipSimple SIP client on it. My mobile phone and my laptop are in the same LAN. The laptop has the OpenSIPS and local SIP client (Jitsi). The laptop is protected by firewall.

Firewall rules

Everything is OK but test2 (on mobile phone) can not register itself. WHY because the firewall prevents this access. So i have to let the firewall allows SIP traffic to come to the OpenSIPS. We need to open the ports that the OpenSIPS is listening on. In my case the UDP ports 5060-5061.  To do this use dynamic firewall with Firewalld  or static firewall (system-config-firewall) with iptables.  Using static firewall means disabling and stopping of dynamic firewall.

For Firewalld you can either use the graphical configuration tool firewall-config or the command line client firewall-cmd. More information is here Firewalld

More information about editing iptables rules is here: Iptables

Note: Be aware of these “enable”, “disable”, “start”,  “stop” when using “systemctl” command.

“opensipsctl” Tool to see the Registered Users

To take information about the regitered users.

# cd /usr/local/opensips_1_11/sbin/

# ./opensipsctl fifo ul_dump
And this is the output:

AOR:: test2
Contact:: sip:test2@;ob Q=
Expires:: 894
Callid:: Vd8CYS9wJO7ffGoNAembj-bnC5Rte-k3
Cseq:: 55430
User-agent:: CSipSimple_MT15i-10/r2330
State:: CS_SYNC
Flags:: 0
Socket:: udp:
Methods:: 8063
AOR:: test1
Contact:: sip:test1@;transport=udp;registering_acc=10_0_0_4 Q=
Expires:: 521
Callid:: 3586ed724fb54b2e7505f24627e93ff6@0:0:0:0:0:0:0:0
Cseq:: 36
User-agent:: Jitsi2.2.4603.9615Linux
State:: CS_SYNC
Flags:: 0
Socket:: udp:
Methods:: 4294967295

You can also do this (# ./opensipsctl ul show). Now test1 is calling test2 :

Jitsi36- Get the Dialog Information from the OpenSIPS-CP Web Interface

During the call establishment, click on “System” menu –> “Dialog”. See the figures below of dialog early state and confirmed state.



What will be different if we want to deploy such a system ?

The answer is the existence of NAT.  I will explain this problem and how to solve it later.

Hairpinning, SIP loop, and Spiral

Here i would like to talk about: Hairpinning, SIP Spiral,  and SIP Loop.

  • Hairpinning: RFC 5128#section-2.10 defines hairpinning as following: ”If two hosts (called X1 and X2) are behind the same NAT and exchanging traffic, the NAT may allocate an address on the outside of the NAT for X2, called X2′:x2′. If X1 sends traffic to X2′:x2′, it goes to the NAT, which must relay the traffic from X1 to X2. This is referred to as hairpinning.”. Here is an example: Hairpinning
  • Spiral in SIP: as defined in RFC 3261: the condition where a SIP request routed to the proxy, forwarded onwards, and arrived again to that proxy, but this time differs in Request-URI. Example: call fowarding. Spiral is not considered as an error.
  • Loop in SIP: this is considered as an error. As in Spiral but when the request arrives the second time to the proxy, its Request-ID is identical to the first time. The proxy makes the same routing decision and we come to loop.

SIP Registration Process


The registration is a way to know the location (FQDN/IP address) of the SIP user-agent. The user-agent exchanges a set of SIP messages with the registrar/Proxy server to register its location in the server’s database. In addition to the user-agent location the registrar/proxy server can receive CPL (Call Processing Language) script.

RFC 3665 shows different registration scenarios: successful new registration, update of current registration, request for current contact list, cancellation of the registration, and unsuccessful registration. In this article i will explain only the first scenario (Successful New Registration).

Investigation of a Successful New Registration



Message F1 is explained in the figure below.

Register 1VIA header field defines 3 important informations: Transport, Last SIP Hop , and the Transaction-ID. In the previous figure we can see the transport as SIP/2.0/TLS. This means SIP messages will be secured carried by TLS transport. The last hop here is the The branch parameter in the VIA header field which is marked by star (*) in the figure, represents the identification of the current transaction. To be able to identify the transaction it must be unique across space and time for all requests sent by the user-agent except CANCEL and ACK for non-2xx responses. CANCEL has the same branch parameter as the request it cancels. An ACK for a non-2xx response will also have the same branch ID as the INVITE whose response it acknowledges. This is part of RFC 3261. Making the Branch parameter begins by the string z9hG4bK” means it is compatible with RFC 3261 regarding uniqueness property.

Each proxy adds its own VIA. The VIA header field is used for routing replies backward without DNS lookup.

Max-Fowards header field defines the maximum number of hops the SIP request can do.

From/To header field: From header field defines the user who initiates the request The ”display-name” is optional and it is used for rendering purposes on the human user-interface (GUI) of the user-agent. For example ”A is calling you” text appears on the screen of the calle.

To header header field represents the calle (user who receives the call). For example ”You are calling B” text appears on the screen of the caller. The From and To header fields are logical identities (AORs and optional display-names). NO IP addresses or FQDNs are allowed here since these are not logical. From and To header fields are not used in routing of the SIP messages.

The AOR (Address Of Record) in both From and To header fields is the same in the registration because registration is not a call.

The From-tag (the tag parameter in the From header field) with To-tag and Call-ID identify the dialog (peer-to-peer relationship between caller and calle).

Call-ID header filed identify the group of SIP messages (requests and responses) in the dialog. All must have the same Call-ID. Call-ID is calculated from random string and the phone’s hostname or IP address. This can not fully identify the dialog (the relationship between the caller and the calle) so we need “From-tag” and “To-tag”.

The generation of Call-ID is critical. The question is “When Call-ID must be globally unique ?”

The Call-ID must be selected by the UAC as globally unique over time and space if the new request is created outside any dialog.

CSeq header field used to order transactions within a dialog. Two CSeq header fields are considered equal if the sequence number and the request method are identical.

Contact header field contains SIP or SIPS URI that represents direct route to contact user-agent A. Usually it looks like: username@FQDN (Preferred) or username@IP-Address . For example: as shown in the figure but it can be also A@

You might have several SIP devices all registered under the same address of record (

Now we have finished the first message in the registration process (REGISTER F1).

F2: 401 Unauthorized

This response is shown in the figure below.

401unauthorized1WWW-Authenticate header field contains the authentication challenge sent by the server. It contains the information the user-agent needs to generate the checksum. The word “Digest” indicates the authentication scheme. The parameters are:

realm which is the associated protection domain,

qop (Quality of Protection) is optional. It can be either “auth” for authentication and “auth-int” for authentication and integrity.

nounce: unique string generated by the server.

opaque: optional, generated by the server to be returned in the subsequent requests.

stale: is flag and it is optional. It indicates if the nounce value in the previous request is stale.

algorithm:the algorithm used for checksum. It is optional and the default is MD5.


The user-agent generates what is called Authorization header and resend the original registration request (REGISTER F1) with the Authorization header field in it. The figure below shows REGISTER F3.

register-2Authorization header field involves mainly the response parameter which is the calculated checksum. The Cseq is 2 now since the request is considered new.

F4: 200 OK

If the authentication is success the server send 200 OK.

200ok1This way is the same way used in HTTP to authenticate the user. It is called WWW-authentication. There is another type of authentication used in SIP called Proxy-Authentication. Here the client receives 407 authentication challenge instead of 401.

Now other scenarios of the registration explained in the RFC 3665 will be easy to understand. Also other SIP Processes.

More Information