Saturday, April 25, 2009

MediaProxy 2.3.x & OpenSIPS 1.5.x Integration

MediaProxy is made up of (at least) two components: A dispatcher and a relay. MediaProxy Server allows specialized processing of clients behind NAT. It has following characteristics:
  • Use of the DNS SRV records to load balance the requests.
  • Can be executed in a seperate server offloading the SIP Proxy.
  • Allows web monitoring.

A detailed description of features and documentation is available at their official site www.ag-projects.com

Latest version can be downloaded at following link:
MediaProxy Download

Basic Steps in Installation:
For people running Debian testing or unstable on an i386 architecture there is an official public repository provided by AG Projects. To use it, add these lines in /etc/apt/sources.list

# AG Projects software
deb http://ag-projects.com/debian unstable main
deb-src http://ag-projects.com/debian unstable main


*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

The MediaProxy source already includes the necessary files to build Debian packages. They should probably also work without changes for Ubuntu, though they have not been tested with it.

To build Debian/Ubuntu packages, you can do the following (this is known to work with Debian testing and unstable and should work without changes in Ubuntu 8.04 Hardy as well, though they were not tested there):

apt-get update
apt-get install devscripts cdbs debhelper python-all-dev python-support \
libnetfilter-conntrack-dev python-application python-cjson \
python-gnutls python-twisted-core python-twisted-names \
python-zopeinterface python-pyrad python-sqlobject

Then unpack MediaProxy and in the directory where it was unpacked run:

debuild

You can safely ignore the pgp signing error at the end of the build process, that is only because you do not have the pgp key for the person who is listed as maintainer for the package. The packages are build fine even if they are not signed.

After building them, you can find the .deb packages in the parent directory, from where you can install them using dpkg:

cd ../
dpkg -i mediaproxy-*.deb

or you can install just the ones you need on that particular system. Please note that mediaproxy-dispatcher and mediaproxy-relay both depend on mediaproxy-common so you have to install it too along with either of them.

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***


Install the AG Projects debian software signing key:
wget http://download.ag-projects.com/agp-debian-gpg.key
apt-key add agp-debian-gpg.key

Now Run
aptitude update
aptitude install mediaproxy-dispatcher mediaproxy-relay mediaproxy-web-sessions

Log:
root@:/usr/local/src# wget http://download.ag-projects.com/agp-debian-gpg.key
root@:/usr/local/src# apt-key add agp-debian-gpg.key
root@:/usr/local/src# aptitude update
root@:/usr/local/src# aptitude install mediaproxy-dispatcher mediaproxy-relay mediaproxy-web-sessions

Above process complains about dependencies thus follow process below...

Manual Installation Process of MediaProxy:
Prerequisites
~~~~~~~~~
In order to build and install, MediaProxy has the following requirements:

- Linux (at least 2.6.18) with the following features compiled in:
- netfilter support
- connection tracking support
- connection tracking netlink interface
- connection tracking event notification API
- netfilter "NOTRACK" target support
- netfilter "CONNMARK" target support
- netfilter "connmark" match support
- IPv4 connection tracking support
- IP tables support
- IP tables Full NAT support

Distribution provided kernel images should normally provide of all these features as modules. The Debian kernel images have all these features available and can be used out of the box.

- libnetfilter-conntrack (at least version 0.0.89)
Most of the Linux distributions separate a library package into runtime and development packages. To build MediaProxy, the development version is needed (it usually has a -dev suffix in the package name).

- Python (at least 2.4)
http://python.org

- Twisted framework (at least 2.5.0 with epollreactor support)
http://twistedmatrix.com

- python-zopeinterface (this is also a requirement for twisted)
http://zope.org/Products/ZopeInterface

- python-application (at least 1.0.9)
http://pypi.python.org/pypi/python-application

- GNU-TLS
http://www.gnu.org/software/gnutls

- python-gnutls
http://pypi.python.org/pypi/python-gnutls

- python-cjson
http://pypi.python.org/pypi/python-cjson

For the database accounting module:
SQLObject
http://sqlobject.org

For the RADIUS accounting module:
pyrad (at least 1.1)
http://www.wiggy.net/code/pyrad/

