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.

Restrictions of FIFO-based Communications in Linux

Problem Definition

To explain this we will take OpenSIPS’s fifo as an example. It is used to communicate with OpenSIPS’s management interface “Mi”. Assume “/tmp/opensips_fifo” is the fifo file. OpenSIPS is the owner of this pipe and OpenSIPS-CP wants to access/read/write to/from the pipe. As we know everything is a file in Linux so this pipe is just a file and we want to manage how OpenSIPS-CP or other programs can access this pipe to send requests or receive reponses to/from OpenSIPS. OpenSIPS is executed by user=opensips and group=opensips. OpenSIPS-CP is executed by user=apache and group=apache. To see this:  # ps -aux | grep httpd or opensips.


And we have this error message “Cannot connect to OpenSIPS Server via Management Interface (/tmp/opensips_fifo)“. Be sure you are using the right name of the fifo file. Be aware if there is a space at the front or at the end of file path. Be sure that you are talking with the intended OpenSIPS server in case you have many OpenSIPS instances working on the same machine. Be sure the opensips is simply running (OpenSIPS restart may solve the problem). If all that is ok and still you have the error message then start your journey through this article.

Here i have Fedora 20, PHP 5.5.17 , Apache 2.4, OpenSIPS-CP 6.0 , OpenSIPS 1.11. Do the corresponding of everything in your system.

What to Do

Temporarily disable SeLinux. We will come back to it.

  • Discretionary Access Control (DAC): In OpenSIPS configuration file we have this line “modparam(“mi_fifo”, “fifo_mode”, 0666)”  so OpenSIPs create the fifo file with the permission 666 (Owner=6,Group=6, Others=6) which is “prw-rw-rw-“. This means read and write permission for the owner, group, and the others. The letter p means this file is pipe.
  • User:Group Ownership: OpenSIPS-CP executed by apache so add apache user to opensips group if you don’t want to give permissions to others. For this, you can use # system-config-users. To list the members in the group:

# lid -g $groupName

  • Access Control List (ACL): use ACL to give permissions to a specific user For example let Apache user has rw access to the fifo file:

# setfacl -m u:apache:rw /tmp/opensips_fifo

To check the list

# getfacl /tmp/opensips_fifo

Eiciel is GNOME tool to visually configure the ACL entries. # yum install eiciel and to run it  # eiciel the GUI will open. Choose the directory and start editing the acl. Visual ACL

  • Programming Language Restrictions: The programming language may apply some kind of restrictions on accessing files. Web programming language like PHP has safe_mode and open_basedir features. Open /etc/php.ini to disable these. For example file_exists() php function check whether the file or directory is exists or not. This Function return False due to safe_mode restrictions. When safe_mode is enabled (safe_mode = On in php.ini), PHP checks to see if the owner of the current php script matches the owner of the file to be operated on. Safe_mode is removed in PHP-5  but we have to keep programming language restrictions in our minds.
  • Web Server Restrictions: For example Apache web server protects directories and files from hosts/web clients by defining policy rules in httpd.conf.

Example 1: “Linux root is inaccessible by everyone”

<Directory />
AllowOverride none
Require all denied

The default is denying access to the entirety of your server’s file system. You must explicitly permit access to the server’s directories

Example 2: The area /var/www/opensips-cp/web can be accessed by everyone:

<Directory  /var/www/opensips-cp/web>

Options Indexes FollowSymLinks MultiViews

AllowOverride None
Require all granted


  • PrivateTmp Feature: This is new feature since Fedora 16 and Red Hat Enterprise Linux 7. “PrivateTmp” is an option in systemd unit configuration files.

PrivateTmp: “Takes a boolean argument. If true sets up a new file system namespace for the executed processes and mounts a private /tmp directory inside it, that is not shared by processes outside of the namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via /tmp impossible. Defaults to false.”

If the fifo file which is shared between two processes (apache and opensips) created in /tmp so you have to disable this feature. To disable it do the following:

