SIP Stress Testing -Part 3 (SIPp)



This is Part 3 of “SIP Stress Testing” topic. In Part 1, I have talked about the definition of the stress, opensipsctl (command line tool), and OpenSIPS-CP (web tool) and how they are used in testing. In Part 2 i have talked about SIPSAK (command line tool) which is used as SIP traffic generator. In this part i will talk about SIPp which is an emulation tool which generates SIP traffic and gives some statistics. The current version (3.4) have these features:

  • Establishes and releases multiple calls with the INVITE and BYE methods.
  • Read custom XML scenarios files which described simple to complex call flows.
  • Dynamic display of statistics.
  • Support of IPv6, TLS, SCTP.
  • Support of SIPauthentication, conditional scenarios, UDP retransmissions, error robustness.
  • Call specific variable.
  • Posix regular expression to extract and re-inject any protocol fields.
  • Custom actions (log, system command exec, call stop).
  • Emulate live users using external CV file .
  • Send RTP traffic (audio/video).

SIPp Installation

Pre-requisites to compile SIPp on Fedora Red Hat:

  • Install C++ compiler: # yum install gcc-c++
  • Install ncurses-devel: # yum install  ncurses-devel
  • For TLS support,  install OpenSSL (version > 0.9.8): #yum install openssl-devel
  • For pcap play support, install libpcap and libnet : #yum install  libnet libnet-devel  libpcap libpcap-devel
  • For SCTP support, install lksctp: #yum install lksctp-tools lksctp-tools-devel
  • For distributed pauses, Install GNU Scientific Libraries (gsl): #yum install gsl gsl-devel

Please check your system for the corresponding libraries names.

Download the source code of SIPp:

To compile SIPp, we have four options:

  • Without TLS, SCTP, or PCAP support.
  • With TLS support.
  • With PCAP support
  • With SCTP support

I will combine these options to compile SIPp which supports TLS, SCTP, and PCAP:

  • # tar -xvzf sipp-3.3.990.tar.gz
  • # cd sipp-3.3.990/
  • # ./configure –with-sctp –with-pcap –with-openssl
  • # make
  • # make install

Controlling SIPp Interactively

You can control SIPp through the keyboard. For example pressing on ‘1’, will display the scenario screen, and pressing ‘2’ will display the statistics screen and so on.

SIPp can alse be controlled via a UDP socket. The default base port is 8888 for the first instance and it will increase by 1 for each following SIPp instance (8889, 8890,…). Use the option -cp to change the base port. For example to put SIPp in pause state, we execute this shell command: # echo p > /dev/udp/x.y.z.t/8888 where x.y.z.t is the IP address of the SIPp instance.

Check SIPs Network State