You have to install the following software in order to get the conntrack-tools working, make sure that you have installed them correctly before going forward:

  • Linux kernel version >= 2.6.18 (http://www.kernel.org) that, at least, has support for:
- connection tracking system
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_IPV4=m

- nfnetlink
CONFIG_NETFILTER_NETLINK=m

- ctnetlink (nf_conntrack_netlink)
CONFIG_NF_CT_NETLINK=m

- connection tracking event notification API
CONFIG_NF_CONNTRACK_EVENTS=y

(To check that the event API is enabled in the kernel, make sure you have loaded nf_netlink_conntrack module, run conntrack -E and generate traffic, you should see network events)

  • libnfnetlink: the netfilter netlink library available at:
http://www.netfilter.org/projects/libnfnetlink/files/

  • libnetfilter_conntrack: the netfilter conntrack library available at:
http://www.netfilter.org/projects/libnetfilter_conntrack/files/


Now proceed by first checking the kernal version:
$ uname -a

My kernel version meets the requirement thus i will skip the steps related to kernel install...

Next download files from official site:
http://www.netfilter.org/projects/libnfnetlink/files/
[x] libnfnetlink-0.0.41.tar.bz2 06-Mar-2009 17:31 234K
[x] libnfnetlink-0.0.41.tar.bz2.sig 06-Mar-2009 17:31 65

# tar xvfj libnfnetlink-0.0.41.tar.bz2
# cd libnfnetlink-0.0.41
# ./configure
# make
# make install

Now download:
http://www.netfilter.org/projects/libnetfilter_conntrack/downloads.html#libnetfilter_conntrack-0.0.99

[x] libnetfilter_conntrack-0.0.99.tar.bz2 : GPG signature (key) : md5sum 960c3d347d7f4e3fe7437aa198f36e6e

# tar xvfj libnetfilter_conntrack-0.0.99.tar.bz2
# cd libnetfilter_conntrack-0.0.99

To compile and install conntrack-tools
just follow the classical steps:


# ./configure
# make
# make install

Next check other dependencies:
Download Python 3.0.1 from the link
http://www.python.org/download/ and install as follows:

root:/usr/local/src# tar -xzvf Python-3.0.1.tgz
root:/usr/local/src# cd Python-3.0.1
root:/usr/local/src/Python-3.0.1# ./configure
root:/usr/local/src/Python-3.0.1# make
...
...
Python build finished, but the necessary bits to build these modules were not found:
_curses _curses_panel _sqlite3
_tkinter bz2 readline
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

root:/usr/local/src/Python-3.0.1# make install
...
...
* Note: not installed as 'python'.
* Use 'make fullinstall' to install as 'python'.
* However, 'make fullinstall' is discouraged,
* as it will clobber your Python 2.x installation.

Next download install Twisted Framework 8.2.0 from this link http://twistedmatrix.com/trac/

root:/usr/local/src# tar xvfj Twisted-8.2.0.tar.bz2
root:/usr/local/src# cd Twisted-8.2.0

Download Zope Interfaces 3.1.0 or above:
http://zope.org/Products/ZopeInterface

Untar file and install as follows:
root:/usr/local/src/Twisted-8.2.0# tar xvfz zope.interface-3.3.0.tar.gz
root:/usr/local/src/Twisted-8.2.0# cd zope.interface-3.3.0
root:/usr/local/src/Twisted-8.2.0/zope.interface-3.3.0# python setup.py build
root:/usr/local/src/Twisted-8.2.0/zope.interface-3.3.0# python setup.py install
root:/usr/local/src/Twisted-8.2.0/zope.interface-3.3.0# cd ..
root:/usr/local/src/Twisted-8.2.0# python setup.py install
...
...
Installed /usr/lib/python2.5/site-packages/Twisted-8.2.0-py2.5-linux-x86_64.egg
Processing dependencies for Twisted==8.2.0
Searching for zope.interface==3.3.1
Best match: zope.interface 3.3.1
Removing zope.interface 3.3.0 from easy-install.pth file
Adding zope.interface 3.3.1 to easy-install.pth file

Using /usr/lib/python2.5/site-packages
Finished processing dependencies for Twisted==8.2.0

Above installations also took care of python-zopeinterface, python-application, python-cjson, and GNU-TLS (python-gnutls) dependencies...

Next Database Dependencies:
SQLObject is a popular Object Relational Manager for providing an object interface to your database, with tables as classes, rows as instances, and columns as attributes.

SQLObject includes a Python-object-based query language that makes SQL more abstract, and provides substantial database independence for applications.
root:/usr/local/src# easy_install -U SQLObject

Next download and install pyrad:
pyrad is an implementation of a RADIUS client as described in RFC2865. It takes care of all the details like building RADIUS packets, sending them and decoding responses.

root:/usr/local/src/Python-3.0.1# mv /home/wiz/Documents/pyrad-1.1.tar.gz .
root:/usr/local/src/Python-3.0.1# tar xvfz pyrad-1.1.tar.gz
root:/usr/local/src/Python-3.0.1# cd pyrad-1.1
root:/usr/local/src/Python-3.0.1/pyrad-1.1# python setup.py install
...
...


Installing MediaProxy:
Add DNS SRV records in the for the SIP domains you wish to serve. Put them at the same priority with different weights to allow load balancing of traffic. Put them at different priorities to allow fallback.

Example:

Considering your domain is mydomain.com and you wan to dedicate 3 main servers and 2 fallbacks. The main servers you want to distribute traffic among are 2 1Ghz machines (named nat1 and nat2) and a 2Ghz machine (nat3). You want 25% from the traffic to go to each 1Ghz machine and 50% to the 2Ghz machine. For the fallbacks (nat4 and nat5) you want to distribute the traffic equally among the 2 machines.

_mediaproxy._tcp.mydomain.com. IN SRV 0 25 25060 nat1.mydomain.com.
_mediaproxy._tcp.mydomain.com. IN SRV 0 25 25060 nat2.mydomain.com.
_mediaproxy._tcp.mydomain.com. IN SRV 0 50 25060 nat3.mydomain.com.
_mediaproxy._tcp.mydomain.com. IN SRV 10 50 25060 nat4.mydomain.com.
_mediaproxy._tcp.mydomain.com. IN SRV 10 50 25060 nat5.mydomain.com.

If your DNS provider does not support SRV records, take a look at Managed DNS http://www.managed-dns.org

In this setup, the traffic will be distributed between the nat1, nat2 and nat3 machines in a proportion of 25%+25%+50%. If one goes offline the other 2 will take it's traffic share redistributing the load balancing according to their own weight. If all of nat1, nat2, nat3 stop responding, nat4 and nat5 will be used distributing the traffic among them equally (50%+50%)

# mkdir /etc/mediaproxy
# mkdir /etc/mediaproxy/tls
# cd usr/local/src/mediaproxy

Download and copy in the directory:
# tar xvfz mediaproxy-2.3.4.tar.gz
# cd mediaproxy-2.3.4
# ./setup.py build
# ./setup.py install

running install
running build
running build_py
running build_ext
running build_scripts
running install_lib
running install_scripts
changing mode of /usr/bin/media-dispatcher to 755
changing mode of /usr/bin/media-relay to 755
running install_egg_info
Removing /usr/lib/python2.5/site-packages/mediaproxy-2.3.4.egg-info
Writing /usr/lib/python2.5/site-packages/mediaproxy-2.3.4.egg-info

Enable IP Forwarding by making changes in /etc/sysctl.conf file...
Permanently enable ip forwarding,,,
# gedit /etc/sysctl.conf &
...

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# echo 1 > /proc/sys/net/ipv4/ip_forward
# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1


+ Make directory, copy necessary files to proper directories, and setup ownership:
$ mkdir /var/run/mediaproxy
$ cp config.ini.sample /etc/mediaproxy/config.ini
$ cp tls/* /etc/mediaproxy/tls/

Starting MediaProxy Dispatcher...
# ./media-dispatcher --no-fork
# ./media-dispatcher &


OpenSIPS+MediaProxy Integration:
# mkdir /var/run/mediaproxy
# gedit config.ini &

Make following changes in file...

[Relay]
dispatchers = mydomain.net:5060 _sip._udp.mydomain.net
port_range = 50000:60000
log_level = DEBUG
on_hold_timeout = 1800

[Dispatcher]
listen = 10.1.10.205:50000
management_use_tls = no
log_level = DEBUG
accounting = radius

[Radius]
; This section needs to be configured if radius accounting is enabled
; OpenSIPS RADIUS configuration file. All RADIUS cofiguration parameters will
; be read from this file, including dictionary files.
;
;config_file = /etc/opensips/radius/client.conf
config_file = /etc/freeradius/clients.conf

; Additional dictionary file with MediaProxy specific attributes.
;additional_dictionary = radius/dictionary
additional_dictionary = /etc/freeradius/dictionary

[OpenSIPS]
socket_path = '/var/run/opensips/socket'


Now edit opensips.cfg file to include MediaProxy...
#
# ----- nat_traversal
#**
loadmodule "nat_traversal.so"
#**
modparam("nat_traversal", "keepalive_interval", 90)
modparam("nat_traversal", "keepalive_method", "OPTIONS")
modparam("nat_traversal", "keepalive_from", "sip:keepalive@mydomain.com")


#
# --> nathelper
#**
loadmodule "nathelper.so"
#**
modparam("nathelper", "natping_interval", 60)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", 7)
modparam("nathelper", "received_avp", "$avp(i:801)")
modparam("nathelper", "sipping_from", "sip:pinger@mydomain.com")

#
#**
loadmodule "mediaproxy.so"
#**
#--------------- Default Values
modparam("mediaproxy", "mediaproxy_socket", "/var/run/mediaproxy/dispatcher.sock")
modparam("mediaproxy", "mediaproxy_timeout", 500)
modparam("mediaproxy", "signaling_ip_avp", "$avp(s:nat_ip)")
modparam("mediaproxy", "media_relay_avp", "$avp(s:media_relay)")

#--------------- Main Routing Logic

#

RTPProxy 1.2.x Installation & Integration with OpenSIPS 1.5x

Before we start any thing, we need to know where we stand. By knowing current status, we could save us lot of headaches and time. Organization is the key to an effecient solution.

Lets first consider some questions about the server you have in place!!!

If you have public IP address for your server then don't worry about comments. If you don't then you have to have a way for a dynamic IP (from your ISP provider) to be resolved. Register with http://www.dyndns.com/ which woulld allow your dynamic IP to be resolved. OpenSIPS has to be on Static IP so you are listening on a specific address but your domain name needs to be resolved to your dynamic IP.

Step 01:
We will install RTP proxy for audio devices since softphone doesn't have media plug-ins; also if you have dynamic IP (from your ISP provider) then install DynDNS Update Clients "ddclient" for dyndns to automatically update the ip address when it changes

Link to ddclient installation instructions:
http://mexpolk.wordpress.com/2008/01/29/ubuntu-gutsy-dyndns-client-setup/

$ sudo apt-get install ssh libio-socket-ssl-perl
$ sudo apt-get install ddclient



Step 02:
@@@@ Server install RTPProxy 03/01/2009 @@@@
Configure Router for the Ports to be used by rtpproxy by opening them first (Read Consideration at the end of this article).

-- Use dpkg command to list installed software "dpkg –get-selections"

$ mkdir /backup
$ dpkg --get-selections > /backup/installed-software.log


Basic steps...

Code:
$ cd /usr/src
$ wget http://b2bua.org/chrome/site/rtpproxy-1.2.0.tar.gz
$ tar -xzvf rtpproxy-1.2.0.tar.gz

Change to the directory and install the program .
Code:
$ cd rtpproxy-1.2
$ ./configure
$ make
$ make install


Create a system user with no privileges and start the daemon running
Code:
$ adduser rtpproxy -d /home/rtpproxy -s /bin/false
$ rtpproxy -u rtpproxy

Now rtpproxy should be running and if you check in /var/run you should see rtpproxy.sock and rtpproxy.pid

Consideration:
Creating the user rtpproxy was not essential, you can run the daemon under whatever user you are logged in as by simply typing rtpproxy at the command but I read that it is safe practice to run the daemon under a non privileged user. (Maybe someone can comment on the linux user I added. I am not 100% on the security of the user added with no password but the way I understand it the user cannot access the system until a password is created.)

By default rtpproxy uses UDP ports 35000-65000 and these should be opened any firewalls in front of rtpproxy.

The Remote Control Mode can be activated by starting RTP Proxy with `-s' command line argument:

$ rtpproxy -s udp:address:port

Arguments: address is either IPv4 or IPv6 local address at which command should be accepted or "*" if rtpproxy should accept commands at all local interfaces; port is UDP port, if omitted port 22222 is used.

If RTPproxy is already running use force_sock function as shown below:
modparam("nathelper", "force_socket", "udp:localhost:22222")

Running Manually:
$ rtpproxy -F -l your-public-ip -s udp:localhost:port-no

e.g. $ rtpproxy -F -l 127.0.0.1 -s udp:192.168.1.2:9000

if above command is used to start rtpproxy then change your opensips.cfg file like this...
modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:port-no")
modparam("nathelper", "force_socket", "udp:localhost:port-no")

Followings are examples for starting manually with user parameter...
$ rtpproxy -l 192.168.1.2 -s udp:127.0.0.1:50000 -u usrname &
OR
$ rtpproxy -s udp:127.0.0.1:50000 -f -u opensips -l 192.168.1.2 &


WARNING: command protocol contains no security or authentication measures, so that you should be using other means to secure RTP Proxy, such as firewall or even better a VPN between machine running RTP Proxy and machine which runs a software that controls it.

I have OpenSIPS operating successfully before installing RTPProxy

Check if process is running with the following command...

Code:
# ps axw /bin/egrep rtp
OR
# netstat -axep grep rtpproxy


Sample config file for RTP proxy Integration with OpenSIPS 1.5.x
#
# $Id: nathelper.cfg 5875 2009-07-15 19:05:20Z bogdan_iancu $
#
# simple quick-start config script including nathelper support
# This default script includes nathelper support. To make it work
# you will also have to install Maxim's RTP proxy. The proxy is enforced
# if one of the parties is behind a NAT.
#
# If you have an endpoing in the public internet which is known to
# support symmetric RTP (Cisco PSTN gateway or voicemail, for example),
# then you don't have to force RTP proxy. If you don't want to enforce
# RTP proxy for some destinations than simply use t_relay() instead of
# route(1)
#
# Sections marked with !! Nathelper contain modifications for nathelper
#
# NOTE !! This config is EXPERIMENTAL !
#
# @@@ There are additional changes made by Rookie which is
# @@@ not functional yet. Its giving only one way audio because
# @@@ RTP packets are being lost...
#
####
###
##
#
# -- Global Parameters
#
##
###
####
/* uncomment and configure the following line if you want opensips to
bind on a specific interface/port/proto (default bind on all available)
*/

children = 8
debug = 6 # debug level (cmd line: -dddddddddd)
fork = yes

group = "opensips"
user = "opensips"
/* uncomment the next line to disable TCP (default on) */
#disable_tcp=yes
disable_tcp = no

log_facility = LOG_LOCAL0 # LOG_DAEMON
log_stderror = yes # (cmd line: -E)
tcp_children = 6

check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)


