Hi guys. I just noticed that when user agents register, the domain in their
SIP URI does not have to equal their domain in the subscribers database
table.
For instance, I have 2 domains in the domain table:
sip.altcall.comsip.voxpak.com
The username "foobar" in my subscribers table has the
domain "sip.altcall.com", but can register and make calls as
foobar(a)sip.voxpak.com .
Why is this?
Cheers,
-- Nick
E: nick.hoffman(a)voxpak.com
P: +61 7 5591 3588
F: +61 7 5591 6588
If you receive this email by mistake, please notify us and do not make any
use of the email. We do not waive any privilege, confidentiality or
copyright associated with it.
Hi,
SER always generates new tuple IDs for newly published tuples. This is
because it can collect information from more sources - more clients can
send PUBLISH with the same tuple IDs, but according to RFC 3903 tuples
can rewrite each other only if they were published with the same entity
tag (SIP-ETag header field).
If you don't want to use tuples created from registration status you can
set PA module parameter "use_callbacks" to 0.
Or do you need for clients which published something not to use
tuples generated from registration status and for those which doesn't
publish anything to use such tuples? This is not possible right now, but
it is not too hard to implement it...
Vaclav
On Tue, Oct 24, 2006 at 06:00:03PM +0200, Diego Do?ate wrote:
>
> Hi,
>
> I am using the "presence snapshot" version of the SER server, and I want
> to use a presence service. My problem is related to the "id" parameter
> within the <tuple> (in the NOTIFY xml). The test is like that:
>
> User A subscribes to the presence of user B : receives a NOTIFY with 1
> <tuple> (id="none", <basic> is closed)
> User B registers in SER: user A receives a NOTIFY with 1 <tuple>
> (id="string", <basic> is open)
> User B publishes a new presence state: user A receives a NOTIFY with 2
> <tuple> (the 2nd is the same as the previous one, and a new one is attached
> first with different "id" string value.
>
> I would like only 1 <tuple>, since the device is the same, is it my
> problem (something in the PUBLISH), or is it in the SER? How can I know this
> "id"? Whatever I put in the PUBLISH <tuple> "id", the SER puts another
> string in the NOTIFY created...
>
> Thaks in advance
>
> Diego Do?ate
>
>
>
>
>
Hi,
doesn't SER send "202 Accepted" instead of "200 OK" before "pending
NOTIFY"? You can set PA module parameter "auth" to "none" as described
in presence handbook.
Registrations are written into database (table "location") only if you
set db_mode parameter of userloc module to nonzero value.
Vaclav
On Tue, Oct 24, 2006 at 09:40:30AM +0200, Diego Do?ate wrote:
>
> Hi,
>
> At the end I have running my SER, the "presence snapshots" version...
> Thanks very much for your help.
>
> I have a doubt with the presence service: when user A subscribes to the
> presence of user B (sends a SUBSCRIBE request), the SER sends the 200 Ok and
> the initial NOTIFY ("pending"). I don't know how user B can authorize the
> subscription (SER sends nothing to user B), or if it is possible not to
> require authorization, that is, that SER sends automatically the 2nd NOTIFY
> (status, not "pending")?
>
> Related to that, when a user is registered, where can I find/delete the
> registration? "Location" table is empty... Maybe the problem with the
> presence is related to that, since there is no "subscriber" table, where are
> created users? In fact, since I had to uninstall and re-install SER, maybe
> the users don't exists yet, is it possible? Although I can register them
> (and SER accepts PUBLISH and SUBSCRIBE requests...)
>
> Thanks a lot in advance
>
>
>
> -----Mensaje original-----
> De: Vaclav Kubart [mailto:vaclav.kubart@iptel.org]
> Enviado el: lunes, 23 de octubre de 2006 7:51
> Para: Diego Do?ate
> CC: serusers(a)iptel.org
> Asunto: Re: pa module: presence "substatus"
>
> Hi,
> you have to set LD_LIBRARY_PATH variable before running ser (see
> "3.4 Running SER" in presence handbook):
>
> export LD_LIBRARY_PATH=/base/ser/directory/lib/ser
>
> /base/ser/directory/sbin/ser -f /base/ser/directory/etc/ser/ser.cfg
>
> Vaclav
>
> On Fri, Oct 20, 2006 at 07:06:54PM +0200, Diego Do?ate wrote:
> >
> > Hi,
> >
> > I have done followed these steps, but still the same errors.
> > Should I unistall something else?
> > ...
> > 0(13168) qm_malloc(0x8113ea0, 24) returns address 0x8148710 frag.
> > 0x81486f8
> > (size=24) on 1 -th hit
> > 0(13168) read 2739142786 from /dev/urandom
> > 0(13168) seeding PRNG with 3900519771
> > 0(13168) test random number 509866974
> > 0(13168) ERROR: load_module: could not open module
> > </usr/local//lib/ser/modules/dialog.so>: lib_ser_cds.so: cannot open
> shared
> > obj ect file: No such file or directory
> > 0(13168) parse error (36,13-14): failed to load module
> > 0(13168) ERROR: load_module: could not open module
> > </usr/local//lib/ser/modules/rls.so>: lib_ser_xcap.so: cannot open shared
> > objec t file: No such file or directory
> > 0(13168) parse error (37,13-14): failed to load module
> > 0(13168) ERROR: load_module: could not open module
> > </usr/local//lib/ser/modules/pa.so>: lib_ser_xcap.so: cannot open shared
> > object file: No such file or directory
> > 0(13168) parse error (38,13-14): failed to load module
> > 0(13168) ERROR: load_module: could not open module
> > </usr/local//lib/ser/modules/presence_b2b.so>: lib_ser_xcap.so: cannot
> open
> > sha red object file: No such file or directory
> > 0(13168) parse error (39,13-14): failed to load module
> > 0(13168) set_mod_param_regex: No module matching <rls> found
> > 0(13168) parse error (76,21-22): Can't set module parameter
> > 0(13168) set_mod_param_regex: No module matching <rls> found 0
> > ....
> >
> >
> > Diego
> >
> > -----Mensaje original-----
> > De: Vaclav Kubart [mailto:vaclav.kubart@iptel.org] Enviado el:
> > viernes, 20 de octubre de 2006 7:15
> > Para: Diego Do?ate
> > CC: serdev-bounces(a)lists.iptel.org
> > Asunto: Re: pa module: presence "substatus"
> >
> > Hi,
> > this seems that you are compiling something else than "presence snapshot"
> > because "presence snapshot" has modified Makefiles to compile
> > libraries automaticaly which was not done in your case.
> >
> > Try to follow the compilation rules "3.2 Installation from CVS":
> >
> > cd sip_router/lib
> > make -f Makefile.ser install prefix=/base/ser/directory cd ..
> > make install include_modules="dialog pa rls presence_b2b xcap mysql
> xmlrpc"
> > prefix=/base/ser/directory
> >
> > [in your case will be prefix=/usr/local if you want to install ser
> > there]
> >
> > Vaclav
> >
> > On Thu, Oct 19, 2006 at 07:57:55PM +0200, Diego Do?ate wrote:
> > >
> > > Hi,
> > >
> > > Thanks for the suggestion. I have download the 0.10.99 version
> > > ("presence
> > > snapshot") but I can not make it work: after the "make install", I
> > > go to /usr/local/etc/ser, where is the ser.cfg to run, but with ser
> > > -f ser.cfg it gives me this errors:
> > >
> > > ERROR: bad config file (47 errors)
> > > -bash-3.00# ser -f ser.cfg -E
> > > 0(15125) ERROR: load_module: could not open module
> > > </usr/local/lib/ser/modules/dialog.so>: lib_ser_cds.so: cannot open
> > > shared object file: No such file or directory
> > > 0(15125) parse error (36,13-14): failed to load module
> > > 0(15125) ERROR: load_module: could not open module
> > > </usr/local/lib/ser/modules/rls.so>: lib_ser_xcap.so: cannot open
> > > shared object file: No such file or directory
> > > 0(15125) parse error (37,13-14): failed to load module
> > > 0(15125) ERROR: load_module: could not open module
> > > </usr/local/lib/ser/modules/pa.so>: lib_ser_xcap.so: cannot open
> > > shared object file: No such file or directory
> > > 0(15125) parse error (38,13-14): failed to load module
> > > 0(15125) ERROR: load_module: could not open module
> > > </usr/local/lib/ser/modules/presence_b2b.so>: lib_ser_xcap.so:
> > > cannot open shared object file: No such file or directory
> > > 0(15125) parse error (39,13-14): failed to load module
> > > 0(15125) set_mod_param_regex: No module matching <rls> found
> > >
> > >
> > > And the last line is repeated with the 4 modules it can not find.
> > > But the 4 of them exists in /usr/local/lib/ser/modules, where it is
> > > looking
> > for...
> > >
> > > I thought the installation was going to be easy, as read in
> > > http://ftp.iptel.org/pub/ser/presence/presence-handbook/ar01s03.html
> (3.3.
> > > Installation from presence-snapshot), but there is something I am
> > > doing wrong.
> > >
> > > Any suggestion? I attach the .cfg
> > >
> > > Thanks a lot
> > >
> > > Diego Do?ate
> > >
> > >
> > > -----Mensaje original-----
> > > De: Vaclav Kubart [mailto:vaclav.kubart@iptel.org] Enviado el:
> > > miércoles, 18 de octubre de 2006 11:22
> > > Para: Diego Do?ate
> > > CC: serdev-bounces(a)lists.iptel.org
> > > Asunto: Re: pa module: presence "substatus"
> > >
> > > Hi,
> > > I'm afraid that there was not good support for presence in 0.9.6. I
> > > recommend to use "presence snapshot".
> > > Vaclav
> > >
> > > On Wed, Oct 18, 2006 at 10:37:27AM +0200, Diego Do?ate wrote:
> > > >
> > > > Hi,
> > > >
> > > > I am using the last version of the SER server (0.9.6), and
> > > > have a problem with the presence management. I want a user (805)
> > > > to subscribe to the presence of another user (806), but when 805
> > > > sends a SUBSCRIBE to the SER, it responses a NOTIFY with
> > > > "closed-offline", while both users had sent previously a successful
> REGISTER to the SER.
> > > >
> > > > Both users are added (serctl) to the server, and are displayed
> > > > in "subscriber" table of the "ser" DB. Once registered, they are
> > > > also in the "location" table. But the ser does not add "open" to
> > > > the NOTIFY.. Any
> > > idea?
> > > >
> > > > Once the user 805 is successfully subscribed to the presence
> > > > of user 806, when 806 modifies its presence (sends a PUBLISH to
> > > > the SER, with
> > > "open"
> > > > and <note>"Away"</note> in the xml, for instance), the SER is
> > > > suppposed to send a NOTIFY with the same xml to user 805
> > > > (subscriber),
> > > isn't it?
> > > >
> > > > "pa" module is added, but in this moment I don't need
> > > > authentication. U can see the ser.cfg file bellow:
> > > >
> > > > Thanks in advance
> > > >
> > > >
> > > > // ******************************** # # $Id: ser.cfg,v 1.25.2.1
> > > > 2005/02/18 14:30:44 andrei Exp $ # # simple quick-start config
> > > > script #
> > > >
> > > > # ----------- global configuration parameters
> > > > ------------------------
> > > >
> > > > #debug=3 # debug level (cmd line: -dddddddddd)
> > > > #fork=yes
> > > > #log_stderror=no # (cmd line: -E)
> > > >
> > > > /* Uncomment these lines to enter debugging mode fork=no
> > > > log_stderror=yes */
> > > >
> > > > check_via=no # (cmd. line: -v)
> > > > dns=no # (cmd. line: -r)
> > > > rev_dns=no # (cmd. line: -R)
> > > > #port=5060
> > > > #children=4
> > > > fifo="/tmp/ser_fifo"
> > > >
> > > > # ------------------ module loading
> > > > ----------------------------------
> > > >
> > > > # Uncomment this if you want to use SQL database loadmodule
> > > > "/usr/local/lib/ser/modules/mysql.so"
> > > >
> > > > loadmodule "/usr/local/lib/ser/modules/sl.so"
> > > > loadmodule "/usr/local/lib/ser/modules/tm.so"
> > > > loadmodule "/usr/local/lib/ser/modules/rr.so"
> > > > loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
> > > > loadmodule "/usr/local/lib/ser/modules/usrloc.so"
> > > > loadmodule "/usr/local/lib/ser/modules/registrar.so"
> > > > loadmodule "/usr/local/lib/ser/modules/textops.so"
> > > >
> > > > loadmodule "/usr/local/lib/ser/modules/pa.so"
> > > >
> > > > # Uncomment this if you want digest authentication # mysql.so must
> > > > be loaded !
> > > > #loadmodule "/usr/local/lib/ser/modules/auth.so"
> > > > #loadmodule "/usr/local/lib/ser/modules/auth_db.so"
> > > >
> > > > # ----------------- setting module-specific parameters
> > > > ---------------
> > > >
> > > > # -- 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("pa","db_url","mysql://ser:heslo@localhost/ser")
> > > >
> > > > # -- auth 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")
> > > >
> > > > # -- rr params --
> > > > # add value to ;lr param to make some broken UAs happy
> > > > #modparam("rr", "enable_full_lr", 1)
> > > >
> > > > # ------------------------- request routing logic
> > > > -------------------
> > > >
> > > > # main routing logic
> > > >
> > > > route{
> > > >
> > > > # 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");
> > > > break;
> > > > };
> > > > if (msg:len >= 2048 ) {
> > > > sl_send_reply("513", "Message too big");
> > > > break;
> > > > };
> > > >
> > > >
> > > > # 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 (!method=="REGISTER") record_route();
> > > >
> > > > # 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);
> > > > break;
> > > > };
> > > >
> > > > if (!uri==myself) {
> > > > # mark routing logic in request
> > > > append_hf("P-hint: outbound\r\n");
> > > > route(1);
> > > > break;
> > > > };
> > > >
> > > > # 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 (method=="PUBLISH"){
> > > > if(t_newtran()){
> > > > handle_publish("registrar");
> > > > break;
> > > > }
> > > > }
> > > > if (method=="SUBSCRIBE") {
> > > > if (!t_newtran()) {
> > > > log(1, "newtran error\n");
> > > > sl_reply_error();
> > > > };
> > > > handle_subscription("registrar");
> > > > break;
> > > > };
> > > >
> > > > if (method=="REGISTER") {
> > > >
> > > > # Uncomment this if you want to use digest authentication
> > > > # if (!www_authorize("192.168.1.118", "subscriber")) {
> > > > # www_challenge("192.168.1.118", "0");
> > > > # break;
> > > > # };
> > > >
> > > > save("location");
> > > > break;
> > > > };
> > > >
> > > > lookup("aliases");
> > > > if (!uri==myself) {
> > > > append_hf("P-hint: outbound alias\r\n");
> > > > route(1);
> > > > break;
> > > > };
> > > >
> > > > # native SIP destinations are handled using our USRLOC DB
> > > > if (!lookup("location")) {
> > > > sl_send_reply("404", "Not Found");
> > > > break;
> > > > };
> > > > };
> > > > append_hf("P-hint: usrloc applied\r\n");
> > > > route(1);
> > > > }
> > > >
> > > > route[1]
> > > > {
> > > > # send it out now; use stateful forwarding as it works reliably
> > > > # even for UDP2TCP
> > > > if (!t_relay()) {
> > > > sl_reply_error();
> > > > };
> > > > }
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > // ********************************
> > > >
> > > > -----Mensaje original-----
> > > > De: Vaclav Kubart [mailto:vaclav.kubart@iptel.org] Enviado el:
> > > > miércoles, 18 de octubre de 2006 6:21
> > > > Para: Diego Do?ate
> > > > CC: serusers(a)iptel.org
> > > > Asunto: Re: [Serdev] pa module: presence "substatus"
> > > >
> > > > Hi,
> > > > notes are quite often used for this.
> > > >
> > > > Can you send your config here? What SER version do you use? And if
> > > > you try register your users via sending REGISTER messages it is
> > > > still the
> > > same?
> > > >
> > > > Vaclav
> > > >
> > > > P.S. Send these messages to serusers too, might be that somebody
> > > > else will have the same problem...
> > > >
> > > > On Tue, Oct 17, 2006 at 05:18:55PM +0200, Diego Do?ate wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > Thanks, then I will use a <note> tag for the presence
> > > > > substatus(<note>Away<\note>, for instance).
> > > > >
> > > > > I have a problem with the Subscription. User A subscribes to
> > > > > the presence of user B and receives a NOTIFY but with
> > > > > "close/offline", and both users are previously registered
> > > > > successfully
> > in SER.
> > > > >
> > > > > Both users are added with serctl, but it seems the SER does
> > > > > not
> > > "save"
> > > > > user A registration when user B subscribes... Where may be the
> > > > > problem? May it be related to autherization? By now, it is
> disabled...
> > > > >
> > > > > Thanks in advance
> > > > >
> > > > >
> > > > >
> > > > > -----Mensaje original-----
> > > > > De: Vaclav Kubart [mailto:vaclav.kubart@iptel.org] Enviado el:
> > > > > lunes,
> > > > > 16 de octubre de 2006 18:57
> > > > > Para: Diego Do?ate
> > > > > CC: serdev(a)lists.iptel.org
> > > > > Asunto: Re: [Serdev] pa module: presence "substatus"
> > > > >
> > > > > Hi,
> > > > > support for PIDF extensions (elements from non-pidf namespace)
> > > > > is nearly finished in current CVS version, but it still needs some
> work.
> > > > > It will be done as soon as possible.
> > > > >
> > > > > Notes should be possible in last presence snapshot without any
> > > > > problems
> > > > > - they can be within tuple or presence elements according
> > specification.
> > > > >
> > > > > Vaclav
> > > > >
> > > > > On Mon, Oct 16, 2006 at 05:52:47PM +0200, Diego Do?ate wrote:
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > In the SER "pa" module, I would like to use a tag like "note"
> > > > > > or "substatus" in the pidf of the NOTIFY when a PUBLISH is
> > > > > > received (with a presence change, to "Away", for instance),
> > > > > > but SER only modified the <status> tag ("open"/"closed").
> > > > > >
> > > > > > How can I implement a more detailed presence status
> > > > > > management in the SER?
> > > > > >
> > > > > > Thanks in advance
> > > > > >
> > > > > >
> > > > > > _______________________________________________
> > > > > > Serdev mailing list
> > > > > > Serdev(a)lists.iptel.org
> > > > > > http://lists.iptel.org/mailman/listinfo/serdev
> > > > >
> > > >
> >
> >
> >
>
Jan 11 16:58:01 NOTICE[3987]: chan_sip.c:5387 sip_reg_timeout: --
Registration for '1000(a)serserv.com' timed out, trying again (Attempt #20000)
Jan 11 16:58:01 WARNING[3987]: chan_sip.c:1989 create_addr: No such host:
serserv.com
Jan 11 16:58:01 WARNING[3987]: chan_sip.c:5470 transmit_register: Probably a
DNS error for registration to 1000(a)serserv.com, trying REGISTER again (after
20 sec onds)
Looked on google and nothing helps with navigating me to the correct answer.
Any suggestion?
Ed
Hi!
In openser-CVS there is a new module called domainpolicy.
It implements draft-lendl-domain-policy-ddds-02. This version supports
draft-lendl-speermint-federations-02 and
draft-lendl-speermint-technical-policy-00.
This is about federation based and static peering (for SIP providers
which do not offer public SIP peering).
For background of this please refer to the SPEERMINT working group:
http://www.ietf.org/html.charters/speermint-charter.html
Attached are 3 documents:
one about building openser+domainpolicy
one about configuration and
one is a small howto about federations and domainpolicies.
You can also find a quick summary of domainpolicy in this mail:
http://www1.ietf.org/mail-archive/web/speermint/current/msg01598.html
Currently, openser CVS does not support interims solutions for
infrastructure ENUM lookups - the patch for this in in the queue.
Meanwhile you can download it from enum.at (see above link) too.
regards
Klaus
PS: If you do not want to use openser-CVS you can find the module or
complete tar balls for openser 1.1 at
http://www.enum.at/index.php?id=dokumente
--
Klaus Darilion
nic.at
This files describes how to install the openser for the Austrian IENUM Trial.
openser-ienum changelog:
Version 0.4:
- based on openser-1.1.0 from 2006-10-02
- domainpolicy module 0.4 + sql patch
- aligns with draft-lendl-domain-policy-ddds-02
- a few updates and bug-fixes
- supports draft-lendl-speermint-federations-02 and draft-lendl-speermint-technical-policy-00
- handling of non-terminal NAPTR records, as well as the DB schema has changed.
Version 0.3:
- based on openser-1.1.0 from 2006-07-14
Version 0.2:
- based on openser-CVS head from 2006-05-22
- tls patch not needed anymore as applied to CVS head
- domainpolicy module 0.2 + sql patch
- supports integer name based AVPs in "attr" column of domainpolicy table
- supports forcing a send_socket via dp_apply_policy
- bug fixed (NAPTR lookup need \0 terminated string)
Version 0.1: initial release
- based on openser-CVS head from 2006-05-17
- ienum patch
- tls patch
- domainpolicy module 0.1 + sql patch
Compared to openser CVS, this openser has the following differences:
- ienum patch to allow ienum queries
- domainpolicy modul to allow ad-hoc peering
This file decribes how to build your IENUM-openser.
1. You have to get the sources. There a 2 choices. You can either download the patched openser-tarball from www.enum.at or you patch it yourself.
1.1. Download the patched tarball: Go to enum.at, download the patched tarball (currently version 0.4).
Untar it using the command "tar -xvjf openser-ienum-0.4.tgz"
cd sip-server
1.2 Checkout openser from sourceforge's CVS and apply the patches manually. (Patches were tested to apply to openser-1.1.0 from 2006-10-02).
checkout openser-cvs
cvs -d:pserver:anonymous@openser.cvs.sourceforge.net:/cvsroot/openser login
cvs -z3 -d:pserver:anonymous@openser.cvs.sourceforge.net:/cvsroot/openser co -r rel_1_1_0 -P sip-server
download ienum patch
wget -O ienum-patch.txt "http://sourceforge.net/tracker/download.php?group_id=139143&atid=743022&fil…"
download domainpolicy modul und SQL patch from enum.at homepage
openser-domainpolicy_0.4.tgz
openser-domainpolicy-sql-patch_0.3.txt
apply patches
cd sip-server
patch -p0 <../openser-domainpolicy-sql-patch_0.3.txt
cd modules
tar -xvzf ../../domainpolicy_0.4.tgz
cd ..
patch -p0 <../ienum-patch.txt
2. Building the ienum-openser
When building openser, you have to install some development libraries, e.g. libssl-dev for TLS and mysql or postgresql development libraries. Further you have to install the libradius-ng-dev package. This must be built from the sources of radiusclient-ng available from berlios.
Depending on your Linux Distribution there are different choices to build:
2.1. Debian
The easiest way is build packages:
make deb
This will build TLS enabled openser packages. As this will build all available modules, you need several development libraries installed on the system. E.g. the libmysql-dev, libpg-dev and the radiusclient-ng devel libraries. As the radiusclient-ng is not part of debian, you have to install it manually as described on the openser wiki: http://www.openser.org/dokuwiki/doku.php?id=howto_make_debian_packages
Depending on your setup, and the used DB (mysql or postgresql) install the built debian packages. E.g.:
NOTE: this step replaces existing installed openser packages. Take care as openser-1.1 syntax is not 100% compatible with openser-1.0 syntax.
cd ..
su
dpkg -i openser_1.1.0-0_i386.deb openser-mysql-module_1.1.0-0_i386.deb
Set up the database tables: NOTE: edit the script /usr/sbin/openser_mysql.sh (or set environment variables, e.g. "export DBNAME=ienum_borderproxy") to reflect your DB environment (e.g. to do not overwrite existing openser databases).
openser_mysql.sh create
Now you can edit the config in /etc/openser/openser.cfg and use the start/stop script /etc/init.d/openser.
For debugging watch syslog logging in /var/log/syslog
2.2. Others
You can install openser manually. First you have to modify the Makefile to remove the needed modules from "exclude_modules", e.g. mysql or postgres. Then build the usual way:
NOTE: this step replaces existing manually installed openser. Take care as openser-1.1 syntax is not 100% compatible with openser-1.0 syntax.
export TLS=1
make all
su
make install
This will install openser in /usr/local/sbin/openser and /usr/local/lib/openser/modules/. The configuration is stored in /usr/local/etc/openser/openser.cfg. There is no startup script installed, thus you have to copy it manually from etc/openser.init to /etc/init.d/openser and adopt it to your paths.
3. Config
If you are used to ser or openser-1.0.x, please the migration info on http://openser.org/dokuwiki/doku.php?id=migrating_openser_v1.0.x_to_v1.1.x
Configuration for the ienum openser
1. Introduction
Using Infrastructure ENUM and SIP VoIP peering requires 2 steps:
1. perform IENUM lookups
2. interconnect with the destination published in the IENUM NAPTRs
Typically, a VoIP setup has a central node which performs the routing logic. I will call this the "main proxy". We can add the previously described steps in the main proxy or use dedicated nodes for doing the IENUM lookup and session peering. This has many advantages regarding security, flexibility and reliability. We suggest a setup of a dedicated "border proxy" which performs the IENUM lookup and takes care of peering (e.g. authentication of peering partners). This border proxy is a logical node, that means it can be installed on the same PC as the main proxy.
Nevertheless doing the IENUM lookup and the peering in the main proxy. If you want to do this, please use the ideas and config snippets from our suggested scenario (a dedicated border proxy) to adopt your main proxy's routing logic.
2. The Border Proxy
The border proxy takes care of the IENUM lookup and the SIP peering. The border proxy will perform the following steps:
For outgoing calls:
- bring number into E.164 format
- perform IENUM lookup
- perform ENUM lookup (optional)
- if no destination is found in IENUM/ENUM, send an apropriate SIP response back to the main proxy. The main proxy will then perform the default routing (usually sends the call to the PSTN gateway)
- perform a domain policy lookup. This step detects if the destination found in IENUM will accept SIP calls from us
- apply destination domain's peering policy (e.g. set proper TLS parameters, send to certain port, ...)
- add P-Asserted-Idendity: Header and Privacy Header the send proper CLI and CLIP/CLIR
- activate accounting
- send the call to the destination
For incoming calls:
- receive call
- authenticate sender (e.g. TLS or IP address)
- activate accounting
- adjust CLI to fit local dialplan (e.g reformat P-Asserted-Idendity header)
- forward the call to the main proxy
3. Configuration
3.1. Main Proxy
The main proxy should forward the call to the border proxy for IENUM lookup and peering. If the main proxy receives a certain response code, it will failover to the standard route to the PSTN.
E.g. if the main proxy is (open)ser based, the respective config snippets will be:
route{
# all the authentication and NAT traversal stuff
...
# user is authenticated. check if destination is an phone number
if (uri =~ "^sip:(\+|\*)?[0-9]+@") { # PSTN number detected
if (uri=~"^sip:[1-9]") {
xlog("L_WARN", "number normalization: illegal number, 404...");
sl_send_reply("404", "Not found - illegal number");
exit;
}
if (uri=~"^sip:0[1-9]") {
xlog("L_INFO","Austria national number detected, remove 0, prefix +43\n");
strip(1);
prefix("+43");
} else if (uri=~"^sip:00[1-9]") {
xlog("L_INFO","international number detected, remove 00, prefix +\n");
strip(2);
prefix("+");
} else if (uri=~"^sip:000") {
xlog("L_INFO", "000 detected, illegal number, 404...");
sl_send_reply("404", "Not found - illegal number");
exit;
}
}
# usually calls sent to the gateway have an Remote-Party-ID header
# to signal the CLI to the gateway. We send this RPID header also to the
# border proxy
# create new AVP with the Remote-Party-ID header
avp_printf("$avp(s:temp)","$avp(s:rpid);party=calling;id-type=subscriber;screen=yes");
append_hf("Remote-Party-ID: $avp(s:temp)\r\n");
# now, usually we would send the call to the PSTN gateway. But instead
# we activate a failure route and send it to the border proxy
t_on_failure("1");
# debpending on your domain setup you may need to rewrite the domain
# to address the border proxy
# rewritehostport("bp1.istp1.com");
# send the request to the border proxy
if (!t_relay()) {
sl_reply_error();
};
exit;
}
failure_route[1] {
# handles error on border proxy
xlog("L_INFO","failure_route(1): reply status = $rs\n");
# if caller cancels the call we will also enter the failure route
if(t_was_cancelled()) {
xlog("L_INFO","caller cancelled call ...exit\n");
exit;
}
# border proxy will return "499" in case of unsuccessful IENUM/domainpolicy lookup
if(t_check_status("499")) {
xlog("L_INFO","callee neither in I-ENUM nor in U-ENUM...sending to PSTN Gateway...");
rewritehostport("gateway.istp1.com");
t_relay();
exit;
}
xlog("L_INFO","send down error code from border proxy to user...exit\n");
exit;
}
If the main proxy is Asterisk based, the respective snippet may look like this (untested):
[frompbx]
; border proxy will send "503" if no IENUM result found
; in this example the Asterisk is also the gateway. If not you
; have to adopt the second Dial parameter to send the call to your
; gateway
exten => _[1-9].,1,Dial(SIP/+431${EXTEN}(a)bp1.itsp1.com,90)
exten => _[1-9].,2,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?103:3)
exten => _[1-9].,3,Hangup
exten => _[1-9].,103,Dial(ZAP/g1/${EXTEN},90)
exten => _0[1-9].,1,Dial(SIP/+43${EXTEN:1}@bp1.itsp1.com,90)
exten => _0[1-9].,2,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?103:3)
exten => _0[1-9].,3,Hangup
exten => _0[1-9].,103,Dial(ZAP/g1/${EXTEN},90)
exten => _00[1-9].,1,Dial(SIP/+${EXTEN:2}@bp1.itsp1.com,90)
exten => _00[1-9].,2,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?103:3)
exten => _00[1-9].,3,Hangup
exten => _00[1-9].,103,Dial(ZAP/g1/${EXTEN},90)
3.2 Border Proxy
The border proxy performs the IENUM/ENUM lookups and the domainpolicy lookup. Further it may perform authentication for peering purposes.
Again some config snippets for openser (you need the patched ienum-openser from www.enum.at)
...config section
...module parameter section
loadmodule "/usr/lib/openser/modules/enum.so"
loadmodule "/usr/lib/openser/modules/domainpolicy.so"
loadmodule "/usr/lib/openser/modules/tlsops.so"
# carrier enum
modparam("enum", "i_enum_suffix", "e164.arpa.")
modparam("enum", "bl_algorithm", "c")
# domainpolicy module (this must be named like in the domainpolicy table)
modparam("domainpolicy", "port_override_avp", "portoverride")
modparam("domainpolicy", "transport_override_avp", "transportoverride")
modparam("domainpolicy", "domain_prefix_avp", "domainprefix")
modparam("domainpolicy", "domain_suffix_avp", "domainsuffix")
modparam("domainpolicy", "send_socket_avp", "sendsocket")
route{
.....
# now, we split routing depending on the direction
# the protocol can be used to identify the direction
# if we require TCP or TLS for peering, but use UDP inside
# we can use the protocol to detect the call direction
# tls: request from peering partner
# udp,tcp: local request
if( (proto==tls) or (proto==tcp) ){
route(2);
} else {
route(3);
};
}
route[2] {
# TLS requests - thus requests received from peering partners.
# This requests are already authenticated via TLS certificate
# validation, thus no further SIP based authentication needed.
# Just forward the requests to the main proxy.
# Beforehand, we map from the anonymous IENUM SIP URIs to the
# user's AoR using the dbaliases module. Note: this mapping can
# also be done in the main proxy.
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(2): TLS requests\n");
if (alias_db_lookup("dbaliases")) {
xlog("L_INFO","dbaliases lookup successful, new URI = $ru\n");
avp_write("s:outbound.itsp1.ienum.labs.nic.at","$avp(i:679)");
avp_pushto("$du","$avp(i:679)");
# route(5); # optional process received P-Asserted_Identiy header
exit;
}
xlog("L_INFO","dbaliases lookup failed ... 404\n");
sl_send_reply("404","Unknown user");
exit;
}
route[3] {
# UDP/TCP - thus requests received from the local main proxy.
# This requests are already authenticated by the main proxy,
# thus no further SIP based authentication needed.
#
# Perform the following steps:
# 1. Try I-ENUM lookup
# 2. Try U-ENUM lookup
# 3. reply with 499
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(3): UDP/TCP requests\n");
if ( i_enum_query() ) {
xlog("L_INFO","I-ENUM lookup successful, new URI = $ru, check if useful...\n");
if (uri == myself) {
xlog("L_INFO","I-ENUM SIP URI belongs to myself, relay back to main proxy...\n");
sl_send_reply("100","I-ENUM succeeded, number belongs to us, sending back to main proxy...");
route(2);
exit;
}
if (dp_can_connect()) { # check the domainpolicy of the destination
xlog("L_INFO","dp_can_connect succeeded:\n");
xlog("L_INFO"," port_override_avp = '$avp(s:portoverride)'\n");
xlog("L_INFO"," transport_override_avp = '$avp(s:transportoverride)'\n");
xlog("L_INFO"," domain_prefix_avp = '$avp(s:domainprefix)'\n");
xlog("L_INFO"," domain_suffix_avp = '$avp(s:domainsuffix)'\n");
xlog("L_INFO"," send_socket_avp = '$avp(s:sendsocket)'\n");
xlog("L_INFO"," tls_client_domain_avp = '$avp(i:400)'\n");
# apply domain policy
if (dp_apply_policy()) {
xlog("L_INFO","I-ENUM SIP URI is a known peering partner, use this uri and relay request...\n");
xlog("L_INFO"," R-URI = $ru\n");
xlog("L_INFO"," d-URI = $du\n");
sl_send_reply("100","I-ENUM und domainpolicy succeeded, sending to other domain...");
route(4);
exit;
}
xlog("L_INFO","dp_apply_policy failed\n");
} else {
xlog("L_INFO","dp_apply_policy failed\n");
}
} else {
xlog("L_INFO","I-ENUM lookup failed, fallback to U-ENUM ...\n");
}
revert_uri();
if ( enum_query() ) {
xlog("L_INFO","U-ENUM lookup successful, new URI = $ru, relay request...\n");
sl_send_reply("100","U-ENUM succeeded, sending to other domain...");
route(4);
exit;
}
xlog("L_INFO","I-ENUM lookup failed, send 499 back to main proxy ...\n");
sl_send_reply("499","Number not in ENUM or domainpolicy failed");
exit;
}
route[4]{
# This route block reformats the rpid from the internal number format
# to the number format used in the I-ENUM trial.
# Thus, the proxy will take the existing rpid information (Remote-Party-ID header
# or P-Asserted_Identity header) and build an P-Asserted-Identity header with
# a tel URI.
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(4): add P-Asserted-Identity header\n");
# write the complete content of the Remote-Party-ID header into an AVP
append_hf("Remote-Party-ID: $avp(s:rpidheader)\r\n");
# replace the sip uri with a tel uri
# \1 \2 \3 \4
avp_subst("$avp(s:rpidheader)", "/^(.*)<sip:([^@]*)@[a-zA-Z0-9.]+(.*)>(.*)/tel:\2/gi");
# remove the Remote-Party-ID header and create the P-Asserted-Identity header
remove_hf("Remote-Party-ID");
append_hf("P-Asserted-Identity: $avp(s:rpidheader)\r\n");
route(1);
exit;
}
4. Appendix
4.1. Full Config of a Main Proxy
#
# $Id: openser.cfg,v 1.5 2005/10/28 19:45:33 bogdan_iancu Exp $
#
# simple quick-start config script
#
# Austrian I-ENUM Trial
# configuration of main proxy
# ----------- global configuration parameters ------------------------
debug=3 # debug level (cmd line: -dddddddddd)
fork=yes
#log_stderror=yes # (cmd line: -E)
/* Uncomment these lines to enter debugging mode
fork=no
log_stderror=yes
*/
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
children=4
fifo="/tmp/openser_fifo"
# syslog logging, configure in /etc/syslog
log_facility=LOG_LOCAL0 # /var/log/openser.log
server_header ="server_header: itsp1, main proxy"
user_agent_header="user_agent_header: itsp1, main proxy"
listen=udp:10.10.0.41:5060
listen=tcp:10.10.0.41:5060
listen=tls:10.10.0.41:5061
# our domain
alias=itsp1.ienum.labs.nic.at
# for addressing via outbound proxy and pre loaded route set
# (otherwise will is_myself in loose_route not match)
alias=outbound.itsp1.ienum.labs.nic.at
#
# uncomment the following lines for TLS support
#disable_tls = 0
#listen = tls:your_IP:5061
#tls_verify = 1
#tls_require_certificate = 1
#tls_method = TLSv1
#tls_certificate = "/etc/openser/tls/user/user-cert.pem"
#tls_private_key = "/etc/openser/tls/user/user-privkey.pem"
#tls_ca_list = "/etc/openser/tls/user/user-calist.pem"
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/lib/openser/modules/mysql.so"
loadmodule "/usr/lib/openser/modules/sl.so"
loadmodule "/usr/lib/openser/modules/tm.so"
loadmodule "/usr/lib/openser/modules/rr.so"
loadmodule "/usr/lib/openser/modules/maxfwd.so"
loadmodule "/usr/lib/openser/modules/usrloc.so"
loadmodule "/usr/lib/openser/modules/registrar.so"
loadmodule "/usr/lib/openser/modules/textops.so"
loadmodule "/usr/lib/openser/modules/xlog.so"
loadmodule "/usr/lib/openser/modules/avpops.so"
loadmodule "/usr/lib/openser/modules/acc.so"
loadmodule "/usr/lib/openser/modules/uri.so"
# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/usr/lib/openser/modules/auth.so"
loadmodule "/usr/lib/openser/modules/auth_db.so"
loadmodule "/usr/lib/openser/modules/enum.so"
loadmodule "/usr/lib/openser/modules/domain.so"
# ----------------- setting module-specific parameters ---------------
# read and write DB access
modparam("acc" , "db_url", "mysql://openser:openserrw@127.0.0.1/openser")
# accounting parameters
modparam("acc", "early_media", 1)
modparam("acc", "report_ack", 1)
modparam("acc", "report_cancels", 0)
modparam("acc", "multi_leg_enabled", 0)
modparam("acc", "failed_transaction_flag", 4) # radius, syslog and DB
modparam("acc", "log_flag", 1) # syslog
modparam("acc", "db_flag", 2) # DB
modparam("acc", "db_missed_flag", 3) # DB missed calles table
# the following modules also supports multidomain, but are not used
# by us: group, group_radius, speeddial, uri_db
modparam("alias_db|usrloc|registrar|avpops", "use_domain", 1)
# -- 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)
# -- auth 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|usrloc|registrar", "use_domain", 1)
# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
# ------------------------- request routing logic -------------------
# main routing logic
route{
xlog("L_ERR","[$Tf] [$si:$sp] $rm $ru (From: $fu -> To: $tu) request received....\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;
};
# mark transaction for accounting
setflag(1);
setflag(2);
setflag(4);
if ( is_method("CANCEL") && !t_check_trans() ) {
# CANCEL without matching INVITE transaction, ignore
# may happen if the INVITE is slower than the CANCEL
# ignore the CANCEL, as the client will retransmit it, and maybe next time
# the INVITE transaction is already created
xlog("L_WARN","CANCEL without matching transaction ... ignore and discard.\n");
exit;
}
if ( is_method("CANCEL") ) {
# CANCEL with matching INVITE transaction, just
# t_relay
xlog("L_INFO","CANCEL with matching transaction ... t_relay.\n");
t_relay();
exit;
}
# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
if (!has_totag()) {
xlog("L_WARN","loose_route request without to-tag, 403...\n");
sl_send_reply("403", "out-of-dialog loose_route not allowed");
exit;
}
xlog("L_WARN","request loose_route processed...\n");
route(1);
};
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after a 487
xlog("L_INFO","local end-to-end ACK for an existent INVITE transaction detected ...t_relay()\n");
t_relay();
} else {
xlog("L_WARN","ACK without matching transaction ... ignore and discard.\n");
}
exit;
}
if ( has_totag() ) {
# in-dialog requests should be handled by loose_route
# this should be fixed in the client or in openser
xlog("L_ERR","in-dialog request was not catched by loose_route block, 403... \n");
xlog("L_ERR","this is the complete message:\n");
xlog("L_ERR","$mb\n");
sl_send_reply("403","in-dialog request without loose_route is not allowed, this is a bug in the client or in this proxy\n");
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
#
# record route will be done after loose_route to do not change the
# ftag parameter in the Route header (eyebeam)
if (!method=="REGISTER")
record_route();
if (!uri==myself) {
xlog("L_WARN","outoing call ...\n");
route(1);
};
# if the request is for our domain use UsrLoc
# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (uri==myself) {
if (method=="REGISTER") {
if (t_newtran()) {
# Uncomment this if you want to use digest authentication
if (!www_authorize("", "subscriber")) {
www_challenge("", "0");
exit;
};
save("location");
exit;
} else sl_reply_error();
t_release();
};
if (is_method("INVITE")) {
# Uncomment this if you want to use digest authentication
if (from_uri == myself) {
xlog("L_INFO","INVITE from local user, check auth\n");
if (!proxy_authorize("", "subscriber")) {
xlog("L_INFO","auth failed...challenge\n");
proxy_challenge("", "0");
exit;
};
consume_credentials();
# if avp rpid available add rpid header
remove_hf("Remote-Party-ID");
remove_hf("P-Asserted-Identity");
if (is_avp_set("$avp(s:rpid)")) {
xlog("L_INFO","RPID defined: rpid=$avp(s:rpid)\n");
#add Remote-Party-ID header
# create new AVP with the Remote-Party-ID header
avp_printf("$avp(s:temp)","$avp(s:rpid);party=calling;id-type=subscriber;screen=yes");
xlog("L_INFO", "Remote-Party-ID header: $avp(s:temp)");
append_hf("Remote-Party-ID: $avp(s:temp)\r\n");
# #add P-Asserted-Identity header
# # create new AVP with the P-Asserted-Identity header
# avp_printf("$avp(s:temp)","$avp(s:rpid)");
# xlog("L_INFO", "P-Asserted-Identity header: $avp(s:temp)");
# append_hf("$avp(s:temp)","P-Asserted-Identity");
} else {
xlog("L_INFO","RPID not defined...\n");
}
if (uri =~ "^sip:(\+|\*)?[0-9]+@") { # PSTN number detected
if (uri=~"^sip:[1-9]") {
xlog("L_WARN", "number normalization: illegal number, 404...");
sl_send_reply("404", "Not found - illegal number");
exit;
}
if (uri=~"^sip:0[1-9]") {
xlog("L_INFO","Austria national number detected, remove 0, prefix +43\n");
strip(1);
prefix("+43");
} else if (uri=~"^sip:00[1-9]") {
xlog("L_INFO","international number detected, remove 00, prefix +\n");
strip(2);
prefix("+");
} else if (uri=~"^sip:000") {
xlog("L_INFO", "000 detected, illegal number, 404...");
sl_send_reply("404", "Not found - illegal number");
exit;
}
t_on_failure("1");
# rewritehostport("bp1.itsp1.ienum.labs.nic.at");
route(1);
}
if (!uri==myself) {
append_hf("P-hint: Proxy1 outbound alias\r\n");
route(1);
};
} else {
xlog("L_INFO","incoming call...\n");
}
}
# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
sl_send_reply("404", "Not Found in location table");
exit;
};
xlog("L_INFO","user found, route(1)...\n");
append_hf("P-hint: usrloc applied\r\n");
};
route(1);
}
route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
xlog("L_INFO","t_relay....\n");
if (!t_relay()) {
sl_reply_error();
};
exit;
}
failure_route[1] {
# handles error on border proxy
xlog("L_INFO","failure_route(1): reply status = $rs\n");
if(t_was_cancelled()) {
xlog("L_INFO","caller cancelled call ...exit\n");
exit;
}
if(t_check_status("499")) {
xlog("L_INFO","callee neither in I-ENUM nor in U-ENUM...sending to PSTN Gateway...404");
t_reply("404","no PSTN gateway configured");
exit;
}
xlog("L_INFO","send down error code from upstream proxy...exit\n");
exit;
}
route[5] {
# dummy route for aliases lookup
lookup("aliases");
}
4.2. Full Config of a Border Proxy
#
# $Id: openser.cfg,v 1.5 2005/10/28 19:45:33 bogdan_iancu Exp $
#
# simple quick-start config script
#
# Austrian I-ENUM Trial
# configuration of main proxy
# ----------- global configuration parameters ------------------------
debug=4 # debug level (cmd line: -dddddddddd)
fork=yes
#log_stderror=yes # (cmd line: -E)
/* Uncomment these lines to enter debugging mode
fork=no
log_stderror=yes
*/
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
children=4
fifo="/tmp/openserbp_fifo"
# syslog logging, configure in /etc/syslog
log_facility=LOG_LOCAL1 # /var/log/openserbp.log
server_header ="server_header: itsp1, border proxy"
user_agent_header="user_agent_header: itsp1, border proxy"
listen=udp:10.10.0.41:5062
listen=udp:10.10.0.46:5062
listen=tcp:10.10.0.41:5062
listen=tcp:10.10.0.41:5080
listen=tls:10.10.0.41:5063
listen=tls:10.10.0.41:5065
alias=itsp1.ienum.labs.nic.at
#
# uncomment the following lines for TLS support
#
# default fed = fedA
disable_tls = 0
tls_verify_server = 1
tls_verify_client = 1
tls_require_client_certificate = 1
tls_method = TLSv1
tls_certificate = "/etc/certs/fedA/itsp1/cert.pem"
tls_private_key = "/etc/certs/fedA/itsp1/privkey.pem"
tls_ca_list = "/etc/certs/fedA/demoCA/cacert.pem"
#tls_ciphers_list= "NULL"
#tls core supports only integer client domain AVPs
tls_client_domain_avp = 400
tls_client_domain["v2"] {
#specify parameters for a domain in particular, otherwise,
#it will use the default. These are the possible parameters to
#change for each domain
tls_certificate = "/etc/certs/fedA/itsp1/cert.pem"
tls_private_key = "/etc/certs/fedA/itsp1/privkey.pem"
tls_ca_list = "/etc/certs/fedA/demoCA/cacert.pem"
tls_method=TLSv1
# tls_ciphers_list= "NULL"
tls_verify_server = 1
}
tls_client_domain["fedc"] {
#specify parameters for a domain in particular, otherwise,
#it will use the default. These are the possible parameters to
#change for each domain
tls_certificate = "/etc/certs/fedC/itsp1/cert.pem"
tls_private_key = "/etc/certs/fedC/itsp1/privkey.pem"
tls_ca_list = "/etc/certs/fedC/demoCA/cacert.pem"
tls_method=TLSv1
tls_verify_server = 1
}
tls_server_domain[10.10.0.41:5065] {
#specify parameters for a domain in particular, otherwise,
#it will use the default. These are the possible parameters to
#change for each domain
tls_certificate = "/etc/certs/fedA/itsp1/cert.pem"
tls_private_key = "/etc/certs/fedA/itsp1/privkey.pem"
tls_ca_list = "/etc/certs/fedA/demoCA/cacert.pem"
tls_method=TLSv1
tls_verify_client = 1
tls_require_client_certificate = 1
}
tls_server_domain[10.10.0.41:5067] {
#specify parameters for a domain in particular, otherwise,
#it will use the default. These are the possible parameters to
#change for each domain
tls_certificate = "/etc/certs/fedC/itsp1/cert.pem"
tls_private_key = "/etc/certs/fedC/itsp1/privkey.pem"
tls_ca_list = "/etc/certs/fedC/demoCA/cacert.pem"
tls_method=TLSv1
tls_verify_client = 0
tls_require_client_certificate = 1
}
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/lib/openser/modules/mysql.so"
loadmodule "/usr/lib/openser/modules/sl.so"
loadmodule "/usr/lib/openser/modules/tm.so"
loadmodule "/usr/lib/openser/modules/rr.so"
loadmodule "/usr/lib/openser/modules/maxfwd.so"
loadmodule "/usr/lib/openser/modules/textops.so"
loadmodule "/usr/lib/openser/modules/xlog.so"
loadmodule "/usr/lib/openser/modules/avpops.so"
loadmodule "/usr/lib/openser/modules/options.so"
loadmodule "/usr/lib/openser/modules/acc.so"
loadmodule "/usr/lib/openser/modules/uri.so"
loadmodule "/usr/lib/openser/modules/alias_db.so"
loadmodule "/usr/lib/openser/modules/enum.so"
loadmodule "/usr/lib/openser/modules/domain.so"
loadmodule "/usr/lib/openser/modules/domainpolicy.so"
loadmodule "/usr/lib/openser/modules/tlsops.so"
# ----------------- setting module-specific parameters ---------------
# -- database configuration --
# read only DB access
# modparam("domain", "db_url", "postgres://openserro:openserro@localhost/openser") # XXX user at43 db for production use
modparam("domain|uri_db|alias_db|lcr", "db_url", "mysql://openserro:openserro@127.0.0.1/openserbp")
#modparam("avpops", "avp_url", "postgres://serro:rororo@83.136.32.160/at43")
# read and write DB access
modparam("acc" , "db_url", "mysql://openser:openserrw@127.0.0.1/openserbp")
# the following modules also supports multidomain, but are not used
# by us: group, group_radius, speeddial, uri_db
modparam("alias_db|usrloc|registrar|avpops", "use_domain", 1)
modparam("domain", "db_mode", 1) # Use caching in domain module
# accounting parameters
modparam("acc", "early_media", 1)
modparam("acc", "report_ack", 1)
modparam("acc", "report_cancels", 0)
modparam("acc", "multi_leg_enabled", 0)
modparam("acc", "failed_transaction_flag", 4) # radius, syslog and DB
modparam("acc", "log_flag", 1) # syslog
modparam("acc", "db_flag", 2) # DB
modparam("acc", "db_missed_flag", 3) # DB missed calles table
#modparam("acc", "swap_direction", 0)
#modparam("acc", "detect_direction", 1)
# extra accounting of TLS paramters and sockets
modparam("acc", "db_extra", "source_ip=$si;source_port=$sp;received_ip=$Ri;received_port=$Rp;tls_peer_subject=$tls_peer_subject;tls_peer_issuer=$tls_peer_issuer;tls_my_subject=$tls_my_subject;tls_my_issuer=$tls_my_issuer")
# carrier enum
modparam("enum", "branchlabel", "i")
modparam("enum", "bl_algorithm", "cc")
# we do never read from the default AVP table, thus we define a dummy
# table which will never be used
#modparam("avpops", "avp_table", "dummy")
# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
modparam("domainpolicy", "port_override_avp", "portoverride")
modparam("domainpolicy", "transport_override_avp", "transportoverride")
modparam("domainpolicy", "domain_prefix_avp", "domainprefix")
modparam("domainpolicy", "domain_suffix_avp", "domainsuffix")
modparam("domainpolicy", "send_socket_avp", "sendsocket")
# ------------------------- request routing logic -------------------
# main routing logic
route{
remove_hf("Supported");
route(21);
# 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;
};
setflag(1);
setflag(2);
setflag(3);
setflag(4);
# we do not allow REGISTER messages, they are
# not needed for VoIP peering
if (is_method("REGISTER")) {
xlog("L_INFO","[$Tf] [$si:$sp] $rm $ru (From: $fu -> To: $tu) reject with 405\n");
sl_send_reply("405","REGISTER is not allowed");
exit;
}
# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
if (!has_totag()) {
xlog("L_WARN","loose_route request without to-tag, 403...\n");
sl_send_reply("403", "out-of-dialog loose_route not allowed");
exit;
}
xlog("L_WARN","request loose_route processed...\n");
route(1);
};
# 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
record_route();
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after a 487
xlog("L_INFO","local end-to-end ACK for an existent INVITE transaction detected ...t_relay()\n");
t_relay();
} else {
xlog("L_WARN","ACK without matching transaction ... ignore and discard.\n");
}
exit;
}
if ( has_totag() ) {
# in-dialog requests should be handled by loose_route
# this should be fixed in the client or in openser
xlog("L_ERR","in-dialog request was not catched by loose_route block, 403... \n");
xlog("L_ERR","this is the complete message:\n");
xlog("L_ERR","$mb\n");
sl_send_reply("403","in-dialog request without loose_route is not allowed, this is a bug in the client or in this proxy\n");
exit;
}
#
# We only allow requests which are directly addressed to us.
# This is a security feature to avoid bypassing of the
# main proxy routing logic
if (!uri==myself) {
xlog("L_INFO","[$Tf] [$si:$sp] $rm $ru (From: $fu -> To: $tu) non local domain, reject with 403\n");
sl_send_reply("403","please address requests directly to me");
exit;
};
# allow OPTIONS requests for keep alive monitoring
if ( is_method("OPTIONS") && !(uri =~ "sip:.*@.*") ) { # OPTIONS request for us
options_reply();
exit;
}
#
# at this time, we only have out-of-dialog requests
# now, we split routing depending on the direction
# the protocol can be used to identify the direction
# tls: request from peering partner
# udp,tcp: local request
if(proto==tls) {
route(2);
} else {
route(3);
};
exit;
}
route[1] {
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}
route[2] {
# TLS requests - thus requests received from peering partners.
# This requests are already authenticated via TLS certificate
# validation, thus no further SIP based authentication needed.
# Just forward the requests to the main proxy.
# Beforehand, we map from the anonymous IENUM SIP URIs to the
# user's AoR using the dbaliases module. Note: this mapping can
# also be done in the main proxy.
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(2): TLS requests\n");
if (alias_db_lookup("dbaliases")) {
xlog("L_INFO","dbaliases lookup successful, new URI = $ru\n");
avp_write("s:outbound.itsp1.ienum.labs.nic.at","$avp(i:679)");
avp_pushto("$du","$avp(i:679)");
route(5);
exit;
}
xlog("L_INFO","dbaliases lookup failed ... 404\n");
sl_send_reply("404","Unknown user");
exit;
}
route[3] {
# UDP/TCP - thus requests received from the local main proxy.
# This requests are already authenticated by the main proxy,
# thus no further SIP based authentication needed.
#
# Perform the following steps:
# 1. Try I-ENUM lookup
# 2. Try U-ENUM lookup
# 3. reply with 499
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(3): UDP/TCP requests\n");
if ( i_enum_query("ienum.labs.nic.at") ) {
xlog("L_INFO","I-ENUM lookup successful, new URI = $ru, check if useful...\n");
if (uri == myself) {
xlog("L_INFO","I-ENUM SIP URI belongs to myself, relay back to main proxy...\n");
sl_send_reply("100","I-ENUM succeeded, number belongs to us, sending back to main proxy...");
route(2);
exit;
}
if (dp_can_connect()) { # check the domainpolicy of the destination
xlog("L_INFO","dp_can_connect succeeded:\n");
xlog("L_INFO"," port_override_avp = '$avp(s:portoverride)'\n");
xlog("L_INFO"," transport_override_avp = '$avp(s:transportoverride)'\n");
xlog("L_INFO"," domain_prefix_avp = '$avp(s:domainprefix)'\n");
xlog("L_INFO"," domain_suffix_avp = '$avp(s:domainsuffix)'\n");
xlog("L_INFO"," send_socket_avp = '$avp(s:sendsocket)'\n");
xlog("L_INFO"," tls_client_domain_avp = '$avp(i:400)'\n");
# apply domain policy
if (dp_apply_policy()) {
xlog("L_INFO","I-ENUM SIP URI is a known peering partner, use this uri and relay request...\n");
xlog("L_INFO"," R-URI = $ru\n");
xlog("L_INFO"," d-URI = $du\n");
sl_send_reply("100","I-ENUM und domainpolicy succeeded, sending to other domain...");
route(4);
exit;
}
xlog("L_INFO","dp_apply_policy failed\n");
} else {
xlog("L_INFO","dp_apply_policy failed\n");
}
} else {
xlog("L_INFO","I-ENUM lookup failed, fallback to U-ENUM ...\n");
}
revert_uri();
if ( enum_query("ienum.labs.nic.at") ) {
xlog("L_INFO","U-ENUM lookup successful, new URI = $ru, relay request...\n");
sl_send_reply("100","U-ENUM succeeded, sending to other domain...");
route(4);
exit;
}
xlog("L_INFO","I-ENUM lookup failed, send 499 back to main proxy ...\n");
sl_send_reply("499","Number not in ENUM or domainpolicy failed");
exit;
}
route[4]{
# This route block reformats the rpid from the internal number format
# to the number format used in the I-ENUM trial.
# Thus, the proxy will take the existing rpid information (Remote-Party-ID header
# or P-Asserted_Identity header) and build an P-Asserted-Identity header with
# a tel URI.
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(4): add P-Asserted-Identity header\n");
# uncomment the next few lines if the local rpid format is
# Remote-Party-ID: <sip:+43101@proxy1.ienum.labs.nic.at>;...
# first the dirty hack version: just use a regexp over the whole message
# this will fail with unusual formated SIP messages
#if (subst('/^Remote-Party-ID:(.*)sip:([^@]*)@[a-zA-Z0-9.]+(.*)$/P-Asserted-Identity: tel:\2\r/ig')) {
# xlog("L_INFO","successfuly replaced Remote-Party-ID with /P-Asserted-Identity...\n");
#} else {
# xlog("L_INFO","failure replacing Remote-Party-ID with P-Asserted-Identity...500\n");
# sl_send_reply("500","failure replacing Remote-Party-ID with P-Asserted-Identity");
# exit;
#}
#
# now the more complicated version using AVPs, should be more robust:
# write the complete content of the Remote-Party-ID header into an AVP
append_hf("Remote-Party-ID: $avp(s:rpidheader)\r\n");
# replace the sip uri with a tel uri
# \1 \2 \3 \4
avp_subst("$avp(s:rpidheader)", "/^(.*)<sip:([^@]*)@[a-zA-Z0-9.]+(.*)>(.*)/tel:\2/gi");
# remove the Remote-Party-ID header and create the P-Asserted-Identity header
remove_hf("Remote-Party-ID");
append_hf("P-Asserted-Identity: $avp(s:rpidheader)\r\n");
route(1);
exit;
}
route[5]{
# This route block reformats the rpid received in the P-Asserted-Identity header
# (the number format used in the I-ENUM trial) into the local used format.
# The local used format may be for example a Remote-Party-ID header, a
# P-Asserted_Identity header or a rewritten From header.
xlog("L_INFO","[$Tf] $rm $ru (From: $fu -> To: $tu) entering route(5): process P-Asserted-Identity header\n");
route(1);
exit;
}
onreply_route {
# default onreply_route
route(22);
}
route[21] {
xlog("L_INFO","$ci [$Tf]: -------------------- new SIP request received --------------------\n");
xlog("L_INFO","$ci [$si:$sp] $rm $ru (From: $fu -> To: $tu)\n");
xlog("L_INFO","[$Tf] $$tls_peer_subject = '$tls_peer_subject'\n");
xlog("L_INFO","[$Tf] $$tls_peer_subject_cn = '$tls_peer_subject_cn'\n");
xlog("L_DBG", "message buffer:\n");
xlog("L_DBG", "$mb\n");
}
route[22] {
xlog("L_INFO","$ci [$Tf]: -------------------- new SIP response received --------------------\n");
xlog("L_INFO","$ci [$si:$sp] $rs ($cs) $rr (From: $fu <- To: $tu)\n");
xlog("L_INFO","[$Tf] $$tls_peer_subject = '$tls_peer_subject'\n");
xlog("L_INFO","[$Tf] $$tls_peer_subject_cn = '$tls_peer_subject_cn'\n");
xlog("L_DBG", "message buffer:\n");
xlog("L_DBG", "$mb\n");
}
1. Why do we need SIP peering?
When SIP was developed, there was no need for SIP peering. SIP was considered to be as open as email. Like everybody can send emails to everyone, every SIP user should be able to contact every other SIP user via SIP. Therefore, two requirements are necessary:
- The SIP provider of the caller must allow calling SIP URIs which are outside of the local SIP domain.
- The SIP provider of the callee has to allow incoming SIP calls from callers outside of the local domain.
For further discussion, a SIP services which fulfill these two requirements will be referred as "open SIP service".
Currently there are lots of open SIP services, e.g. iptel.org or fwd.pulver.com.
But there are also other SIP services, which are "closed" or "restricted". Closed means, that the SIP service provider allows only internal SIP calls (when calling other users of this SIP service provider). All calls to other users will be routed via the PSTN. Restricted means, that the SIP service provider allows SIP calls from/to certain domains, but not all domains. This of course requires authentication of incoming calls. (examples of closed service providers are yahoo broadband, inode, vonage, IMS/NGN)
There are mainly 3 reasons why a service provider does not offer an open service, but only closed or restricted:
- business model: The service provider need the PSTN fees for its business model.
- security: The service provider is afraid of possible security impacts
- spit: The service provider is afraid of SPIT (VoIP SPAM) which will probably occur sooner or later (like email spam)
Having "open" SIP providers while other SIP providers are "closed" leads to several interconnection problems. Following are a few examples:
- A user of an open SIP service calls a user of a closed SIP service using the callees SIP URI. The callees SIP provider ignores the incoming SIP messages, causing failed call setups (without any information why the call failed).
- A user of a closed SIP service calls a user of an open SIP service via its E.164 phone number. Although the callee can be called directly via ENUM+SIP, the call will be routed via the PSTN causing higher call setup times, call costs and probably worse quality due to multiple transcoding and packetization.
- Two users want to have a SIP video conversation amongst them. Both SIP providers support video sessions, but as the interconnect between both providers will be done via the PSTN, there is no possibility to have multimedia session (video, IM, presence).
To resolve these issues, a dedicated peering mode is necessary. Probably lots of people will argue that peering is not necessary and SIP providers should just open their SIP services. But this will lead to the same problems we have with email. Further, if there are service providers which do not want open there service for everybody, their position should be accepted.
Even if a service provider opens its SIP service, it might want to apply some restrictions on how the interconnect will be done.
Thus, to encourage SIP providers to open their SIP service, we need to offer them mechanisms to authenticate other service providers. There are several ways to authenticate SIP users or other SIP service providers, e.g: SIP over TLS (certificate based authentication), IP address based (TCP or TLS as UDP can be spoofed easily), SIP identity-draft, SIP+S/MIME, SIP+domainkeys, Layer2 VPNs, IPsec, ...
Regardless of the technology the service provider requires for authenticating calls, the technology must be somehow announced to the other service providers. This is the reason why we need
- draft-lendl-domain-policy-ddds-02.txt and
- draft-lendl-speermint-federations-02.txt
These drafts define federations and how a service prodiver can publish its peering policies (= federation memberships).
2. What is a federation
A federation is like a club. All the members share a common interest. In case of VoIP peering, the members share the common wish to interconnect directly via SIP instead of the old style TDM/SS7 interconnect. A federation needs at least 2 members (this is like a bilateral peering agreement), but usualy may have several members which treat each other as identical.
There will be lots of different federations with different goals an dinterconnect policies. E.g. one federation may have to policy to have settlement free peering (sender keeps all) and everbody may participate as long they authenticate via TLS. Other federations may still stay with current settlement policies (termination fees ...) and members most fulfill certain requirements (e.g. must be a mobile operator ...).
Thus, it may often happen that a VoIP service provider is a member of several federations. The next sections shows how service providers may participate in several federations and how the domainpolicy technology can be used to achieve "plug-and-play" interworking in several federations.
3. Use Cases - The Federations
In the following example we show the use case of a VoIP service provider. This virtual VoIP service provicer is located in Austria and offers VoIP services via cable technology. It is an early adopter of the "triple play" offering TV, Internet and Voice to its customers. Let's call this VoIP service provider "CableItsp1".
There are also other cable technology based VoIP service providers in Austria. As they mostly have their local regions without overlapping, these cable guys are not competitors. Their competitors are traditional voice service providers (VSPs). These cable guides set up a federation called "cable-guys-austria" to fight jointly against their competitors. Further there business model is not based on selling voice mintues, but an a monthly subscription fee with flat rate. Thus, having settlement free voice interconnect between each others will be a benefit as they can simplify their billing systems.
Further, there is a worldwide federation called "voip-providers-international" which allow every VoIP service provider to join and allow settlement free worldwide interconnect - as long as the members pay they monthly federation subscription. Thus this federation may be interesting for VoIP service providers with a lot of international connections.
To have one more example, there is an Austrian federation called "voip-peering-austria" which still insists of interconnect fees. Thus, the simple but very reasonable goal is to keep VoIP calls on IP and avoid transcoding and gatewaying for TDM based interconnect. The settlement must be still agreed bilatereal between the VSPs.
All of these federations have different goals and different interconnect policies:
cable-guys-austria
==================
subscription fee: no
settlement: no fees
technology: SIP via UDP via IPsec (commom shared secret) via well known IP addresses
URI (identifier): http://www.cableguysaustria.at/peering-v1
domain-suffix: cableguysaustria.at
voip-providers-international
============================
subscription fee: yes, monthly
settlement: no fees
technology: SIP via TCP with IP access lists
SIP-port: 5080
URI (identifier): http://www.voip-providers-international.com/peeringv1
voip-peering-austria
====================
subscription fee: no
settlement: fees must be agreed bilateral
technology: SIP via TLS, certificate signed by voip-peering-austria
TLS-port: 6666
URI (identifier): http://www.voip-peering-austria.at/TlsPeeringV1
Note: Why some use a dedicated port instead of the SIP default port will be described later.
4. Finding and Peering
4.1. Is the callee reachable via SIP?
Before any interconnect policies can be applied, the originating service provider has to find out to which VSP a phone number belongs. These can be done via lookup tables. Probably the most open and commen lookup mechanism is ENUM, especially infrastructure ENUM. The VSP registers the ENUM domains for its numbers and announces the SIP URI for inbound routing in the NAPTR. Thus, the originating service provider performs an IENUM lookup for the called phone number. If there is no ENUM entry for a called number, the originating VSP will send the call to its PSTN gateway as usual. If there is a SIP URI in ENUM, the next step is:
4.2. Does the callee's VSP accept VoIP interconnect from the originator?
The SIP URI returned from the IENUM lookup points to the terminating service provider. Thus, the domain in the SIP URI is the "key" to find out the peering policies of the terminating service provider.
For example, the IENUM lookup for the called number returns sip:+4312345@sip.itsp66.com. Then, the domain "sip.itsp66.com" will be used as the input data for the domainpolicy algorithm described in draft-lendl-domain-policy-ddds. The originating service provider will perform NAPTR DNS lookups for the domain "sip.itsp66.com" with service types "D2P+...". In this example, there will be 3 NAPTRs returned:
$ORIGIN sip.itsp66.com.
IN NAPTR 10 50 "U" "D2P+SIP:fed" "!^.*$!http://www.cableguysaustria.at/peering-v1!" .
IN NAPTR 20 50 "U" "D2P+SIP:fed" "!^.*$!http://www.voip-peering-austria.at/TlsPeeringV1!" .
IN NAPTR 30 50 "U" "D2P+SIP:fed" "!^.*$!http://sipxyconnect.example.org/!" .
Now the originator verifies the published federation identifiers agains a local table, in which the originating VSP has configured its federation membership. If there is a matching federation, the next step will applies.
4.3. Apply the federation policies
Different federations will use different techniques to interconnect and authenticate each other. Thus, before sending the call to the terminating VSP, the federatations policy must be applied. E.g. if a federation authenticate each other using TLS with certificates signed by the federation's CA, the border proxy must switch to TLS and present the proper certificate to the ingress point of the terminating VSP. Some of these "attributes" must be applied by the border proxy (e.g. tranport protocol, dedicated SIP signaling port, TLS certificate ...) whereas others might be application agnostic (e.g. IPsec encryption, VPNs ...).
5. ENUM routing and federation policies
When a VSP publishes its ingress proxy for VoIP peering in ENUM, it publishes only a single NAPTR. Although then ENUM standard allows publishing of several "SIP NAPTRs" for a certain number there is no semantics defined how to deal with multiple received SIP NAPTRs (serial forking? parallel forking? which one to choose?). Thus it is suggested to publish only a single SIP NAPTR in ENUM.
Using plain ENUM and plain SIP, all incoming requests for a certain phone number will be received on the same ingress proxy. This is fine in a "open SIP service" environment, but not in a dedicated peering scenario where traffic from certain peering partners should be received on certain ingress points. A common use case is the use of TLS. As TLS does not allow "virtual hosting", authentication with different certificates for different peering partners requires a dedicated socket for each "TLS domain". Another use case is peering in a dedicated VLAN with public IP addresses. If a VSP has an ingress proxy in the public Internet and an ingress proxy in a private LAN (for dedicated peering partners), there must be an algorithm which allows to originating VSP to resolve from the common SIP URI to the respective IP address (public or private).
This can be done by applying federation policies to the SIP URI. We will call these "override attributes" as they override the default SIP routing behavior described in RFC 3263. Each federation defines its override attributes which allow to "manipulate" the default RFC3263 call routing according to the federation's policy.
Currently the openser domainpolicy module supports the following override attributes:
- port_override: If this attribute is set, the port in the destination URI is set to this port. Setting an override port disables NAPTR and SRV lookups according to RFC 3263.
- transport_override: If this attribute is set, the transport parameter in the destination URI is set to the specified transport ("udp", "tcp", "tls"). Setting an override
transport also disables NAPTR lookups, but retains an SRV lookup according to RFC 3263.
- domain_prefix: If this attribute is set, the domain in the destination URI will be prefixed with this "subdomain". E.g. if the domain in the request URI is "example.com" and the domain_prefix contains "inbound", the domain in the destinaton URI is set to "inbound.example.com".
- domain_suffix: If this attribute is set, the domain in the destination URI will have the content of the attribute appended to it. E.g. if the domain in the request URI is "example.com" and the domain_suffix contains "myroot.com", the domain in the destination URI is set to "example.com.myroot.com".
Thus, using override attributes manipulates the destination URI - the socket to which the message will be sent. Nevertheless, the request URI (the SIP URI in the first line of the SIP request) is untouched as will always be the value of the ENUM lookup.
6. Configuring inbound routing
This section shows how the previously presented VSP "CableItsp1" configures it inbound routing. As desrcribed earlier, CableItsp1 is member of 3 different federations, each having its own interconnect policies.
6.1. ENUM
CableItsp1 chooses a simple format for its NAPTRs: the user part is the E.164 phone number and the domain part is its domain cableitsp1.at, for example:
$ORIGIN 5.4.3.2.1.3.4.e164.arpa.
IN NAPTR 10 50 "U" "E2U+sip" "!^.*$!sip:+4312345@cableitsp1.at!" .
6.2. Announcing federation memberships
CableItsp1 announces its federation memberships (= its interconnect policies) in the DNS:
$ORIGIN cableitsp1.at.
IN NAPTR 10 50 "U" "D2P+SIP:fed" "!^.*$!http://www.cableguysaustria.at/peering-v1!" .
IN NAPTR 20 50 "U" "D2P+SIP:fed" "!^.*$!http://www.voip-peering-austria.at/TlsPeeringV1!" .
IN NAPTR 30 50 "U" "D2P+SIP:fed" "!^.*$!http://www.voip-providers-international.com/peeringv1!" .
6.3. Federation ingress configuration
6.3.1 Federation cable-guys-austria
As this federation uses IPsec for authentication, CableItsp1 decided to use a dedicated IP address 11.22.33.44 on its border proxy for dealing with the IPsec stuff. Thus, the domain cableitsp1.at.cableguysaustria.at (SIP URI domain + domain-suffix according to the federation policies) will resolve to 11.22.33.44. CableItsp1 configues the IPsec to use the shared secret of the federation and forbidds any SIP signalling from/to 11.22.33.44 without IPsec. The list of IP addresses of interconnect partners (members of this federation) will be downloaded once a day from the federations web server and the IPsec configuration will be updated accordingly.
In the openser call routing, inbound calls from this federation can be detected by:
if(dst_ip==11.22.33.44) {
log("message received via IPsec\n");
...
};
6.3.2 Federation voip-providers-international
This federation uses SIP over TCP over port 5080. Thus, CableItsp1 configures its border proxy to also listen on port 5080 for TCP, and adds the IP addresses of the peers to the IP access list on its firewall.
In the openser call routing, inbound calls from this federation can be detected by:
if( (dst_port==5080) && (proto==TCP) ) {
log("message received via TCP port 5080\n");
...
};
6.3.3 Federation voip-peering-austria
This federation uses TLS for authentication. CableItsp1 generated a certificate signing request (CSR) using the openssl tools. This CSR was signed by the voip-peering-austria CA. Then the border proxy was configured to listen on port 6666 for TLS and use the respective certificate and CA list:
listen=tls:10.10.0.41:6666
tls_server_domain[10.10.0.41:6666] {
tls_certificate = "/etc/certs/voip-peering-austria/cert.pem"
tls_private_key = "/etc/certs/voip-peering-austria/privkey.pem"
tls_ca_list = "/etc/certs/voip-peering-austria/cacert.pem"
tls_method=TLSv1
tls_verify_client = 1
tls_require_client_certificate = 1
}
In the openser call routing, inbound calls from this federation can be detected by:
if( (dst_port==6666) && (proto==TLS) ) {
log("message received via TLS on port 6666\n");
...
};
7. Configuring outbound routing
The call routing configuration for domainpolicy based routing is rather simple:
if (dp_can_connect()) { # check the domainpolicy of the destination
# apply domain policy
if (dp_apply_policy()) {
t_relay();
exit;
}
...
}
The configuration for the domainpolicy module is mainly entering the federation policy in the domainpolicy table.
The domainpolicy table consists of the following columns:
id: unique id
rule: Name of column containing the domain policy rule name which is equal to the URI as published in the domain policy NAPTRs (the federation identifier).
att: The override attribute. Name of column containing the AVP's name. If the rule stored in this row triggers, than dp_can_connect() will add an AVP with that name.
val: Value of the override attribute. Name of column containing the value for AVPs created by dp_can_connect().
comment: a description of these table entry
The id and comment table are not used by openser.
The following table shows the required domainpolicy table for the previously defined federations:
id rule type att val comment
1 http://www.voip-providers-international.com/peeringv1 fed portoverride 5080
2 http://www.voip-providers-international.com/peeringv1 fed transportoverride tcp
3 http://www.voip-peering-austria.at/TlsPeeringV1 fed tls_client_domain voip-peering-austria
4 http://www.voip-peering-austria.at/TlsPeeringV1 fed portoverride 6666
5 http://www.voip-peering-austria.at/TlsPeeringV1 fed transportoverride tls
6 http://www.cableguysaustria.at/peering-v1 fed transportoverride udp
7 http://www.cableguysaustria.at/peering-v1 fed sendsocket 11.22.33.44
Further, it requires the configuration of a TLS client domain and the AVPs for the domainpolicy module:
tls_client_domain["voip-peering-austria"] {
tls_certificate = "/etc/certs/voip-peering-austria/cert.pem"
tls_private_key = "/etc/certs/voip-peering-austria/privkey.pem"
tls_ca_list = "/etc/certs/voip-peering-austria/cacert.pem"
tls_method=TLSv1
tls_require_server_certificate = 1
}
modparam("domainpolicy", "port_override_avp", "portoverride")
modparam("domainpolicy", "transport_override_avp", "transportoverride")
modparam("domainpolicy", "domain_prefix_avp", "domainprefix")
modparam("domainpolicy", "domain_suffix_avp", "domainsuffix")
modparam("domainpolicy", "sendsocket_avp", "sendsocket")
Hi all,
I've read about the dialog module and the new "default_timeout" or
"timeout_avp" features. What i need to know it's if in case of
default_timeout or timeout by avp the calls are anyway accounted.
How are accounted the calls if dialog timeout expired?
thanks
:tele
Hello,
for those which haven't spotted yet, OpenSER dokuwiki site has been
updated. Lot of useful documentation was brought to light, the new index
should ease the browsing and let find quickly the relevant pages. Also,
the information is grouped now on namespaces, based on topics. We would
like to thank to all that contributed with examples, code snippets or
they shared the VoIP experiences there.
http://www.openser.org/dokuwiki/
Cheers,
Daniel
Hello,
the agenda is getting close to final version. I just want to preview the
content of the event, now with two weeks before the event.
I believe we manged to bring there in discussion most of the domains
VoIP could touch and hot topics nowadays. We cover from development to
business cases, from research to IMS, 3/4G. Next is a briefing of
agenda, as of today, although it may change a bit in the future.
The summit day (November 8) will start with introduction of special
guests and history of OpenSER. It will be followed by a set of heavy
subjects of VoIP: Application Server based on Java SipServlet
technology, geographic redundancy and VoIP on mobile network. VoIPUser
open VoIP services will then show their statistics and evolution over
the years, and how they become one of the biggest VoIP communities world
wide.
Noon break will allow to visit the exhibition and group chats for hot
discussions. Afternoon session will bring very interesting subjects:
safe peering; high availability; OpenSER IMS prototype; developing VoIP
applications; a look educational VoIP infrastructures - INRIA & SIP.edu
plus a walk through VoIP opportunities.
We end the day with what should be very entertaining: open discussion
about OpenSER future and roadmap. This is not all, there are other
special guests that can give you key notes about other topics and
products of VoIP.
As usual, details at:
http://www.openser.org/index.php?option=com_content&task=view&id=57&Itemid=…
More will come as the event approaches.
Cheers,
Daniel
Hello Users,
I don't Know What Happening in this Issues... Help me in this .
When Testing the X-lite Softphones, is not working. When I use the Sip
EyeMedia Softphone it Working Fine.
Is Problem in X-lite Configuration or Router(Firewall Gateway Keepers )
is blocking it...
Help me .
--
Thanks & Regards,
*Ravi Prakash Sunkara*
*M*:+91 9985077535*
O*:+91 40 23114549*
F*:+91 40 40208727
/*ravi.sunkara(a)hyperion-tech.com
www.hyperion-tech.com
*/
Hi,
I know that what I want to do is a bit odd but here is why:
When using Asterisk as PSTN gateway and using SIP INFO for DTMF digits,
there is a problem with devices not understanding SIP INFO. When Asterisk
sends out its INFO packet and gets back a negative reply, it stops bridging
and throws away the whole call. That is a really bad issue on Asterisk side,
but I just wanted to find a workaround.
So what I wanted to do is drop negative replies on INFO packets, so Asterisk
just retransmits them and does not get any feedback. Those INFO packets come
through my loose route and there I put the following little statement in
there:
if(method=="INFO" && src_ip == 10.0.0.1 ) {
xlog("L_NOTICE"," - INFO Request: %mb");
t_on_reply("7");
setflag(3);
};
With that answers jump into onreply_route[7]. This part works ok.
onreply_route[7] {
if (search("CSeq:[0-9 ]+INFO")) {
xlog("L_NOTICE"," - INFO Reply: %mb");
if(t_check_status("405")) {
xlog("L_NOTICE"," - Dropping INFO Reply");
drop();
}
}
}
This part does not work. I also tried creating a route just for dropping and
then jumpinng into this route from my reply_route, but then I also only have
the log line from that route, but drop does not work. I tried sl_send_reply,
t_release and other commands of which I thought they might be helpful. But
the "offending answer" is always transmitted to my gateway.
Does anybody have an idea how to just "throw away" reply packets?
Thanks in advance,
Sebastian