# vim /usr/lib/systemd/system/httpd.service

Change the line PrivateTmp=true to PrivateTmp=false

# systemctl –system daemon-reload

# systemctl restart httpd.service

  • Umask

It could be helpful if you check the umask of the running process which accessing the file and the umask of the file. umask of the specific file can be changed by setfacl command and graphically by Eiciel . To change the  umask of running process, take the id of the process for example httpd # ps -ef |grep httpd.  Enter the gdp # gdp –pid=httpd-Process-Id. To change the umask to 0, type  call umask(0) in gdp console. The umask will be 0 and the command will give you the previous umask value.

  • SeLinux: SeLinux might prevent the access to the file (access, link, unlink,…. ). Selinux Troubleshooter can help you to know how to fix this. How to allow for example httpd process to access FIFO file. Keep your eyes on the SeLinux alerts and do what the troubleshooter suggests. The file “/var/log/audit/audit.log”  contain the alerts and what you did is this:

# grep httpd /var/log/audit/audit.log | audit2allow -M minpol
# semodule -i minpol.pp

If you go through all the points above you will be able to solve the problem .Remember if you make any changes in the configuration file, restart the service.

Where to Look to Trace the Error

Reading the log files is the key (basically here /var/log/*). Make some changes in the configuration somewhere, restart the corresponding service and re-read the log files again. Repeat this till you get no errors. Now  in our use case of opensips’s fifo we can see a list of available fifo commands in opensips-cp web interface. This means Apache (opensips-cp) and the opensips can communicates through the fifo file.


OpenSIPS-CP can request the dialog information from OpenSIPS through the fifo file. See the figures below of the early dialog and the confirmed dialog.



Below is a php client which try to connect to opensips fifo file and send commands. Copy the text and save it in opensips-cp/web/Fifotest.php and then call it from the browser /ipaddress/cp/Fifotest.php. Use it to test the fifo connection.

Source: FIFO Client PHP Example

Some of Packet Capturing Tools


Ngrep Command-Line Tool

“ngrep” is a network layer grepping tool. It is pcap-aware and has been used to debug plain-text protocol such as HTTP, SMTP, FTP, SIP, Raw protocols across Ethernet etc.. We will see how we can use it to track SIP transactions.

  •  Install ngrep tool

# yum install ngrep

  • Start capturing packets using ngrep

Example 1: Capturing SIP packets on port 5060 on the interface “wlp2s0”

# ngrep -q -d wlp2s0 -W byline port 5060 > test.txt &
Type “#man ngrep” to know about command options.

Example 2: Capturing SIP packets containing “username”‘on port 5060

# ngrep -W byline -tqd any username port 5060

Tshark Command-Line Tool

Example:  Capture SIP packets on port 5060 on the interface “wlp2s0”

# tshark -nq -i wlp2s0 port 5060

Type “# man tshark” to know about the options and do more sophisticated commands.

Wireshark Graphical Interface

Tshark capture files are supported by Wireshark.

snap10Sipgrep Command-Line Tool

It is a pcap-aware capturing tool. It was a wrapper for ngrep but now it is a standalone application with numerous additional features for SIP signaling. The user can specify extended regular expressions to match against SIP headers. Among other features, you can kill the scanner automatically and friendly. You can use it to duplicate all traffic to Homer sipcapture node. Please see the whole agenda in the project’s github wiki page.

More Information

Troubleshooting of Query Execution in Mysql DB


To know what mysql is doing we enable the query logging.

Enable Query logging

  • Enter mysql console as root

# mysql -uroot -p

  • Enable logging:mysql> SET global general_log = 1; SET global log_output = ‘table’;
  • View the log and see what is supposed to be executed

mysql> select * from mysql.general_log;

Disable Query loggning

mysql> SET global general_log = 0;

This is useful when you want to track whats going on in your SIP server’s database.

To know about other types of mysql logging Mysql-Server-Logs



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.