If we have SIPp instance running on the machine (UAS instance :# sipp -sn uas -i and we want to check the network state of that instance, we execute “netstat” command as following:

# netstat -lpn  |grep sipp

The output will be like this

udp        0      0  *                           14144/sipp
udp        0      0 *                           14144/sipp
udp        0      0 *                           14144/sipp
udp        0      0 *                           14144/sipp


  • 8888 is the port for SIPp control. Use the option -cp in the command line to change the base number.
  • 5067 is the port for SIP signaling. Use the option -p in the command line to change it.
  • 6000 is  the default local RTP echo port.Use the option -mp in the command line to change it. RTP/UDP packets received on this port are echoed to their sender
  • 6002 is the RTP echo port +2. RTP/UDP packets coming on this port are also echoed to their sender.

SIP User Agent Definition

  • User Agent Client (UAC): It is a logical entity that creates a new SIP request. This role (the role of being UAC) lasts only for the duration of the transaction (SIP transaction).
  • User Agent Server (UAS): It is a logical entity that generates a response to a SIP request. This role (the role of being UAS) lasts  only for the duration of the transaction (SIP transaction).

UACUAS Example

SIP traffic between two SIP user agents on the same host (IP: The traffic is passed directly from the user agent client (UAC) to the user agent server (UAS) without passing a SIP proxy.

Scenario Definition

We want to generate SIP traffic with this specification:

  • Number of calls per second (call rate) = 100 cps. This can be specified as a parameter in the “sipp” command line after the option -r. This rate can be changed interactively (i.e. during the test) by pressing keys on the keyboard. For example pressing ‘+’ will increase the rate by 1 (‘-‘ decrease by 1, ‘*’ increase by 10, ‘/’ decrease by 10).
  • Rate Period in milliseconds for the call rate=10000 ms. This can be specified in the “sipp” command line after the option -rp.

To have n calls every m milliseconds, we mix the previous command line parameters together. So it will be like this –r n -rp m. Here in this scenario, i want to generate 100 calls per 10 seconds so the parameters will be -r 100 -rp 10000.

  • The UAC and UAS are on the same machine. For UAC, i will choose the port 5061 for SIP signaling. For UAS, i will choose the port 5067 for SIp signaling.
  • I will use IPv4 addresses.
  • Call Flow between UAC and UAS: The default behaviour of the UAC (what UAC sends and what it expects as response for each request it sends) is defined in the scenario file (uac.xml). As it is the default scenario so i don’t need to pass the name of the xml file as a parameter in the command line “sipp”. This is the default call flow of the UAC and UAS :


In the default scenario, authentication is not used and there is no record routing.

Here is the XML scenario file of the UAS  uas.xml.You can create your own custom XML scenarios as i will do in the next article. In this case you have to pass the names of the XML files which describes the call flows as parameters to “sipp” command (after the option -sf).

Run the UAC and UAS

SIPp will generate SIP traffic according to scenario defined above. SIPp has an embedded SIP user agent client (UAC) which will generate this traffic. Open one terminal and execute this command “# sipp -sn uac  -r 100 -rp 10000  -i -p 5061” to run the SIP client (uac). According to this, the UAC ( will send 100 calls per 10 seconds to the UAS (

SIPp has an embedded user agent server (UAS). Open another terminal on the same host and execute this command “# sipp -sn uas -i -p 5067“. This will run the UAS on

Be sure that the ports you want to use are free (not used by another application). This article is like a tutorial so run your UAC and UAS on different machine. Note that we are using the same command “sipp” to run the UAC and UAS. Remember SIPp is an emulation tool for testing the SIP protocol.

Scenario Screenshots

The scenario screen display the call flow as well as some information. This is the scenario screen of the UAC:

Here is the scenario screen of the UAS:

Several screens are available to monitor SIP traffic. You can change the screen by pressing 1 to 9 keys on the keyboard. For example click key ‘2’ to display the statistics screen. Here is the statistics screen of the UAC:

Here is the statistics screen of the UAS:

As you can see the number of successful calls is 150 and the number of failed calls is 0.

UACSIP ProxyUAS Example

SIP traffic between two SIP user agents. The traffic is passing the proxy from the user agent client (UAC) to the user agent server (UAS).  We will take the same previous scenario but with proxy. The UAC, UAS, and the proxy are all on the same machine. The proxy will be OpenSIPS. The routing script of the proxy must work properly with UAC and UAS.


Register and Run the UAS

Assume OpenSIPS is running on We will send packets continuously to the UAS through the proxy. So we need UAS to stay registered during the test (OpenSIPs always knows UAS IP address). So we will register UAS manually by adding a static mapping in the OpenSIPS ‘s “Location” table and this entry will be permanent (available at any time).  

Do as following:

  • Go to OpenSIPS’s sbin directory: # cd /usr/local/opensips_1_11/sbin/
  • Add UAS with the user name = 1234Test: # opensipsctl ul add 1234Test@ sip:1234Test@ This will add an entry for this user in the location table.


We have added in OpenSIPS “Domain table” (# opensipsctl domain add

  • Run the UAS:  sippsn uas -rsa  -i -p 5067. The address which comes after the option -rsa  is the remote sending address (Here it is the OpenSIPS proxy).

Now the UAS is ready. You can check its status by executing “# ./opensipsctl ul show”. The output will be as this:

Domain:: location table=512 records=1
AOR:: 1234Test
Contact:: sip:1234Test@ Q=1
Expires:: permanent
Callid:: dfjrewr12386fd6-343@opensips.mi
Cseq:: 1
User-agent:: OpenSIPS MI Server
State:: CS_SYNC
Flags:: 0
Methods:: 4294967295

As you can see this is a static entry and it is permanent (No need for refreshment). The OpenSIPS now always can route all requests destined to UAS (Request-URI=1234Test@ (OpenSIPS URI)).

Avoid Authentication of SIP Requests and Loose Routing for Sequential Requests:

Here i am taking the default routing script of OpenSIPS which is generated for residential service. Do the following changes:

  • Avoid loose routing of SIPp packets by skipping the loose routing section where the client is sipp ($fU is “sipp”):

 if (has_totag()  && ($fU!=“sipp”)) {

// Do the loose routing


  • Avoid Authentication for SIPp packets: Comment these lines in your routing script:

  # if (!proxy_authorize(“”, “subscriber”)) {
#                   proxy_challenge(“”, “0”);
#                   exit;
# }
# if (!db_check_from()) {
#                sl_send_reply(“403″,”Forbidden auth ID”);
#               exit;
# }

# consume_credentials();
# caller authenticated

  • Restart OpenSIPS (# systemctl restart opensips.service)

Run The UAC

Run this command : #sipp  -sn uac -s 1234Test -i -p 5061 -d 20000 -r 100 -rp 10000

The option ‘-s’ sets the username part of the request URI. The option -d controls the length of calls (duration of pause).


The following is the scenario screens of UAS:

Server-Scenario-Ex2and the statistics screen of the UAS:



If you got some errors, enable logging by setting the option -trace_err in command line. For example enable logging at UAC side:

#sipp -trace_err -sn uac -s 1234Test -i -p 5061

Press the key ‘q’ to quit and check the log file. The scenarios of the UAC and UAS and the routing script of the proxy, should be compatible with each other regarding what have been received and what should be sent otherwise you will get unexpected messages.

What does play a role in the results of this test ?

  • The operating system (CPU, Memory, Scheduler,….etc): Fedora Red Hat
  • The Proxy (internal design, routing script, Private and shared memory) : OpenSIPS
  • The traffic generator Performance (internal design): SIPp
  • The network design: UAS, Proxy, and UAS are on the same machine (This article is like a tutorial).

Now you can do what is called tuning (change the parameters that affect the performance). Best is using tools that help you to do the tuning and give you some statistics.

The Part 4 of “SIP Stress Testing” topic will also be about SIPp.  It will be writing custom scenario for the example UAC-SIP Proxy-UAS above.

More Information

Compilation, Installation, and Configuration of OpenSIPS’s Perl Module


If you want to implement a new feature (i.e. not exist in OpenSIPS), you can extend OpenSIPS by either writing new module (in C) or writing Perl script and call it within the routing script using OpenSIPS’s Perl module. In this article i will explain how to compile, install and configure OpenSIP’s Perl module. Then you will be ready to write your own extension.  To do that, follow these steps.

Installation of “ExtUtils::Embed” Perl Module

It is Perl module used for embedding Perl interpreter and extensions in C/C++ (i.e. Cross Compiling). To install this module on Fedora: #yum install perl-ExtUtils-Embed. The Makefile of the application can call functions from this module while building the application. In OpenSIPS, we will call the functions manually and set the results in environment variables accessed by the Makefile. One of these functions is “ldopts” which gives the GCC ‘s arguments for linking the perl library to  C/C++ application (Perl is dynamically linked to OpenSIPS). You can call this function as following:

# perl –MExtUtils::Embed –e ldopts.

Set the option -M to specify the module name which is “ExtUtils::Embed” and the option -e to call the function “ldopts”.

Pre Compilation Procedures

OpenSIPS is C application. C is a compiling language whereas Perl is a scripting language with C++ interpreter. OpenSIPS uses Perl interpreter and extensions in its Perl module to Parse/Load/Execute Perl scripts. So we need  to prepare  GCC (C/C++ compiler) to be able to compile OpenSIPS’ s Perl module. In this tutorial i am using perl (v5.18.4) and GCC (v4.8.3) on Fedora 20.

  • Execute the command #perl -MExtUtils::Embed -e ldopts.

In my case the output is:

-Wl,–enable-new-dtags  -fstack-protector  -L/usr/lib64/perl5/CORE -lperl -lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc

Assign the output to the environment variable PERLLDOPTS:

#export PERLLDOPTS=-Wl,–enable-new-dtags  -fstack-protector  -L/usr/lib64/perl5/CORE -lperl -lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc.

To make this permanently, edit the file “.bash_profile” and write the previous export statement there. Check its value: # echo $PERLLDOPTS

  • Execute the command #perl -MExtUtils::Embed -e ccopts.

In my case the output is:

-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -I/usr/lib64/perl5/CORE

Assign the output to the environment variable PERLCCOPTS. Check its value : # echo $PERLCCOPTS

  • Execute the command : #echo “`perl -MConfig -e ‘print $Config{installprivlib}’`/ExtUtils/typemap” and assign the output to environment variable TYPEMAP.
  • OpenSIPS’s Makefile is already prepared for cross compilation. It will recognize these variables. For example “Makefile.defs-> CROSS_COMPILE ?=” will include PERLCCOPTS‘s value (DON’T DO ANYTHING).


  • If you write these variables in bash profile (.bash_profile), you must reload the file: # source .bash_profile
  • See the corresponding procedures in your system.

Compilation & Installation of OpenSIPS’s Perl Module

  • If you don’t have OpenSIPS yet, have a look  here. Include Perl in the compilation (i.e. Click on “Configure Compile Options” –> “Configure Excluded Modules”. Then compile the OpenSIPS by selecting “Compile and Install OpenSIPS”. This will not rebuild everything only the new selected modules.


From the OpenSIPS ‘s src  folder (“/usr/local/src/opensips_1_11”), execute:

#make include_modules=”perl”modules

# make install

  • To see if the module is compiled and installed , check the Perl module path “/usr/local/opensips_1_11/lib64/opensips/perl/”. Check also in the OpenSIPS’s C modules path: In my case  “ /usr/local/opensips_1_11/lib64/opensips/modules/“.

Configuration of OpenSIPS’s Perl Module

♣ The module “Perl” must be loaded in OpenSIPS’s routing script (i.e. the configuration file) after loading the module “sl”.  To load the module, write this statement:

loadmodule “

♣ Set the name of the new extension (i.e. the name of your Perl script):

modparam(“perl”, “filename”, “/usr/local/opensips_1_11/Your-Extensions-Folder/”)

♣ Set the module path

modparam(“perl”, “modpath”, “/usr/local/opensips_1_11/lib64/opensips/perl/”)

♣ Restart OpenSIPS: #systemctl restart opensips.service

♣ Check the permission to execute the script: # ls -l  /Path-To-Your-Script/ (  use “chmod +x” to give it execute permission).

♣ Use “strace”  to debug the script execution. # strace file Name-Of-Your-Script.

Writing a New OpenSIPS ‘s Perl Extension

Later i will write a Perl script that extend the feature “Advice of Charge (AOC) in SIP”. If you are in hurry you can go here and see an example ( Replace 183 early media reply with 180 (Ringing)). Now you can write your Perl script and call functions from OpenSIPS’s Perl module. For example the package Message  provides access functions for an OpenSIPS sip_msg structure. For example calling the function getRURI() gives the Request-URI of the current message.

More Information

SIP Stress Testing -Part 2 (SIPSAK)


This is part 2 of the “SIP Stress Testing” topic. In Part 1, I have talked about the definition of the stress, opensipsctl (command line tool) and OpenSIPS-CP (Web tool) and how they are used in testing. In this part, i will talk about SIPSAK. SIPSAK is a command line tool used by SIP administrators to test the performance and the security of the SIP servers or user agents. SIPSAK is a SIP traffic generator. It generates SIP requests and sends them to the target addressed by SIP-URI . To download SIPSAK on Fedora, simply:

 # yum install sipsak

SIPSAK runs in the following modes:

♣ Default mode: Using the OPTIONS SIP method, you can  ping a target addressed by SIP-URI.

♣ Traceroute mode (-T): This is useful for learning the request’s path. The number of SIP servers on the way to the destination is counted plus the round trip time of each request is printed out.

♣ Message mode (-M): Send a short message using MESSAGE SIP request. The content of the message will be set using the option (-B).

♣ Usrloc mode (-U): Register the user addressed by SIP-URI (Set by option -s).

♣ Randtrash mode (-R) :keeps sending randomly corrupted messages to torture a SIP server’s parser. OPTIONS requests with increasing numbers of randomly crashed characters are sent to the server.

♣ Flood Mode (-F): keeps sending requests to a SIP server at high pace. OPTIONS requests with increasing CSeq numbers are sent to the server.

Current SIPSAK is missing support for the Record-Route and Route headers and IPv6 is not supported. At the stressed SIP server’s side, you need monitoring and analyzing tool which display the state of the server as numbers and figures.


  • Ping the target “test1”: #sipsak -s In this tutorial i will ping the user test1@

Here is the messages sent by SIPSAK and captured by SIPTRACE. See the User-Agent header field in the traced SIP message (User-Agent: sipsak 0.9.6). The message is taken from OpenSIPPS-CP SIPTRACE page.

If the server allows pinging. It will relay the ping message (SIP OPTION Request) and the response from the pinged target will come back to SIPSAK through the SIP server. The response will look like:

sipsak3The User-Agent: Jitsi2.2.4603.9615Linux . The target user (test1) must be registered otherwise you will get an error response message sent from the server (in case the server is programmed to do this in its routing script). The test server in this tutorial sends “404 Not Found” SIP failure:

sipsak4The server is “OpenSIPS (1.11.2-notls (x86_64/linux))” as written in the server’s response.

If you put the option -F , SIPSAK will flood the server with SIP OPTION Requests.

# sipsak -F  -s

SIPSAK is also used to test the security of the SIP server. In the previous example, flooding the server with OPTIONS SIP Requests (a lot of ping messages) is considered attack because after a short time the SIP service will be not available and the server became unable to handle more SIP requests. The test server in this tutorial sends an error message ” 500 Internal Error” after short time of flooding.

sipsak5Pinging is a way to check that the server is awake and not down. It must be available only for administration’s purposes.

Other SIPSAK examples:

  • Trace a call: # sipsak –T –s
  • Send a message to the user “test1” :# sipsak –M –s –c –B “Message Text”
  • Register the user “test1” # sipsak –U –s

Nagios monitoring tool are good complement to SIPSAK traffic generator.

SO to test the server, generate requests and check the system’s response. If you get something you don’t like, change it and do it again (Make changes, Restart the server, Generate traffic , and Check the server’s response).

More Information


The Next Part will be about SIPp which is an emulation tool which generates SIP traffic and gives some statistics.

Det Första Intrycket i en VOIP-JobbIntervju


Hur mycket kan det första intrycket va rätt ? Det är inte 100% i alla fall. Man bör uttrycka sig väl annars blir det inget jobb. Hur kan din kropp utrycka din personlighet rätt ?. Stämning mellan vad du tror på och hur det utkommer inifrån dig är viktig. Den som intervjuar dig, borde kunna fånga alla signaler som kommer från din kropp (Hur du hälsar, hur du pratar, och hur du  presenterar dig själv). Dina ögon är superviktiga och signaler de skickar är ännu vitigare.


Diagram1I nuförtiden är det svårt för internationella företag att möta alla jobbsökande på riktigt och kommer de att använda VOIP som alternativ.  Hur mycket stämmer VOIP bilden med verkligheten ?. Du kan inte hälsa som vanligt. Du kan inte hålla handen eller gör vad är kallad kroppspråk. Om internet inte är bra, kommer din röst eller ditt ansikte att bli oklar. Om internet bortkopplad när arbetsgivaren väntar ditt svar på nåt, kommer du kanske att byta svaret efter återkopplingen.

Ni (arbetsgivaren och arbetssökanden) kan inte see hela bilden. Hur blir det första intrycket då ?

Om Internet leverantörer tar hand om sin tjänstekvalitet, tänker man om ändå.

By Binan AL Halabi Posted in Ethic

SIPTRACE OpenSIPS Tracing Tool


What is SIPTRACE ?

siptraceIt is a tracing tool tied to OpenSIPS. With this tool, you can trace all calls or a specific user calls in real time (i.e. You can see the SIP messages related to a specific user and passed the OpenSIPS in real time).  As this tool logs the signalling messages in the database, this affects the the performance when enabled. To enable this tool, the module “siptrace” must be loaded and configured in the configuration file of the OpenSIPS (routing script).

Steps To Trace Specific User’s  SIP Messages

  • Load “siptrace” module. Add this line in the configuration file:

loadmodule “”

  • Set db_url module parameter (database URL).

modparam(“siptrace”, “db_url“, “mysql://user:passwd@host/dbname”)

  • Set trace_flag parameter (Which flag is used to mark messages to trace):

modparam(“siptrace”, “trace_flag“, “22”)    # Here the trace_flag will 22.

  • The module parametertraced_user_avp” specifies the AVP which stores the SIP URI of the traced user. The name of the user will be shown in the “traced_user” field in the “sip_trace” table. Setting the “traced_user_avp” will automatically enable tracing. You can store multiple values in the AVP if you want to trace more than one user.

modparam(“siptrace”, “traced_user_avp“, “$avp(traced_user)”)

  • Set trace_on parameter (1(on) or 0(off)): Default value is 0.

modparam(“siptrace”, “trace_on”, 1)

If this parameter is not set (remained 0) in the configuration file, the tracing can be enabled by setting the module parameter “traced_user_avp” or using opensipsctl tool:

# opensipsctl fifo sip_trace on

  • Before writing the code responsible for actual tracing of sip messages, You should be familiar with what is called Attribute Value Pair (AVP) variables. This is found here. Add this block to load and configure the “avpops” module which is needed for managing AVPs (Add/Remove/Update/Delete) in the database.

loadmodule “”
modparam(“avpops”,”db_url”,“mysql://user:passwd@host/dbname”) # Customize This
modparam(“avpops”, “avp_table”, “New_usr_preferences”) # Customize this If you are using another table.

  • To trace the current SIP message, we need to call the function (sip_trace). To trace all messages related to the current SIP meesage (i.e. messages related to the transaction created by that request), we need to set  the tracing flag (setflag(22)). Remember this flag is defined as trace_flag (modparam(“siptrace”, “trace_flag“, “22“)).

Write the following code in the main request routing block of the routing script.

if(avp_db_load(“$fu”,”$avp(trace)”)) {
xlog(“L_INFO”,”User $fu being traced”);

The $fu is a reference to URI of “From” header. The function avp_db_load(“$fu”,”$avp(trace)”) loads the AVP which belongs to $fu and has the name “trace”. This AVP must be added in the “usr_preferences” table.  Use “opensipsctl” tool to add it. # opensipsctl avp add –T usr_preferences test@youripaddress trace 1 1. This add AVP which has the name “trace”, type 1 (string,integer), and the value =1 (e.g. <=> true). This correspond to $(AVP(trace)) in the routing script. This AVP when loaded by avp_db_load function, its value will be 1 (<=> True ). The function returns true if it loaded a value in $(AVP(trace)) and this means the message/transaction belongs to that user will be traced.

Note: In the request route, you get only requests (no replies can be traced there). setting the tracing flag will solve the problem.

  • Restart OpenSIPS

# systemctl restart opensips.service

  • Use opensipsctl tool to start tracing

# opensipsctl fifo sip_trace on

OpenSIPS-CP view of “sip_trace” Table

To see the traced messages, you can look directly in the “sip_trace” table or in the OpenSIPS Control Panel. OpenSIPS-CP ‘s siptrace should also be configured. Open the local configuration of the siptrace tool in your OpenSIPS-CP folder :”opensips-cp/config/tools/system/siptrace/” and update the proxy list addresses and the name of OpenSIPS ‘s  sip_trace table.

$config->table_trace = “sip_trace”; # Table Name


To see the traced messages, open the web page “System –> SIP Trace”. You will get something like these figures.




You can also disable or enable tracing through the web (the red/green button on the right of the page “System –> SIP Trace”).

trace3SIPTRACE as a SIP Capturing Agent

SIPTRACE module can send the captured packets to an external HEP server (e.g. Homer) instead of storing them in the local database. The following is the configuration:

modparam(“siptrace”, “duplicate_uri”, “sip:″) # The capturing server address to send a duplicate of traced message to.

modparam(“siptrace”, “duplicate_with_hep”, 1)  # Enable HEP

modparam(“siptrace”, “trace_to_database”, 0) # Disable tracing to the local database

 Here you can find an example to make OpenSIPS (SIPTRACE module) operate as a SIP capturing agent.

More Information

Attribute Value Pair (AVP) Variables in OpenSIPS


Here i want to talk about AVPs from routing script’s point of view and the database’s point of view.

AVPs IN The Routing Script

These variables are used in the routing script. They are allocated at the beginning of the transaction and unallocated when the transaction is completed. So they are called transaction-persistent variables (if stateful processing is used). If stateless processing is used, theses variables will be attached to a singular message. When the message is received or the transaction is created, it will initially have an empty list of AVPs. The AVPs will be created directly in the routing script or through functions called from the script. They will automatically attached to the message/transaction.

The AVPs are visible in the routes where the message will be processed (i.e. branch_route , failure_route, onreply_route). If we want the AVPs to be visible in the onreply_route, we need to enable the TM parameter “onreply_avp_mode”.

OpenSIPS ‘s AVPs are Read-Write variables (You can read data from AVP or write data to AVP). AVP can also deleted. When we assign a value to an AVP, the new value is appended to the AVP. So the AVP may contain multiple values. New assignment (write operation) will add a new value to the AVP. The AVP is like a stack (Last in First out).

AVP’s Synatx: The name starts with $ sign. It looks like $avp(name) or $(avp(name)[N]). The index “N”  referes to a specific value. If no index is used, the last added value will be returned. See the figure below

The assignment can be done directly in the script or by calling a function which brings values from database and add them to the AVP. To delete a specific AVP’s value, we do this  $(avp(test)[N])=NULL. To remove the last value, we do this $(avp(test))=NULL. If no values remained, the AVP will be deleted. You can also delete the AVP by avp_delete(“$avp(test)/g”).

AVPs In The Database

The AVPs in the routing script can be loaded by values taken from the database. The default table to store the AVPs is “usr_preferences”. This table is used by the “avpops” module. Each user which uniquely identified by Unique User ID (UUID) or (username and domain), may have several preferences formed in (attribute, value) pairs and stored in the usr_preferences table.  The AVP is defined by this tuple (Attribute, Type , Value). The Attribute is the name of the AVP(The name can be string or number). The type is number (0 (str:str), 1 (str:int), 2 (int:str), 3 (int:int)). For example $avp(123)=2 <=> Type = 3 (integer name and integer value). The value (as a field) is a string.

The figure below explains the structure of the usr_preferences table.

The table “usr_preferences” is the default but you can change it by adding this line in the opensips configuration file with your table’s name:

modparam(“avpops”, “avp_table”, “usr_preferences”)

When a SIP message is received or new SIP transaction is created, the user’s preferences should be taken into account otherwise it will not called preferences, right?.

The function avp_db_load(“$fu”,”$avp(test-name)”) loads the AVP which belongs to $fu and has the name “test_name”.  This function exists in the “avpops” module. So the module must be loaded when using this function or any other AVP ‘s functions. The second parameter of this function can be empty – which means all AVPs identified by the source(first parameter).

Opensipsctl and AVPs

You can use opensipsctl tool to manage AVPs (add, remove, or configure) in the database. To get help info, type #./opensipsctl avp help

For example to add AVP which has the name “trace”, type 1 (string,integer), and the value =1 (e.g. <=> true):

opensipsctl avp add  -T usr_preferences test@youripaddress trace 1 1

This correspond to $(AVP(trace)) in the routing script. The value will be 1.

Note: You can use your favourite database editor to manage  the AVPs  in the database directly (in “usr_preferences” table). For example “phpMyAdmin” (Mysql Administration on the web).

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.

DNS mapping of E.164 numbers to a list of URIs and IP Addresses


The Domain Name System (DNS) can be used to store the telephone numbers in E.164 format and identify the corresponding service. The domain “” is populated to make the DNS able to store the E.164 numbers. This domain is divided in subdomains so you should contact the corresponding zone administrator in order to list your E.164 number.

Explanation by Example

The DNS client string is “+441632910011” . It is a telephone number in E.164 format and we want to get the information about the service associated with this number (Service Type, Transport Protocol, Port number, IP Address). The DNS client which performs the look up operations, can be part of any kind of network servers .The corresponding domain name for that number will be “”. The figure below shows the steps to get the IP address of the server which provides the service and some information about the service. We will explain this below.

Step 1: Getting SIP URI as a Result of First DNS Look Up Operation

The DNS client performs the first DNS lookup on the domain name “”. The output are two NAPTR records:


NAPTR 10 100u” “E2U+sip” “!^.*$!!.             # Record Number 1

NAPTR 10 101 “u” “E2U+h323” “!^.*$!!” .       # Record Number 2

Here we have two records associated with that name. The fields in each record are: order, preference, flags, service, regular expression, and replacement.The “order” specifies the processing order of the NAPTR records. The “preference” specifies the processing order of the NAPTR records that have same order value. Here both records have an “order” value of 10 but the first one has the lowest “preference” value. So the DNS client will pickup the first record.

The “u” flag means that the output will be a URI. The service name in the selected record is “E2U+sip” and it means the record is used in Telephone Number-to-SIP URI queries.

The regular expression “!^.*$!!”  takes this form: “Delimit ERE Delimit Substitution Delimit Flag”.

Delimit = !

ERE (Extended Reqular Expression ) = ^.*$ which means everything from the beginning of the user string till the end.



and No flags.

The replacement field in the NAPTR record if not present must be indicated by dot (.). if the replacement field is present then the reqular expresion field should be an empty string (“”). The replacement field if present must be a FQDN. So when DNS Client pickup the first record, the result of the first step will be the SIP URI sip:info@example.comThe pattern provided in the regular expression filed is used. As we see here, we get SIP URI from E.164 telephone number. We can stop here if that is what we want.   Note: You can use “Dig” in linux terminal to perform a DNS  lookup: # dig -t naptr

Step 2: Getting the service’s FQDN (Include Service type + Transport Protocol)

Now the DNS client string is “” .The client performs a second  DNS lookup on the domain name “ The output are two NAPTR records:

IN NAPTR 100 10 “S” “SIP+D2U” “!^.*$!!”
IN NAPTR 102 10 “S” “SIP+D2T” “!^.*$!!”

Here the replacement field is present and the regular expression is also present (i.e. the regular expression should be empty but this is not mandatory). The flag “S” means the replacement field contains a FQDN which points to SRV record. The DNS client picks the first record because it has the lowest order value. The replacement is applied and the result will be ”“. The service is SIP  and the transport protocol is UDP.

Step 3: Getting Server’s FQDN and Listening Port Number

Now the DNS client string is ““. The client performs the third look up on “ and it gets the SRV records. This record takes this form  “_Service._Protocol.Name TTL Class SRV Priority Weight Port Target”

The record in this example: 86400 IN SRV 0 5 5060

Service: The service name is sip,

Protocol: The transport protocol is UDP,

Name : The domain name is,

TTL: Time to live is in seconds is 86400

Class: The  DNS class is IN

Priority: the priority of the Target is 0.

Weight: The relative weight of this record is 5.

Port: 5060,

Target: The hostname of machine which provides the service.

The result of this step is the FQDN “” which represents SIP server listening on port 5060.

Step 4: Getting the IP Address

The client prforms DNS look up on “ . The output is A record which contains the IP Address.


Using Domain Name System (DNS) we can get the service information (Mainly the Service Type, Transport Protocol, Port number, and  IP Address) associated with a specific telephone number (E.164 number) .

More Information RFC 2916 , RFC 3761

Globally Routable User Agent URIs (GRUUs) in SIP



The SIP URI in the “Contact” header field of the SIP message, refers to a specific device. This URI should be global (can be used by anyone on the internet) otherwise the call will not be established to that device. This address will be mapped to what is called Address of Record (AOR) after the registration of the user. This mapping will be stored in a database accessed by the registrar/proxy.

Address of Record (AOR): This address represents the user. This address does not have a dependency on any device. So this address can move between devices and can be associated with multiple devices at the same time. Example: This is seen in the From, To, and (generally) Request-URI header field.

Contact Address: This address is associated with a particular device (<=> user agent). Examples:, sip:binan@IP-Address, or just sip:IP-Address. This address is seen in the Contact header field of the SIP message.  If the client is behind a NAT,  then a client-based or server-based procedure must be taken to fix the IP address.

Association between AOR and Contact Addresses

The SIP client sends REGISTER SIP Request to the registrar/proxy to temporarily associate its contact address with the user AOR. In this way the proxy can route the SIP requests (that are sent to the AOR) to the associated device. The mapping between AOR and the device is stored in the database of the registrar/proxy. The user needs to periodically send REGISTER Request to maintain this association or update it. In SIP a single user (<=> one AOR) can have a number of user agents (<=> number of contact addresses).

Why GRUU ?

GRUU is a SIP URI points to specific user agent. In this way we can route a call (sent to an AOR) to a specific user agent. For example a call with Request-URI = ;gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 will be routed to the contact address associated with gr parameter . The gr parameter is an index points to the contact address of the user agent who is registered for this GRUU.

Creation of a GRUU URI -Example

The GRUU is a SIP URI created by the Registrar/Proxy of the domain.The UAC includes “Supported:gruu” header field in a REGISTER request and provides an instance ID in the “+sip.instance” Contact header field parameter. For example the REGISTER SIP request can look like:

Via: SIP/2.0/UDP;branch=z9hG4bKnashds7
Max-Forwards: 70
From: binan <>;tag=a73kszlfl
Supported: gruu
To: binan <>
Call-ID: 1j9FpLxk3uxtm8tn@
Contact: <>
Content-Length: 0

The proxy/registrar uses the Instance-ID , generates the gruu, and send it in the response. This is the response:

SIP/2.0 200 OK
Via: SIP/2.0/UDP;branch=z9hG4bKnashds7
From: binan <>;tag=a73kszlfl
To: binan <> ;tag=b88sn
Call-ID: 1j9FpLxk3uxtm8tn@
Contact: <>
Content-Length: 0

The  “temp-gruu” and “pub-gruu” are “Contact” header field parameters.

  • The “pub-gruu” It exposes the underlying AOR. Constructed by setting the Instance-ID as a value of the “gr” parameter. It is valid as long as the registration is refreshed.
  • The “temp-gruu” changes each time the registration is refreshed. It hides the underlying AOR.

OpenSIPS GRUU Support

OpenSIPS Registrar module includes GRUU support. I would like to mention two important issues:

  • When OpenSIPS receives a SIP REGISTER Request like the one in the example above, the function save() will be called. Upon calling this function, the Instance-ID (f81d4fae-7dec-11d0-a765-00a0c91e6bf6) and the contact address ( in the user Location table. Then it generates the gruu, and send it in the response.
  •  When OpenSIPS receives a call (INVITE Request) in its domain, it checks the Request-URI. If the Request-URI is a GRUU (pub-gruu or temp-gruu), the proxy will route the request just to the contact address indexed by the Instance-ID. Using gr parameter as an index for user location table.

More Information

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