/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no

/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes

/* uncomment the next line to disable the auto discovery of local aliases
based on revers DNS on IPs (default on) */
#auto_aliases=no

/* uncomment the following lines to enable TLS support (default off) */
#disable_tls = no
#listen = tls:your_IP:5061
#tls_verify_server = 1
#tls_verify_client = 1
#tls_require_client_certificate = 0
#tls_method = TLSv1
#tls_certificate = "/usr/local/etc/opensips/tls/user/user-cert.pem"
#tls_private_key = "/usr/local/etc/opensips/tls/user/user-privkey.pem"
#tls_ca_list = "/usr/local/etc/opensips/tls/user/user-calist.pem"

port=5060

/* uncomment and configure the following line if you want opensips to
bind on a specific interface/port/proto (default bind on all available)
*/
listen=udp:mydomain.com:5060

#*** set module path
mpath="//lib64/opensips/modules/"


####
###
##
# Modules Section
# ```````````````
# Loading moduels and
# Setting module-specific parameters
##
###
####


# Uncomment this if you want to use SQL database
loadmodule "db_mysql.so"

loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"

# !! Nathelper
loadmodule "nathelper.so"

#
#***
#
loadmodule "uri_db.so"
loadmodule "uri.so"
loadmodule "xlog.so"
loadmodule "acc.so"
#
#**
#


