This issue is primarily a bug-fix issue. The format of the document has been changed to docbook in order to simplify maintainance by several authors, as well as to support auto-generation of html and Adobe Acrobat (pdf) formats of the document. NAT-handling has been improved with a test around RTP proxy enforcement to avoid doing it twice and the handling of an issue with ACKs (without Route header) when using this setup together with Asterisk . Also, the handling of loose routed messages has fixed a security issued where pre-setting a Route header pointing to the PSTN gateway would bypass authentication for INVITE and REFER messages.
Note that this issue is compatible with version 0.9.x of SER and is most likely NOT to work for the latest OpenSER
(but probably the 0.9.x of OpenSER). The next issue will be compatible with 0.10.x and new functionality from
this forth-coming release will be introduced.
Chapter 2. About This Document
This document will not tell you the basics about SIP, IP Telephony, how SER relates to other open source software,
and why you should use SER. We assume you have decided to use SER for your SIP-related needs, and you now
need to get up to speed on the concepts and how to realize most of the core functionality that SER can offer. This
document describes how to set up SER to function as a SIP Proxy, SIP Registrar and SIP Redirect Server. It is
based upon version 0.9.3 of SER and section 10 Appendix - How to download and configure the latest version of
tells you how to download this version and install.
This section covers the most important concepts that you must understand in order to get SER up and running and
start adapting it to your needs and that from experience many people have problems understanding. However, this
document is NOT a manual. The official SER manual can be found at http://www.iptel.org/ser/admin.html
All ser.cfg configuration files can be downloaded from http://www.onsip.org/ under the Downloads section. Onsip.
org has been started to facilitate a sharing community around SER and was initiated as part of the effort to
write the first version of this Getting Started document. Please register and become a contributor to the success of
SER!
NOTE: It is important to understand that SER is a SIP router. It only processes SIP messages. All other IP telephony functionality, such as voice mail, can only be implemented by using external applications.
Chapter 3. SER or OpenSER - A Brief Comparison
History of SER
SER was developed by a team of developers employed by Fraunhofer Fokus, a German research institute. The
iptel.org project was to build a website for Voice over IP information and a free Voice over IP service. SIP Express
Router (SER) was developed as a part of this effort, lead by Jiri Kuthan. SER was offered as open source (GNU
Public License, GPL) and the iptel.org website is still the entry point with SER information, as well as SIP tutorials
and other related resources (though now not very actively maintained).
As another result of the iptel.org project, Fraunhofer Fokus spun off iptelorg.com as a commercial venture to further
develop SER (for both open source and commercial purposes) and to offer services and software packages and
support based on the iptel.org projects developed code (which by the way are more than just SER. See http://
www.iptel.org/products/) Iptelorg.com got the main control and responsibility for developing SER, the open
source SIP server. Jiri Kuthan and Jan Janak (Chief Software Architect) are both a part of this group. Andrei
Pelinescu Onciul is another name that you can see on the serusers mailing list.
Some of the other former employees in the Fraunhofer iptel.org project launched another commercial SER-based
venture called Voice System (http://www.voice-system.ro/). Daniel-Constantin Mierla and Bogdan-Andrei Iancu
are two well-known names on the serusers mailing list
This is how those known as the core developers were split in two groups. However, they all participated in the
development of what we know as SER. In addition, other companies (like AG Projects responsible for mediaproxy)
and individual developers joinded the group of developers. At the time of writing this, SER has 25 registered developers.
OpenSER
On June 14, 2005, Voice System announced that they had created OpenSER. This is the reason stated on the
OpenSER website (http://www.openser.org/): The reason for this new venture is the lack of progressing and contributions
to the SER project from the other SER team members as well as the reticience to new contributions from
project's community members.
The Voice System SER developers felt that iptelorg.com, who made the final decisions on releases and code, had
failed to take in new code contributions and also been too slow in releasing new versions of SER. The announcement
made a stir on the serusers mailing list. The general feeling was that new features are good, it had been difficult
to get code into the code versioning system (CVS) due to slow response from developers who had to accept the
code, but most people felt that it would be easier for the community if both the stability and quality assurance
found in SER could be combined in the same project with the OpenSER goals.
SER and OpenSER development
We now know that both projects continued separately. What does it mean to us, the users? First of all, you need
to decide whether to go for SER or OpenSER. Deciding is based on knowledge, so first a few words about the organization
of SER and OpenSER developments.
Understanding naming of versions
SERs source code is hosted in a CVS at cvs.berlios.de. The versioning of SER has confused many. The reason is
that the versioning is based on CVS terminology. For example, the latest stable release of SER is 0.9.3, but in the
CVS, this stable release has the branch name rel_0_9_0. A branch can be named anything, for example
rel_stable_to_be. rel_0_9_0 means loosely "the branch that will be the next stable releasewith version 0.9.something".
A less confusing branch name would probably berel_0_9_x.
Once a branch has been created it has a life on its own and the developers can continue to develop the main code
branch, also called the HEAD or the trunk. This is important to know, because once a new branch has been created
and is destined to become a stable release, no new features will be added, only bugs will be fixed. Any new features
are added to the trunk. Currently, the trunk is also referred to as 0.10.x or 0.10.0 because the next main release
will be 0.10.something.
This means that even though you have downloaded a package of 0.9.3, the rel_0_9_0 branch in the CVS may later
be updated, but only with bug fixes. In order to get these bug fixes, you either have to download the code from
the CVS repository or you have to wait until a new updated package is created.
The source package called 0.9.3 at http://ONsip.org/ is a package with the source files from the stable branch
rel_0_9_0 at the date specified in the description field and in the README.ONSIP file. You can run the update_
from_cvs script to get the latest changes from CVS.We also update the package once in a while where this
update has been done.
If you are adventurous, you can download the trunk/head, but it can at times be impossible to compile, because
developers add new functionality that may break things they didn't foresee (even though it compiled on their machine,
other things may influence compilation). Also, added functionality may break other functionality, so even though
SER compiles, you may end up with problems with your ser.cfg because the developer haven't tested exactly that
scenario. These problems should be reported at http://bugs.sip-router.org [http://bugs.sip-router.org/]
When Voice System announced OpenSER, they took SER 0.9.3, added (backported) many of the features found
in the SER CVS trunk (0.10.x), and added additional features not found in SER CVS trunk. They called this release
OpenSER 0.9.4, which was the first OpenSER release. Since then, they have released OpenSER 0.9.5.
Compatibility now and in the future
Currently, OpenSER can use SER configuration files (ser.cfg), but not the other way around. This is because
OpenSER have added new commands and in some cases new syntax. Now, that sounds good. The safe bet would
be to go for OpenSER, right? Well, for now. The development and maintenance of SER and OpenSER can become
complex. First of all, the developers of OpenSER have stated that they will continue to contribute to the SER development
in addition to OpenSER. We still dont know what this means. Will all the OpenSER features be introduced
in SERs CVS? This means a lot of double work and other SER developers may have introduced features that are
not compatible with OpenSERs.
Also, it is highly likely that features found in OpenSER will find its way into SER. SERs developers may for some
technical reason decide to implement the feature in a different way. This means that the ser.cfg used for SER can
no longer be used by OpenSER.
Already, OpenSER has a different database format than SER. This means that migrating user data from one to
another can be a problematic task. These differences are likely to increase.
And finally, it seems that most of the developments that are done by SER developers are ported to OpenSER by
the OpenSER developers. At the time of writing this, OpenSER has six (6) registered developers, while SER has
25. Only time will show how interoperable the two projects will be.
As a side note: One of the authors of this document is the maintainer of a relatively new SER module called experimental.
This CVS module is currently only available in the trunk/HEAD and contains SER modules and code
that has not yet found its way into the CVS. The modules can thus be tried out and feedback gathered before they are introduced into the CVS trunk. The current modules are TLS support, SIP Path extension, and an Oracle database
back-end.
Choosing between SER and OpenSER
Many of you have probably skipped right to this section. Well, you can still read the above when you are finished
with this.
The table below has listed some criteria and how SER and OpenSER address each. You should find the criteria
important for you and decide based on that. Please contact gettingstarted@onsip.org
[mailto:gettingstarted@onsip.org] if you have other criteria you feel should be present.
ONsip.org Getting Started and SER vs OpenSER
Maintaining and further developing the Getting Started document and the corresponding configuration files is a
major undertaking. We simply do not have the capacity to track the differences between SER and OpenSER and update the documentation accordingly. Thus, the most rationale decision is to focus on SER only and just hope
that OpenSER will continue to be able to use SER configuration files
Chapter 4. Getting Started What is SIP and
how does it work?
SER Architecture and ser.cfg
Core and Modules
SER is built around a processing core that receives SIP messages and enables the basic functionality of handling
SIP messages. Most of SERs functionality is offered through its modules, much like the Apache web server. By
having a modular architecture, SER is able to have a core that is very small, fast, and stable. SER modules expose
functionality that can be utilized in the SER configuration file, ser.cfg. The ser.cfg configuration file controls which
modules shall be loaded and defines how the modules shall behave by setting module variables. You can think of
the ser.cfg file as the brains of the SIP router.
ser.cfgs Seven Sections
ser.cfg has seven main logical sections:
1. Global Definitions Section. This portion of ser.cfg usually contains the IP address and port to listen on, debug
level, etc. Settings in this section affect the SER daemon itself;
2. Modules Section. This section contains a list of external libraries that are needed to expose functionality not
provided by the core as noted above. These modules are shared object .so files and are loaded with the loadmodule
command;
3. Module Configuration Section. Many of the external libraries specified in the Modules Section need to have
parameters set for the module to function properly. These module parameters are set by use of the modparam
command, which takes this form: modparam(module_name, module_parameter, parameter_value)
4. Main Route Block. The main route block is analogous to a C programs main function. This is the entry point
of processing a SIP message and controls how each received message is handled;
5. Secondary Route Blocks. In addition to the main route block, ser.cfg may contain additional route blocks that
can be called from the main route block or from other secondary route blocks. A secondary route block is
analogous to a subroutine;
6. Reply Route Block. Optional reply route blocks may be utilized to handle replies to SIP messages. Most often
these are OK messages;
7. Failure Route Block. Optional failure route blocks may be used when special processing is needed to handle
failure conditions such as a busy or timeout;
It is important to understand the SIP protocol and the various types of messages that are used in SIP signalling.
Of course, by following the instructions in this document, you will get a working setup. However, before starting
to tweak and adapt to your needs, we recommend that you do yourself a favour and read up on SIP. Please refer
to http://www.iptel.org/ser/doc/sip_intro/sip_introduction.html as a good introduction. http://www.iptel.org/sip/siptutorial.
pdf provides more depth. The official SIP RFC can be found at http://www.ietf.org/rfc/rfc3261.txt for
those interested.
Transactions, Dialogs, and Session
In order to understand ser.cfg properly, you need to understand three SIP concepts:
1. SIP transaction: A SIP message (and any resends) and its direct (most often immediate) response (ex. User
agent sends REGISTER to SER and receives OK);
2. SIP dialog: A relationship between (at least) two SIP phones that exists for some time (ex. Dialog is established
with an INVITE message and ended by a BYE message);
3. Session: An actual media stream of audio between the SIP phones;
These concepts are hard to understand and you may want to revisit this section when you have read later sections
or studied the ser.cfg in this document. The concepts are used in the sections below to explain some things commonly
confused.
NOTE: If you look at a SIP message, you can identify messages in a particular SIP transaction by looking at the
Cseq number in the header. Each SIP dialog will have a Call-Id header (as well as one ID called a tag for each
peer in the dialog)
Understanding Message Processing in ser.cfg
You can think of ser.cfg as a script that is executed every time a new SIP message is received. For example, a user
agent (UA) (Johns SIP phone) wanting to INVITE another UA (Joans SIP phone) to a conversation (John makes
a call to Joan). John sends an INVITE SIP message to SER and ser.cfgs main route{} block will start at the top
and execute through the commands found there.
The processing continues until it reaches a point where processing is finished and a decision is made whether to
send the INVITE to Joan (using the t_relay() command), to send John a reply with an error (using sl_send_reply()),
or just drop the whole INVITE (by reaching the end of the main route or break;), which, of course, is not recommended.
Joan will answer the INVITE with an OK message. The OK is a direct response to the initial INVITE and this
message is handled by the last section in an on_reply_route[x]. If Joan didnt respond, or responded with an error
(busy, etc), the failure_route[x] is called.
Finally, John will send an ACK to tell Joan that everything was received and accepted.
NOTE 1: The described behaviour is dependent on using t_relay() in ser.cfg. Your SER is then said to be transaction
stateful (see also next section)
NOTE 2: An INVITE dialogue also includes provisional responses (trying, your call is important to us) before the
OK, but we will not concern ourselves with these for simplicity.
So, how is all this handled in ser.cfg? All SIP messages starting a new SIP transaction will enter the top of the
main route{}. In the above, Johns INVITE starts a transaction that is answered with OK from Joan.
You have a lot of freedom in how SIP messages are handled in ser.cfg. For example, to record that Joan is online,
you use the save(location) function for all REGISTER messages from Joans IP phone. A call to lookup(location)
will retrieve where Joans IP phone can be found so that that a call can be made. Also, very limited info about Joans
phone can be stored in the form of flags using the setflags() function. (From version 0.9.0 there is also support for
attribute-value pairs that can be loaded/stored for a given subscriber, but more on this later).
The consequence of ser.cfg as a routing logic script is that you have to make sure that each SIP message type is
handled correctly (flows through the script in a correct fashion) and that each possible response in a transaction is
appropriately handled by reply or failure routes to realize what you want (forward on busy etc). This can be quite
complex and opens up for many possible errors. Especially when changes to ser.cfg easily affect more than the
messages you intended to target. This is usually the root cause of SER administrators that question whether SER
is RFC3261 compliant or not. SER is RFC3261 compliant from point of view of can it properly process any particular
SIP message, however any seemingly harmless error in ser.cfg can have dramatic impact on the SIP router
and cause SER to deviate from RFC3261 compliance.
This document presents a reference design with a corresponding ser.cfg to enable you to quickly set up SER to do
what most people would like SER to do.
Stateful vs. stateless
An often misunderstood concept is stateful vs. stateless processing. The description of the INVITE SIP transaction
above is an example of stateful processing. This means that SER will know that the OK belongs to the initial INVITE
and you will be able to handle the OK in an onreply_route[x] block. With stateless processing (or simply forwarding),
each message in the dialogue is handled with no context. Stateless forwarding is used for simple processing of SIP
messages like load distribution.
In order to implement any advanced functionality like call accounting, forward on busy, voicemail, and other
functionality in this documents reference setup, you will need to use stateful processing. Each SIP transaction will
be kept in SERs memory so that any replies, failures, or retransmissions can be recognized. One consequence is
that when using t_relay() for a SIP message, SER will recognize if a new INVITE message is a resend and will
act accordingly. If stateless processing is used, the resent INVITE will just be forwarded as if it was the first.
The confusion arises because this stateful processing is per SIP transaction, not per SIP dialog (or an actual phone
call)! A phone call (SIP dialog) consists of several transactions, and SER does not keep information about transactions
throughout a particular phone call. The consequence is that SER cannot terminate an on-going call (it doesnt
know that the call is on-going), nor can SER calculate the length of an ended call (accounting). However, SER
can store when an INVITE (or ACK) and a BYE message are received and record this info together with the Call-
Id. A billing application can then match the INVITE with the BYE and calculate the length of the call.
Understanding SIP and RTP
In order to understand the subsequent sections, you must understand a few things about SIP and RTP. First of all,
SIP is a signalling protocol handling the call control like inviting to a call, cancel (hang up while ringing), hanging
up after ended call and so on. SIP messaging can be done directly from user agent to user agent, but often a SIP
server is needed for one user agent to find another.
When a SIP server like SER receives a message, it can decide that it wants to stay in the loop or not. If not, SER
will provide the user agents with the information they need to contact each other and then SIP messages will go
directly between the two user agents.
If SER wants to stay in the loop, for example to make sure that a BYE message is received for accounting, SER
must insert a Route header in the SIP message (using the record_route() function) to tell everybody that it wants
to participate. In order for this to work, SER and potentially other SIP servers who participate must do what is
called loose routing. A bit simplified, it means that SIP messages should not be sent directly to the user agent, but
rather indirectly via all who have put a Route header in the SIP message (to check for such a recorded route, the
loose_route() function is used).
SIP can also include additional information, for example related to how to set up a call with an audio or video
stream (called SDP, Session Description Protocol). The SDP information will result in one or more RTP streams
(or sessions) to be set up, normally directly between the two user agents. SER will NEVER participate in the RTP
stream. RTP streams are by nature bandwidth and processing intensive. However, as we will describe later, SER
can make sure that a third party application like a B2BUA or RTP Proxy can become the middle man.
Finally, the Real-Time Control Protocol (RTCP) communicates information about the RTP streams between the
user agents (RTCP will either use the specified RTP port + 1 or the port indicated in the SDP message).
Back-end applications and B2BUA
We
But, if you want to play a voice prompt saying that the user is not available or provide voicemail capabilities, you
will need something that can act as a user agent and be a peer in a SIP dialog, so that a session is actually set up
between the calling user agent and that something playing the voice prompt. Modules or third party applications
can provide this back-end user agent functionality, and SER will be in the middle. Again, SER is used in its
stateful processing to enable these back-end applications.
NOTE: To add to the confusion, when SER is used in stateful processing to enable back-end user agent functionality,
it is said to act as a stateful user agent server.
Also, if you want to implement a pre-paid service, you have a problem because SER cannot terminate the call
when no money is left! In this scenario you need a third party in the SIP dialog (and quite possibly in the session).
This third party will act as the middle man both in the SIP messages and in the audio. Thus, each user agent will
only talk to the middle man and not know about the remote user agent. This middle man is what you probably
have seen referenced as a B2BUA (Back-to-Back User Agent) on the serusers mailing list. A B2BUA can handle
SIP messaging only or both SIP and RTP.
NAT, STUN, and RTP proxy
One of the things causing the most problems is one-way audio or no audio when dealing with user agents behind
NAT devices that attempt to communicate with user agents on the public internet or behind a different NAT device.
These NAT devices can be ADSL routers, firewalls, wireless LAN routers, etc. In order to understand NAT and
RTP proxying, you must understand what happens when a user agent registers with a SIP Registrar and when a
call is made.
In the following sections, functions from the nathelper module will be used as examples. Mediaproxy will be
covered later in this document.
NOTE: SER has two different offerings for dealing with NAT and RTP proxying, namely rtpproxy and mediaproxy.
These two solutions work independently of each other and are covered else where in this document. Much confusion
has been caused by these two NAT solutions. Also, the nathelper module noted above is generally considered part
of the rtpproxy solution, although you can use its exposed functions with mediaproxy.
Registration behind NAT
When a user agent contacts SER with a REGISTER message, the user agent will only see its private IP address
behind the NAT (ex. 192.0.2.13). Thus, it will believe that the correct contact information is myself@192.0.2.13
[mailto:myself@192.168.1.13]:5060 and will include that in the REGISTER message (port 5060 is assumed to be
the port the user agent is listening on). Of course, nobody can reach myself@192.0.2.13
[mailto:myself@192.168.1.13]:5060 on the Internet as this address is valid only behind the users NAT device.
SER will receive a REGISTER message from a.b.c.d:f where a.b.c.d is the public IP address of the NAT and f is
the to port allocated by the NAT to this communication just initiated. SER will be able to respond to a.b.c.d:f and
reach the user agent and must therefore register this address instead of the one presented by the user agent. Nathelpers
function for testing if the user agent is behind NAT is called nat_uac_test(). A parameter can be specified to indicate
which tests should be done. We recommend using 19 (all tests). A description of the various tests is beyond the
scope of this document.
Also, SER must record whether the user agent is behind NAT in order to properly process later messages. This is
done by setting a flag for the UA using the setflag() function. This flag will be available for testing for both caller
and callee.
Nathelper provides the fix_nated_contact() function for re-writing the Contact header. This action is not strictly
according to the RFC, so nathelper (>0.9.0) has another function fix_nated_register() that will only register the
correct address and port without rewriting the Contact header.
NOTE: Section 10.3 of RFC3261 says you must not alter the contact header while processing REGISTER messages,
therefore, you should never use fix_nated_contact() while processing REGISTER requests. Instead, always use
fix_nated_register() and use fix_nated_contact() for all other message types.
Also, the core function force_rport() is often used for all NATed messages to ensure that the Via headers (used
for matching transactions etc) include the remote port number. This way the response in the transaction is sent
back to the correct port. This only works for clients that support symmetric signalling (listen on the same port as
they send). However, most clients are now symmetric.
An extra problem is that the NAT device will only reserve port f for a certain time, so if nothing more happens,
the NAT will close the port and ser will not be able to contact the user agent. This is solved by either the user agent
sending regular messages to SER or SER must send regular messages to a.b.c.d:f (keep-alive).
INVITEs behind NAT
When an INVITE message is sent from a user agent, it will contain an SDP (Session Description Protocol) payload
(read attachment or content). This payload describes various things about the user agent, ex. what type of sessions
it supports, and where the party being called can reach the caller. As above, this information will for example be
192.0.2.13:23767. 23767 is the port the user agent has allocated and where it will listen for the actual sound (Real
Time Protocol/RTP) for the session. At the time of the INVITE, there is no corresponding port on the NAT (as no
RTP has yet been sent). The related SDP lines in the INVITE would look like this (c=contact, m=media):
c=IN IP4 192.0.2.13
m=audio 23767 RTP/AVP 0 101.
In addition, the contact information will, as for the REGISTER message, be wrong. SER must change the contact
information to the public address a.b.c.d:f as for the REGISTER message. With nathelper, this is done by calling
fix_nated_contact(). Other transaction-starting messages like ACK, CANCEL, and BYE should also have the
contact header fixed.
For the audio, SER can only do three things with the INVITE before forwarding to the user agent being called:
1. Add an SDP command direction:active to the SDP content
2. Change the c= line to a.b.c.d
3. Force RTP to go through a proxy by changing the c-line to c=IN IP4 address-of-proxy and the m-line to
m=audio port-on-proxy RTP/AVP 0 101.
#1 is a way to tell the called user agent that it should wait until it receives audio and then just assume that it should
send its own audio back to the same address (this is called symmetric RTP). This only works for user agents with
a public IP or with a known RTP port on the NAT (for example by using STUN). If both are behind NAT, both
will wait for the other to start and nothing will happen. However, this can be a good method for PSTN gateways
with public addresses. You do this with nathelper by calling fix_nated_sdp("1").
#2 is basically the same as #1, but the called user agent gets some more information. You can do this with nathelper
by calling fix_nated_sdp("2"). You can do both #1 and #2 at the same time by specifying 3.
#3 means that you need to set up a separate daemon called an RTP proxy (with a public IP address) that both user
agents can send their audio to. You thus add an extra step (which can add latency in the audio) and for each call
you need to handle 2 x required bandwidth for the codec the user agents are using (ex. 88 Kbps for G.711). With
nathelper, you call force_rtp_proxy().
Please note that the calling user agent can have a public IP address, while the called user agent is behind a NAT.
The OK returned by the called user agent will have to be manipulated as above and thus NAT handling code must
also be included in the onreply_route[x] part of ser.cfg. The called user agent also has the flag set as described in
the REGISTER section above (setflag). So, in the onreply route one can check whether the called user agent is
behind NAT. If so, the contact header should be changed and (if desired) RTP proxying enforced.
STUN
Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs) also known
as STUN…
STUN is a protocol for the user agent to discover its own public IP address. You will need to install a STUN
server (not part of SER). The user agent will then try to change the contact and SDP information itself. When
STUN is used by a user agent, SER does not have to do any rewriting as described in previous section. The exception
is when a user agent is behind a symmetric NAT (the different types of NAT is beyond the scope of this document).
In this situation the user agent should NOT try to rewrite as the STUN protocol will provide the wrong port. SER
can then be used to rewrite contact and SDP information for these situations. For outgoing calls from a symmetric
NAT, the direction:active rewrite can be used, but calls between user agents behind symmetric NATs must always
be handled with an RTP Proxy server.
WARNING: Some user agents have faulty implementations of STUN. If STUN then has a wrong conclusion, you
may end up with one-way audio (or no audio) or calls that are disconnected. Some situations can actually be detected
by SERs NAT detection tests (by comparing the senders source address/port with the contact header in the INVITE,
nathelper test flag 16), but it is recommended to test new user agents in different NAT scenarios to make sure that
a combined.
Other non-ser NAT traversal techniques
Some NATs and firewalls have a built-in SIP Traversal mechanism, such as Cisco 3600 routers with IOS version
12.3(9). Such a capability is often referred to as an Application Level Gateway (ALG). A SIP ALG will rewrite
all SIP messages transparently (both ways). If this is done correctly, both the user agent and SER will be happy.
If not, nobody is happy and you either have to turn off the ALG in the router or you have to use SER on another
SIP port (like 5065). However, you will then get other NAT-related problems. The fix-faulty-ALG-problem is not
really possible to do in SER 0.9.0, but the next version will introduce new features designed to address this issue.
A second variant is Session Border Controllers (SBC). These are difficult to define as a group as they can do many
things, but most often they will act as a full B2BUA (terminate the SIP and RTP sessions for both user agents so
that both only see the SBC). SBCs are most often used by service providers to control the edge of their networks.
URI, R-URI, and Branches
The URI, Uniform Resource Identifier, is used to identify a user uniquely. The URI is used as an address when
INVITEing a party to a call. A typical SIP URI is in the form sip:username@domain.com. The original URI found
in the first line of a SIP message is called the request-URI (R-URI). This uri can be referred to in ser.cfg using uri
(ex. if(uri=~sip:username@.*) )
The uri can be manipulated throughout ser.cfg using many different functions from different modules. For example,
lookup(location) will take the uri as changed through uri manipulations, look it up in the location database and
rewrite the uri to the correct contact information (including @ipaddress:port). When t_relay() is called, the URI
in it final form after transformations will be used as the target URI.
Some functions, like lookup(location) can append branches to the target set of URIs. This means that when t_relay()
is called, the INVITE message will be duplicated to all the URIs in the target set. Note that the uri command will
still refer to the request-URI in its (potentially) transformed form. The core command revert_uri() will replace the
current target URI back to the original request-URI.
NOTE: A backported version of xlog (to 0.9.x) has new parameters that can be used to print the full target set. The
backported version can be found on http://www.onsip.org/
Chapter 5. Reference Design
This document will help you understand how SER can be configured for a number of network designs and functional
examples. We will start with a very simple hello world example and then build up to a complex network
with both SER and Asterisk servers together with firewalls and NAT routers.
To help give you an idea of the type of network we will eventually cover and therefore understand the power and
flexibility of SER, the diagram below shows our complete reference design.
But first let us start with our hello world design. Based upon our reference design, we will just take a standalone
LAN segment that has a single SIP server together with a few SIP phones. .
The area in orange highlights this Hello World design and we will show how to configure SER to perform the
following functions:
1. Registration of devices ( UAs ) to the sip server without any authentication
2. Establishment of a sip to sip call using INVITE messages
Chapter 6. Hello World ser.cfg
It is a very good idea to start SER with a basic Hello World ser.cfg to ensure that the SIP server is working.
What this ser.cfg will do:
1. Establish a SIP server on your internal LAN
2. Allow you to connect IP phones on your internal LAN to SER
3. Make calls between the IP phones on the LAN
What this ser.cfg will NOT do:
1. There is no authentication for the IP telephones nor any database support. These will be added later.
2. there is no support for PSTN, the phones connected to the LAN can only communicate between themselves.
ser.cfg Listing
Listed below is the Hello Word configuration to support the simple configuration above. You can download a
version of this file from www.ONsip.org [http://www.ONsip.org/]. A detailed analysis of this ser.cfg follows the
example.
debug=3
fork=no
log_stderror=yes
listen=192.0.2.13 # INSERT YOUR IP ADDRESS HERE
port=5060
children=4
Hello World ser.cfg Analysis
Now that you have seen our 'Hello World' SIP proxy configuration, we'll explain each line in the file so that you
can begin to understand the basics of SER.
This configuration is a complete, albeit, minimal SIP router. SIP clients can register with the SIP proxy and can
call other registered users. This configuration however is far from complete in terms of functionality. For one
thing, if the SIP proxy is restarted then all client registration information is lost because there was no mechanism
for persisting registration information to disk. Call features are also absent as well as NAT traversal and voice
mail. But don't worry as we will cover all these topics later on. For now, lets just concentrate on a bare bones SIP
router.
1. SER has debug information that can be enabled or suppressed using the debug directive. A nominal value of
3 is usually specified to obtain enough debug information when errors occur. The debug directive specifies
how much information to write to syslog. The higher the number, the more verbose SER becomes. The most
verbose debug level is 9. When the debug level is set higher than 3 SER becomes very verbose and the start
up time can take a bit longer.
2. The fork directive tells the SER daemon to run in the foreground or the background. When you are ready to
operate SER as a system service, you must set this directive to yes. For now we will just operate SER as a
foreground process.
NOTE: See the appendix for a SER init.d start script
3. Since we are running SER as a foreground process we must set the log_stderror directive equal to yes in order
to see the output
4. The listen directive instructs SER to listen for SIP traffic on a specific IP address. Your server must physically
listen on the IP address you enter here. If you omit this directive then SER will listen on all interfaces.
NOTE: When you start SER, it will report all the interfaces that it is listening on.
5. In addition to specifying the IP address to listen on you can also specify a port. The default port used on most
SIP routers is 5060. If you omit this directive then SER assumes port 5060.
6. The children directive tells SER how many processes to spawn upon server start up. A good number here is
4, however, in a production environment you may need to increase this number.
7. These lines are really to prevent SER from attempting to lookup its IP address in DNS. By adding these two
lines to ser.cfg we suppress any warnings if your IP is not in your DNS server.
8. The fifo directive specifies the location of the SER FIFO. The FIFO is sort of like the Linux proc file system
and can be used to examine the current SIP proxy activity. The FIFO can also be used if you want to inject
a new SIP message directly in to the SIP proxy with an external application. A good example of this is the
serctl utility that is usually located in /usr/local/sbin/. With this utility you can manage users, ping SIP URIs,
and even email a SIP user. Serctl does all of this internally using the FIFO.
9. The FIFO can be located just about anywhere on disk, however, the user account that SER runs under must
be able to create the FIFO in the specified directory.
Here we have external modules that are necessary for our 'hello world' SIP proxy to function. SER modules
may be located anywhere on the disk system, but /usr/local/lib/ser/modules is the default location. Loading
a module is as simple as specifying in a loadmodule directive as shown.
If you're wondering how you know which module or modules you need, well there is no clear cut way to
know. In general the modules shown here will be needed by every SIP proxy configuration. When you need
to add additional functionality, such as MySQL connectivity, then you will load the appropriate module, in
this case the mysql.so module.
All SER modules are distributed with the source code and located at /modules. Every SER
module has a README file that explains all the items that it exposes for use in a ser.cfg file. It is highly recommended
that you spend some time familiarizing your self with the available SER modules. This document
makes a valid attempt at explaining the most important SER modules and how to use them, but there is no
substitute for reading the actual module README files.
10. Some modules have parameters that need to be set in ser.cfg in order for the module to function properly.
Other modules, however, operate normally in most cases without any parameter adjustments. The next section
will show our 'hello world' requirements.
The usrloc module is responsible for keeping track of SIP client registration locations. In other words, when
a SIP client registers with the SIP proxy, SER will store the contact information, also known as the Address
Of Record (AOR), in a table. This table is then queried when another SIP client makes a call. The location
of this table can vary depending on the value of the usrloc db_mode parameter.
Our SIP proxy sets db_mode to zero to indicate that we do not want to persist registration data to a database.
Instead we will only store this information in memory.
We will show how to persist AORs in a later example.
11 The rr parameter called enable_full_lr is really a work-around for older SIP clients that don't properly handle
SIP record-route headers. SIP RFC3261 says that specifying loose routing by including a ;lr in the recordroute
header is the correct way to tell other SIP proxies that our SIP proxy is a loose router. However, some
older and/or broken SIP clients incorrectly dropped the ;lr tag because it didn't have value associated with it
(ie, lr=true).
12. Therefore, by setting enable_full_lr to one, SER will write all ;lr tags as ;lr=on to avoid this problem.
This is the beginning of the SIP processing logic. This line defines the main route block. A route block must
have a beginning and ending curly bracket.
The main route block is where all received SIP messages are sent. From the main route block you can call
other route blocks, test the message for certain conditions, reject the message, relay the message, and basically
do anything you need to fit your business needs.
Here is a main overview of what happens:
1. A message enters the main route and we do some checks
2. We determine if the message is for us, if not we just send it to where it belongs (route[1])
3. If its for us, we explicitly handle REGISTER messages (a message from a phone asking to register itself).
Route[2] handles REGISTERs by saving where we can reach the phone, while route[1] is a default
handler for all other messages.
NOTE: It may appear odd to present such simple functionality this way, but we will use this structure as the
basis for a much more complex ser.cfg which is presented step-by-step in following sections.
13 The details are below.
mf_process_maxfwd_header is a safety check that you should always include as the first line of your main
route block. This function is exposed in the mf.so module and is used to keep track of how many times a SIP
message has passed through SER. Erroneous ser.cfg files can send a SIP message to the wrong location and
cause looping conditions. Also other SIP proxies that SER interacts with can do the same thing.
14. The basic rule here is that if this function ever returns 'true' then you need to stop processing the problematic
message to avoid endless looping.
If a looping situation is detected then SER needs a way to tell the SIP client that an error has occurred. The
sl_send_reply() function performs this job. sl_send_reply() is exposed in the sl.so module and all it does is
sends a stateless message to the SIP client. This means that SER will send the message and forget about it.
It will not try to resend if it does not reach the recipient or expect a reply.
15. You can specify an appropriate error message as shown. The error message can only selected by the defined
SIP error codes and messages. Many IP phones will show the text message to the user.
The break statement tells SER to stop processing the SIP message and exit from the route block that it is
currently executing. Since we are calling break in the main route block, SER will completely stop processing
the current message.
16. msg:len is a core SER function that returns the length in bytes of the current SIP message. This, like
mf_process_maxfwd_header() should be called at the beginning of the main route block in all ser.cfg files.
17. This statement simply tests the length of the SIP message against the maximum length allowed. If the SIP
message is too large, then we stop processing because a potential buffer overflow has been detected.
Here we look to see if the SIP message that was received is a REGISTER message. If it is not a register
message then we must record-route the message to ensure that upstream and/or downstream SIP proxies that
we may interact with keep our SIP proxy informed of all SIP state changes. By doing so, we can be certain
that SER has a chance to process all SIP messages for the conversation.
18. The keyword 'method' is provided by the SER core and allows you to find out what type of SIP message you
are dealing with.
The record_route() function simply adds a Record-Route header field to the current SIP message. The inserted
field will be inserted before any other Record-Route headers that may already be present in the SIP message.
Other SIP servers or clients will use this header to know where to send an answer or a new message in a SIP
dialog.
In all ser.cfg files you should call loose_route() after the record_route() function.
This is the basic definition of loose routing. Refer to RFC3261 for a complete explanation of loose routing.
Note for interested readers:
# RFC3261 states that a SIP proxy is said to be "loose routing" if it
# follows the procedures defined in this specification for processing of
# request (present in the Request-URI) from the set of proxies that need to
# be visited along the way (present in the Route header field). A proxy
# compliant to these mechanisms is also known as a "loose router".
#
# SER is a loose router, therefore you do not need to do anything aside
# from calling loose_route() in order to implement this functionality.
#
# A note on SIP message dialogs (contributed by Jan Janak):
#When it comes to SIP messages, you can classify them as those that
#create a dialog and those that are within a dialog. A message within
#a dialog (ACK, BYE, NOTIFY) typically requires no processing on the
#right after loose_route function.
#
#Messages creating dialogs can be further classified as those that
#belong to the server (they have the domain or IP of the server in
#the Request-URI) and those that do not. Messages that do not have a
#domain or IP of the proxy in the Request-URI should be immediately
Download Information
Worldwide voip billing solution provider since 1999
Address: 850 Ives Dairy Rd., Ste. T/57-320 - Miami, FL 33179 - United States
Tel: +1.305.655.0311 - +1-305-655-1605
E-mail: info@cyneric.com