# Uncomment this if you want digest authentication
# db_mysql.so must be loaded !
loadmodule "auth.so"
loadmodule "auth_db.so"

/* uncomment next line for aliases support
NOTE: a DB (like db_mysql) module must be also loaded */
loadmodule "alias_db.so"

/* uncomment next line for multi-domain support
NOTE: a DB (like db_mysql) module must be also loaded
NOTE: be sure and enable multi-domain support in all used modules
(see "multi-module params" section ) */
loadmodule "domain.so"

#
#**
#
loadmodule "dialog.so"
loadmodule "avpops.so"

#loadmodule "drouting.so"
#loadmodule "nat_traversal.so"
#loadmodule "mediaproxy.so"
#
#**
#

/* uncomment the next two lines for presence server support
NOTE: a DB (like db_mysql) module must be also loaded */
#loadmodule "presence.so"
#loadmodule "presence_xml.so"


####
###
##
# ----------------- setting module-specific parameters ---------------
##
###
####

# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")

#**
modparam("mi_fifo", "fifo_mode", 0660)
modparam("mi_fifo", "fifo_group", "opensips")
modparam("mi_fifo", "fifo_user", "opensips")
modparam("mi_fifo", "reply_dir", "/tmp/")
modparam("mi_fifo", "reply_indent", "\t")


# ----- registrar params -----
modparam("registrar", "method_filtering", 1)

/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)

# -- usrloc params --
#modparam("usrloc", "db_mode", 0)
# Uncomment this if you want to use SQL database
# for persistent storage and comment the previous line
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")

modparam("usrloc", "user_column", "username")
modparam("usrloc", "domain_column", "domain")
modparam("usrloc", "contact_column", "contact")
modparam("usrloc", "expires_column", "expires")
modparam("usrloc", "q_column", "q")
modparam("usrloc", "callid_column", "callid")
modparam("usrloc", "cseq_column", "cseq")
modparam("usrloc", "methods_column", "methods")
modparam("usrloc", "flags_column", "flags")
modparam("usrloc", "user_agent_column", "user_agent")
modparam("usrloc", "received_column", "received")
modparam("usrloc", "socket_column", "socket")
modparam("usrloc", "use_domain", 0)
modparam("usrloc", "desc_time_order", 0)
modparam("usrloc", "timer_interval", 60)
modparam("usrloc", "matching_mode", 0)

# ----- uri_db params -----
/* by default we disable the DB support in the module as we do not need it
in this configuration */
modparam("uri_db", "use_uri_table", 0)
modparam("uri_db", "db_url", "")


# -- auth db params --
# Uncomment if you are using auth module
modparam("auth_db", "calculate_ha1", yes)

#
# If you set "calculate_ha1" parameter to yes (which true in this config),
# uncomment also the following parameter)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
modparam("auth_db", "load_credentials", "")


# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)

#
# !! Nathelper
#
modparam("usrloc", "nat_bflag", 6)
modparam("nathelper", "ping_nated_only", 1) # Ping only clients behind NAT
modparam("nathelper", "sipping_bflag", 8)
modparam("nathelper", "received_avp", "$avp(i:801)")

# RTPProxy setup
modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:50100")
modparam("nathelper", "force_socket", "udp:localhost:50100")


# ----- acc params -----
/* what sepcial events should be accounted ? */
modparam("acc", "early_media", 1)
modparam("acc", "report_ack", 1)
modparam("acc", "report_cancels", 1)

/* by default ww do not adjust the direct of the sequential requests.
if you enable this parameter, be sure the enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)

/* account triggers (flags) */
modparam("acc", "failed_transaction_flag", 3)
modparam("acc", "log_flag", 1)
modparam("acc", "log_missed_flag", 2)

/* uncomment the following lines to enable DB accounting also */
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 2)


#
# ----- multi-module params -----
/* uncomment the following line if you want to enable multi-domain support in the modules (dafault off) */
#modparam("alias_dbauth_dbusrlocuri_db", "use_domain", 1)

# ----- alias_db params -----
/* uncomment the following lines if you want to enable the DB based
aliases */
modparam("alias_db", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")


# ----- domain params -----
/* uncomment the following lines to enable multi-domain detection support */
modparam("domain", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
modparam("domain", "db_mode", 1) # Use caching

#**
modparam("domain", "domain_table", "domain")
modparam("domain", "domain_col", "domain")

#
# ------- dialog --------
#**
modparam("dialog", "db_mode", 1)
modparam("dialog", "db_update_period", 30)
modparam("dialog", "dlg_flag", 4)
modparam("dialog", "dlg_match_mode", 1)

#
# --> avpops params -----
#**
modparam("avpops", "avp_table", "usr_preferences")
modparam("avpops", "use_domain", 1)


# ************
# ----- presence params -----
/* uncomment the following lines if you want to enable presence */
#modparam("presencepresence_xml", "db_url",
# "mysql://opensips:opensipsrw@localhost/opensips")
#modparam("presence_xml", "force_active", 1)
#modparam("presence", "server_address", "sip:192.168.1.2:5060")


#*** MySQL DB ***
modparam("dialogavpopsuri_db", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")


###
##
# -- MAIN request routing logic
##
###


route{
#
# -- 1 -- Request Validation
#
xlog("L_INFO", "New request - Request/failure/branch routes: M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$ci\n");

# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops...");
exit;
};
if (msg:len >= 2048 ) {
sl_send_reply("513", "Message too big...");
exit;
};

#
# -- 2 -- Routing Preprocessing
#
xlog("L_INFO", "MsgFlag:[$mf] \n");

# Some systems (like Asterisk) use OPTIONS as a kind of "ping", than we
# answer it with 200 OK.
if (method == "OPTIONS") {
sl_send_reply("200", "OK");
return;
};


# !! Nathelper
# Special handling for NATed clients; first, NAT test is
# executed: it looks for via!=received and RFC1918 addresses
# in Contact (may fail if line-folding is used); also,
# the received test should, if completed, should check all
# vias for rpesence of received
if (nat_uac_test("3")) {
# Allow RR-ed requests, as these may indicate that
# a NAT-enabled proxy takes care of it; unless it is
# a REGISTER

if (is_method("REGISTER") !is_present_hf("Record-Route")) {
log("LOG:Someone trying to register from private IP, rewriting\n");
# This will work only for user agents that support symmetric
# communication. We tested quite many of them and majority is
# smart enough to be symmetric. In some phones it takes a
# configuration option. With Cisco 7960, it is called
# NAT_Enable=Yes, with kphone it is called "symmetric media" and
# "symmetric signalling".

# Rewrite contact with source IP of signalling
fix_nated_contact();
if ( is_method("INVITE") ) {
fix_nated_sdp("1"); # Add direction=active to SDP
};
force_rport(); # Add rport parameter to topmost Via
setbflag(6); # Mark as NATed

# if you want sip nat pinging
setbflag(8);
};
};

# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
exit;
};

# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!is_method("REGISTER"))
record_route();

if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(1);
exit;
};

# if the request is for other domain use UsrLoc
# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (uri==myself) {

if (is_method("REGISTER")) {

# Uncomment this if you want to use digest authentication
#if (!www_authorize("siphub.org", "subscriber")) {
# www_challenge("siphub.org", "0");
# return;
#};

save("location");
exit;
};

lookup("aliases");
if (!uri==myself) {
append_hf("P-hint: outbound alias\r\n");
route(1);
exit;
};

# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
};
append_hf("P-hint: usrloc applied\r\n");
route(1);
}

route[1]
{
# !! Nathelper
if (uri=~"[@:](192\.168\.10\.172\.(1[6-9]2[0-9]3[0-1])\.)" && !search("^Route:")){
sl_send_reply("479", "We don't forward to private IP addresses");
exit;
};

# if client or server know to be behind a NAT, enable relay
if (isbflagset(6)) {
force_rtp_proxy();
};

# NAT processing of replies; apply to all transactions (for example,
# re-INVITEs from public to private UA are hard to identify as
# NATed at the moment of request processing); look at replies
t_on_reply("1");

# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}

# !! Nathelper
onreply_route[1] {
# NATed transaction ?
if (isbflagset(6) && status =~ "(183)2[0-9][0-9]") {
fix_nated_contact();
force_rtp_proxy();
# otherwise, is it a transaction behind a NAT and we did not
# know at time of request processing ? (RFC1918 contacts)
} else if (nat_uac_test("1")) {
fix_nated_contact();
};
}