|
@@ -24,6 +24,12 @@
|
|
|
<!ENTITY install SYSTEM "../../INSTALL">
|
|
|
<!ENTITY voicemail SYSTEM "voicemail.sgml">
|
|
|
<!ENTITY voicemailcfg SYSTEM "../../modules/vm/etc/ser.cfg">
|
|
|
+<!ENTITY intro SYSTEM "intro.sgml">
|
|
|
+<!ENTITY operation SYSTEM "operation.sgml">
|
|
|
+<!ENTITY apps SYSTEM "apps.sgml">
|
|
|
+<!ENTITY reference SYSTEM "reference.sgml">
|
|
|
+<!ENTITY general SYSTEM "general.sgml">
|
|
|
+<!ENTITY otherapps SYSTEM "otherapps.sgml">
|
|
|
|
|
|
|
|
|
|
|
@@ -35,23 +41,23 @@
|
|
|
<?dbhtml filename="index.html">
|
|
|
|
|
|
|
|
|
- <title>iptel.org SIP Express Router v0.9.0 -- Admin's Guide</title>
|
|
|
+ <title>iptel.org SIP Express Router v0.11.0 -- Admin's Guide</title>
|
|
|
<bookinfo>
|
|
|
<authorgroup>
|
|
|
<author>
|
|
|
<firstname>Jiri</firstname>
|
|
|
<surname>Kuthan</surname>
|
|
|
- <email>[email protected]</email>
|
|
|
+ <!-- <email>[email protected]</email> -->
|
|
|
</author>
|
|
|
<author>
|
|
|
<firstname>Jan</firstname>
|
|
|
<surname>Janak</surname>
|
|
|
- <email>[email protected]</email>
|
|
|
+ <!-- <email>[email protected]</email> -->
|
|
|
</author>
|
|
|
<author>
|
|
|
<firstname>Yacine</firstname>
|
|
|
<surname>Rebahi</surname>
|
|
|
- <email>[email protected]</email>
|
|
|
+ <!-- <email>[email protected]</email> -->
|
|
|
</author>
|
|
|
|
|
|
</authorgroup>
|
|
@@ -106,5700 +112,19 @@
|
|
|
</bookinfo>
|
|
|
|
|
|
<toc></toc>
|
|
|
-
|
|
|
- <chapter id="general">
|
|
|
- <title>General Information</title>
|
|
|
- <section id="aboutser">
|
|
|
- <title>About <acronym>SIP</acronym> Express Router (<acronym>SER</acronym>)</title>
|
|
|
- <para>
|
|
|
- SIP Express Router (<acronym>SER</acronym>) is an industrial-strength, free VoIP
|
|
|
- server based on the Session Initiation Protocol (<acronym>SIP</acronym>, RFC3261).
|
|
|
- It is engineered to power <acronym>IP</acronym> telephony infrastructures up to large
|
|
|
- scale. The server keeps track of users, sets up VoIP sessions,
|
|
|
- relays instant messages and creates space for new plug-in applications.
|
|
|
- Its proven interoperability guarantees seamless integration with
|
|
|
- components from other vendors, eliminating the risk of a single-vendor
|
|
|
- trap. It has successfully participated in various interoperability
|
|
|
- tests in which it worked with the products of other leading <acronym>SIP</acronym> vendors.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The <acronym>SIP</acronym> Express Router enables a flexible plug-in model for new
|
|
|
- applications: Third parties can easily link their plug-ins with
|
|
|
- the server code and provide thereby advanced and customized services.
|
|
|
- In this way, plug-ins such as <acronym>SNMP</acronym> support, RADIUS accounting,
|
|
|
- or SMS gateway have already been developed and are provided as
|
|
|
- advanced features. Other modules are underway: Presence server,
|
|
|
- firewall control, and more.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Its performance and robustness allows it to serve millions of users
|
|
|
- and accommodate needs of very large operators. With a $3000 dual-CPU PC, the
|
|
|
- <acronym>SIP</acronym> Express Router is able to power <acronym>IP</acronym> telephony services in an area
|
|
|
- as large as the Bay Area during peak hours. Even on an IPAQ <acronym>PDA</acronym>, the server
|
|
|
- withstands 150 calls per second (<acronym>CPS</acronym>)! The server has been powering our
|
|
|
- iptel.org free <acronym>SIP</acronym> site withstanding heavy daily load that is further
|
|
|
- increasing with the popularity of Microsoft's Windows Messenger.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The <acronym>SIP</acronym> Express Router is extremely configurable to allow the creation of
|
|
|
- various routing and admission policies as well as setting up new and
|
|
|
- customized services. Its configurability allows it to serve many roles:
|
|
|
- network security barrier, application server, or <acronym>PSTN</acronym> gateway guard for
|
|
|
- example.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> can be also
|
|
|
- used with contributed applications. Currently,
|
|
|
- <application moreinfo="none">serweb</application>, a
|
|
|
- <application moreinfo="none">ser</application> web interface,
|
|
|
- and <application moreinfo="none">SIPSak</application>
|
|
|
- diagnostic tool are available. Visit our site,
|
|
|
- <ulink url="http://www.iptel.org/">http://www.iptel.org/</ulink>,
|
|
|
- for more information on contributed packages.
|
|
|
- </para>
|
|
|
- </section>
|
|
|
-
|
|
|
- <section id="aboutiptel">
|
|
|
- <title>About iptel.org</title>
|
|
|
- <para>
|
|
|
- iptel.org is a know-how company spun off from Germany's national
|
|
|
- research company FhG Fokus. One of the first <acronym>SIP</acronym> implementations ever,
|
|
|
- low-QoS enhancements, interoperability tests and VoIP-capable firewall
|
|
|
- control concepts are examples of well-known FhG's work.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- iptel.org continues to keep this know-how leadership in <acronym>SIP</acronym>.
|
|
|
- The access rate of the company's site, a well-known source of
|
|
|
- technological information, is a best proof of interest. Thousands
|
|
|
- of hits come every day from the whole Internet.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The iptel.org site, powered by SER, offers SIP services on the public
|
|
|
- Internet. Feel free to apply for a free SIP account at
|
|
|
- <ulink url="http://www.iptel.org/user/">http://www.iptel.org/user/
|
|
|
- </ulink>
|
|
|
- </para>
|
|
|
-
|
|
|
-
|
|
|
- </section> <!-- iptel -->
|
|
|
- <section id="serfeatures">
|
|
|
- <title>Feature List</title>
|
|
|
- <para>
|
|
|
- Based on the latest standards, the <acronym>SIP</acronym> Express Router (<acronym>SER</acronym>) includes
|
|
|
- support for registrar, proxy and redirect mode. Further it acts as
|
|
|
- an application server with support for instant messaging and
|
|
|
- presence including a <acronym>2G/SMS</acronym> and Jabber gateway, a call control policy
|
|
|
- language, call number translation, private dial plans and accounting,
|
|
|
- authorization and authentication (<acronym>AAA</acronym>) services. <application>SER</application> runs on Sun/Solaris,
|
|
|
- PC/Linux, PC/BSD, IPAQ/Linux platforms and supports both <acronym>IPv4</acronym> and <acronym>IPv6</acronym>.
|
|
|
- Hosting multiple domains and database redundancy is supported.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Other extensions are underway: presence server, firewall control and more.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application>ser</application> has been carefully engineered with the following
|
|
|
- design objectives in mind:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Speed</emphasis> - With <application>ser</application>,
|
|
|
- thousands of calls per seconds are achievable
|
|
|
- even on low-cost platforms. This competitive capacity allows
|
|
|
- setting up networks which are inexpensive and easy to manage
|
|
|
- due to low number of devices required. The processing capacity
|
|
|
- makes dealing with many stress factors easier. The stress
|
|
|
- factors may include but are not limited to broken configurations and implementations,
|
|
|
- boot avalanches on power-up, high-traffic applications such as presence,
|
|
|
- redundancy replications and denial-of-service attacks.
|
|
|
- </para>
|
|
|
- <para> The speed has been achieved by extensive code optimization, use of customized code,
|
|
|
- <acronym>ANSI C</acronym> combined with assembly instructions and leveraging latest
|
|
|
- <acronym>SIP</acronym> improvements. When powered by a dual-CPU Linux PC,
|
|
|
- <application>ser</application> is able to process thousands of calls per second,
|
|
|
- capacity needed to serve call signaling demands of Bay Area population.
|
|
|
-
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Flexibility</emphasis> - <application>SER</application> allows its users
|
|
|
- to define its behavior.
|
|
|
- Administrators may write textual scripts which determine <acronym>SIP</acronym> routing
|
|
|
- decisions, the main job of a proxy server. They may use the script to
|
|
|
- configure numerous parameters and introduce additional logic. For example,
|
|
|
- the scripts can determine for which destinations record routing should be
|
|
|
- performed, who will be authenticated, which transactions should be processed
|
|
|
- statefully, which requests will be proxied or redirected, etc.
|
|
|
- </para>
|
|
|
-
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Extensibility</emphasis> - <application>SER</application>'s extensibility allows linking of
|
|
|
- new C code to ser to
|
|
|
- redefine or extend its logic. The new code can be developed independently
|
|
|
- on <application>SER</application> core and linked to it in run-time. The concept is similar to
|
|
|
- the module concept known for example in Apache Web server. Even such essential parts such
|
|
|
- as transaction management have been developed as modules to keep the <application>SER</application> core
|
|
|
- compact and fast.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- Portability.
|
|
|
- </emphasis>
|
|
|
- <application>ser</application> has been written in ANSI C. It has been extensively tested
|
|
|
- on PC/Linux and Sun/Solaris. Ports to BSD and IPAQ/Linux exist.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- Interoperability.
|
|
|
- </emphasis>
|
|
|
- <application>ser</application> is based on the open <acronym>SIP</acronym> standard.
|
|
|
- It has undergone extensive tests with products of other vendors both in iptel.org
|
|
|
- labs and in the SIP Interoperability Tests (SIPIT). <application>ser</application>
|
|
|
- powers the public iptel.org site 24 hours a day, 356 days a year
|
|
|
- serving numerous SIP implementations using this site.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Small size.</emphasis>
|
|
|
- Footprint of the core is 300k, add-on modules take up to 630k.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- </section> <!-- serfeatures -->
|
|
|
-
|
|
|
- <section id="usecases">
|
|
|
- <title>Use Cases</title>
|
|
|
- <para>
|
|
|
- This section illustrates the most frequent uses of SIP. In all these scenarios,
|
|
|
- the SIP Express Router (SER) can be easily deployed as the glue connecting all
|
|
|
- SIP components together, be it soft-phones, hard-phones, PSTN gateways or any other
|
|
|
- SIP-compliant devices.
|
|
|
- </para>
|
|
|
- <section>
|
|
|
- <title>Added-Value ISP Services</title>
|
|
|
- <para>
|
|
|
- To attract customers, ISPs frequently offer applications bundled with IP access.
|
|
|
- With SIP, the providers can conveniently offer a variety of services running on top
|
|
|
- of a single infrastructure. Particularly, deploying VoIP and instant messaging and
|
|
|
- presence services is as easy as setting up a SIP server and guiding customers to use
|
|
|
- Windows Messenger. Additionally, the ISPs may offer advanced services such as PSTN
|
|
|
- termination, user-driven call handling or unified messaging all using the same infrastructure.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- SIP Express Router has been engineered to power large scale networks: its capacity can deal
|
|
|
- with large number of customers under high load caused by modern applications. Premium
|
|
|
- performance allows deploying a low number of boxes while keeping investments and operational
|
|
|
- expenses extremely low. ISPs can offer SIP-based instant messaging services and interface
|
|
|
- them to other instant messaging systems (Jabber, SMS). VoIP can be easily integrated along
|
|
|
- with added-value services, such as voicemail.
|
|
|
- </para>
|
|
|
- </section> <!-- Added-value ISP -->
|
|
|
- <section>
|
|
|
- <title>PC2Phone</title>
|
|
|
- <para>
|
|
|
- Internet Telephony Service Providers (ITSPs) offer the service of interconnecting
|
|
|
- Internet telephony users using PC softphone or appliances to PSTN. Particularly with
|
|
|
- long-distance and international calls, competitive pricing can be achieved by
|
|
|
- routing the calls over the Internet.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- SIP Express Router can be easily configured to serve pc2phone users, distribute
|
|
|
- calls to geographically appropriate PSTN gateway, act as a security barrier and keep
|
|
|
- track of charging.
|
|
|
- </para>
|
|
|
- </section>
|
|
|
- <section>
|
|
|
- <title>PBX Replacement</title>
|
|
|
- <para>
|
|
|
- Replacing a traditional PBX in an enterprise can achieve reasonable
|
|
|
- savings. Enterprises can deploy a single infrastructure for both voice
|
|
|
- and data and bridge distant locations over the Internet. Additionally, they can
|
|
|
- benefit of integration of voice and data.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The SIP Express Router scales from SOHOs to large, international enterprises.
|
|
|
- Even a single installation on a common PC is able to serve VoIP signaling of any
|
|
|
- world's enterprise. Its policy-based routing language makes implementation of numbering
|
|
|
- plans of companies spread across the world very easy. ACL features allow for protection of
|
|
|
- PSTN gateway from unauthorized callers.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- SIP Express Router's support for programmable routing and accounting efficiently allows for
|
|
|
- implementation of such a scenario.
|
|
|
- </para>
|
|
|
- </section>
|
|
|
- </section> <!-- Use Cases -->
|
|
|
- <section id="aboutsip">
|
|
|
- <title>About SIP Technology</title>
|
|
|
- <para>
|
|
|
- The SIP protocol family is the technology which integrates services.
|
|
|
- With SIP, Internet users can easily contact each other; figure out
|
|
|
- willingness to have a conversation and couple different applications such as VoIP, video
|
|
|
- and instant messaging. Integration with added-value services is seamless and easy. Examples
|
|
|
- include integration with web (click-to-dial), E-mail (voice2email, UMS), and PSTN-like
|
|
|
- services (conditional forwarding).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The core piece of the technology is the Session Initiation Protocol (SIP, RFC3261) standardized by IETF.
|
|
|
- Its main function is to establish communication sessions between users connected to the public
|
|
|
- Internet and identified by e-mail-like addresses. One of SIP's greatest features is its transparent
|
|
|
- support for multiple applications: the same infrastructure may be used for voice, video, gaming
|
|
|
- or instant messaging as well as any other communication application.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There are numerous scenarios in which SIP is already deployed: PBX replacement allows for
|
|
|
- deployment of single inexpensive infrastructure in enterprises; PC-2-phone long-distance
|
|
|
- services (e.g., Deltathree) cut callers long-distance expenses; instant messaging offered
|
|
|
- by public severs (e.g., iptel.org) combines voice and text services with presence information.
|
|
|
- New deployment scenarios are underway: SIP is a part of UMTS networks and research publications
|
|
|
- suggest the use of SIP for virtual home environments or distributed network games.
|
|
|
- </para>
|
|
|
- </section> <!-- about sip -->
|
|
|
- <section id="serlimitations">
|
|
|
- <title>Known SER Limitations</title>
|
|
|
- <para>
|
|
|
- The following items are not part of current distribution and are planned for next releases:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- TCP transport
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Script processing of multiple branches on forking
|
|
|
- </para>
|
|
|
-
|
|
|
- <warning>
|
|
|
- <para>
|
|
|
- <application>ser</application>'s request processing language allows
|
|
|
- to make request decisions based on current URI.
|
|
|
- When a request if forked to multiple destinations, only the first branch's URI is used as
|
|
|
- input for script processing. This might lead to unexpected results. Whenever a URI resolves
|
|
|
- to multiple different next-hop URIs, only the first is processed which may result in handling
|
|
|
- not appropriate for the other branch. For example, a URI might resolve to an IP phone SIP
|
|
|
- address and PSTN gateway SIP address. If the IP phone address is the first, then script
|
|
|
- execution ignores the second branch. If a script includes checking gateway address in
|
|
|
- request URI, the checks never match. That might result in ignoring of
|
|
|
- gateway admission control rules or applying them unnecessarily to non-gateway
|
|
|
- destinations.
|
|
|
- </para>
|
|
|
- </warning>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- List of known bugs is publicly available at
|
|
|
- <ulink url="http://developer.berlios.de/bugs/?group_id=480">
|
|
|
- http://developer.berlios.de/bugs/?group_id=480
|
|
|
- </ulink>.
|
|
|
- </para>
|
|
|
- </section> <!-- limitations -->
|
|
|
- <section id="licensing">
|
|
|
- <title>Licensing</title>
|
|
|
- <para>
|
|
|
- <application>ser</application> is freely available under terms and
|
|
|
- conditions of the GNU General Public License.
|
|
|
- </para>
|
|
|
- <!-- COPYING -->
|
|
|
- <screen>
|
|
|
- &gpllicense;
|
|
|
- </screen>
|
|
|
-
|
|
|
- </section>
|
|
|
- <section id="support">
|
|
|
- <title>Obtaining Technical Assistance</title>
|
|
|
- <para>
|
|
|
- We offer best-effort free support for <application>ser</application>.
|
|
|
- "best-effort" means that we try to solve your problems via email
|
|
|
- as soon as we can, subject to available manpower. If you need
|
|
|
- commercial support, contact [email protected].
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- To receive feedback to your inquiries, we recommend you to subscribe
|
|
|
- to the <emphasis>serusers</emphasis> mailing list and post your
|
|
|
- queries there. This mailing list is set up for mutual help by
|
|
|
- the community of <application>ser</application> users and developers.
|
|
|
- </para>
|
|
|
- <itemizedlist>
|
|
|
- <title>Mailing List Instructions</title>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Public archives and subscription form:
|
|
|
- <ulink url="http://mail.iptel.org/mailman/listinfo/serusers">
|
|
|
- http://mail.iptel.org/mailman/listinfo/serusers
|
|
|
- </ulink>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- To post, send an email to [email protected]
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- If you think you encountered an error, please submit the
|
|
|
- following information to avoid unnecessary round-trip times:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Name and version of your operating system --
|
|
|
- you can obtain it by calling
|
|
|
- <command>uname -a</command>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <application>ser</application> distribution:
|
|
|
- release number and package
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <application>ser</application> build --
|
|
|
- you can obtain it by calling
|
|
|
- <command moreinfo="none">ser -V</command>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Your <application>ser</application> configuration file
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <application>ser</application> logs -- with default settings
|
|
|
- few logs are printed to <command>syslog</command> facility which
|
|
|
- typically dumps them to
|
|
|
- <filename moreinfo="none">/var/log/messages</filename>. To
|
|
|
- enable detailed logs dumped to <filename>stderr</filename>,
|
|
|
- apply the following configuration options: <command moreinfo="none">
|
|
|
- debug=8, log_stderror=yes, fork=no</command>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Captured SIP messages -- you can obtain them
|
|
|
- using tools such as <application>ngrep</application>
|
|
|
- or <application moreinfo="none">ethereal</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
-
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
-
|
|
|
- <para>
|
|
|
- If you are concerned about your privacy and do not wish your
|
|
|
- queries to be posted and archived publicly, you may post to
|
|
|
- [email protected]. E-mails to this address are only forwarded
|
|
|
- to iptel.org's <application>ser</application> development team.
|
|
|
- However, as the team is quite busy you should not be surprised
|
|
|
- to get replies with considerable delay.
|
|
|
-
|
|
|
- </para>
|
|
|
- </section>
|
|
|
-
|
|
|
- <section id="moreinfo">
|
|
|
- <title>More Information</title>
|
|
|
- <para>
|
|
|
- Most up-to-date information including latest and most complete version
|
|
|
- of this documentation is always available at our website,
|
|
|
- <ulink url="http://www.iptel.org/ser/">http://www.iptel.org/ser/</ulink>.
|
|
|
- The site includes links to other important information about
|
|
|
- <application moreinfo="none">ser</application>, such
|
|
|
- as installation guidelines (INSTALL), download links,
|
|
|
- development pages, programmer's manual, etc.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- A SIP tutorial (slide set) is available at
|
|
|
- <ulink url="http://www.iptel.org/sip/">http://www.iptel.org/sip/</ulink> .
|
|
|
- </para>
|
|
|
- </section> <!-- info -->
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>Release Notes</title>
|
|
|
- <literallayout format="linespecific" class="normal">
|
|
|
-&releasenotes;
|
|
|
- </literallayout>
|
|
|
- </section> <!-- release notes -->
|
|
|
-
|
|
|
-
|
|
|
- </chapter> <!-- general -->
|
|
|
-
|
|
|
- <chapter>
|
|
|
- <title>Introduction to SER</title>
|
|
|
-
|
|
|
- <section id="requestrouting">
|
|
|
- <title>Request Routing and SER Scripts</title>
|
|
|
- <para>
|
|
|
- The most important concept of every SIP server is that of
|
|
|
- request routing. The request routing logic determines the next
|
|
|
- hop of a request. It can be for example used to implement user
|
|
|
- location service or enforce static routing to a gateway. Real-world
|
|
|
- deployments actually ask for quite complex routing logic, which
|
|
|
- needs to reflect static routes to PSTN gateways, dynamic routes
|
|
|
- to registered users, authentication policy, capabilities of
|
|
|
- SIP devices, etc.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- SER's answer to this need for routing flexibility is a routing
|
|
|
- language, which allows administrators to define the SIP request
|
|
|
- processing logic in a detailed manner. They can for example easily
|
|
|
- split SIP traffic by method or destination, perform user location,
|
|
|
- trigger authentication, verify access permissions, and so on.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The primary building block of the routing language are <emphasis>actions</emphasis>.
|
|
|
- There are built-in actions (like <command>forward</command> for stateless forwarding
|
|
|
- or <command>strip</command> for stripping URIs) as
|
|
|
- well as external actions imported from shared library modules. All actions can
|
|
|
- be combined in compound actions by enclosing them in braces,
|
|
|
- e.g. <command>{a1(); a2();}</command>.
|
|
|
- Actions are aggregated in one or more <emphasis>route blocks</emphasis>.
|
|
|
- Initially, only the default routing block denoted by <command>route[0]</command>
|
|
|
- is called. Other routing blocks can be called by the action
|
|
|
- <command>route(blocknumber)</command>, recursion is permitted.
|
|
|
- The language includes <emphasis>conditional statements</emphasis>.
|
|
|
- </para>
|
|
|
-
|
|
|
- <para>
|
|
|
- The routing script is executed for every received request in sequential order.
|
|
|
- Actions may return positive/negative/zero value.
|
|
|
-
|
|
|
- Positive values are considered success and evaluated as
|
|
|
- TRUE in conditional expressions. Negative values are considered FALSE.
|
|
|
-
|
|
|
- Zero value means error and leaves execution of currently processed
|
|
|
- route block. The route block is left too, if <command>break</command> is explicitly
|
|
|
- called from it.
|
|
|
-
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The easiest and still very useful way for <application>ser</application>
|
|
|
- users to affect request routing logic is
|
|
|
- to determine next hop statically. An example is
|
|
|
- routing to a PSTN gateway whose static IP address is well known.
|
|
|
- To configure static routing, simply use the action
|
|
|
- <command>forward( IP_address, port_number)</command>.
|
|
|
- This action forwards an incoming request "as is" to the
|
|
|
- destination described in action's parameters.
|
|
|
- </para>
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Static Forwarding</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# if requests URI is numerical and starts with
|
|
|
-# zero, forward statelessly to a static destination
|
|
|
-
|
|
|
-if (uri=~"^sip:0[0-9]*@iptel.org) {
|
|
|
- forward( 192.168.99.3, 5080 );
|
|
|
-}
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
-
|
|
|
- <para>
|
|
|
- However, static forwarding is not sufficient in many cases.
|
|
|
- Users desire mobility and change their location frequently.
|
|
|
- Lowering costs for termination of calls in PSTN requires
|
|
|
- locating a least-cost gateway. Which next-hop is taken may
|
|
|
- depend on user's preferences. These and many other scenarios
|
|
|
- need the routing logic to be more dynamic. We describe in
|
|
|
- <xref linkend="conditions"> how to make request processing
|
|
|
- subject to various conditions and in
|
|
|
- <xref linkend="urirewriting"> how to determine next SIP hop.
|
|
|
- </para>
|
|
|
- </section>
|
|
|
-
|
|
|
- <section id="conditions">
|
|
|
- <title>Conditional Statements</title>
|
|
|
- <para>
|
|
|
- A very useful feature is the ability to make routing
|
|
|
- logic depend on a condition. A script condition may for
|
|
|
- example distinguish between request processing for
|
|
|
- served and foreign domains, IP and PSTN routes,
|
|
|
- it may split traffic by method or username, it
|
|
|
- may determine whether a request should be authenticated
|
|
|
- or not, etc. <application moreinfo="none">ser</application>
|
|
|
- allows administrators to form conditions based on
|
|
|
- properties of processed request, such as method or uri,
|
|
|
- as well as on virtually any piece of data on the
|
|
|
- Internet.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Conditional Statement</title>
|
|
|
- <para>
|
|
|
- This example shows how a conditional statement is
|
|
|
- used to split incoming requests between a PSTN
|
|
|
- gateway and a user location server based on
|
|
|
- request URI.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# if request URI is numerical, forward the request to PSTN gateway...
|
|
|
-if (uri=~"^sip:[0-9][email protected]") { # match using a regular expression
|
|
|
- forward( gateway.foo.bar, 5060 );
|
|
|
-} else { # ... forward the request to user location server otherwise
|
|
|
- forward( userloc.foo.bar, 5060 );
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
-
|
|
|
- <para>
|
|
|
- Conditional statements in <application>ser</application> scripts may depend
|
|
|
- on a variety of expressions. The simplest expressions are
|
|
|
- action calls. They return true if they completed successfully or false otherwise.
|
|
|
- An example of an action frequently used in conditional statements is
|
|
|
- <command moreinfo="none">search</command> imported from textops module.
|
|
|
- <command moreinfo="none">search</command> action leverages textual
|
|
|
- nature of SIP and compares SIP requests against a regular expression.
|
|
|
- The action returns true if the expression matched, false otherwise.
|
|
|
- <example>
|
|
|
- <title>Use of <command>search</command> Action in Conditional Expression</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# prevent strangers from claiming to belong to our domain;
|
|
|
-# if sender claims to be in our domain in From header field,
|
|
|
-# better authenticate him
|
|
|
-if (search("(f|From): .*@mydomain.com)) {
|
|
|
- if (!(proxy_authorize("mydomain.com" /* realm */,"subscriber" /* table name */ ))) {
|
|
|
- proxy_challenge("mydomain.com /* ream */, "1" /* use qop */ );
|
|
|
- break;
|
|
|
- }
|
|
|
-}
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- As modules may be created, which export new functions, there is virtually
|
|
|
- no limitation on what functionality <application moreinfo="none">ser</application>
|
|
|
- conditions are based on. Implementers may introduce new actions whose
|
|
|
- return status depends on request content or any external data as well. Such actions
|
|
|
- can query SQL, web, local file systems or any other place which can provide
|
|
|
- information wanted for request processing.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Furthermore, many request properties may be examined using existing built-in operands
|
|
|
- and operators. Available left-hand-side operands and legal combination with
|
|
|
- operators and right-hand-side operands are described in <xref linkend="logicalexpr">.
|
|
|
- Expressions may be grouped together using logical operators:
|
|
|
- negation (<command>!</command>), AND (<command>&&</command>), OR (<command moreinfo="none">
|
|
|
- ||</command> and precedence parentheses (<command>()</command>).
|
|
|
- </para>
|
|
|
-
|
|
|
- <section id="operators">
|
|
|
- <title>Operators and Operands</title>
|
|
|
- <para>
|
|
|
- There is a set of predefined operators and operands
|
|
|
- in ser, which in addition to actions may be evaluated
|
|
|
- in conditional expressions.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Left hand-side operands, which <application>ser</application>
|
|
|
- understands are the following:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>method</emphasis>, which refers to
|
|
|
- request method
|
|
|
- such as REGISTER or INVITE
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>uri</emphasis>, which refers to current request URI,
|
|
|
- such as
|
|
|
- "sip:[email protected]"
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- Note that "uri" always refers to current
|
|
|
- value of URI, which is subject to change
|
|
|
- be uri-rewriting actions.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>src_ip</emphasis>, which refers to IP address from
|
|
|
- which a request came.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>dst_ip</emphasis> refers to server's IP address
|
|
|
- at which a request was received
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>src_port</emphasis> port number from which a SIP
|
|
|
- request came
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- ser understands the following operators:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- == stands for equity
|
|
|
- </para>
|
|
|
-
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- =~ stands for regular expression matching
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- logical operators: and, or, negation, parentheses
|
|
|
- (C-notation for the operators may be used too)
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
-
|
|
|
- <table id="logicalexpr">
|
|
|
- <title>Valid Combinations of Operands and Operators in Expressions</title>
|
|
|
- <tgroup cols="4">
|
|
|
- <thead>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- left-hand-side operand
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- valid operators
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- valid right-hand side operators
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- examples/comments
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- </thead>
|
|
|
- <tbody>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- method
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- == (exact match), =~ (regular expression matching)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- string
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- method=="INVITE" || method=="ACK" || method=="CANCEL"
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- uri
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- == (exact match), =~ (regular expression matching)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- string
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- uri=="sip:[email protected]" matches only if exactly this uri
|
|
|
- is in request URI
|
|
|
-
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
-
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- == (exact match)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- myself
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
-
|
|
|
- the expression uri==myself is true if the host part in
|
|
|
- request URI equals a server name or a server alias (set using
|
|
|
- the alias option in configuration file)
|
|
|
-
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- src_ip
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- == (match)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- IP, IP/mask_length, IP/mask, hostname, myself
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- src_ip==192.168.0.0/16 matches requests coming from
|
|
|
- a private network
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- dst_ip
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- == (match)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- IP, IP/mask_length, IP/mask, hostname, myself
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- dst_ip==127.0.0.1 matches if a request was received
|
|
|
- via loopback interface
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- src_port
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- == (match)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- port number
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- port number from which a request was sent, e.g. src_port==5060
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
-
|
|
|
- </tbody>
|
|
|
- </tgroup>
|
|
|
- </table>
|
|
|
-
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>
|
|
|
- More examples of use of <application>ser</application> operators and operands in conditional
|
|
|
- statements
|
|
|
- </title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# using an action as condition input; in this
|
|
|
-# case, an actions 'search' looks for Contacts
|
|
|
-# with private IP address in requests; the condition
|
|
|
-# is processed if such a contact header field is
|
|
|
-# found
|
|
|
-
|
|
|
-if (search("^(Contact|m): .*@(192\.168\.|10\.|172\.16)")) {
|
|
|
-# ....
|
|
|
-
|
|
|
-# this condition is true if request URI matches
|
|
|
-# the regular expression "@bat\.iptel\.org"
|
|
|
- if (uri=~"@bat\.iptel\.org") {
|
|
|
-# ...
|
|
|
-
|
|
|
-# and this condition is true if a request came
|
|
|
-# from an IP address (useful for example for
|
|
|
-# authentication by IP address if digest is not
|
|
|
-# supported) AND the request method is INVITE
|
|
|
-
|
|
|
-# if ( (src_ip==192.68.77.110 and method=="INVITE")
|
|
|
-# ...
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- </section> <!-- operators and operands -->
|
|
|
- <section>
|
|
|
- <title>URI Matching</title>
|
|
|
- <para>URI matching expressions have a broad use in a SIP server
|
|
|
- and deserve more explanation. Typical uses of
|
|
|
- URI matching include implementation of numbering plans,
|
|
|
- domain matching,
|
|
|
- binding external applications to specific URIs,
|
|
|
- etc. This section shows examples of typical applications
|
|
|
- of URI-matching.
|
|
|
- </para>
|
|
|
- <section id="domainmatching">
|
|
|
- <title>Domain Matching</title>
|
|
|
- <para>
|
|
|
- One of most important uses of URI matching is deciding
|
|
|
- whether a request is targeted to a served or outside domain.
|
|
|
- Typically, different request
|
|
|
- processing applies. Requests for outside domains
|
|
|
- are simply forwarded to them, whereas
|
|
|
- more complex logic applies to requests for a served domain.
|
|
|
- The logic may include saving user's contacts
|
|
|
- when REGISTER requests are received, forwarding requests
|
|
|
- to current user's location or a PSTN gateways,
|
|
|
- interaction with external applications, etc.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The easiest way to decide whether a request belongs
|
|
|
- a served domain is using the <command moreinfo="none">myself</command>
|
|
|
- operand.
|
|
|
- The expression "uri==myself" returns true if domain name
|
|
|
- in request URI matches name of the host at which
|
|
|
- <application moreinfo="none">ser</application> is
|
|
|
- running. This may be insufficient in cases when
|
|
|
- server name is not equal to domain name for which the server
|
|
|
- is responsible. For example, the "uri==myself" condition
|
|
|
- does not match if a server "sipserver.foo.bar"
|
|
|
- receives a request for "sip:[email protected]". To
|
|
|
- match other names in URI than server's own,
|
|
|
- set up the <varname>alias</varname> configuration
|
|
|
- option. The option may be used multiple times,
|
|
|
- each its use adds a new item to a list of aliases.
|
|
|
- The myself condition returns then true
|
|
|
- also for any hostname on the list of aliases.
|
|
|
- <example>
|
|
|
- <title>Use of uri==myself Expression</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# ser powers a domain "foo.bar" and runs at host sipserver.foo.bar;
|
|
|
-# Names of served domains need to be stated in the aliases
|
|
|
-# option; myself would not match them otherwise and would only
|
|
|
-# match requests with "sipserver.foo.bar" in request-URI
|
|
|
-alias="foo.bar"
|
|
|
-alias="sales.foo.bar"
|
|
|
-route[0] {
|
|
|
- if (uri==myself) {
|
|
|
- # the request either has server name or some of the
|
|
|
- # aliases in its URI
|
|
|
- log(1,"request for served domain")
|
|
|
- # some domain-specific logic follows here ....
|
|
|
- } else {
|
|
|
- # aha -- the server is not responsible for this
|
|
|
- # requests; that happens for example with the following URIs
|
|
|
- # - sip:[email protected]
|
|
|
- # - sip:[email protected]
|
|
|
- log(1,"request for outbound domain");
|
|
|
- # outbound forwarding
|
|
|
- t_relay();
|
|
|
- };
|
|
|
-} </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- It is possible to recognize whether a request belongs to
|
|
|
- a domain using regular expressions too. Care needs to
|
|
|
- be paid to construction of regular expressions. URI
|
|
|
- syntax is rich and an incorrect expression would result
|
|
|
- in incorrect call processing. The following example shows
|
|
|
- how an expression for domain matching can be formed.
|
|
|
- <example id="redomainmatching">
|
|
|
- <title>Domain Matching Using Regular Expressions</title>
|
|
|
- <para>
|
|
|
- In this example, server named "sip.foo.bar" with
|
|
|
- IP address 192.168.0.10 is responsible for the
|
|
|
- "foo.bar" domain. That means, requests with the
|
|
|
- following hostnames in URI should be matched:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- foo.bar, which is the name of server domain
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- sip.foo.bar, since it is server's name and some
|
|
|
- devices put server's name in request URI
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- 192.168.0.10, since it is server's IP address and
|
|
|
- some devices put server's IP address in request URI
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- Note how this regular expression is constructed. In particular:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- User name is optional (it is for example never included
|
|
|
- in REGISTER requests) and there are no restrictions on
|
|
|
- what characters it contains. That is what
|
|
|
- <emphasis>(.+@)?</emphasis> mandates.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Hostname must be followed by port number, parameters
|
|
|
- or headers -- that is what the delimiters
|
|
|
- <emphasis>[:;\?]</emphasis> are good for. If none
|
|
|
- it these follows, the URI must be ended
|
|
|
- (<emphasis>$</emphasis>). Otherwise, longer hostnames
|
|
|
- such as 192.168.0.101 or foo.bar.otherdomain.com would
|
|
|
- mistakenly match.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Matches are case-insensitive. All hostnames "foo.bar", "FOO.BAR"
|
|
|
- and "FoO.bAr" match.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- <programlisting>
|
|
|
-if (uri=~"^sip:(.+@)?(192\.168\.0\.10|(sip\.)?foo\.bar)([:;\?].*)?$")
|
|
|
- log(1, "yes, it is a request for our domain");
|
|
|
- break;
|
|
|
- };
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </section> <!-- domain matching -->
|
|
|
- <section id="numberingplans">
|
|
|
- <title>Numbering Plans</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- Other use of URI matching is implementation of dialing
|
|
|
- plans. A typical task when designing a dialing plan for SIP networks
|
|
|
- is to distinguish between "pure-IP" and PSTN destinations.
|
|
|
- IP users typically have either alphanumerical or numerical
|
|
|
- usernames. The numerical usernames are convenient for PSTN
|
|
|
- callers who can only
|
|
|
- use numeric keypads. Next-hop destination of IP users is looked up dynamically
|
|
|
- using user location database. On the other hand, PSTN destinations are
|
|
|
- always indicated by nummerical usernames. Requests to PSTN are statically
|
|
|
- forwarded to well-known PSTN gateways.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>A simple Numbering Plan</title>
|
|
|
- <para>
|
|
|
- This example shows a simple dialing plan which reserves
|
|
|
- dialing prefix "8" for IP users, other numbers
|
|
|
- are used for PSTN destinations and all other non-nummerical
|
|
|
- usernames are used for IP users.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# is it a PSTN destination? (is username nummerical and does not begin with 8?)
|
|
|
-if (uri=~"^sip:[0-79][0-9]*@") { # ... forward to gateways then;
|
|
|
- # check first to which PSTN destination the requests goes;
|
|
|
- # if it is US (prefix "1"), use the gateway 192.168.0.1...
|
|
|
- if (uri=~"^sip:1") {
|
|
|
- # strip the leading "1"
|
|
|
- strip(1);
|
|
|
- forward(192.168.0.1, 5060);
|
|
|
- } else {
|
|
|
- # ... use the gateway 10.0.0.1 for all other destinations
|
|
|
- forward(10.0.0.1, 5060);
|
|
|
- }
|
|
|
- break;
|
|
|
-} else {
|
|
|
- # it is an IP destination -- try to lookup it up in user location DB
|
|
|
- if (!lookup("location")) {
|
|
|
- # bad luck ... user off-line
|
|
|
- sl_send_reply("404", "Not Found");
|
|
|
- break;
|
|
|
- }
|
|
|
- # user on-line...forward to his current destination
|
|
|
- forward(uri:host,uri:port);
|
|
|
-}
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </section> <!-- numbering plans -->
|
|
|
- </section>
|
|
|
- </section> <!-- conditional statements -->
|
|
|
-
|
|
|
- <section id="urirewriting">
|
|
|
- <title>Request URI Rewriting</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- The ability to give users and services a unique name using URI
|
|
|
- is a powerful tool. It allows users to advertise how to reach
|
|
|
- them, to state to whom they wish to communicate and what services
|
|
|
- they wish to use.
|
|
|
- Thus, the ability to change URIs is very important and is
|
|
|
- used for implementation of many services.
|
|
|
- "Unconditional forwarding" from user "boss" to user
|
|
|
- "secretary" is a typical example of application relying
|
|
|
- on change of URI address.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> has the ability
|
|
|
- to change request URI in many ways.
|
|
|
- A script can use any of the following
|
|
|
- built-in actions to change request URI or a part of it:
|
|
|
-
|
|
|
- <command>rewriteuri</command>,
|
|
|
- <command>rewritehost</command>,
|
|
|
- <command>rewritehostport</command>,
|
|
|
- <command>rewriteuser</command>,
|
|
|
- <command>rewriteuserpass</command> and
|
|
|
- <command>rewriteport</command>.
|
|
|
- When later in the script
|
|
|
- a forwarding action is encountered, the action forwards
|
|
|
- the request to address in the rewritten URI.
|
|
|
- <example>
|
|
|
- <title>Rewriting URIs</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-if (uri=~"[email protected]") {
|
|
|
- rewriteuri("sip:[email protected]")
|
|
|
- # forward statelessly to the destination in current URI, i.e.,
|
|
|
- # to sip:[email protected]:5060
|
|
|
- forward( uri:host, uri:port);
|
|
|
-}
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>Two more built-in URI-rewriting commands are of special importance
|
|
|
- for implementation of dialing plans and manipulation of dialing
|
|
|
- prefixes. <command>prefix(s)
|
|
|
- </command>, inserts
|
|
|
- a string "s" in front of SIP address and
|
|
|
- <command>strip(n)</command> takes
|
|
|
- away the first "n" characters of a SIP address.
|
|
|
- See <xref linkend="urirewritingexamples"> for examples of use of
|
|
|
- built-in URI-rewriting actions.
|
|
|
- </para>
|
|
|
-
|
|
|
- <para>
|
|
|
- Commands exported by external modules can change URI too
|
|
|
- and many do so.
|
|
|
- The most important application is changing URI using the
|
|
|
- user location database. The command
|
|
|
- <command>lookup(table)</command> looks up current
|
|
|
- user's location and rewrites user's address with it.
|
|
|
- If there is no registered contact, the command returns a negative value.
|
|
|
-
|
|
|
-
|
|
|
- <example id=rewriteuri>
|
|
|
- <title>Rewriting URIs Using User Location Database</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# store user location if a REGISTER appears
|
|
|
-if (method=="REGISTER") {
|
|
|
- save("mydomain1");
|
|
|
-} else {
|
|
|
-# try to use the previously registered contacts to
|
|
|
-# determine next hop
|
|
|
- if(lookup("mydomain1")) {
|
|
|
- # if found, forward there...
|
|
|
- t_relay();
|
|
|
- } else {
|
|
|
- # ... if no contact on-line, tell it upstream
|
|
|
- sl_send_reply("404", "Not Found" );
|
|
|
- };
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- External applications can be used to rewrite URI too.
|
|
|
- The "exec" module provides script actions, which start external programs
|
|
|
- and read new URI value from their output. <command moreinfo="none">exec_uri</command>
|
|
|
- and <command moreinfo="none">exec_user</command> both call an external program,
|
|
|
- pass current URI or its user part to it respectively, wait until it completes,
|
|
|
- and eventually rewrite current URI with its output.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- It is important to realize that <application moreinfo="none">ser</application>
|
|
|
- operates over <emphasis>current URI</emphasis> all the time. If an original
|
|
|
- URI is rewritten by a new one, the original will will be forgotten and the new one will
|
|
|
- be used in any further processing. In particular, the uri matching operand
|
|
|
- and the user location action <command moreinfo="none">lookup</command>
|
|
|
- always take current URI as input, regardless what the original URI was.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <xref linkend="urirewritingexamples"> shows how URI-rewriting actions affect
|
|
|
- an example URI, sip:[email protected]:6060.
|
|
|
- <table id="urirewritingexamples">
|
|
|
- <title>URI-rewriting Using Built-In Actions</title>
|
|
|
- <tgroup cols="2">
|
|
|
- <thead>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- Example Action
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Resulting URI
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- </thead>
|
|
|
- <tbody>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">rewritehost("192.168.0.10")</command> rewrites
|
|
|
- the hostname in URI, other parts (including port number) remain unaffected.
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]:6060
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">rewriteuri("sip:[email protected]");</command> rewrites
|
|
|
- the whole URI completely.
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">rewritehostport("192.168.0.10:3040")</command>rewrites
|
|
|
- both hostname and port number in URI.
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]:3040
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">rewriteuser("alice")</command> rewrites user part of URI.
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]:6060
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">rewriteuserpass("alice:pw")</command> replaces the pair
|
|
|
- user:password in URI with a new value.
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:alice:[email protected]:6060
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">rewriteport("1234")</command> replaces port number in URI
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]:1234
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">prefix("9")</command> inserts a string ahead of user part of URI
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]:6060
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- <command moreinfo="none">strip(2)</command> removes leading characters from user part of URI
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sip:[email protected]:6060
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
-
|
|
|
- </tbody>
|
|
|
- </tgroup>
|
|
|
- </table>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- You can verify whether you understood URI processing by
|
|
|
- looking at the following example. It rewrites URI
|
|
|
- several times. The question is what is the final URI to which
|
|
|
- the script fill forward any incoming request.
|
|
|
- <example>
|
|
|
- <title>URI-rewriting Exercise</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-exec_uri("echo sip:[email protected]; echo > /dev/null");
|
|
|
-strip(2);
|
|
|
-if (uri=~"^sip:2") {
|
|
|
- prefix("0");
|
|
|
-} else {
|
|
|
- prefix("1");
|
|
|
-};
|
|
|
-forward(uri:host, uri:port);
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The correct answer is the resulting URI will be
|
|
|
- "sip:[email protected]". <command moreinfo="none">exec_uri</command>
|
|
|
- rewrites original URI to "sip:[email protected]",
|
|
|
- <command moreinfo="none">strip(2)</command> takes
|
|
|
- two leading characters from username away resulting
|
|
|
- in "[email protected]", the condition does not match
|
|
|
- because URI does not begin with "2" any more,
|
|
|
- so the prefix "1" is inserted.
|
|
|
- </para>
|
|
|
-
|
|
|
-
|
|
|
- </section> <!-- URI rewriting -->
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>Destination Set</title>
|
|
|
- <para>
|
|
|
- Whereas needs of many scenarios can by accommodated by maintaining
|
|
|
- a single request URI, some scenarios are better served by
|
|
|
- multiple URIs. Consider for example a user with address
|
|
|
- [email protected]. The user wishes to be reachable at his
|
|
|
- home phone, office phone, cell phone, softphone, etc.
|
|
|
- However, he still wishes to maintain a single public address
|
|
|
- on his business card.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- To enable such scenarios, <application>ser</application>
|
|
|
- allows translation of a single request URI into multiple
|
|
|
- outgoing URIs. The ability to forward a request to multiple
|
|
|
- destinations is known as <emphasis>forking</emphasis>
|
|
|
- in SIP language. All outogoing URIs (in trivial case one of them)
|
|
|
- are called <emphasis>destination set</emphasis>. The destination
|
|
|
- set always includes one default URI, to which additional URIs
|
|
|
- can be appended. Maximum size of a destination set is limited by
|
|
|
- a compile-time constant, MAX_BRANCHES,
|
|
|
- in <filename moreinfo="none">config.h</filename>.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Some actions are designed for use with a single URI whereas
|
|
|
- other actions work with the whole destination set.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Actions which are currently available for creating the destination
|
|
|
- set are <command>lookup</command> from usrloc module and
|
|
|
- <command>exec_uri/exec_user</command> from exec module.
|
|
|
- <command moreinfo="none">lookup</command> fills in the destination
|
|
|
- set with user contact's registered previously with REGISTER
|
|
|
- requests. The <command moreinfo="none">exec</command> actions
|
|
|
- fill in the destination set with output of an external program.
|
|
|
- In both cases, current destination set is completely rewritten.
|
|
|
- New URIs can be appended to destination set by a call to the built-in
|
|
|
- action <command>append_branch(uri)</command>.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Currently supported features which utilize destination sets
|
|
|
- are <emphasis>forking</emphasis> and <emphasis>redirection</emphasis>.
|
|
|
- Action <command>t_relay</command> (TM module) for stateful
|
|
|
- forwarding supports forking. If called with a non-trivial destination
|
|
|
- set, <command moreinfo="none">t_relay</command> forks
|
|
|
- incoming request to all URIs in current destination set.
|
|
|
- See <xref linkend="rewriteuri">. If a user
|
|
|
- previously registered from three locations, the destination set is filled with
|
|
|
- all of them by <command>lookup</command> and the <command>t_relay</command>
|
|
|
- command forwards the incoming request to all these destinations.
|
|
|
- Eventually, all user's phone will be ringing in parallel.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- SIP redirection is another feature which leverages destination sets.
|
|
|
- It is a very light-weighted method to establish communication
|
|
|
- between two parties with minimum burden put on the server. In
|
|
|
- <application>ser</application>, the action <command>sl_send_reply</command>
|
|
|
- (SL module) is used for this purpose. This action
|
|
|
- allows to generate replies to SIP requests without keeping
|
|
|
- any state. If the status code passed to the action is 3xx,
|
|
|
- the current destination set is printed in reply's Contact header
|
|
|
- fields. Such a reply instructs the originating client to
|
|
|
- retry at these addresses. (See <xref linkend="redirectexample">).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Most other <application>ser</application> actions ignore destination
|
|
|
- sets: they either do not relate to URI processing (<command moreinfo="none">
|
|
|
- log</command>, for example) or they work only with the default URI.
|
|
|
- All URI-rewriting functions such as
|
|
|
- <command moreinfo="none">rewriteuri</command> belong in this
|
|
|
- category. URI-comparison operands only refers to the first URI
|
|
|
- (see <xref linkend="operators">). Also, the built-in action
|
|
|
- for stateless forwarding, <command>forward</command> works only
|
|
|
- with the default URI and ignores rest of the destination set. The reason
|
|
|
- is a proxy server willing to fork must guarantee that the burden
|
|
|
- of processing multiple replies is not put unexpectedly on upstream
|
|
|
- client. This is only achievable with stateful processing.
|
|
|
- Forking cannot be used along with stateless <command>forward</command>,
|
|
|
- which thus only processes one URI out of the whole destination set.
|
|
|
- Also, the uri comparison operand (see <xref linkend="operators">)
|
|
|
- refers only to current URI and ignores the rest of destination
|
|
|
- set.
|
|
|
- </para>
|
|
|
-
|
|
|
- </section> <!-- Destination Set -->
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>User Location</title>
|
|
|
- <para>
|
|
|
- Mobility is a key feature of SIP. Users are able to use one
|
|
|
- one or more SIP devices and be reachable at them. Incoming requests
|
|
|
- for users are forwarded to all user's devices in use. The key
|
|
|
- concept is that of soft-state registration. Users can
|
|
|
- -- if in possession of valid credentials -- link SIP
|
|
|
- devices to their e-mail like address of record. Their SIP devices
|
|
|
- do so using a REGISTER request, as in <xref linkend="register">.
|
|
|
- The request creates a binding between the public address of
|
|
|
- record (To header field) and SIP device's current address
|
|
|
- (Contact header field).
|
|
|
- <example id="register">
|
|
|
- <title>REGISTER Request</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-REGISTER sip:192.168.2.16 SIP/2.0
|
|
|
-Via: SIP/2.0/UDP 192.168.2.16;branch=z9hG4bKd5e5.5a9947e4.0
|
|
|
-Via: SIP/2.0/UDP 192.168.2.33:5060
|
|
|
-From: sip:[email protected]
|
|
|
-To: sip:[email protected]
|
|
|
-Call-ID: [email protected]
|
|
|
-Date: Wed, 29 Jan 2003 18:13:15 GMT
|
|
|
-CSeq: 101 REGISTER
|
|
|
-User-Agent: CSCO/4
|
|
|
-Contact: sip:[email protected]:5060
|
|
|
-Content-Length: 0
|
|
|
-Expires: 600
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- Similar requests can be used to query all user's current contacts or to
|
|
|
- delete them. All Contacts have certain time to live, when the time expires,
|
|
|
- contact is removed and no longer used for processing of incoming requests.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> is built to do both: update
|
|
|
- user location database from received REGISTER requests and look-up these
|
|
|
- contacts when inbound requests for a user arrive. To achieve high performance,
|
|
|
- the user location table is stored in memory. In regular intervals
|
|
|
- (usrloc module's parameter <varname>timer_interval</varname> determines
|
|
|
- their length), all changes to the in-memory table are backed up in
|
|
|
- <application moreinfo="none">mysql</application> database to achieve
|
|
|
- peristence accross server reboots. Administrators or application writers
|
|
|
- can lookup list of current user's contacts stored in memory using the
|
|
|
- <application moreinfo="none">serctl</application> tool (see <xref linkend="serctl">).
|
|
|
- <example>
|
|
|
- <title>Use of <application>serctl</application> Tool to Query User Location</title>
|
|
|
- <screen format="linespecific">
|
|
|
-<![CDATA[
|
|
|
-[jiri@fox jiri]$ sc ul show jiri
|
|
|
-<sip:[email protected]>;q=0.00;expires=456
|
|
|
-<sip:[email protected]>;q=0.00;expires=36000
|
|
|
-]]>
|
|
|
- </screen>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Building user location in <application moreinfo="none">ser</application> scripts is
|
|
|
- quite easy. One first needs to determine whether a request is for served domain,
|
|
|
- as described in <xref linkend="domainmatching">. If that is the case, the script
|
|
|
- needs to distinguish between REGISTER requests, that update user location table,
|
|
|
- and all other requests for which next hop is determined from the table. The
|
|
|
- <command moreinfo="none">save</command> action is used to update user location
|
|
|
- (i.e., it writes to it). The <command moreinfo="none">lookup</command> actions
|
|
|
- reads from the user location table and fills in destination set with current
|
|
|
- user's contacts.
|
|
|
- <example>
|
|
|
- <title>Use of User Location Actions</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# is the request for my domain ?
|
|
|
-if (uri==myself) {
|
|
|
- if (method=="REGISTER") { # REGISTERs are used to update
|
|
|
- save("location");
|
|
|
- break; # that's it, we saved the contacts, exit now
|
|
|
- } else {
|
|
|
- if (!lookup("location") { # no registered contact
|
|
|
- sl_send_reply("404", "Not Found");
|
|
|
- break;
|
|
|
- }
|
|
|
- # ok -- there are some contacts for the user; forward
|
|
|
- # the incoming request to all of them
|
|
|
- t_relay();
|
|
|
- };
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Note that we used the action for stateful forwarding,
|
|
|
- <command moreinfo="none">t_relay</command>. That's is because
|
|
|
- stateful forwarding allows to fork an incoming request to
|
|
|
- multiple destinations. If we used stateful forwarding,
|
|
|
- the request would be forwarded only to one uri out of
|
|
|
- all user's contacts.
|
|
|
- </para>
|
|
|
- </section> <!-- User Location -->
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>External Modules</title>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> provides the ability to link the server with external
|
|
|
- third-party shared libraries. Lot of functionality which is
|
|
|
- included in the <application moreinfo="none">ser</application> distribution is actually located in
|
|
|
- modules to keep the server "core" compact and clean.
|
|
|
- Among others, there are modules for checking max_forwards
|
|
|
- value in SIP requests (maxfwd), transactional processing (tm),
|
|
|
- record routing (rr), accounting (acc), authentication (auth),
|
|
|
- SMS gateway (sms), replying requests (sl), user location
|
|
|
- (usrloc, registrar) and more.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- In order to utilize new actions exported by a module,
|
|
|
- ser must first load it. To load a module, the directive
|
|
|
- <command moreinfo="none">loadmodule "filename"</command>
|
|
|
- must be included in beginning of
|
|
|
- a <application>ser</application> script file.
|
|
|
- </para>
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Using Modules</title>
|
|
|
- <para>
|
|
|
- This example shows how a script instructs
|
|
|
- <application moreinfo="none">ser</application> to
|
|
|
- load a module and use actions exported by it.
|
|
|
- Particularly, the sl module exports an action
|
|
|
- <command>sl_send_reply</command> which makes
|
|
|
- <application>ser</application> act as a stateless
|
|
|
- user agent and reply all incoming requests with 404.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# first of all, load the module!
|
|
|
-loadmodule "/usr/lib/ser/modules/sl.so
|
|
|
-route{
|
|
|
- # reply all requests with 404
|
|
|
- sl_send_reply("404", "I am so sorry -- user not found");
|
|
|
-}
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- <note>
|
|
|
- <para>Note that unlike with core commands, all actions
|
|
|
- exported by modules must have parameters enclosed
|
|
|
- in quotation marks in current version of
|
|
|
- <application moreinfo="none">ser</application>.
|
|
|
- In the following example, the built-in action
|
|
|
- <command moreinfo="none">forward</command> for
|
|
|
- stateless forwarding takes
|
|
|
- IP address and port numbers as parameters without
|
|
|
- quotation marks whereas a module action
|
|
|
- <command moreinfo="none">t_relay</command> for
|
|
|
- stateful forwarding takes parameters enclosed in
|
|
|
- quotation marks.
|
|
|
- <example>
|
|
|
- <title>Parameters in built-in and exported
|
|
|
- actions</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# built-in action doesn't enclose IP addresses and port numbers
|
|
|
-# in quotation marks
|
|
|
-forward(192.168.99.100, 5060);
|
|
|
-# module-exported functions enclose all parameters in quotation
|
|
|
-# marks
|
|
|
-t_relay_to("192.168.99.100", "5060");
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <para>
|
|
|
- Many modules also allow users to change the way how they
|
|
|
- work using predefined parameters. For example, the
|
|
|
- authentication module needs to know location of MySQL
|
|
|
- database which contains users' security credentials.
|
|
|
- How module parameters
|
|
|
- are set using the <command moreinfo="none">modparam</command>
|
|
|
- directive is shown in <xref linkend="moduleparameters">.
|
|
|
- <command moreinfo="none">modparam</command>
|
|
|
- always contains identification of module, parameter
|
|
|
- name and parameter value. Description of parameters
|
|
|
- available in modules is available in module documentation.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Yet another thing to notice in this example is module
|
|
|
- dependency. Modules may depend on each other. For example,
|
|
|
- the authentication modules leverages the mysql module
|
|
|
- for accessing mysql databases and sl module for generating
|
|
|
- authentication challenges. We recommend that modules are
|
|
|
- loaded in dependency order to avoid ambiguous server
|
|
|
- behaviour.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <example id="moduleparameters">
|
|
|
- <title>Module Parameters</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# ------------------ module loading ----------------------------------
|
|
|
-
|
|
|
-# load first modules on which 'auth' module depends;
|
|
|
-# sl is used for sending challenges, mysql for storage
|
|
|
-# of user credentials
|
|
|
-loadmodule "modules/sl/sl.so"
|
|
|
-loadmodule "modules/mysql/mysql.so"
|
|
|
-loadmodule "modules/auth/auth.so"
|
|
|
-
|
|
|
-# ------------------ module parameters -------------------------------
|
|
|
-# tell the auth module the access data for SQL database:
|
|
|
-# username, password, hostname and database name
|
|
|
-modparam("auth", "db_url","sql://ser:secret@dbhost/ser")
|
|
|
-
|
|
|
-
|
|
|
-# ------------------------- request routing logic -------------------
|
|
|
-
|
|
|
-# authenticate all requests prior to forwarding them
|
|
|
|
|
|
-route{
|
|
|
+&general;
|
|
|
|
|
|
- if (!proxy_authorize("foo.bar" /* realm */,
|
|
|
- "subscriber" /* table name */ )) {
|
|
|
- proxy_challenge("foo.bar", "0");
|
|
|
- break;
|
|
|
- };
|
|
|
- forward(192.168.0.10,5060);
|
|
|
-}
|
|
|
+&intro;
|
|
|
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </section>
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>Writing Scripts</title>
|
|
|
- <para>
|
|
|
- This section demonstrates simple examples
|
|
|
- how to configure server's behaviour using the
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- request routing language. All scripts follow the
|
|
|
- <application moreinfo="none">ser</application> language
|
|
|
- syntax, which dictates the following block ordering:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>global configuration parameters</emphasis> --
|
|
|
- these value affect behaviour of the server such as port
|
|
|
- number at which it listens, number of spawned children
|
|
|
- processes, and log-level. See <xref linkend="coreoptions">
|
|
|
- for a list of available options.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>module loading</emphasis> -- these statements
|
|
|
- link external modules, such as transaction management
|
|
|
- (tm) or stateless UA server (sl) dynamically. See
|
|
|
- <xref linkend="modulereference"> for a list of modules
|
|
|
- included in <application moreinfo="none">ser</application>
|
|
|
- distribution.
|
|
|
- </para>
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- If modules depend on each other, than the depending
|
|
|
- modules must be loaded after modules on which they
|
|
|
- depend. We recommend to load first modules
|
|
|
- <command>tm</command> and <command>sl</command>
|
|
|
- because many other modules (authentication, user
|
|
|
- location, accounting, etc.) depend on these.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>module-specific parameters</emphasis> -- determine
|
|
|
- how modules behave; for example, it is possible to configure
|
|
|
- database to be used by authentication module.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- one or more <emphasis>route blocks</emphasis> containing the
|
|
|
- request processing logic, which includes built-in actions
|
|
|
- as well as actions exported by modules. See <xref linkend="builtinref">
|
|
|
- for a list of built-in actions.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- optionally, if modules supporting reply
|
|
|
- processing (currently only TM) are loaded,
|
|
|
- one or more <emphasis>reply_route blocks</emphasis> containing
|
|
|
- logic triggered by received replies. Restrictions on use of
|
|
|
- actions within <command moreinfo="none">reply_route</command>
|
|
|
- blocks apply -- see <xref linkend="builtinref"> for more
|
|
|
- information.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
-
|
|
|
- <para>
|
|
|
- For more complex examples, see the etc directory in
|
|
|
- <application>ser</application> source distribution.
|
|
|
- It contains the
|
|
|
- <filename moreinfo="none">iptel.cfg</filename> script which is
|
|
|
- in production use at iptel.org's public SIP site and exploits most of
|
|
|
- <application>ser</application> features.
|
|
|
- </para>
|
|
|
-
|
|
|
- <section id="defaultscript">
|
|
|
- <title>Default Configuration Script</title>
|
|
|
- <para>
|
|
|
- The configuration script, <filename moreinfo="none">ser.cfg</filename>,
|
|
|
- is a part of every <application moreinfo="none">ser</application>
|
|
|
- distribution and defines default behaviour. It allows users
|
|
|
- to register with the server and have requests proxied to each
|
|
|
- other.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- After performing
|
|
|
- routine checks, the script looks whether incoming request is for
|
|
|
- served domain. If so and the request is "REGISTER", <application moreinfo="none">ser</application>
|
|
|
- acts as SIP registrar and updates database of user's contacts.
|
|
|
- Optionally, it verifies user's identity first to avoid
|
|
|
- unauthorized contact manipulation.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Non-REGISTER request for served domains are then processed using
|
|
|
- user location database. If a contact is found for requested URI,
|
|
|
- script execution proceeds to stateful forwarding, a negative 404
|
|
|
- reply is generated otherwise. Requests outside served domain
|
|
|
- are always statefully forwarded.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Note that this simple script features several limitations:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- By default, authentication is turned off to avoid
|
|
|
- dependency on mysql. Unless it it turned on, anyone
|
|
|
- can register using any name and "steal" someone else's
|
|
|
- calls.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Even it authentication is turned on, there is no relationship
|
|
|
- between authentication username and address of record. That
|
|
|
- means that for example a user authenticating himself correctly
|
|
|
- with "john.doe" id may register contacts for "gw.bush".
|
|
|
- Site policy may wish to mandate authentication id to be equal
|
|
|
- to username claimed in To header field. <action moreinfo="none">check_to</action>
|
|
|
- action from auth module can be used to enforce such a policy.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- There is no dialing plan implemented. All users are supposed to
|
|
|
- be reachable via user location database. See <xref linkend="numberingplans">
|
|
|
- for more information.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- The script assumes users will be using server's name as a part of
|
|
|
- their address of record. If users wish to use another name (domain
|
|
|
- name for example), this must be set using the <varname>alias</varname>
|
|
|
- options. See <xref linkend="domainmatching"> for more information.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- If authentication is turned on by uncommenting related configuration
|
|
|
- options, clear-text user passwords will by assumed in back-end database.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Default Configuration Script</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&defscr;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </section>
|
|
|
-
|
|
|
- <section id="statefulua">
|
|
|
- <title>Stateful User Agent Server</title>
|
|
|
- <para>
|
|
|
- This examples shows how to make ser act as a stateful user
|
|
|
- agent (UA). Ability to act as as a stateful UA is essential
|
|
|
- to many applications which terminate a SIP path. These
|
|
|
- applications wish to focus on their added value. They
|
|
|
- do not wish to be involved in all SIP gory details, such
|
|
|
- as request and reply retransmission, reply formatting, etc.
|
|
|
- For example, we use the UA functionality to shield
|
|
|
- SMS gateway and instant message store from SIP transactional
|
|
|
- processing.
|
|
|
- The simple example bellow issues a log report on receipt
|
|
|
- of a new transaction.
|
|
|
- If we did not use a stateful UA, every single request retransmission
|
|
|
- would cause the application to be re-executed which would result in
|
|
|
- duplicated SMS messages, instant message in message store or
|
|
|
- log reports.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The most important actions are <command moreinfo="none">
|
|
|
- t_newtran</command> and <command moreinfo="none">
|
|
|
- t_reply</command>. <command moreinfo="none">
|
|
|
-
|
|
|
- t_newtran</command> shields subsequent code from retransmissions.
|
|
|
- It returns success and continues when a new request arrived.
|
|
|
- It exits current route block immediately on receipt of
|
|
|
- a retransmissions. It only returns a negative value when
|
|
|
- a serious error, such as lack of memory, occurs.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <command moreinfo="none">t_reply</command> generates
|
|
|
- a reply for a request. It generates the reply statefully,
|
|
|
- i.e., it is kept for future retransmissions in memory.
|
|
|
- </para>
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- Applications that do not need stateful processing
|
|
|
- may act as stateless UA Server too. They just use
|
|
|
- the <command>sl_send_reply</command> action to
|
|
|
- send replies to requests without keeping any
|
|
|
- state. The benefit is memory cannot run out,
|
|
|
- the drawback is that each retransmission needs to
|
|
|
- be processed as a new request. An example of use
|
|
|
- of a stateless server is shown in
|
|
|
- <xref linkend="redirectserver"> and
|
|
|
- <xref linkend="executingscript">.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <example>
|
|
|
- <title>Stateful UA Server</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
- <!-- ../../examples/uas.cfg -->
|
|
|
- &statefuluaexample;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </section> <!-- Stateful UAS -->
|
|
|
-
|
|
|
- <section id="redirectserver">
|
|
|
- <title>Redirect Server</title>
|
|
|
- <para>
|
|
|
- The redirect example shows how to redirect a request
|
|
|
- to multiple destination using 3xx reply. Redirecting
|
|
|
- requests as opposed to proxying them is essential to
|
|
|
- various scalability scenarios. Once a message is
|
|
|
- redirected, <application moreinfo="none">ser</application>
|
|
|
- discards all related state and is no more involved
|
|
|
- in subsequent SIP transactions (unless the redirection
|
|
|
- addresses point to the same server again).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The key <application>ser</application> actions in this example
|
|
|
- are <command moreinfo="none">append_branch</command> and
|
|
|
- <command moreinfo="none">sl_send_reply</command> (sl module).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <command moreinfo="none">append_branch</command> adds
|
|
|
- a new item to the destination set. The destinations set always
|
|
|
- includes the current URI and may be enhanced up to
|
|
|
- <constant>MAX_BRANCHES</constant> items.
|
|
|
- <command moreinfo="none">sl_send_reply</command> command,
|
|
|
- if passed SIP reply code 3xx, takes all values in current
|
|
|
- destination set and adds them to Contact header field in
|
|
|
- the reply being sent.
|
|
|
- </para>
|
|
|
- <example id="redirectexample">
|
|
|
- <title>Redirect Server</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
- <!-- ../../examples/redirect.cfg -->
|
|
|
- &redirectexample;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </section> <!-- redirect server-->
|
|
|
-
|
|
|
- <section id="executingscript">
|
|
|
- <title>Executing External Script</title>
|
|
|
- <para>
|
|
|
- Like in the previous example, we show how to
|
|
|
- make ser act as a redirect server. The difference is
|
|
|
- that we do not use redirection addresses hardwired in
|
|
|
- <application moreinfo="none">ser</application> script but
|
|
|
- get them from external shell commands. We also use
|
|
|
- ser's ability to execute shell commands to log
|
|
|
- source IP address of incoming SIP requests.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The new commands introduced in this example are
|
|
|
- <command moreinfo="none">exec_msg</command> and
|
|
|
- <command moreinfo="none">exec_uri</command>.
|
|
|
- <command moreinfo="none">exec_msg</command> takes
|
|
|
- current requests, starts an external command, and
|
|
|
- passes the requests to the command's standard input.
|
|
|
- It also passes request's source IP address in
|
|
|
- environment variable named <constant>SRC_IP</constant>.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <command moreinfo="none">exec_uri</command> serves
|
|
|
- for URI rewriting by external applications. The
|
|
|
- <command moreinfo="none">exec_uri</command> action
|
|
|
- passes current URI to the called external program as
|
|
|
- command-line parameter, and rewrites current destination
|
|
|
- set with the program's output. An example use would
|
|
|
- be an implementation of a Least-Cost-Router, software which
|
|
|
- returns URI of the cheapest PSTN provider for a given
|
|
|
- destination based on some pricing tables. <xref linkend="execscript">
|
|
|
- is much easier: it prints fixed URIs on its output using
|
|
|
- shell script <command moreinfo="none">echo</command> command.
|
|
|
- </para>
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- This script works statelessly -- it uses this action for
|
|
|
- stateless replying, <command>sl_send_reply</command>.
|
|
|
- No transaction is kept in memory and each request retransmission
|
|
|
- is processed as a brand-new request. That may be a particular
|
|
|
- concern if the server logic (<command>exec</command> actions
|
|
|
- in this example) is too expensive. See
|
|
|
- <xref linkend="statefulua"> for instructions on how
|
|
|
- to make server logic stateful, so that retransmissions
|
|
|
- are absorbed and do not cause re-execution of the logic.
|
|
|
-
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <example id="execscript">
|
|
|
- <title>Executing External Script</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
- <!-- ../../examples/exec.cfg -->
|
|
|
- &execexample;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </section> <!-- exec example -->
|
|
|
-
|
|
|
- <section id="replyprocessingsection">
|
|
|
- <title>On-Reply Processing (Forward on Unavailable)</title>
|
|
|
- <para>
|
|
|
- Many services depend on status of messages relayed
|
|
|
- downstream: <emphasis>forward on busy</emphasis> and
|
|
|
- <emphasis>forward on no reply</emphasis> to name the
|
|
|
- most well-known ones. To support implementation of
|
|
|
- such services, <application moreinfo="none">ser</application>
|
|
|
- allows to return to request processing when request
|
|
|
- forwarding failed. When a request is reprocessed,
|
|
|
- new request branches may be initiated or the transaction
|
|
|
- can be completed at discretion of script writer.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The primitives used are <command moreinfo="none">t_on_negative(r)</command>
|
|
|
- and <command moreinfo="none">reply_route[r]{}.</command> If
|
|
|
- <command>t_on_negative</command> is called before
|
|
|
- a request is statefuly forwarded and a forwarding failure occurs,
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- will return to request processing in a <command moreinfo="none">reply_route</command>
|
|
|
- block. Failures include receipt of a SIP error
|
|
|
- (status code >= 300 ) from upstream or not receiving
|
|
|
- any final reply within final response period.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The length of the timer is governed by parameters of the
|
|
|
- tm module. <varname>fr_timer</varname> is the length of
|
|
|
- timer set for non-INVITE transactions and INVITE transactions
|
|
|
- for which no provisional response is received. If a timer
|
|
|
- hits, it indicates that a downstream server is unresponsive.
|
|
|
- <varname>fr_inv_timer</varname> governs time to wait for
|
|
|
- a final reply for an INVITE. It is typically longer than
|
|
|
- <varname>fr_timer</varname> because final reply may take
|
|
|
- long time until callee (finds a mobile phone in a pocket and)
|
|
|
- answers the call.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- In <xref linkend="replyprocessing">, <command moreinfo="none">reply_route[1]</command>
|
|
|
- is set to be entered on error using the <command moreinfo="none">t_on_negative(1)</command>
|
|
|
- action. Within this reply block, <application moreinfo="none">ser</application>
|
|
|
- is instructed to initiate a new branch and try to reach called party
|
|
|
- at another destination (sip:[email protected]). To deal with the case when neither the alternate
|
|
|
- destination succeeds, <application moreinfo="none">t_on_negative</application>
|
|
|
- is set again. If the case really occurs, <command moreinfo="none">reply_route[2]</command>
|
|
|
- is entered and a last resort destination (sip:[email protected]) is tried.
|
|
|
- </para>
|
|
|
- <example id="replyprocessing">
|
|
|
- <title>On-Reply Processing</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
- <!-- ../../examples/onr.cfg -->
|
|
|
- &replyexample;
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </example>
|
|
|
- </section> <!-- reply processing -->
|
|
|
- </section> <!-- examples -->
|
|
|
- </chapter>
|
|
|
-
|
|
|
-
|
|
|
- <chapter>
|
|
|
- <title>Server Operation</title>
|
|
|
- <section id="operationalpractices">
|
|
|
- <title>Recommended Operational Practices</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- Operation of a SIP server is not always easy task.
|
|
|
- Server administrators are challenged by broken or
|
|
|
- misconfigured user agents, network and host failures,
|
|
|
- hostile attacks and other stress-makers. All such
|
|
|
- situations may lead to an operational failure. It is sometimes
|
|
|
- very difficult to figure out the root reason of
|
|
|
- a failure, particularly in a distributed environment
|
|
|
- with many SIP components involved.
|
|
|
- In this section,
|
|
|
- we share some of our practices and refer to tools
|
|
|
- which have proven to
|
|
|
- make life of administrators easier
|
|
|
- </para>
|
|
|
-
|
|
|
- <qandaset>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Keeping track of messages is good
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- Frequently, operational errors are discovered or reported
|
|
|
- with a delay.
|
|
|
- Users frustrated by an error
|
|
|
- frequently approach administrators
|
|
|
- and scream "even though my SIP requests were absolutely ok
|
|
|
- yesterday, they were mistakenly denied by your server".
|
|
|
- If administrators do not record all SIP traffic at
|
|
|
- their site, they will be no more able to identify
|
|
|
- the problem reason.
|
|
|
- We thus recommend that site
|
|
|
- operators record all messages passing their site and keep them
|
|
|
- stored for some period of time.
|
|
|
- They may use utilities such as
|
|
|
- <application>ngrep
|
|
|
- </application> or
|
|
|
- <application>tcpdump
|
|
|
- </application>.
|
|
|
- There is also a utility <application moreinfo="none">
|
|
|
- scripts/harv_ser.sh</application> in <application moreinfo="none">
|
|
|
- ser</application> distribution for post-processing
|
|
|
- of captured messages. It summarizes messages captured
|
|
|
- by reply status and user-agent header field.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Real-time Traffic Watching
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- Looking at SIP messages in real-time may help to gain
|
|
|
- understanding of problems. Though there are commercial
|
|
|
- tools available, using a simple, text-oriented tool
|
|
|
- such as <application>ngrep</application> makes the job very well thanks to SIP's textual nature.
|
|
|
- </para>
|
|
|
- <example id="usingngrep">
|
|
|
- <title>Using <application>ngrep</application>
|
|
|
- </title>
|
|
|
- <para>In this example, all messages at port 5060
|
|
|
- which include the string "bkraegelin" are captured
|
|
|
- and displayed</para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@fox s]$ ngrep bkraegelin@ port 5060
|
|
|
-interface: eth0 (195.37.77.96/255.255.255.240)
|
|
|
-filter: ip and ( port 5060 )
|
|
|
-match: bkraegelin@
|
|
|
-#
|
|
|
-U +0.000000 153.96.14.162:50240 -> 195.37.77.101:5060
|
|
|
-REGISTER sip:iptel.org SIP/2.0.
|
|
|
-Via: SIP/2.0/UDP 153.96.14.162:5060.
|
|
|
-From: sip:[email protected].
|
|
|
-To: sip:[email protected].
|
|
|
-Call-ID: [email protected].
|
|
|
-Date: Thu, 26 Sep 2002 22:03:55 GMT.
|
|
|
-CSeq: 101 REGISTER.
|
|
|
-Expires: 10.
|
|
|
-Content-Length: 0.
|
|
|
-.
|
|
|
-
|
|
|
-#
|
|
|
-U +0.000406 195.37.77.101:5060 -> 153.96.14.162:5060
|
|
|
-SIP/2.0 401 Unauthorized.
|
|
|
-Via: SIP/2.0/UDP 153.96.14.162:5060.
|
|
|
-From: sip:[email protected].
|
|
|
-To: sip:[email protected].
|
|
|
-Call-ID: [email protected].
|
|
|
-CSeq: 101 REGISTER.
|
|
|
-WWW-Authenticate: Digest realm="iptel.org", nonce="3d9385170000000043acbf6ba9c9741790e0c57adee73812", algorithm=MD5.
|
|
|
-Server: Sip EXpress router(0.8.8 (i386/linux)).
|
|
|
-Content-Length: 0.
|
|
|
-Warning: 392 127.0.0.1:5060 "Noisy feedback tells: pid=31604 req_src_ip=153.96.14.162 in_uri=sip:iptel.org out_uri=sip:iptel.org via_cnt==1".
|
|
|
-
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Tracing Errors in Server Chains
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- A request may pass any number of proxy servers on
|
|
|
- its path to its destination. If an error occurs
|
|
|
- in the chain, it is difficult for upstream troubleshooters
|
|
|
- and/or users complaining to administrators to learn
|
|
|
- more about error circumstances.
|
|
|
- <application moreinfo="none">ser
|
|
|
- </application> does its best and displays extensive
|
|
|
- diagnostics information in SIP replies. It allows
|
|
|
- troubleshooters and/or users who report to troubleshooters
|
|
|
- to gain additional knowledge about request processing
|
|
|
- status.
|
|
|
- This extended debugging information is part of the warning
|
|
|
- header field. See <xref linkend="usingngrep"> for an illustration
|
|
|
- of a reply that includes such a warning header field. The header
|
|
|
- field contains the following pieces of information:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Server's IP Address -- good to identify
|
|
|
- from which server in a chain the reply
|
|
|
- came.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Incoming and outgoing URIs -- good to
|
|
|
- learn for which URI the reply was
|
|
|
- generated, as it may be rewritten
|
|
|
- many times in the path. Particularly
|
|
|
- useful for debugging of numbering plans.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Number of Via header fields in replied
|
|
|
- request -- that helps in assessment of
|
|
|
- request path length. Upstream clients would
|
|
|
- not know otherwise, how far away in terms
|
|
|
- of SIP hops their requests were replied.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Server's process id. That is useful for
|
|
|
- debugging to discover situations when
|
|
|
- mutliple servers listen at the same
|
|
|
- address.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- IP address of previous SIP hop as seen by
|
|
|
- the SIP server.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- If server administrator is not comfortable with
|
|
|
- disclosing all this information, he can turn them
|
|
|
- off using the <varname>sip_warning</varname> configuration
|
|
|
- option.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- A nice utility for debugging server chains is
|
|
|
- <application moreinfo="none">sipsak</application>,
|
|
|
- Swiss Army Knife, traceroute-like tool for SIP
|
|
|
- developed at iptel.org. It allows you to send
|
|
|
- OPTIONS request with low, increasing Max-Forwards
|
|
|
- header-fields and follow how it propagates in
|
|
|
- SIP network. See its webpage at
|
|
|
- <ulink url="http://sipsak.berlios.de/">
|
|
|
- http://sipsak.berlios.de/
|
|
|
- </ulink>.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Use of SIPSak for Learning SIP Path</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@bat sipsak]$ ./sipsak -T -s sip:[email protected]
|
|
|
-warning: IP extract from warning activated to be more informational
|
|
|
-0: 127.0.0.1 (0.456 ms) SIP/2.0 483 Too Many Hops
|
|
|
-1: ?? (31.657 ms) SIP/2.0 200 OK
|
|
|
- without Contact header
|
|
|
-
|
|
|
- </programlisting>
|
|
|
- <para>
|
|
|
- Note that in this example, the second hop
|
|
|
- server does not issue any warning header fields
|
|
|
- in replies and it is thus impossible to display
|
|
|
- its IP address in <application moreinfo="none">
|
|
|
- SIPsak</application>'s output.
|
|
|
- </para>
|
|
|
- </example>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Watching Server Health
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- Watching Server's operation status in real-time may
|
|
|
- also be a great aid for trouble-shooting.
|
|
|
- <application>ser</application> has an excellent
|
|
|
- facility, a FIFO server, which allows UNIX
|
|
|
- tools to access server's internals. (It is
|
|
|
- similar to how Linux tool access Linux kernel
|
|
|
- via the proc file system.) The FIFO server
|
|
|
- accepts commands via a FIFO (named pipe) and
|
|
|
- returns data asked for. Administrators do not
|
|
|
- need to learn details of the FIFO communication
|
|
|
- and can serve themselves using a front-end
|
|
|
- utility <application moreinfo="none">serctl</application>.
|
|
|
- Of particular interest for
|
|
|
- monitoring server's operation are
|
|
|
- <application moreinfo="none">serctl</application>
|
|
|
- commands
|
|
|
- <command moreinfo="none">ps</command> and
|
|
|
- <command moreinfo="none">moni</command>.
|
|
|
- The former displays running
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- processes, whereas the latter shows statistics.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>serctl ps command</title>
|
|
|
- <para>
|
|
|
- This example shows 10 processes running at a host.
|
|
|
- The process 0, "attendant" watches child processes
|
|
|
- and terminates all of them if a failure occurs in
|
|
|
- any of them. Processes 1-4 listen at local
|
|
|
- interface and processes 5-8 listen at Ethernet
|
|
|
- interface at port number 5060. Process number
|
|
|
- 9 runs FIFO server, and process number 10
|
|
|
- processes all server timeouts.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@fox jiri]$ serctl ps
|
|
|
-0 31590 attendant
|
|
|
-1 31592 receiver child=0 sock=0 @ 127.0.0.1::5060
|
|
|
-2 31595 receiver child=1 sock=0 @ 127.0.0.1::5060
|
|
|
-3 31596 receiver child=2 sock=0 @ 127.0.0.1::5060
|
|
|
-4 31597 receiver child=3 sock=0 @ 127.0.0.1::5060
|
|
|
-5 31604 receiver child=0 sock=1 @ 195.37.77.101::5060
|
|
|
-6 31605 receiver child=1 sock=1 @ 195.37.77.101::5060
|
|
|
-7 31606 receiver child=2 sock=1 @ 195.37.77.101::5060
|
|
|
-8 31610 receiver child=3 sock=1 @ 195.37.77.101::5060
|
|
|
-9 31611 fifo server
|
|
|
-10 31627 timer
|
|
|
-
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Is Server Alive
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- It is essential for solid operation to know
|
|
|
- continuously that server is alive. We've been
|
|
|
- using two tools for this purpose.
|
|
|
- <application moreinfo="none">sipsak</application>
|
|
|
- does a great job of "pinging" a server, which
|
|
|
- may be used for alerting on unresponsive servers.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">monit</application> is
|
|
|
- a server watching utility which alerts when
|
|
|
- a server dies.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Dealing with DNS
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- SIP standard leverages DNS. Administrators of
|
|
|
- <application moreinfo="none">ser</application> should
|
|
|
- be aware of impact of DNS on server's operation.
|
|
|
- Server's attempt to resolve an unresolvable address
|
|
|
- may block a server process in terms of seconds. To be
|
|
|
- safer that the server doesn't stop responding
|
|
|
- due to being blocked by DNS resolving, we recommend
|
|
|
- the following practices:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Start a sufficient number of children processes.
|
|
|
- If one is blocked, the other children will
|
|
|
- keep serving.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Use DNS caching. For example, in Linux,
|
|
|
- there is an <application moreinfo="none">
|
|
|
- nscd</application> daemon available for
|
|
|
- this purpose.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Process transactions statefully if memory
|
|
|
- allows. That helps to absorb retransmissions
|
|
|
- without having to resolve DNS for each of
|
|
|
- them.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Logging
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <anchor id="logging">
|
|
|
- <para>
|
|
|
- <application>ser</application> by default logs
|
|
|
- to <application>syslog</application> facility.
|
|
|
- It is very useful to watch log messages for
|
|
|
- abnormal behaviour. Log messages, subject to
|
|
|
- <application>syslog</application> configuration
|
|
|
- may be stored at different files, or even at remote
|
|
|
- systems. A typical location of the log file is
|
|
|
- <filename>/var/log/messages</filename>.
|
|
|
- </para>
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- One can also use other <application>syslogd</application>
|
|
|
- implementation. <application>metalog</application>
|
|
|
- (<ulink url="http://http://metalog.sourceforge.net//">
|
|
|
- http://metalog.sourceforge.net/
|
|
|
- </ulink>)
|
|
|
- features regular expression matching that enables
|
|
|
- to filter and group log messages.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <para>
|
|
|
- For the purpose of debugging configuration scripts, one may
|
|
|
- want to redirect log messages to console not to pollute
|
|
|
- syslog files. To do so configure <application moreinfo="none">ser</application>
|
|
|
- in the following way:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Attach ser to console by setting <varname>fork=no</varname>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Set explicitely at which address
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- should be listening, e.g., <varname>listen=192.168.2.16</varname>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Redirect log messages to standard error by setting
|
|
|
- <varname>log_stderror=yes</varname>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Set appropriately high log level. (Be sure that you redirected logging
|
|
|
- to standard output. Flooding system logs with many detailed messages
|
|
|
- would make the logs difficult to read and use.) You can set the global
|
|
|
- logging threshold value with the option <varname>debug=nr</varname>,
|
|
|
- where the higher <varname>nr</varname> the more detailed output.
|
|
|
- If you wish to set log level only for some script events, include
|
|
|
- the desired log level as the first parameter of the
|
|
|
- <command moreinfo="none">log</command> action in your script.
|
|
|
- The messages will be then printed if <command moreinfo="none">log</command>'s
|
|
|
- level is lower than the global threshold, i.e., the lower the more
|
|
|
- noisy output you get.
|
|
|
- <example>
|
|
|
- <title>Logging Script</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&logging;
|
|
|
- </programlisting>
|
|
|
- <para>
|
|
|
- The following SIP message causes then logging output as shown
|
|
|
- bellow.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-REGISTER sip:192.168.2.16 SIP/2.0
|
|
|
-Via: SIP/2.0/UDP 192.168.2.33:5060
|
|
|
-From: sip:[email protected]
|
|
|
-To: sip:[email protected]
|
|
|
-Call-ID: [email protected]
|
|
|
-Date: Thu, 27 Feb 2003 15:10:52 GMT
|
|
|
-CSeq: 101 REGISTER
|
|
|
-User-Agent: CSCO/4
|
|
|
-Contact: sip:[email protected]:5060
|
|
|
-Content-Length: 0
|
|
|
-Expires: 600
|
|
|
- </programlisting>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@cat sip_router]$ ./ser -f examples/logging.cfg
|
|
|
-Listening on
|
|
|
- 192.168.2.16 [192.168.2.16]::5060
|
|
|
-Aliases: cat.iptel.org:5060 cat:5060
|
|
|
-WARNING: no fork mode
|
|
|
- 0(0) INFO: udp_init: SO_RCVBUF is initially 65535
|
|
|
- 0(0) INFO: udp_init: SO_RCVBUF is finally 131070
|
|
|
- 0(17379) REGISTER received
|
|
|
- 0(17379) request for other domain received
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- Labeling Outbound Requests
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- Without knowing, which pieces of script code a relayed
|
|
|
- request visited, trouble-shooting would be difficult.
|
|
|
- Scripts typically apply different processing to
|
|
|
- different routes such as to IP phones and PSTN
|
|
|
- gateways. We thus recommend to label outgoing
|
|
|
- requests with a label describing the type of processing
|
|
|
- applied to the request.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Attaching "routing-history" hints to relayed
|
|
|
- requests is as easy as using the
|
|
|
- <command moreinfo="none">append_hf</command>
|
|
|
- action exported by textops module. The following
|
|
|
- example shows how different labels are attached
|
|
|
- to requests to which different routing logic
|
|
|
- was applied.
|
|
|
- <example>
|
|
|
- <title>"Routing-history" labels</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# is the request for our domain?
|
|
|
-# if so, process it using UsrLoc and label it so.
|
|
|
-if (uri=~[@:\.]domain.foo") {
|
|
|
- if (!lookup("location")) {
|
|
|
- sl_send_reply("404", "Not Found");
|
|
|
- break;
|
|
|
- };
|
|
|
- # user found -- forward to him and label the request
|
|
|
- append_hf("P-hint: USRLOC\r\n");
|
|
|
-} else {
|
|
|
-# it is an outbound request to some other domain --
|
|
|
-# indicate it in the routing-history label
|
|
|
- append_hf("P-hint: OUTBOUND\r\n");
|
|
|
-};
|
|
|
-t_relay();
|
|
|
- </programlisting>
|
|
|
- <para>
|
|
|
- This is how such a labeled requests looks
|
|
|
- like. The last header field includes
|
|
|
- a label indicating the script processed
|
|
|
- the request as outbound.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-#
|
|
|
-U 2002/09/26 02:03:09.807288 195.37.77.101:5060 -> 203.122.14.122:5060
|
|
|
-SUBSCRIBE sip:[email protected] SIP/2.0.
|
|
|
-Max-Forwards: 10.
|
|
|
-Via: SIP/2.0/UDP 195.37.77.101;branch=53.b44e9693.0.
|
|
|
-Via: SIP/2.0/UDP 203.122.14.115:16819.
|
|
|
-From: sip:[email protected];tag=5c7cecb3-cfa2-491d-a0eb-72195d4054c4.
|
|
|
-To: sip:[email protected].
|
|
|
-Call-ID: [email protected].
|
|
|
-CSeq: 2 SUBSCRIBE.
|
|
|
-Contact: sip:203.122.14.115:16819.
|
|
|
-User-Agent: Windows RTC/1.0.
|
|
|
-Proxy-Authorization: Digest username="rajeshacl", realm="iptel.org", algorithm="MD5", uri="sip:[email protected]", nonce="3d924fe900000000fd6227db9e565b73c465225d94b2a938", response="a855233f61d409a791f077cbe184d3e3".
|
|
|
-Expires: 1800.
|
|
|
-Content-Length: 0.
|
|
|
-P-hint: OUTBOUND. </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- </qandaset>
|
|
|
- </section> <!-- operational practises -->
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>HOWTOs</title>
|
|
|
- <para>
|
|
|
- This section is a "cookbook" for dealing with common tasks,
|
|
|
- such as user management or controlling access
|
|
|
- to PSTN gateways.
|
|
|
- </para>
|
|
|
- <section>
|
|
|
- <title>User Management</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- There are two tasks related to management of SIP users:
|
|
|
- maintaining user accounts and maintaining user contacts.
|
|
|
- Both these jobs can be done using the
|
|
|
- <application moreinfo="none">serctl</application>
|
|
|
- command-line tool. Also, the complimentary web
|
|
|
- interface, <application moreinfo="none">serweb</application>,
|
|
|
- can be used for this purpose as well.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- If user authentication is turned on, which is a highly
|
|
|
- advisable practice, user account must be created before
|
|
|
- a user can log in. To create a new user account, call the
|
|
|
- <command moreinfo="none">serctl add</command> utility
|
|
|
- with username, password and email as parameters. It
|
|
|
- is important that the environment <varname>SIP_DOMAIN</varname>
|
|
|
- is set to your realm and matches realm values used in
|
|
|
- your script. The realm value is used for calculation
|
|
|
- of credentials stored in subscriber database, which are
|
|
|
- bound permanently to this value.
|
|
|
- <screen format="linespecific">
|
|
|
-[jiri@cat gen_ha1]$ export SIP_DOMAIN=foo.bar
|
|
|
-[jiri@cat gen_ha1]$ serctl add newuser secret [email protected]
|
|
|
-MySql Password:
|
|
|
-new user added
|
|
|
- </screen>
|
|
|
- </para>
|
|
|
- <para><application moreinfo="none">serctl</application> can
|
|
|
- also change user's password or remove existing accounts
|
|
|
- from system permanently.
|
|
|
- <screen format="linespecific">
|
|
|
-[jiri@cat gen_ha1]$ serctl passwd newuser newpassword
|
|
|
-MySql Password:
|
|
|
-password change succeeded
|
|
|
-[jiri@cat gen_ha1]$ serctl rm newuser
|
|
|
-MySql Password:
|
|
|
-user removed
|
|
|
- </screen>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- User contacts are typically automatically uploaded by SIP phones
|
|
|
- to server during registration process and administrators do not
|
|
|
- need to worry about them. However, users
|
|
|
- may wish to append permanent contacts to PSTN gateways
|
|
|
- or to locations in other administrative domains.
|
|
|
- To manipulate the contacts in such cases, use
|
|
|
- <application moreinfo="none">serctl ul</application>
|
|
|
- tool. Note that this is the only correct way
|
|
|
- to update contacts -- direct changes to back-end
|
|
|
- MySql database do not affect server's memory. Also note,
|
|
|
- that if persistence is turned off (usrloc "db_mode"
|
|
|
- parameter set to "0"), all contacts are gone on server
|
|
|
- reboot. Make sure that persistence is enabled if you
|
|
|
- add permanent contacts.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- To add a new permanent contact for a user, call
|
|
|
- <application moreinfo="none">serctl ul add <username>
|
|
|
- <contact></application>. To delete
|
|
|
- all user's contacts, call
|
|
|
- <application>serctl ul rm <username></application>.
|
|
|
- <application moreinfo="none">serctl ul show <username></application>
|
|
|
- prints all current user's contacts.
|
|
|
- <screen format="linespecific">
|
|
|
-[jiri@cat gen_ha1]$ serctl ul add newuser sip:[email protected]
|
|
|
-sip:[email protected]
|
|
|
-200 Added to table
|
|
|
-('newuser','sip:[email protected]') to 'location'
|
|
|
-[jiri@cat gen_ha1]$ serctl ul show newuser
|
|
|
-<sip:[email protected]>;q=1.00;expires=1073741812
|
|
|
-[jiri@cat gen_ha1]$ serctl ul rm newuser
|
|
|
-200 user (location, newuser) deleted
|
|
|
-[jiri@cat gen_ha1]$ serctl ul show newuser
|
|
|
-404 Username newuser in table location not found
|
|
|
- </screen>
|
|
|
- </para>
|
|
|
- </section> <!-- user management -->
|
|
|
- <section>
|
|
|
- <title>User Aliases</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- Frequently, it is desirable for a user to have multiple
|
|
|
- addresses in a domain. For example, a user with username "john.doe" wants to be
|
|
|
- reachable at a shorter address "john" or at a nummerical address
|
|
|
- "12335", so that PSTN callers with digits-only key-pad can reach
|
|
|
- him too.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- With <application moreinfo="none">ser</application>, you can maintain
|
|
|
- a special user-location table and translate existing aliases to canonical
|
|
|
- usernames using the <command moreinfo="none">lookup</command>
|
|
|
- action from usrloc module. The following script fragment demonstrates
|
|
|
- use of <command moreinfo="none">lookup</command> for this purpose.
|
|
|
- <example>
|
|
|
- <title>Configuration of Use of Aliases</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-if (!uri==myself) { # request not for our domain...
|
|
|
- route(1); # go somewhere else, where outbound requests are processed
|
|
|
- break;
|
|
|
-};
|
|
|
-# the request is for our domain -- process registrations first
|
|
|
-if (method=="REGISTER") { route(3); break; };
|
|
|
-
|
|
|
-# look now, if there is an alias in the "aliases" table; don't care
|
|
|
-# about return value: whether there is some or not, move ahead then
|
|
|
-lookup("aliases");
|
|
|
-
|
|
|
-# there may be aliases which translate to other domain and for which
|
|
|
-# local processing is not appropriate; check again, if after the
|
|
|
-# alias translation, the request is still for us
|
|
|
-if (!uri==myself) { route(1); break; };
|
|
|
-
|
|
|
-# continue with processing for our domain...
|
|
|
-...
|
|
|
-
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The table with aliases is updated using the
|
|
|
- <application moreinfo="none">serctl</application>
|
|
|
- tool. <application moreinfo="none">
|
|
|
- serctl alias add <alias> <uri></application>
|
|
|
- adds a new alias,
|
|
|
- <application moreinfo="none">serctl alias show <user></application>
|
|
|
- prints an existing alias, and
|
|
|
- <application moreinfo="none">serctl alias rm <user></application>
|
|
|
- removes it.
|
|
|
- <screen format="linespecific">
|
|
|
-[jiri@cat sip_router]$ serctl alias add 1234 sip:[email protected]
|
|
|
-sip:[email protected]
|
|
|
-200 Added to table
|
|
|
-('1234','sip:[email protected]') to 'aliases'
|
|
|
-[jiri@cat sip_router]$ serctl alias add john sip:[email protected]
|
|
|
-sip:[email protected]
|
|
|
-200 Added to table
|
|
|
-('john','sip:[email protected]') to 'aliases'
|
|
|
-[jiri@cat sip_router]$ serctl alias show john
|
|
|
-<sip:[email protected]>;q=1.00;expires=1073741811
|
|
|
-[jiri@cat sip_router]$ serctl alias rm john
|
|
|
-200 user (aliases, john) deleted
|
|
|
- </screen>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Note that persitence needs to be turned on in usrloc
|
|
|
- module. All changes to aliases will be otherwise lost
|
|
|
- on server reboot. To enable persistence, set the
|
|
|
- db_mode usrloc parameter to a non-zero value.
|
|
|
- <programlisting format="linespecific">
|
|
|
-# ....load module ...
|
|
|
-loadmodule "modules/usrloc/usrloc.so"
|
|
|
-# ... turn on persistence -- all changes to user tables are immediately
|
|
|
-# flushed to mysql
|
|
|
-modparam("usrloc", "db_mode", 1)
|
|
|
-# the SQL address:
|
|
|
-modparam("usrloc", "db_url","sql://ser:secret@dbhost/ser")
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
- </section> <!-- user aliases -->
|
|
|
- <section id=acl>
|
|
|
- <title>Access Control (PSTN Gateway)</title>
|
|
|
- <para>
|
|
|
- It is sometimes important to exercise some sort of
|
|
|
- access control. A typical use case is when
|
|
|
- <application moreinfo="none">ser</application> is used
|
|
|
- to guard a PSTN gateway. If a gateway was not well guarded,
|
|
|
- unauthorized users would be able to use it to terminate calls in PSTN,
|
|
|
- and cause high charges to its operator.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There are few issues you need to understand when
|
|
|
- configuring <application moreinfo="none">ser</application>
|
|
|
- for this purpose. First, if a gateway is built or configured to
|
|
|
- accept calls from anywhere, callers may easily bypass your
|
|
|
- access control server and communicate with the gateway
|
|
|
- directly. You then need to enforce at transport layer
|
|
|
- that signaling is only accepted if coming via
|
|
|
- <application moreinfo="none">ser</application> and
|
|
|
- deny SIP packets coming from other hosts and port numbers.
|
|
|
- Your network must be configured not to allow forged
|
|
|
- IP addresses. Also, you need to turn on record-routing
|
|
|
- to assure that all session requests will travel via
|
|
|
- <application moreinfo="none">ser</application>.
|
|
|
- Otherwise, caller's devices would send subsequent SIP requests
|
|
|
- directly to your gateway, which would fail because of transport
|
|
|
- filtering.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Authorization (i.e., the process of determining who may call where)
|
|
|
- is facilitated in <application moreinfo="none">ser</application>
|
|
|
- using <emphasis>group membership</emphasis> concept. Scripts make
|
|
|
- decisions on whether a caller is authorized to make a call to
|
|
|
- a specific destination based on user's membership in a group.
|
|
|
- For example a policy may be set up to allow calls to international
|
|
|
- destinations only to users, who are members of an "int" group.
|
|
|
- Before user's group membership is checked, his identity
|
|
|
- must be verified first. Without cryptographic verification of user's
|
|
|
- identity, it would be impossible to assert that a caller really
|
|
|
- is who he claims to be.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The following script demonstrates, how to configure <application moreinfo="none">ser</application>
|
|
|
- as an access control server for a PSTN gateway. The script verifies user
|
|
|
- identity using digest authentication, checks user's privileges,
|
|
|
- and forces all requests to visit the server.
|
|
|
- <example>
|
|
|
- <title>Script for Gateway Access Control</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&gatewayacl;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Use the <application moreinfo="none">serctl</application> tool to
|
|
|
- maintain group membership.
|
|
|
- <application moreinfo="none">serctl acl grant <username> <group></application>
|
|
|
- makes a user member of a group,
|
|
|
- <application>serctl acl show <username></application> shows groups
|
|
|
- of which a user is member, and
|
|
|
- <application>serctl acl revoke <username> [<group>]</application>
|
|
|
- revokes user's membership in one or all groups.
|
|
|
- <screen format="linespecific">
|
|
|
-[jiri@cat sip_router]$ serctl acl grant john int
|
|
|
-MySql Password:
|
|
|
-+------+-----+---------------------+
|
|
|
-| user | grp | last_modified |
|
|
|
-+------+-----+---------------------+
|
|
|
-| john | int | 2002-12-08 02:09:20 |
|
|
|
-+------+-----+---------------------+
|
|
|
- </screen>
|
|
|
- </para>
|
|
|
- </section> <!-- access control -->
|
|
|
- <section>
|
|
|
- <title>Accounting</title>
|
|
|
- <para>
|
|
|
- In some scenarios, like termination of calls in PSTN, SIP administrators
|
|
|
- may wish to keep track of placed calls. <application moreinfo="none">ser</application>
|
|
|
- can be configured to report on completed transactions. Reports are sent
|
|
|
- by default to <application moreinfo="none">syslog</application> facility.
|
|
|
- Experimental support for RADIUS and mysql accounting exists as well.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Note that <application moreinfo="none">ser</application> is no way
|
|
|
- call-stateful. It reports on completed transactions, i.e., after
|
|
|
- a successful call set up is reported, it drops any call-related
|
|
|
- state. When a call is terminated, transactional state for BYE request
|
|
|
- is created and forgotten again after the transaction completes.
|
|
|
- This is a feature and not a bug -- keeping only transactional
|
|
|
- state allows for significantly higher scalability. It is then
|
|
|
- up to the accounting application to correlate call initiation
|
|
|
- and termination events.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- To enable call accounting, tm and acc modules need to be loaded,
|
|
|
- requests need to be processed statefuly and labeled for
|
|
|
- accounting. That means, if you want a transaction to be reported,
|
|
|
- the initial request must have taken the path
|
|
|
- "<command>setflag(X)</command>, <command>t_relay</command>"
|
|
|
- in <application>ser</application> script. X must have the
|
|
|
- value configured in <varname>acc_flag</varname>
|
|
|
- configuration option.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Also note, that by default only transactions that initiate
|
|
|
- a SIP dialog (typically INVITE) visit a proxy server.
|
|
|
- Subsequent transactions are exhanged directly between
|
|
|
- end-devices, do not visit proxy server and cannot be
|
|
|
- reported. To be able to report on subsequent transactions,
|
|
|
- you need to force them visit proxy server by turning
|
|
|
- record-routing on.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Configuration with Enabled Accounting</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&accountingexample;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </section> <!-- accounting -->
|
|
|
- <section>
|
|
|
- <title>Reliability</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- It is essential to guarantee continuous
|
|
|
- service operation even under erroneous conditions,
|
|
|
- such as host or network failure. The major issue in such
|
|
|
- situations is transfer of operation to a backup
|
|
|
- infrastructure and making clients use it.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The SIP standard's use of DNS SRV records has been
|
|
|
- explicitly constructed to handle with server failures.
|
|
|
- There may be multiple servers responsible for a domain
|
|
|
- and referred to by DNS. If it is impossible to communicate
|
|
|
- with a primary server, a client can proceed to another one.
|
|
|
- Backup servers may be located in a different geographic
|
|
|
- area to minimize risk caused by areal operational
|
|
|
- disasters: lack of power, flooding, earthquake, etc.
|
|
|
- <note>
|
|
|
- <sidebar>
|
|
|
- <para>Unless there are redundant DNS
|
|
|
- servers, fail-over capability cannot be guaranteed.
|
|
|
- </para>
|
|
|
- </sidebar>
|
|
|
- </note>
|
|
|
- Unfortunately, at the moment of writing this documentation
|
|
|
- (end of December 2002) only very few SIP products
|
|
|
- actually implement the DNS fail-over mechanism. Unless
|
|
|
- networks with SIP devices supporting this mechanism are
|
|
|
- built, alternative mechanisms must be used to force
|
|
|
- clients to use backup servers. Such a mechanism is
|
|
|
- disconnecting primary server and replacing him with
|
|
|
- a backup server locally.
|
|
|
- It unfortunately precludes geographic dispersion and
|
|
|
- requires network multihoming to avoid dependency on
|
|
|
- single IP access. Another method is to update DNS
|
|
|
- when failure of the primary server is detected.
|
|
|
- The primary drawback of this method is its latency:
|
|
|
- it may take long time until all clients learn to use
|
|
|
- the new server.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The easier part of the redundancy story is replication of
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- data. <application moreinfo="none">ser</application>
|
|
|
- relies on replication capabilities of its back-end database.
|
|
|
- This works with one exception: user location database.
|
|
|
- User location database is a frequently accessed table,
|
|
|
- which is thus cached in server's memory to improve
|
|
|
- performance. Back-end replication does not affect
|
|
|
- in-memory tables, unless server reboots. To facilitate
|
|
|
- replication of user location database,
|
|
|
- server's SIP replication feature must be enabled
|
|
|
- in parallel with back-end replication.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The design idea of replication of user location database
|
|
|
- is easy: Replicate any successful REGISTER requests to
|
|
|
- a peer server. To assure that digest credentials can
|
|
|
- be properly verified, both servers need to use the same
|
|
|
- digest generation secret and maintain synchronized time.
|
|
|
- A known limitation of this method is it does not replicate
|
|
|
- user contacts entered in another way, for example using
|
|
|
- web interface through FIFO server.
|
|
|
- The following script example shows configuration of
|
|
|
- a server that replicates all REGISTERs.
|
|
|
- <example>
|
|
|
- <title>Script for Replication of User Contacts</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&replicateexample;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </section> <!-- reliability -->
|
|
|
- <section>
|
|
|
- <title>Stateful versus Stateless Forwarding</title>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> allows both stateless
|
|
|
- and stateful request processing. This memo explains what are pros and cons of
|
|
|
- using each method. The rule of thumb is "stateless for scalability,
|
|
|
- stateful for services". If you are unsure which you need, stateful
|
|
|
- is a safer choice which supports more usage scenarios.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Stateless forwarding with the
|
|
|
- <command moreinfo="none">forward(uri:host, uri:port)</command> action
|
|
|
- guarantees high scalability. It withstands high load and
|
|
|
- does not run out of memory. A perfect use of stateless forwarding
|
|
|
- is load distribution.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Stateful forwarding using the <command moreinfo="none">t_relay()</command>
|
|
|
- action is known to scale worse. It can quickly run out of memory and
|
|
|
- consumes more CPU time. Nevertheless, there are scenarios which are
|
|
|
- not implementable without stateful processing. In particular:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Accounting</emphasis> requires stateful processing
|
|
|
- to be able to collect transaction status and issue a single
|
|
|
- report when a transaction completes.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Forking</emphasis> only works with stateful forwarding.
|
|
|
- Stateless forwarding only forwards to the default URI out of the
|
|
|
- whole destination set.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>DNS resolution</emphasis>. DNS resolution may be
|
|
|
- better server with stateful processing. If a request is forwarded
|
|
|
- to a destination whose address takes long time to resolve,
|
|
|
- a server process is blocked and unresponsive. Subsequent
|
|
|
- request retransmissions from client will cause other processes
|
|
|
- to block too if requests are processed statelessly. As a result,
|
|
|
- <application moreinfo="none">ser</application> will quickly
|
|
|
- run out of available processes. With stateful forwarding,
|
|
|
- retransmissions are absorbed and do not cause blocking of
|
|
|
- another process.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>Forwarding Services</emphasis>. All sort of services
|
|
|
- with the "forward_on_event" logic, which rely on
|
|
|
- <command moreinfo="none">t_on_negative</command> tm
|
|
|
- action must be processed statefuly.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- Fail-over.
|
|
|
- </emphasis>
|
|
|
- If you wish to try out another destination, after a primary destination
|
|
|
- failed you need to use stateful processing. With stateless processing
|
|
|
- you never know with what status a forwarded request completed downstream
|
|
|
- because you immediately release all processing information after the
|
|
|
- request is sent out.
|
|
|
-
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- Positive return value of stateless
|
|
|
- <command moreinfo="none">forward</command> action only indicates that
|
|
|
- a request was successfuly sent out, and does not gain any knowledge
|
|
|
- about whether it was successfuly received or replied. Neither does
|
|
|
- the return value of
|
|
|
- the stateful <command moreinfo="none">t_relay</command> action family
|
|
|
- gain you this knowledge. However, these actions store transactional
|
|
|
- context with which includes original request and allows you to
|
|
|
- take an action when a negative reply comes back or a timer strikes.
|
|
|
- See <xref linkend="replyprocessingsection"> for an example script
|
|
|
- which launches another
|
|
|
- branch if the first try fails.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
-
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- </section> <!-- stateful vs. stateless -->
|
|
|
- <section>
|
|
|
- <title>Serving Multiple Domains</title>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> can be configured to
|
|
|
- serve multiple domains. To do so, you need to take the following steps:
|
|
|
- <orderedlist>
|
|
|
- <listitem id="createtable">
|
|
|
- <para>
|
|
|
- Create separate subscriber and location database table
|
|
|
- for each domain served and name them uniquely.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Configure your script to distinguish between multiple
|
|
|
- served domains. Use regular expressions for domain
|
|
|
- matching as described in <xref linkend="redomainmatching">.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Update table names in usrloc and auth actions to reflect
|
|
|
- names you created in <xref linkend="createtable">.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- </orderedlist>
|
|
|
- </para>
|
|
|
- </section> <!-- multiple domains -->
|
|
|
- <section id="missedcalls">
|
|
|
- <title>Reporting Missed Calls</title>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> can report missed
|
|
|
- calls via <application moreinfo="none">syslog</application> facility
|
|
|
- or to mysql. Mysql reporting can be utilized by
|
|
|
- <application moreinfo="none">ser</application>'s
|
|
|
- complementary web-interface, <application moreinfo="none">serweb</application>.
|
|
|
- (See more in <xref linkend="serweb">).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Reporting on missed calls is enabled by acc module.
|
|
|
- There are two cases, on which you want to report. The first
|
|
|
- case is when a callee is off-line. The other case is when
|
|
|
- a user is on-line, but call establishment fails. There
|
|
|
- may be many failure reasons (call cancellation, inactive phone,
|
|
|
- busy phone, server timer, etc.), all of them leading to
|
|
|
- a negative (>=300) reply sent to caller. The acc module
|
|
|
- can be configured to issue a missed-call report whenever
|
|
|
- a transaction completes with a negative status. Two following
|
|
|
- script fragment deals with both cases.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- First, it reports
|
|
|
- on calls missed due to off-line callee status
|
|
|
- using the <command moreinfo="none">acc_request</command>
|
|
|
- action. The action is wrapped in transactional
|
|
|
- processing (<command moreinfo="none">t_newtran</command>)
|
|
|
- to guarantee that reports are not
|
|
|
- duplicated on receipt of retransmissions.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Secondly, transaction to on-line users are marked
|
|
|
- to be reported on failure. That is what the
|
|
|
- <command moreinfo="none">setflag(3)</command> action
|
|
|
- is responsible for, along with the configuration option
|
|
|
- "missed_flag". This option configures <application moreinfo="none">ser</application>
|
|
|
- to report on all transactions, which were marked
|
|
|
- with flag 3.
|
|
|
- <programlisting format="linespecific">
|
|
|
-loadmodule("modules/tm/tm.so");
|
|
|
-loadmodule("modules/acc/acc.so");
|
|
|
-....
|
|
|
-# if a call is labeled using setflag(3) and is missed, it will
|
|
|
-# be reported
|
|
|
-...
|
|
|
-modparam("acc", "missed_flag", 3 );
|
|
|
-if (!lookup("location")) {
|
|
|
- # call invitations to off-line users are reported using the
|
|
|
- # acc_request action; to avoid duplicate reports on request
|
|
|
- # retransmissions, request is processed statefuly (t_newtran,
|
|
|
- # t_reply)
|
|
|
- if ((method=="INVITE" || method=="ACK") && t_newtran() ) {
|
|
|
- t_reply("404", "Not Found");
|
|
|
- acc_request("404 Not Found");
|
|
|
- break;
|
|
|
- };
|
|
|
- # all other requests to off-line users are simply replied
|
|
|
- # statelessly and no reports are issued
|
|
|
- sl_send_reply("404", "Not Found");
|
|
|
- break;
|
|
|
-} else {
|
|
|
- # user on-line; report on failed transactions; mark the
|
|
|
- # transaction for reporting using the same number as
|
|
|
- # configured above; if the call is really missed, a report
|
|
|
- # will be issued
|
|
|
- setflag(3);
|
|
|
- # forward to user's current destination
|
|
|
- t_relay();
|
|
|
- break;
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </para>
|
|
|
- </section> <!-- missed calls -->
|
|
|
- <section>
|
|
|
- <title>NAT Traversal</title>
|
|
|
- <para>
|
|
|
- NATs are worst things that ever happened to SIP. These devices
|
|
|
- are very popular because they help to conserve IP address space
|
|
|
- and save money charged for IP addresses. Unfortunately, they
|
|
|
- translate addresses in a way which is not compatible with SIP.
|
|
|
- SIP advertises receiver addresses in its payload. The advertised
|
|
|
- addresses are invalid out of NATted networks. As a result,
|
|
|
- SIP communication does not work accross NATs without extra
|
|
|
- effort.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There are few methods that may be deployed to traverse NATs.
|
|
|
- How proper their use is depends on the deployment scenario.
|
|
|
- Unfortunatelly, all the methods have some limitations and
|
|
|
- there is no straight-forward solution addressing all
|
|
|
- scenarios. Note that none of these methods takes explicit
|
|
|
- support in <application moreinfo="none">ser</application>.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The first issue is whether SIP users are in control of
|
|
|
- their NATs. If not (NATs are either operated by ISP or
|
|
|
- they are sealed to prevent users setting them up), the
|
|
|
- only method is use of a STUN-enabled phone. STUN is
|
|
|
- a very simple protocol used to fool NAT in such a way,
|
|
|
- they permit SIP sessions. Currently, we are aware of
|
|
|
- one softphone (kphone) and one hardphone (snom) with
|
|
|
- STUN support, other vendors are working on STUN support
|
|
|
- too. Unfortunately, STUN gives no NAT traversal
|
|
|
- guarantee -- there are types of NATs, so called
|
|
|
- symmetric NATs, over which STUN fails to work.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- There is actually yet another method to address
|
|
|
- SIP-unaware, user-uncontrolled NATs. It is based
|
|
|
- on a proxy server, which relays all signaling and
|
|
|
- media and mangles packets to make them more
|
|
|
- NAT-friendly. The very serious problem with this
|
|
|
- method is it does not scale.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- If users are in control of their own NAT, as typically residential
|
|
|
- users are, they can still use STUN. However, they may use other
|
|
|
- alternatives too. One of them is to replace their NAT with
|
|
|
- a SIP-aware NAT. Such NATs have built-in SIP awareness,
|
|
|
- that patches problems caused by address translations. Prices
|
|
|
- of such devices are getting low and there are available
|
|
|
- implementations (Intertex, Cisco/PIX). No special support
|
|
|
- in phones is needed.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Other emerging option is UPnP. UPnP is a protocol that allows
|
|
|
- phones to negotiate with NAT boxes. You need UPnP support in
|
|
|
- both, NAT and phones. As UPnP NATs are quite affordable,
|
|
|
- costs are not an obstacle. Currently, we are aware of one
|
|
|
- SIP phone (SNOM) with UPnP support.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Geeks not wishing to upgrade their firewall to a SIP-aware or
|
|
|
- UPnP-enabled one may try to configure static address translation.
|
|
|
- That takes phones with configuration ability to use fixed port
|
|
|
- numbers and advertise outside address in signaling. Cisco phones
|
|
|
- have this capability, for example. The NAT devices need to
|
|
|
- be configured to translate outside port ranges to the
|
|
|
- ranges configured in phones.
|
|
|
- </para>
|
|
|
- </section> <!-- NAT traversal -->
|
|
|
- <section>
|
|
|
- <title>Authentication Policy: Prevention of Unauthorized Domain
|
|
|
- Name Use in From and More</title>
|
|
|
- <para>
|
|
|
- Malicous users can claim a name of domain, to which they do
|
|
|
- not administratively belong, in From header field. This
|
|
|
- behaviour cannot be generally prevented. The reason is
|
|
|
- that requests with such a faked header field do not need
|
|
|
- to visit servers of the domain in question. However, if they
|
|
|
- do so, it is desirable to assure that users claiming
|
|
|
- membership in a domain are actually associated with it.
|
|
|
- Otherwise the faked requests would be relayed and appear
|
|
|
- as coming from the domain, which would increase
|
|
|
- credibility of the faked address and decrease credibility of
|
|
|
- the proxy server.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Preventing unathorized domain name use in relayed requests
|
|
|
- is not difficult.
|
|
|
- One needs to authenticate each request with name of the
|
|
|
- served domain in From header field. To do so, one can
|
|
|
- search for such a header field using <command moreinfo="none">search</command>
|
|
|
- action (textops module) and force authentication if the
|
|
|
- search succeeds.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- A straight-forward solution might be to authenticate
|
|
|
- ALL requests. However, that only works in closed
|
|
|
- networks in which all users have an account in the
|
|
|
- server domain. In open networks, it is desirable to permit
|
|
|
- incoming calls from callers from other domains without
|
|
|
- any authentication. For example, a company may wish
|
|
|
- to accept calls from unknown callers who are
|
|
|
- new prospective customers.
|
|
|
-
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# does the user claim our domain "foo.bar" in From?
|
|
|
-if (search("^(f|From):.*foo.bar")) {
|
|
|
- # if so, verify credential
|
|
|
- if (!proxy_authorize("foo.bar", "subscriber")) {
|
|
|
- # don't proceed if credentials broken; challenge
|
|
|
- proxy_challenge("foo.bar", "0");
|
|
|
- break;
|
|
|
- };
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- In general, the authentication policy may be very rich. You may not
|
|
|
- forget each request deserves its own security and you need to
|
|
|
- decide whether it shall be authenticated or not. As mentioned
|
|
|
- above, in closed networks, you may want to authenticate absolutely
|
|
|
- every request. That however prohibits traffic from users from
|
|
|
- other domains. A pseudo-example of a reasonable policy is attached:
|
|
|
- it looks whether a request is registration, it claims to originate
|
|
|
- from our domain in From header field, or is a local request to
|
|
|
- another domain.
|
|
|
- <programlisting format="linespecific">
|
|
|
-# (example provided by Michael Graff on [serusers] mailing list
|
|
|
-if (to me):
|
|
|
- if register
|
|
|
- www_authorize or fail if not a valid register
|
|
|
- done
|
|
|
- if claiming to be "From" one of the domains I accept registrations for
|
|
|
- proxy_authorize
|
|
|
- done
|
|
|
- if not to me (I'm relaying for a local phone to an external address)
|
|
|
- proxy_authorize
|
|
|
- done
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- You also may want to apply additional restriction to how
|
|
|
- digest username relates to usernames claimed in From and
|
|
|
- To header fields. For example, the <command moreinfo="none">check_to</command>
|
|
|
- action enforces the digest id to be equal to username
|
|
|
- in To header fields. That is good in preventing someone
|
|
|
- with valid credentials to register as someone else
|
|
|
- (e.g., sending a REGISTER with valid credentials of
|
|
|
- "joe" and To belonging to "alice"). Similarly,
|
|
|
- <command moreinfo="none">check_from</command> is used
|
|
|
- to enforce username in from to equal to digest id.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- There may be a need for a more complex relationship
|
|
|
- between From/To username and digest id. For example,
|
|
|
- providers with an established user/password database
|
|
|
- may wish to keep using it, whereas permitting users
|
|
|
- to claim some telephone numbers in From. To address
|
|
|
- such needs generally, there needs to be a 1:N mapping
|
|
|
- between digest id and all usernames that are acceptable
|
|
|
- for it. This is being addressed in a newly contributed
|
|
|
- module "domain", which also addresses more generally
|
|
|
- issues of domain matching for multidomain scenarios.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Other operational aspect affecting the authentication policy
|
|
|
- is guarding PSTN gateways (see <xref linkend="acl">). There
|
|
|
- may be destinations that are given away for free whereas
|
|
|
- other destinations may require access control using
|
|
|
- group membership, to which authentication is a prerequisity.
|
|
|
- </para>
|
|
|
-
|
|
|
- </section> <!-- authentication policy, faked froms -->
|
|
|
- <section>
|
|
|
- <title>Connecting to PBX Voicemail Using a Cisco Gateway</title>
|
|
|
- <para>
|
|
|
- In some networks, administrators may wish to utilize their
|
|
|
- PBX voicemail systems behind PSTN gateways. There is a practical problem
|
|
|
- in many network settings: it is not clear for whom a call to
|
|
|
- voicemail is. If voicemail is identified by a single number,
|
|
|
- which is then put in INVITE's URI, there is no easy way to
|
|
|
- learn for whom a message should be recorded. PBX voicemail
|
|
|
- utilize that PSTN protocols signal the number of originally
|
|
|
- called party. If you wish to make the PBX voicemail work,
|
|
|
- you need to convey the number in SIP and translate it in
|
|
|
- PSTN gateways to its PSTN counterpart.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There may be many different ways to achieve this scenario. Here
|
|
|
- we describe the proprietary mechanism Cisco gateways use and how to
|
|
|
- configure <application moreinfo="none">ser</application> to
|
|
|
- make the gateways happy. Cisco gateways expect the number
|
|
|
- of originally called party to be located in proprietary
|
|
|
- <varname>CC-Diversion</varname> header field. When a SIP
|
|
|
- INVITE sent via a PSTN gateway to PBX voicemail has number
|
|
|
- of originally called party in the header field, the voicemail
|
|
|
- system knows for whom the incoming message is. That is at least
|
|
|
- true for AS5300/2600 with Cisco IOS 12.2.(2)XB connected to
|
|
|
- Nortel pbxs via PRI. (On the other hand, 12.2.(7b) is known
|
|
|
- not to work in this scenario.)
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> needs then to
|
|
|
- be configured to append the <varname>CC-Diversion</varname>
|
|
|
- header field name for INVITEs sent to PBX voicemail.
|
|
|
- The following script shows that: when initial forwarding
|
|
|
- fails (nobody replies, busy is received, etc.), a new branch
|
|
|
- is initiated to the pbx's phone number.
|
|
|
- <command moreinfo="none">append_urihf</command> is used to
|
|
|
- append the <varname>CC-Diversion</varname> header field. It
|
|
|
- takes two parameters: prefix, which includes header name,
|
|
|
- and suffix which takes header field separator.
|
|
|
- <command moreinfo="none">append_urihf</command> inserts
|
|
|
- original URI between those two.
|
|
|
- <example>
|
|
|
- <title>Forwarding to PBX/Voicemail via Cisco Gateways</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&ccdiversion;
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
-
|
|
|
- </para>
|
|
|
- </section>
|
|
|
- </section> <!-- howtos -->
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>Troubleshooting</title>
|
|
|
- <para>
|
|
|
- This section gathers practices how to deal with errors
|
|
|
- known to occur frequently. To understand how to watch
|
|
|
- SIP messages, server logs, and in genereal how to
|
|
|
- troubleshoot, read also <xref linkend="operationalpractices">.
|
|
|
- </para>
|
|
|
- <qandaset>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- SIP requests are replied by <application>ser</application> with
|
|
|
- "483 Too Many Hops" or "513 Message Too Large"
|
|
|
- </para>
|
|
|
- </question>
|
|
|
-
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- In both cases, the reason is probably an error in
|
|
|
- request routing script which caused an infinite loop.
|
|
|
- You can easily verify whether this happens by
|
|
|
- watching SIP traffic on loopback interface. A typical
|
|
|
- reason for misrouting is a failure to match local
|
|
|
- domain correctly. If a server fails to recognize
|
|
|
- a request for itself, it will try to forward it
|
|
|
- to current URI in believe it would forward them
|
|
|
- to a foreign domain. Alas, it forwards the request
|
|
|
- to itself again. This continues to happen until
|
|
|
- value of max_forwards header field reaches zero
|
|
|
- or the request grows too big. Solutions is easy:
|
|
|
- make sure that domain matching is correctly
|
|
|
- configured. See <xref linkend="domainmatching">
|
|
|
- for more information how to get it right.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
-
|
|
|
- <question>
|
|
|
-
|
|
|
- <para>
|
|
|
-
|
|
|
- Windows Messenger authentication fails.
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <anchor id="msmbug">
|
|
|
- <para>
|
|
|
- The most likely reason for this problem is a bug
|
|
|
- in Windows Messenger. WM only authenticates if
|
|
|
- server name in request URI equals authentication
|
|
|
- realm. After a challenge is sent by SIP server,
|
|
|
- WM does not resubmit the challenged request at all
|
|
|
- and pops up authentication window again.
|
|
|
- If you want to authenticate WM, you need to
|
|
|
- set up your realm value to equal server name.
|
|
|
- If your server has no name, IP address can be used
|
|
|
- as realm too. The realm value is configured in
|
|
|
- scripts as the first parameter of all
|
|
|
- <command>{www|proxy}_{authorize|challenge}</command>
|
|
|
- actions.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- On a multihomed host, forwarded messages carry other
|
|
|
- interface in Via than used for sending, or messages
|
|
|
- are not sent and an error log is issued "invalid
|
|
|
- sendtoparameters one possible reason is the server
|
|
|
- is bound to localhost".
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <anchor id="mhomed">
|
|
|
- <para>
|
|
|
- Set the configuration option <varname>mhome</varname>
|
|
|
- to "1". <application moreinfo="none">ser</application>
|
|
|
- will then attempt to calculate the correct interface.
|
|
|
- It's not done by default as it degrades performance
|
|
|
- on single-homed hosts or multi-homed hosts that are
|
|
|
- not set-up as routers.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- I receive "ERROR: t_newtran: transaction already in process" in my logs.
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- That looks like an erroneous use of tm module in script.
|
|
|
- tm can handle only one transaction per request. If you
|
|
|
- attempt to instantiate a transaction multiple times,
|
|
|
- <application moreinfo="none">ser</application> will complain.
|
|
|
- Anytime any of <command moreinfo="none">t_newtran</command>,
|
|
|
- <command moreinfo="none">t_relay</command> or
|
|
|
- <command moreinfo="none">t_relay_to</command> actions is
|
|
|
- encountered, tm attempts to instantiate a transaction.
|
|
|
- Doing so twice fails. Make sure that any of this
|
|
|
- commands is called only once during script execution.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- <qandaentry>
|
|
|
- <question>
|
|
|
- <para>
|
|
|
- I try to add an alias but
|
|
|
- <command moreinfo="none">serctl</command>
|
|
|
- complains that table does not exist.
|
|
|
- </para>
|
|
|
- </question>
|
|
|
- <answer>
|
|
|
- <para>
|
|
|
- You need to run <application moreinfo="none">ser</application>
|
|
|
- and use the command
|
|
|
- <command moreinfo="none">lookup("aliases")</command>
|
|
|
- in its routing script. That's because the table
|
|
|
- of aliases is
|
|
|
- stored in cache memory for high speed. The cache
|
|
|
- memory is only set up when the
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- is running and configured to use it. If that is
|
|
|
- not the case,
|
|
|
- <application moreinfo="none">serctl</application>
|
|
|
- is not able to manipulate the aliases table.
|
|
|
- </para>
|
|
|
- </answer>
|
|
|
- </qandaentry>
|
|
|
- </qandaset>
|
|
|
- </section> <!-- troubleshooting -->
|
|
|
- </chapter> <!-- operation -->
|
|
|
-
|
|
|
-
|
|
|
- <chapter>
|
|
|
- <title>Application Writing</title>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> offers several
|
|
|
- ways to couple its functionality with applications. The coupling
|
|
|
- is bidirectional: <application moreinfo="none">ser</application>
|
|
|
- can utilize external applications and external applications can
|
|
|
- utilize <application moreinfo="none">ser</application>.
|
|
|
- An example of the former direction would be an external program
|
|
|
- determining a least-cost route for a called destination using
|
|
|
- a pricing table. An example of the latter case
|
|
|
- is a web application for server provisioning.
|
|
|
- Such an application may want to send instant
|
|
|
- messages, query all current user's locations and monitor server
|
|
|
- health. An existing web interface to <application moreinfo="none">ser</application>,
|
|
|
- <application moreinfo="none">serweb</application>, actually
|
|
|
- does all of it.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The easiest, language-independent way of using external logic
|
|
|
- from <application moreinfo="none">ser</application> is provided
|
|
|
- by exec module. exec module allows <application moreinfo="none">ser</application>
|
|
|
- to start external programs on receipt of a request. The
|
|
|
- programs can execute arbitrary logic and/or affect routing of SIP
|
|
|
- requests. A great benefit of this programming method is it
|
|
|
- is language-independent. Programmers may use programming languages
|
|
|
- that are effective or with which they are best familiar.
|
|
|
- <xref linkend="usingexec"> gives additional examples illustrating
|
|
|
- use of the exec module.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Another method for extending <application moreinfo="none">ser</application>
|
|
|
- capabilities is to write new modules in C. This method takes
|
|
|
- deeper understanding of <application moreinfo="none">ser</application>
|
|
|
- internals but gains the highest flexibility. Modules can implement
|
|
|
- arbitrary brand-new commands upon which <application moreinfo="none">ser</application>
|
|
|
- scripts can rely on. Guidelines on module programming can be
|
|
|
- found in <application moreinfo="none">ser</application>
|
|
|
- programmer's handbook available from iptel.org website.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- To address needs of applications wishing to leverage
|
|
|
- <application moreinfo="none">ser</application>,
|
|
|
- <application moreinfo="none">ser</application> exports
|
|
|
- parts of its functionality via its built-in
|
|
|
- "Application FIFO server". This is a simple textual
|
|
|
- interface that allows any external applications
|
|
|
- to communicate with the server. It can be used to
|
|
|
- send instant messages, manipulate user contacts,
|
|
|
- watch server health, etc. Programs written in any
|
|
|
- language (PHP, shell scripts, Perl, C, etc.) can
|
|
|
- utilize this feature. How to use it is shown in
|
|
|
- <xref linkend="fifoserver">.
|
|
|
- </para>
|
|
|
-
|
|
|
-
|
|
|
- <section id="usingexec">
|
|
|
- <title>Using exec Module</title>
|
|
|
- <para>
|
|
|
-
|
|
|
- The easiest way is to couple <application moreinfo="none">ser</application>
|
|
|
- with external applications via the <emphasis>exec</emphasis>
|
|
|
- module. This module allows execution of logic and URI manipulation
|
|
|
- by external applications on request receipt. While very
|
|
|
- simple, many useful services can be
|
|
|
- implemented this way. External applications can be written in
|
|
|
- any programming language and do not be aware of SIP at all.
|
|
|
- <application moreinfo="none">ser</application> interacts with
|
|
|
- the application via standard input/output and environment
|
|
|
- variables.
|
|
|
-
|
|
|
-
|
|
|
- </para>
|
|
|
-
|
|
|
-
|
|
|
- <para>
|
|
|
- For example, an external shell script
|
|
|
- may send an email whenever a request for a user arrives.
|
|
|
- </para>
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Using exec: Step 1</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# send email if a request for user "jiri" arrives
|
|
|
-if (uri=~"^sip:jiri@") {
|
|
|
- exec_msg("echo 'body: call arrived'|mail -s 'call for you' jiri");
|
|
|
-}
|
|
|
- </programlisting>
|
|
|
- </example> <!-- step 1 -->
|
|
|
- <para>
|
|
|
- In this example, the <command moreinfo="none">exec_msg</command>
|
|
|
- action starts an external shell. It passes a received SIP request
|
|
|
- to shell's input. In the shell, <command>mail</command> command
|
|
|
- is called to send a notification by e-mail.
|
|
|
- The script however features several simplifications:
|
|
|
- <orderedlist inheritnum="ignore" continuation="restarts">
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- The email notification does not tell who was calling.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- The logic is not general: it only supports one well-known user (jiri).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- The logic is stateless. It will be executed on
|
|
|
- every retransmission.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- It is a script fragment not explaining the
|
|
|
- context. This particular example may be for
|
|
|
- example used to report on missed calls.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </orderedlist>
|
|
|
- All of these simplifications are addressed step-by-step
|
|
|
- in the following examples.
|
|
|
- </para>
|
|
|
- <example> <!-- step 2: who called me -->
|
|
|
- <title>Using exec: Step 2, Who Called Me</title>
|
|
|
- <para>
|
|
|
- This example shows how to display caller's address
|
|
|
- in email notification. The trick is easy: process
|
|
|
- request received on shell programm's input
|
|
|
- and grep From header field.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&execstep2;
|
|
|
- </programlisting>
|
|
|
- <para>
|
|
|
- The following two figures show an example SIP request and
|
|
|
- email notification generated on its receipt.
|
|
|
-
|
|
|
- <screen format="linespecific">
|
|
|
-
|
|
|
-<![CDATA[
|
|
|
-INVITE sip:[email protected] SIP/2.0
|
|
|
-Via: SIP/2.0/UDP 195.37.77.100:5040
|
|
|
-Max-Forwards: 10
|
|
|
-From: "alice" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
|
|
|
-To: <sip:[email protected]>
|
|
|
-Call-ID: [email protected]
|
|
|
-CSeq: 2 INVITE
|
|
|
-Contact: <sip:123.20.128.35:9315>
|
|
|
-Content-Type: application/sdp
|
|
|
-Content-Length: 451
|
|
|
-
|
|
|
---- SDP payload snipped ---
|
|
|
-]]>
|
|
|
-
|
|
|
- </screen>
|
|
|
-
|
|
|
- email received:
|
|
|
-
|
|
|
- <screen format="linespecific">
|
|
|
-<![CDATA[
|
|
|
-Date: Thu, 12 Dec 2002 14:25:02 +0100
|
|
|
-From: root <[email protected]>
|
|
|
-To: [email protected]
|
|
|
-Subject: request for you
|
|
|
-
|
|
|
-From: "alice" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
|
|
|
-request received
|
|
|
-]]>
|
|
|
- </screen>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There is another way to learn values of request
|
|
|
- header fields, simpler than use of <command moreinfo="none">grep</command>.
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- parses header fields and passes their values in
|
|
|
- environment variables. Their names correspond
|
|
|
- to header field names prefixed with "SIP_HF_".
|
|
|
- <programlisting format="linespecific">
|
|
|
-# send email if a request for "jiri" arrives
|
|
|
-if (uri=~"^sip:jiri@") {
|
|
|
- exec_msg("echo request received from $SIP_HF_FROM | mail -s 'request for you' jiri");
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
- Moreover, several other values are passed in environment
|
|
|
- variables. <varname>SIP_TID</varname> is a token uniquely identifying
|
|
|
- transaction, to which the request belongs. <varname>SIP_DID</varname>
|
|
|
- includes to-tag, and is empty in requests creating a dialog.
|
|
|
- <varname>SIP_SRCIP</varname> includes IP address, from which the
|
|
|
- request was sent. <varname>SIP_RURI</varname> and <varname>SIP_ORURI</varname>
|
|
|
- include current request-uri and original request-uri respectively,
|
|
|
- <varname>SIP_USER</varname> and <varname>SIP_OUSER</varname> username
|
|
|
- parts of these. The following listing shows environment variables
|
|
|
- passed to a shell script on receipt of the previous message:
|
|
|
- <programlisting format="linespecific">
|
|
|
-<![CDATA[
|
|
|
-SIP_HF_MAX_FORWARDS=10
|
|
|
-SIP_HF_VIA=SIP/2.0/UDP 195.37.77.100:5040
|
|
|
-SIP_HF_CSEQ=2 INVITE
|
|
|
-SIP_HF_FROM="alice" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
|
|
|
-SIP_ORUI=sip:[email protected]
|
|
|
-SIP_HF_CONTENT_LENGTH=451
|
|
|
-SIP_TID=3b6b8295db0835815847b1f35f3b29b8
|
|
|
-SIP_DID=
|
|
|
-SIP_RURI=iptel.org
|
|
|
-SIP_HF_TO=<sip:[email protected]>
|
|
|
-SIP_OUSER=jiri
|
|
|
-SIP_HF_CALLID=d10815e0-bf17-4afa-8412-d9130a793d96@213.20.128.35
|
|
|
-SIP_SRCIP=195.37.77.100
|
|
|
-SIP_HF_CONTENT_TYPE=application/sdp
|
|
|
-SIP_HF_CONTACT=<sip:123.20.128.35:9315>
|
|
|
-]]>
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </para>
|
|
|
- </example> <!-- step 2, who called me -->
|
|
|
-
|
|
|
-
|
|
|
- <example> <!-- step 3, make the script work for anyone -->
|
|
|
- <title>Using exec: step 3, Make The Script Work For Anyone</title>
|
|
|
- <para>
|
|
|
- A drawback of the previous example is it works only
|
|
|
- for one well-known user: request URI is matched against
|
|
|
- his SIP address and notification is sent to his hard-wired email
|
|
|
- address. In real scenarios, one would like
|
|
|
- to enable such a service for all users without enumerating
|
|
|
- their addresses in the script. The missing piece
|
|
|
- is translation of user's SIP name to his email address.
|
|
|
- This information is maintained in subscriber profiles,
|
|
|
- stored in MySQL by <application moreinfo="none">ser</application>.
|
|
|
- To translate the username to email address, the executed script
|
|
|
- needs to query the MySQL database. That is what this example
|
|
|
- shows. First, an SQL query is constructed which looks up
|
|
|
- email address of user, for whom a request arrived. If the
|
|
|
- query does not return a valid email address, the script
|
|
|
- returns with an error status and <application moreinfo="none">ser</application>
|
|
|
- script replies with "user does not exist". Otherwise
|
|
|
- an email notification is sent.
|
|
|
-
|
|
|
- <programlisting format="linespecific">
|
|
|
-&execstep3;
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
- </example> <!-- step 3 make the script work for anyone -->
|
|
|
- <example> <!-- step 4, stateful processing -->
|
|
|
- <title>Adding Stateful Processing</title>
|
|
|
- <para>
|
|
|
- The previously improved example still features a shortcoming.
|
|
|
- When a message retransmission arrives due to a nework
|
|
|
- mistake such as lost reply, the email notification is
|
|
|
- executed again and again. That happens because the script
|
|
|
- is stateless, i.e., no track of current transactions is
|
|
|
- kept. The script does not know whether a request is
|
|
|
- a new or a retransmitted one. Transaction management may
|
|
|
- be introduced by use of tm module as described in
|
|
|
- <xref linkend="statefulua">. In the script,
|
|
|
- <command moreinfo="none">t_newtran</command> is first
|
|
|
- called to absorb requests retransmission -- if they
|
|
|
- occur, script does not continue. Then, as in the previous
|
|
|
- example, an exec module action is called. Eventually,
|
|
|
- a reply is sent statefully.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- Note carefuly: it is important that the stateful
|
|
|
- reply processing (<command moreinfo="none">t_reply</command>)
|
|
|
- is used as opposed to using stateless replies
|
|
|
- (<command moreinfo="none">sl_send_reply</command>).
|
|
|
- Otherwise, the outgoing reply would not affect
|
|
|
- transactional context and would not be resent on
|
|
|
- receipt of a request retransmission.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <programlisting format="linespecific">
|
|
|
-&execstep4;
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </para>
|
|
|
- </example> <!-- step 4, stateful processing -->
|
|
|
- <example> <!-- step 5, full exec use -->
|
|
|
- <title>Full Example of exec Use</title>
|
|
|
- <para>
|
|
|
- The last example iteration shows how to integrate the
|
|
|
- email notification on missed calls with the default
|
|
|
- <application moreinfo="none">ser</application> script
|
|
|
- (see <xref linkend="defaultscript">). It generates an
|
|
|
- email for every call invitation to an off-line user.
|
|
|
- <programlisting format="linespecific">
|
|
|
-&execstep5;
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
-
|
|
|
- <para>
|
|
|
- Production "missed calls" services may want to
|
|
|
- report on calls missed for other reasons than
|
|
|
- being off-line too. Particularly, users may wish to be
|
|
|
- reported calls missed due to call cancellation,
|
|
|
- busy status or a downstream failure. Such missed
|
|
|
- calls can be easily reported to syslog or mysql
|
|
|
- using the acc module (see <xref linkend="missedcalls">).
|
|
|
- The other, more general way, is to return to request
|
|
|
- processing on receipt of a negative reply.
|
|
|
- (see <xref linkend="replyprocessingsection">). Before
|
|
|
- a request is forwarded, it is labeled to be
|
|
|
- re-processed in a <command moreinfo="none">reply_route</command>
|
|
|
- on receipt of a negative reply -- this is what
|
|
|
- <command moreinfo="none">t_on_negative</command> action
|
|
|
- is used for. It does not matter what caused the transaction
|
|
|
- to fail -- it may be unresponsive downstream server,
|
|
|
- server responding with 6xx, or server sending a 487
|
|
|
- reply, because an INVITE was cancelled. When any such
|
|
|
- circumstances occur (i.e., transaction does not complete
|
|
|
- with a 2xx status code), <command moreinfo="none">reply_route</command>
|
|
|
- is entered.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The following <application moreinfo="none">ser</application>
|
|
|
- script reports missed calls in all possible cases.
|
|
|
- It reports them when a user is off-line as well as when
|
|
|
- a user is on-line, but INVITE transaction does not complete
|
|
|
- successfully.
|
|
|
- <programlisting format="linespecific">
|
|
|
-&execstep5b;
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
-
|
|
|
- </example> <!-- step 5, full exec use -->
|
|
|
-
|
|
|
- </section> <!-- using exec -->
|
|
|
-
|
|
|
- <section id="fifoserver">
|
|
|
- <title>Application FIFO Server</title>
|
|
|
-
|
|
|
- <para>
|
|
|
- Application FIFO server is a very powerful method to program
|
|
|
- SIP services. The most valuable benefit
|
|
|
- is it works with SIP-unaware applications
|
|
|
- written in any programming language. Textual nature of the
|
|
|
- FIFO interface allows for easy integration with a lot of
|
|
|
- existing programs. Today, <application moreinfo="none">ser</application>'s
|
|
|
- complementary web-interface, <application moreinfo="none">serweb</application>,
|
|
|
- written in PHP, leverages the FIFO interface when displaying
|
|
|
- and changing user location records stored in server's memory.
|
|
|
- It uses this interface to send instant messages too, without
|
|
|
- any knowledge of underlying <acronym>SIP</acronym> stack.
|
|
|
- Another application relying on the FIFO interface is
|
|
|
- <application moreinfo="none">serctl</application>, <application moreinfo="none">ser</application>
|
|
|
- management utility. The command-line utility can browse
|
|
|
- server's in-memory user-location database, display
|
|
|
- running processes and operational statistics.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The way the FIFO server works is similar to how
|
|
|
- <filename moreinfo="none">/proc</filename> filesystem works
|
|
|
- on some operating systems. It provides a human-readable way
|
|
|
- to access <application moreinfo="none">ser</application>'s
|
|
|
- internals. Applications dump their requests into the FIFO
|
|
|
- server and receive a status report when request processing
|
|
|
- completes. <application moreinfo="none">ser</application>
|
|
|
- exports a lot of its functionality located in both the
|
|
|
- core and external modules through the FIFO server.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- FIFO requests are formed easily. They begin with a command
|
|
|
- enclosed in colons and followed by name of file or pipe (relative
|
|
|
- to <filename moreinfo="none">/tmp/</filename> path), to which
|
|
|
- a reply should be printed. The first request line may be
|
|
|
- followed by additional lines with command-specific
|
|
|
- parameters. For example, the <command moreinfo="none">t_uac_dlg</command>
|
|
|
- FIFO command for initiating a transaction allows
|
|
|
- to pass additional header fields and message body to
|
|
|
- a newly created transaction. Each request is terminated by
|
|
|
- an empty line. Whole requests must be sent by applications
|
|
|
- atomically in a single batch to avoid mixing with
|
|
|
- requests from other applications. Requests are sent to
|
|
|
- pipe at which <application moreinfo="none">ser</application>
|
|
|
- listens (filename configured by the <varname>fifo</varname> config
|
|
|
- file option).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- An easy way to use the FIFO interface is via the
|
|
|
- <application moreinfo="none">serctl</application>
|
|
|
- command-line tool. When called along with "fifo",
|
|
|
- FIFO command name, and optional parameters, the tool
|
|
|
- generates a FIFO request and prints request result.
|
|
|
- The following example shows use of this tool with
|
|
|
- the <command moreinfo="none">uptime</command> and
|
|
|
- <command moreinfo="none">which</command> commands.
|
|
|
- <command moreinfo="none">uptime</command> returns
|
|
|
- server's running time, <command moreinfo="none">which</command>
|
|
|
- returns list of available FIFO commands. Note that only
|
|
|
- the built-in FIFO command set is displayed as no modules
|
|
|
- were loaded in this example.
|
|
|
- <example>
|
|
|
- <title>Use of <application moreinfo="none">serctl</application>
|
|
|
- to Access FIFO Server</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@cat test]$ serctl fifo uptime
|
|
|
-Now: Fri Dec 6 17:56:10 2002
|
|
|
-Up Since: Fri Dec 6 17:56:07 2002
|
|
|
-Up time: 3 [sec]
|
|
|
-
|
|
|
-[jiri@cat test]$ serctl fifo which
|
|
|
-ps
|
|
|
-which
|
|
|
-version
|
|
|
-uptime
|
|
|
-print
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- The request which the <application moreinfo="none">serctl</application>
|
|
|
- command-line tool sent to FIFO server looked like this:
|
|
|
- <example>
|
|
|
- <title><command moreinfo="none">uptime</command> FIFO Request</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-:uptime:ser_receiver_1114
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- This request contains no parameters and consists only of
|
|
|
- command name enclosed in colons and name of file, to which
|
|
|
- a reply should be printed. FIFO replies consist of a status
|
|
|
- line followed by optional parameters. The status line consists,
|
|
|
- similarly to <acronym>SIP</acronym> reply status, of
|
|
|
- a three-digit status code and a reason phrase. Status codes
|
|
|
- with leading digit 2 (200..299) are considered positive,
|
|
|
- any other values indicate an error. For example, FIFO server
|
|
|
- returns "500" if execution of a non-existing FIFO command is
|
|
|
- requested.
|
|
|
- <example>
|
|
|
- <title>FIFO Errors</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@cat sip_router]$ serctl fifo foobar
|
|
|
-500 command 'foobar' not available
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Showing User Contacts Using serctl</title>
|
|
|
- <para>
|
|
|
- Another example of use of FIFO is accessing server's
|
|
|
- in-memory user location database. That's a very powerful
|
|
|
- feature: web applications and other tools can use it
|
|
|
- to gain users access to the database. They can add new
|
|
|
- contacts (like permanent gateway destinations), remove
|
|
|
- and review their whereabouts. The example here utilizes
|
|
|
- FIFO command <command>ul_show_contact</command> to
|
|
|
- retrieve current whereabouts of user "jiri".
|
|
|
- <programlisting>
|
|
|
-<![CDATA[
|
|
|
-[jiri@fox ser]$ serctl fifo ul_show_contact location jiri
|
|
|
-<sip:195.37.78.160:14519>;q=0.00;expires=1012
|
|
|
-]]>
|
|
|
- </programlisting>
|
|
|
- </para>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The user location example demonstrates an essential feature
|
|
|
- of the FIFO server: extensibility. It is able to export new
|
|
|
- commands implemented in new modules.
|
|
|
- Currently, usrloc module exports FIFO
|
|
|
- commands for maintaining in-memory user location
|
|
|
- database and tm module exports FIFO commands for
|
|
|
- management of SIP transactions. See the
|
|
|
- example in
|
|
|
- <filename moreinfo="none">examples/web_im/send_im.php</filename>
|
|
|
- for how to initiate a SIP transaction
|
|
|
- (instant message)
|
|
|
- from a PHP script via the FIFO server. This example
|
|
|
- uses FIFO command
|
|
|
- <command moreinfo="none">t_uac_dlg</command>. The command
|
|
|
- is followed by parameters: header fields and
|
|
|
- message body. The same FIFO command can be used from
|
|
|
- other environments to send instant messages too. The
|
|
|
- following example shows how to send instant messages
|
|
|
- from a shell script.
|
|
|
- <example>
|
|
|
- <title>Sending IM From Shell Script</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-#!/bin/sh
|
|
|
-#
|
|
|
-# call this script to send an instant message; script parameters
|
|
|
-# will be displayed in message body
|
|
|
-#
|
|
|
-# paremeters mean: message type, request-URI, outbound server is
|
|
|
-# left blank ("."), required header fields From and To follow,
|
|
|
-# then optional header fields terminated by dot and optional
|
|
|
-# dot-terminated body
|
|
|
-
|
|
|
-cat > /tmp/ser_fifo <<EOF
|
|
|
-:t_uac_dlg:hh
|
|
|
-NOTIFY
|
|
|
-sip:[email protected]
|
|
|
-.
|
|
|
-From: sip:[email protected]
|
|
|
-To: sip:[email protected]
|
|
|
-foo: bar_special_header
|
|
|
-x: y
|
|
|
-p_header: p_value
|
|
|
-Contact: <sip:[email protected]:9>
|
|
|
-Content-Type: text/plain; charset=UTF-8
|
|
|
-.
|
|
|
-Hello world!!!! $@
|
|
|
-.
|
|
|
-EOF
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Manipulation of User Contacts</title>
|
|
|
- <para>
|
|
|
- The following example shows use of FIFO server to change
|
|
|
- user's contacts. This may be very practical, if for example
|
|
|
- a user wishes to set up his cell phone number as his temporary
|
|
|
- contact. The cell phone, which is behind a PSTN gateway, cannot
|
|
|
- register automatically using SIP. The user needs to set
|
|
|
- forwarding manually through some convenient web interface.
|
|
|
- The web interface needs to have the ability to upload new user's
|
|
|
- contacts to <application moreinfo="none">ser</application>.
|
|
|
- This is what the <command moreinfo="none">ul_add</command> FIFO
|
|
|
- command is good far. Paremeterized by user's name, table name,
|
|
|
- expiration time and wight, it allows external applications to
|
|
|
- introduce new contacts to server's in-memory user location table.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The example is borrowed from <application moreinfo="none">serweb</application>,
|
|
|
- <application moreinfo="none">ser</application>'s web
|
|
|
- PHP-written interface.
|
|
|
- It consists of a short "stub" function which carries out
|
|
|
- all mechanics of FIFO communication and of forming the FIFO
|
|
|
- request.
|
|
|
- </para>
|
|
|
- <programlisting format="linespecific">
|
|
|
-<![CDATA[
|
|
|
-
|
|
|
-/* construct and send a FIFO command; the command parameters $sip_address,
|
|
|
- $expires are PHP variables originating from an HTML form
|
|
|
- */
|
|
|
- $fifo_cmd=":ul_add:".$config->reply_fifo_filename."\n".
|
|
|
- $config->ul_table."\n". //table
|
|
|
- $user_id."\n". //username
|
|
|
- $sip_address."\n". //contact
|
|
|
- $expires."\n". //expires
|
|
|
- $config->ul_priority."\n\n"; //priority
|
|
|
- $message=write2fifo($fifo_cmd, $errors, $status);
|
|
|
-
|
|
|
-/* .......... snip .................. */
|
|
|
-
|
|
|
-/* this is the stub function for communicating with FIFO server.
|
|
|
- it dumps a request to FIFO server, opens a reply FIFO and
|
|
|
- reads server's reply from it
|
|
|
-*/
|
|
|
-function write2fifo($fifo_cmd, &$errors, &$status){
|
|
|
- global $config;
|
|
|
-
|
|
|
- /* open fifo now */
|
|
|
- $fifo_handle=fopen( $config->fifo_server, "w" );
|
|
|
- if (!$fifo_handle) {
|
|
|
- $errors[]="sorry -- cannot open fifo"; return;
|
|
|
- }
|
|
|
-
|
|
|
- /* create fifo for replies */
|
|
|
- @system("mkfifo -m 666 ".$config->reply_fifo_path );
|
|
|
-
|
|
|
- /* add command separator */
|
|
|
- $fifo_cmd=$fifo_cmd."\n";
|
|
|
-
|
|
|
- /* write fifo command */
|
|
|
- if (fwrite( $fifo_handle, $fifo_cmd)==-1) {
|
|
|
- @unlink($config->reply_fifo_path);
|
|
|
- @fclose($fifo_handle);
|
|
|
- $errors[]="sorry -- fifo writing error"; return;
|
|
|
- }
|
|
|
- @fclose($fifo_handle);
|
|
|
-
|
|
|
- /* read output now */
|
|
|
- @$fp = fopen( $config->reply_fifo_path, "r");
|
|
|
- if (!$fp) {
|
|
|
- @unlink($config->reply_fifo_path);
|
|
|
- $errors[]="sorry -- fifo reading error"; return;
|
|
|
- }
|
|
|
-
|
|
|
- $status=fgetS($fp,256);
|
|
|
- if (!$status) {
|
|
|
- @unlink($config->reply_fifo_path);
|
|
|
- $errors[]="sorry -- fifo reading error"; return;
|
|
|
- }
|
|
|
-
|
|
|
- $rd=fread($fp,8192);
|
|
|
- @unlink($config->reply_fifo_path);
|
|
|
-
|
|
|
- return $rd;
|
|
|
-}
|
|
|
-]]>
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- <para>
|
|
|
- See
|
|
|
- <xref linkend="fiforeference"> for a complete listing
|
|
|
- of FIFO commands available with current
|
|
|
- <application moreinfo="none">ser</application>
|
|
|
- distribution.
|
|
|
- </para>
|
|
|
- <section>
|
|
|
- <title>Advanced Example: Click-To-Dial</title>
|
|
|
- <para>
|
|
|
- A very useful SIP application is phonebook with
|
|
|
- "click-to-dial" feature. It allows users to keep their
|
|
|
- phonebooks on the web and dial by clicking on an entry.
|
|
|
- The great advantage is that you can use the phonebook
|
|
|
- alone with any phone you have. If you temporarily use
|
|
|
- another phone, upgrade it permanently with another make,
|
|
|
- or use multiple phones in parallel, your phonebook will
|
|
|
- stay with you on the web. You just need to click an entry
|
|
|
- to initiate a call. Other scenario using "click-to-dial"
|
|
|
- feature includes "click to be connected with our
|
|
|
- sales representative".
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There are basically two ways how to build such a feature:
|
|
|
- distributed and centralized. We prefer the distributed
|
|
|
- approach since it is very robust and leight-weighted.
|
|
|
- The "click-to-dial" application just needs to instruct
|
|
|
- the calling user to call a destination and that's it.
|
|
|
- (That's done using "REFER" method.)
|
|
|
- Then, the calling user takes over whereas the initating
|
|
|
- application disappears from signaling and
|
|
|
- is no longer involved in subsequent communication. Which
|
|
|
- is good because such a simple design scales well.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The other design alternative is use of a B2BUA
|
|
|
- <footnote>
|
|
|
- <para>
|
|
|
- See <filename moreinfo="none">
|
|
|
- draft-ietf-sipping-3pcc-02.txt
|
|
|
- </filename> for more details.
|
|
|
- </para>
|
|
|
- </footnote>
|
|
|
- which acts as a "middleman" involved in signaling during the
|
|
|
- whole session. It is complex: ringing needs to be achieved
|
|
|
- using a media server, it introduces session state,
|
|
|
- mangling of SIP payloads, complexity when QoS reservation
|
|
|
- is used and possibly other threats which result from
|
|
|
- e2e-unfriendly design. The only benefit
|
|
|
- is it works even for poor phones which do not support
|
|
|
- REFER -- which should not matter because you do not wish
|
|
|
- to buy such.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- So how does "distributed click-to-dial" application
|
|
|
- work? It is simple. The core piece is sending a REFER
|
|
|
- request to the calling party. REFER method is typically
|
|
|
- used for call transfer and it means "set up a call
|
|
|
- to someone else".
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- There is an issue -- most phones
|
|
|
- don't accept unsolicited REFER. If a malicious
|
|
|
- user made your phone to call thirty destinations without
|
|
|
- your agreement, you would certainly not appreciate it.
|
|
|
- The workaround is that first of all the click-to-dial
|
|
|
- application gives you a "wrapper call". If you accept it,
|
|
|
- the application will send a REFER which will be considered
|
|
|
- by the phone as a part of approved communication and
|
|
|
- granted. Be aware that without cryptography,
|
|
|
- security is still weak. Anyone who saw an INVITE can
|
|
|
- generate an acceptable REFER.
|
|
|
- <example>
|
|
|
- <title>Call-Flow for Click-To-Dial Using REFER</title>
|
|
|
-
|
|
|
- <programlisting format="linespecific">
|
|
|
+&operation;
|
|
|
|
|
|
- CTD Caller Callee
|
|
|
- #1 INVITE
|
|
|
- ----------------->
|
|
|
- ...
|
|
|
- caller answers
|
|
|
- #2 200
|
|
|
- <-----------------
|
|
|
- #3 ACK
|
|
|
- ----------------->
|
|
|
- #4 REFER
|
|
|
- ----------------->
|
|
|
- #5 202
|
|
|
- <-----------------
|
|
|
- #6 BYE
|
|
|
- ----------------->
|
|
|
- #7 200
|
|
|
- <-----------------
|
|
|
- #8 INVITE
|
|
|
- ------------------>
|
|
|
- #9 180 ringing
|
|
|
- <------------------
|
|
|
+&apps;
|
|
|
|
|
|
+&otherapps;
|
|
|
|
|
|
-#1 click-to-dial (CTD) is started and the "wrapper call" is initiated
|
|
|
-INVITE caller
|
|
|
-From: controller
|
|
|
-To: caller
|
|
|
-SDP: on hold
|
|
|
-
|
|
|
-#2 calling user answes
|
|
|
-200 OK
|
|
|
-From: controller
|
|
|
-To: caller
|
|
|
-
|
|
|
-#3 CTD acknowledges
|
|
|
-ACK caller
|
|
|
-From controller
|
|
|
-To: caller
|
|
|
-
|
|
|
-#4 CTD initiates a transfer
|
|
|
-REFER caller
|
|
|
-From: controller
|
|
|
-To: caller
|
|
|
-Refer-To: callee
|
|
|
-Refered-By: controller
|
|
|
-
|
|
|
-#5 caller confirms delivery of REFER
|
|
|
-202 Accepted
|
|
|
-From: controller
|
|
|
-To: caller
|
|
|
-
|
|
|
-#6 CTD terminates the wrapper call -- it is no longer needed
|
|
|
-BYE caller
|
|
|
-From: controller
|
|
|
-To: caller
|
|
|
-
|
|
|
-#7 BYE is confirmed
|
|
|
-200 Ok
|
|
|
-From: controller
|
|
|
-To: caller
|
|
|
-
|
|
|
-#8 caller initates transaction solicited through REFER
|
|
|
-INVITE callee
|
|
|
-From: caller
|
|
|
-To: callee
|
|
|
-Referred-By: controller
|
|
|
-
|
|
|
-#9 that's it -- it is now up to callee to answer the INVITE
|
|
|
-180 ringing
|
|
|
-From: caller
|
|
|
-To: callee
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Implementation of this scenario is quite
|
|
|
- straight-forward: you initiate INVITE, BYE and
|
|
|
- REFER transaction.
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- The largest amount of code
|
|
|
- is spent with getting dialog processing right.
|
|
|
- The subsequent BYE and REFER transactions need to
|
|
|
- be build using information learned from the reply
|
|
|
- to INVITE: Contact header field, To-tag and Route
|
|
|
- set. That's what the function
|
|
|
- <function moreinfo="none">filter_fl</function>
|
|
|
- is used for. The "main" part just initiates
|
|
|
- each of the transactions, waits for its completion
|
|
|
- and proceeds to the next one until BYE is over.
|
|
|
- Source code of the example written in Bourne shell
|
|
|
- is available in source distrubtion, in
|
|
|
- <filename moreinfo="none">examples/ctd.sh</filename>.
|
|
|
- A PHP implementation exists as well.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Running the CTD Example</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-[jiri@cat examples]$ ./ctd.sh
|
|
|
-destination unspecified -- taking default value sip:[email protected]
|
|
|
-caller unspecified -- taking default value sip:[email protected]
|
|
|
-invitation succeeded
|
|
|
-refer succeeded
|
|
|
-bye succeeded
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </section> <!-- click-to-dial -->
|
|
|
-<!-- for some reason, this does not work :-(
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Initiating a SIP Transaction from PHP via FIFO</title>
|
|
|
-
|
|
|
-
|
|
|
- <programlisting format="linespecific">
|
|
|
- <textobject>
|
|
|
- <textdata fileref="../../examples/web_im/send_im.php" format="linespecific">
|
|
|
- </textobject>
|
|
|
-
|
|
|
- </programlisting>
|
|
|
-
|
|
|
-
|
|
|
- </example>
|
|
|
--->
|
|
|
-
|
|
|
- </section> <!-- FIFO server -->
|
|
|
- </chapter>
|
|
|
-
|
|
|
- <chapter id="complementaryapps">
|
|
|
- <title>Complementary Applications</title>
|
|
|
- <section id="serctl">
|
|
|
- <title><application>serctl</application> command-line tool</title>
|
|
|
- <para>
|
|
|
- <application>serctl</application> is a command-line utility which allows to
|
|
|
- perform most of management tasks needed to operate
|
|
|
- <application moreinfo="none">ser</application>: adding users, changing their passwords,
|
|
|
- watching server status, etc. Usage of utility is
|
|
|
- as follows:
|
|
|
-
|
|
|
- <example>
|
|
|
- <title><application>serctl</application> usage</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-
|
|
|
-usage:
|
|
|
- * subscribers *
|
|
|
- serctl add <username> <password> <email> .. add a new subscriber (*)
|
|
|
- serctl passwd <username> <passwd> ......... change user's password (*)
|
|
|
- serctl rm <username> ...................... delete a user (*)
|
|
|
- serctl mail <username> .................... send an email to a user
|
|
|
- serctl alias show [<alias>] ............... show aliases
|
|
|
- serctl alias rm <alias> ................... remove an alias
|
|
|
- serctl alias add <alias> <uri> ............ add an aliases
|
|
|
-
|
|
|
- * access control lists *
|
|
|
- serctl acl show [<username>] .............. show user membership
|
|
|
- serctl acl grant <username> <group> ....... grant user membership (*)
|
|
|
- serctl acl revoke <username> [<group>] .... grant user membership(s) (*)
|
|
|
-
|
|
|
- * usrloc *
|
|
|
- serctl ul show [<username>]................ show in-RAM online users
|
|
|
- serctl ul rm <username> ................... delete user's UsrLoc entries
|
|
|
- serctl ul add <username> <uri> ............ introduce a permanent UrLoc entry
|
|
|
- serctl showdb [<username>] ................ show online users flushed in DB
|
|
|
-
|
|
|
- * server health *
|
|
|
- serctl monitor ............................ show internal status
|
|
|
- serctl ps ................................. show runnig processes
|
|
|
- serctl fifo ............................... send raw commands to FIFO
|
|
|
-
|
|
|
- Commands labeled with (*) will prompt for a MySQL password.
|
|
|
- If the variable PW is set, the password will not be prompted.
|
|
|
-
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- <note>
|
|
|
- <para>
|
|
|
-
|
|
|
- Prior to using the utility, you have to first
|
|
|
- set the environment variable <constant>SIP_DOMAIN</constant>
|
|
|
- to locally appropriate value (e.g., "foo.com"). It is
|
|
|
- needed for calculation of user credentials, which depend
|
|
|
- on SIP digest realm.
|
|
|
- (see also <link linkend="msmbug">MSM Authentication Issue</link>)
|
|
|
- </para>
|
|
|
- </note>
|
|
|
-
|
|
|
- <example>
|
|
|
- <title>Example Output of Server Watching Command
|
|
|
- <command moreinfo="none">sc monitor</command>
|
|
|
- </title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-
|
|
|
-[cycle #: 2; if constant make sure server lives and fifo is on]
|
|
|
-Server: Sip EXpress router(0.8.8 (i386/linux))
|
|
|
-Now: Thu Sep 26 23:16:48 2002
|
|
|
-Up Since: Thu Sep 26 12:35:27 2002
|
|
|
-Up time: 38481 [sec]
|
|
|
-
|
|
|
-Transaction Statistics
|
|
|
-Current: 0 (0 waiting) Total: 606 (0 local)
|
|
|
-Replied localy: 34
|
|
|
-Completion status 6xx: 0, 5xx: 1, 4xx: 86, 3xx: 0,2xx: 519
|
|
|
-
|
|
|
-Stateless Server Statistics
|
|
|
-200: 6218 202: 0 2xx: 0
|
|
|
-300: 0 301: 0 302: 0 3xx: 0
|
|
|
-400: 0 401: 7412 403: 2 404: 1258 407: 116 408: 0 483: 0 4xx: 25 500: 0 5xx: 0
|
|
|
-6xx: 0
|
|
|
-xxx: 0
|
|
|
-failures: 0
|
|
|
-
|
|
|
-UsrLoc Stats
|
|
|
-Domain Registered Expired
|
|
|
-'aliases' 9 0
|
|
|
-'location' 29 17
|
|
|
-
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </example>
|
|
|
- </section>
|
|
|
-
|
|
|
- <section id="serweb">
|
|
|
- <title>Web User Provisioning -- <application>serweb</application></title>
|
|
|
- <para>
|
|
|
- To make provisioning of user accounts convenient,
|
|
|
- a web front-end to <application moreinfo="none">ser</application>,
|
|
|
- <application moreinfo="none">serweb</application> has been
|
|
|
- developed. <application moreinfo="none">serweb</application>,
|
|
|
- a PHP-written web application,
|
|
|
- allows users to apply for new <application moreinfo="none">ser</application>
|
|
|
- accounts, and maintain these.
|
|
|
- Users can manipulate their contacts, keep a phone-book
|
|
|
- with SIP addresses, change password, send instant SIP messages,
|
|
|
- and more. Administrators can manipulate any accounts and
|
|
|
- grant or revoke user privileges.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">serweb</application> is freely
|
|
|
- available from berlios site at
|
|
|
- <ulink url="http://developer.berlios.de/cvs/?group_id=500">
|
|
|
- http://developer.berlios.de/cvs/?group_id=500</ulink>. Installation
|
|
|
- takes unpacking tarball to a safe destination at web server
|
|
|
- (better not in the HTML tree) and configuring
|
|
|
- <filename moreinfo="none">config.php</filename> accordingly
|
|
|
- to local conditions.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Running <application moreinfo="none">serweb</application> can
|
|
|
- be seen at iptel.org's SIP site. Just create and use a SIP
|
|
|
- account at <ulink url="http://www.iptel.org/user/">http://www.iptel.org/user/</ulink>
|
|
|
- </para>
|
|
|
- </section> <!-- serweb -->
|
|
|
-
|
|
|
-
|
|
|
- <section>
|
|
|
- <title>Voicemail</title>
|
|
|
-&voicemail;
|
|
|
- </section> <!-- voicemail -->
|
|
|
-
|
|
|
- </chapter> <!-- other apps -->
|
|
|
+&reference;
|
|
|
|
|
|
- <chapter>
|
|
|
- <title>Reference</title>
|
|
|
- <section id="coreoptions">
|
|
|
- <title>Core Options</title>
|
|
|
- <para>Core options are located in beginning of configuration file and
|
|
|
- affect behaviour of the server.</para>
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>debug</varname> - Set log level, this is number between 0 and 9. Default
|
|
|
- is 0.
|
|
|
-
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>fork</varname> - If set to yes, the server will spawn children. If set to no, the main
|
|
|
- process will be processing all messages. Default is yes.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- Disabling child spawning is useful mainly for
|
|
|
- debugging. When <varname>fork</varname> is turned off,
|
|
|
- some features are unavailable:
|
|
|
- there is no attendant process, no pid file is generated,
|
|
|
- and server listens only at one address. Make sure you
|
|
|
- are debugging the same interface at which
|
|
|
- <application moreinfo="none">ser</application> listens.
|
|
|
- The easiest way to do so is to set the interface using
|
|
|
- <varname>listen</varname> option explicitly.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>log_stderror</varname> - If set to yes, the server will print its debugging
|
|
|
- information to standard error output. If set to no, <command moreinfo="none">syslog</command>
|
|
|
- will be used. Default is no (printing to syslog).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>listen</varname> - list of all IP addresses or hostnames SER should listen on.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- This parameter may repeat several times, then SER will
|
|
|
- listen on all addresses. For example, the following
|
|
|
- command-line options (equivalent to "listen" config
|
|
|
- option) may be used:
|
|
|
- <command>
|
|
|
- ser -l foo -l bar -p 5061 -l x -l y
|
|
|
- </command>
|
|
|
- will listen on foo:5060, bar:5061 & x:5061 & y:5061
|
|
|
-
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>alias</varname> - Add IP addresses or hostnames to list of name aliases.
|
|
|
- All requests with hostname matching an alias will satisfy the condition
|
|
|
- "uri==myself".
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>dns</varname> - Uses dns to check if it is necessary to add a "received=" field to a via.
|
|
|
- Default is no.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>rev_dns</varname> - Same as dns but use reverse DNS. Default is no.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>port</varname> - Listens on the specified port (default 5060). It applies to the last
|
|
|
- address specified in listen and to all the following that do not have a corresponding "port" option.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>maxbuffer</varname> - Maximum receive buffer size which will not be exceeded by
|
|
|
- the auto-probing procedure even if the OS allows. Default value is MAX_RECV_BUFFER_SIZE,
|
|
|
- which is 256k.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>children</varname> - Specifies how many children should be created when fork is set to yes.
|
|
|
- Default value is CHILD_NO, which is 8. Running multiple children allows a server to
|
|
|
- server multiple requests in parallel when request processing block (e.g., on DNS
|
|
|
- lookup). Note that <application>ser</application> typically spawns additional
|
|
|
- processes, such as timer process or FIFO server. If FIFO server is turned on,
|
|
|
- you can watch running processes using the <application moreinfo="none">serctl</application>
|
|
|
- utility.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>check_via</varname> - Turn on or off Via host checking when forwarding replies.
|
|
|
- Default is no.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>syn_branch</varname> - Shall the server use stateful synonym branches? It is faster but not
|
|
|
- reboot-safe. Default is yes.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>memlog</varname> - Debugging level for final memory statistics report. Default is L_DBG --
|
|
|
- memory statistics are dumped only if <varname>debug</varname> is set high.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>sip_warning</varname> - Should replies include extensive warnings? By default yes,
|
|
|
- it is good for trouble-shooting.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>fifo</varname> - FIFO special file pathname, for example "/tmp/ser_fifo". Default is
|
|
|
- no filename -- no FIFO server is started then. We recommend to set it so that
|
|
|
- accompanying applications such as <application moreinfo="none">serweb</application> or
|
|
|
- <application moreinfo="none">serctl</application> can communicate with
|
|
|
- <application moreinfo="none">ser</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>fifo_mode</varname> - Permissions of the FIFO special file.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>server_signature</varname> - Should locally-generated messages include server's signature?
|
|
|
- By default yes, it is good for trouble-shooting.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>reply_to_via</varname> - A hint to reply modules
|
|
|
- whether they should send reply
|
|
|
- to IP advertised in Via.
|
|
|
- Turned off by default, which means that replies are
|
|
|
- sent to IP address from which requests came from.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>user | uid</varname> - uid to be used by the server.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>group | gid</varname> - gid to be used by the server.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>mhomed</varname> -- enable calculation of
|
|
|
- outbound interface; useful on multihomed servers,
|
|
|
- ser <link linkend="mhomed"></link>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>loadmodule</varname> - Specifies a module to be loaded (for example "/usr/lib/ser/modules/tm.so")
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <varname>modparam</varname> - Module parameter configuration. The commands takes three parameters:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>module</emphasis> - Module in which the parameter resides.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>parameter</emphasis> - Name of the parameter to be configured.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>value</emphasis> - New value of the parameter.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </section>
|
|
|
- <section id="builtinref">
|
|
|
- <title>Core Commands</title>
|
|
|
-
|
|
|
-
|
|
|
- <itemizedlist id="routeblocks">
|
|
|
- <title>Route Blocks and Process Control</title>
|
|
|
- <!--<para>
|
|
|
- Route block and process control keywords determine
|
|
|
- the order in which SIP requests are processed.
|
|
|
- </para>-->
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>route[number]{...}</command> - This marks a "route block" in configuration files.
|
|
|
- route blocks are basic building blocks of <application>ser</application> scripts.
|
|
|
- Each route block contains a sequence of
|
|
|
- <application>SER</application> actions enclosed in braces. Multiple route blocks
|
|
|
- can be included in a configuration file.
|
|
|
- When script execution begins on request receipt,
|
|
|
- route block number 0 is entered. Other route blocks serve as a kind of sub-routines and
|
|
|
- may be entered by calling the action <command>route(n)</command>,
|
|
|
- where n is number of the block. The action <command>break</command>
|
|
|
- exits currently executed route block. It stops script execution for
|
|
|
- route block number 0 or returns to calling route block otherwise.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>route</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-route[0] {
|
|
|
- # call routing block number 2
|
|
|
- route(2);
|
|
|
-}
|
|
|
-
|
|
|
-route[2] {
|
|
|
- forward("host.foo.bar", 5060);
|
|
|
-}
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>reply_route</command> is used to restart request processing
|
|
|
- when a negative reply for a previously relayed request is received. It is only
|
|
|
- used along with tm module, which stores the original requests and
|
|
|
- can return to their processing later. To activate processing
|
|
|
- of a <command>reply_route</command> block, call the TM action
|
|
|
- <command>t_on_negative(route_number)</command> before calling
|
|
|
- <command moreinfo="none">t_relay</command>. When a negative reply
|
|
|
- comes back, the desired <command moreinfo="none">reply_route</command>
|
|
|
- will be entered and processing of the original request may
|
|
|
- continue.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The set of actions applicable from within
|
|
|
- <command moreinfo="none">reply_route</command> blocks is limited.
|
|
|
- Permitted actions are URI-manipulation actions, logging and
|
|
|
- sending stateful replies using <command moreinfo="none">t_reply</command>.
|
|
|
- Use of other actions may lead to
|
|
|
- unpredictable results. (We plan to add syntactical checks in the future
|
|
|
- so that improper action use will be detected during server start-up.)
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>reply_route</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-reply_route[1] {
|
|
|
- # for some reason, the original forwarding attempt
|
|
|
- # failed, try at another URI
|
|
|
- append_branch("sip:[email protected]");
|
|
|
- # if this new attempt fails too, try another reply_route
|
|
|
- t_on_negative("2");
|
|
|
-}
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- The action <command>break</command> exits currently executed route block.
|
|
|
- It stops script execution for route block number 0 or returns to calling
|
|
|
- route block otherwise.
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- We recommend to use <command moreinfo="none">break</command>
|
|
|
- after any request forwarding or replying. This practice
|
|
|
- helps to avoid erroneous scripts that
|
|
|
- continue execution and mistakenly send another reply or
|
|
|
- forward a request to another place, resulting in
|
|
|
- protocol confusion.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> break;
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>route(n)</command> - call routing block route[n]{...};
|
|
|
- when the routing block n finishes processing, control is passed
|
|
|
- back to current block and processing continues.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>if (condition) statement</command> - Conditional statement.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Use of <command>if</command></title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-if (method=="REGISTER) {
|
|
|
- log("register received\n");
|
|
|
-};
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>if - else</command> - If-Else Conditional statement.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Use of <command>if-else</command></title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-if (method=="REGISTER) {
|
|
|
- log("register received\n");
|
|
|
-} else {
|
|
|
- log("non-register received\n");
|
|
|
-};
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- </itemizedlist>
|
|
|
- <itemizedlist>
|
|
|
- <title>Flag Manipulation</title>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>setflag</command> - Set flag in the message.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> setflag(1);
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>resetflag</command> - Reset flag in the message.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> resetflag(1);
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>isflagset</command> - Test whether a particular flag is set.
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>isflagset</title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-if (isflagset(1)) {
|
|
|
- ....
|
|
|
-};
|
|
|
-</programlisting>
|
|
|
- </example>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- <itemizedlist>
|
|
|
- <title>Manipulation of URI and Destination Set</title>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>rewritehost | sethost | seth</command> - Rewrite host part of the Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> sethost("foo.bar.com");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>rewritehostport | sethostport | sethp</command> - Rewrite host and port part of the Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> sethostport("foo.bar.com:5060");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>rewriteuser | setuser | setu</command> - Rewrite or set username part of the Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> setuser("joe");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>rewriteuserpass | setuserpass | setup</command> - Rewrite or set username and password part
|
|
|
- of the Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> setuserpass("joe:mypass");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>rewriteport | setport | setp</command> - Rewrite or set port of the Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> setport("5060");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>rewriteuri | seturi</command> - Rewrite or set the whole Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> seturi("sip:[email protected]:5060");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>revert_uri</command> - Revert changes made to the Request URI and use original Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> revert_uri();
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>prefix</command> - Add prefix to username in Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> prefix("123");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>strip</command> - Remove first n characters of username in Request URI.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> strip(3);
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>append_branch</command> - Append a new destination to destination set of the message.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <example>
|
|
|
- <title>Use of <command>append_branch</command></title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# redirect to these two destinations: [email protected] and [email protected]
|
|
|
-# 1) rewrite the current URI
|
|
|
-rewriteuri("sip:[email protected]");
|
|
|
-# 2) append another entry to the destination ser
|
|
|
-append_branch("sip:[email protected]");
|
|
|
-# redirect now
|
|
|
-sl_send_reply("300", "redirection");
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- <itemizedlist>
|
|
|
- <title>Message Forwarding</title>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>forward(uri, port)</command> - Forward the request to given
|
|
|
- destination statelessly. The uri and port parameters may take special
|
|
|
- values 'uri:host'
|
|
|
- and 'uri:port' respectively, in which case SER forwards to destination
|
|
|
- set in current URI. All other elements in a destination set are
|
|
|
- ignored by stateless forwarding.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> forward("foo.bar.com"); # port defaults to 5060
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>send</command> - Send the message as is to a third party
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> send("foo.bar.com");
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- <itemizedlist>
|
|
|
- <title>Logging</title>
|
|
|
-
|
|
|
-
|
|
|
- <listitem>
|
|
|
-
|
|
|
- <para>
|
|
|
- <command>log([level], message)</command> - Log a message.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <emphasis>Example:</emphasis> log(1, "This is a message with high log-level set to 1\n");
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Logging is very useful for troubleshooting or attracting administrator's
|
|
|
- attention to unusual situations. <application moreinfo="none">ser</application>
|
|
|
- reports log messages to <application moreinfo="none">syslog</application>
|
|
|
- facility unless it is configured to print them to <filename moreinfo="none">stderr</filename>
|
|
|
- with the <varname>log_stderr</varname> configuration option. Log messages
|
|
|
- are only issued if their log level exceeds threshold set with the
|
|
|
- <varname>debug</varname> configuration option. If log level is omitted,
|
|
|
- messages are issued at log level 4.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
-
|
|
|
- </itemizedlist>
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- <itemizedlist>
|
|
|
- <title>Miscellaneous</title>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <command>len_gt</command> - If length of the message is greater than value given as parameter, the
|
|
|
- command will return 1 (indicating true). Otherwise -1 (indicating false) will be returned. It may
|
|
|
- take 'max_len' as parameter, in which case message size is limited
|
|
|
- to internal buffer size BUF_SIZE (3040 by default).
|
|
|
- </para>
|
|
|
- <example>
|
|
|
- <title>Use of <command>len_gt</command></title>
|
|
|
- <programlisting format="linespecific">
|
|
|
-# deny all requests larger in size than 1 kilobyte
|
|
|
-if (len_gt(1024)) {
|
|
|
- sl_send_reply("513", "Too big");
|
|
|
- break;
|
|
|
-};
|
|
|
- </programlisting>
|
|
|
- </example>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </section>
|
|
|
- <section>
|
|
|
- <title>Command Line Parameters</title>
|
|
|
- <note>
|
|
|
- <para>
|
|
|
- Command-Line parameters may be overridden by configuration
|
|
|
- file options which take precedence over them.
|
|
|
- </para>
|
|
|
- </note>
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-h</emphasis> - Displays a short usage description, including all available options.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-c</emphasis> - Performs loop checks and computes branches.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-r</emphasis> - Uses dns to check if it is necessary to add a "received=" field to a via.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-R</emphasis> - Same as -r but uses reverse dns.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-v</emphasis> - Turns on via host checking when forwarding replies.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-d</emphasis> - Turns on debugging, multiple -d increase debugging level.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-D</emphasis> - Runs ser in the foreground (it doesn't fork into daemon mode).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-E</emphasis> - Sends all the log messages to stderr.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-V</emphasis> - Displays the version number.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-f config-file</emphasis> - Reads the configuration from "config-file" (default ./ser.cfg).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-l address</emphasis> - Listens on the specified address. Multiple -l mean listening
|
|
|
- on multiple addresses. The default behaviour is to listen on all the ipv4 interfaces.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-p port</emphasis> - Listens on the specified port (default 5060). It applies to the last
|
|
|
- address specified with -l and to all the following that do not have a corresponding -p.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-n processes-no</emphasis> - Specifies the number of children processes forked per
|
|
|
- interface (default 8).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-b max_rcv_buf_size</emphasis> - Maximum receive buffer size which will not be exceeded by
|
|
|
- the auto-probing procedure even if the OS allows.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-m shared_mem_size</emphasis> - Size of the shared memory which will be allocated (in Megabytes).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-w working-dir</emphasis> - Specifies the working directory. In the very improbable event
|
|
|
- that will crash, the core file will be generated here.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-t chroot-dir</emphasis> - Forces ser to chroot after reading the config file.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-u uid</emphasis> - Changes the user id under which ser runs.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-g gid</emphasis> - Changes the group id under which ser runs.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-P pid-file</emphasis> - Creates a file containing the pid of the main ser process.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>-i fifo-path</emphasis> - Creates a fifo, useful for monitoring ser status.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </section>
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- <section id="modulereference">
|
|
|
- <title>Modules</title>
|
|
|
- <para>
|
|
|
- Module description is currently located in READMEs of
|
|
|
- respective module directories. <filename moreinfo="none">README-MODULES</filename>
|
|
|
- lists all available modules, including their maturity status.
|
|
|
- In the current <application moreinfo="none">ser</application>
|
|
|
- distribution, there are the following modules:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- acc
|
|
|
- </emphasis>
|
|
|
- -- call accounting using <application moreinfo="none">syslog</application> facility.
|
|
|
- Depends on tm.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- auth
|
|
|
- </emphasis>
|
|
|
- -- digest authentication. Depends on sl and mysql.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- exec
|
|
|
- </emphasis>
|
|
|
- -- execution of shell programs.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- jabber
|
|
|
- </emphasis> -- gateway between SIMPLE and Jabber instant messaging. Depends
|
|
|
- on tm and mysql.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- maxfwd
|
|
|
- </emphasis>
|
|
|
- -- checking max-forwards header field.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>msilo</emphasis>
|
|
|
-
|
|
|
- -- message silo. Store for undelivered instant messages. Depends on tm and mysql.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- mysql
|
|
|
- </emphasis>
|
|
|
- -- mysql database back-end.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- registrar, usrloc
|
|
|
- </emphasis>
|
|
|
- -- User Location database. Works in in-memory mode or with mysql persistence
|
|
|
- support. Depends on sl, and on mysql if configured for use with mysql.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- rr
|
|
|
- </emphasis>
|
|
|
- -- Record Routing (strict and loose)
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- sl
|
|
|
- </emphasis>
|
|
|
- -- stateless User Agent server.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- sms
|
|
|
- </emphasis>
|
|
|
- -- SIMPLE/SMS gateway. Depends on tm. Takes special hardware.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- textops
|
|
|
- </emphasis>
|
|
|
- -- textual request operations.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- <emphasis>
|
|
|
- tm
|
|
|
- </emphasis>
|
|
|
- -- transaction manager (stateful processing).
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- The most frequently used actions exported by modules are summarized
|
|
|
- in <xref linkend="moduleactions">. For a full explanation of
|
|
|
- module actions, see documentation in respective module directories
|
|
|
- in source distribution of <application moreinfo="none">ser</application>.
|
|
|
- </para>
|
|
|
- <table id="moduleactions">
|
|
|
- <title>Frequently Used Module Actions</title>
|
|
|
- <tgroup cols="4">
|
|
|
- <thead>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- Command
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Modules
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Parameters
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Comments
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- </thead>
|
|
|
-
|
|
|
- <tbody>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- append_hf
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- textops
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- header field
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- append a header field to the end of request's header
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- check_from
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- none
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- check if username in from header field matches authentication id
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- check_to
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- none
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- check if username in To header field matched authentication id
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- exec_dset
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- exec
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- command name
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- execute an external command and replace destination set with
|
|
|
- its output
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- exec_msg
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- exec
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- command name
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- execute an external command and pass received SIP request
|
|
|
- to its input
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- is_in_group
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- group name
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- check if a user, as identified by digest credentials,
|
|
|
- is a member of a group`
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- is_user
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- user id
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- returns true if request credentials belong to a user
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- is_user_in
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- user, group
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- check if user is member of a group; user can be gained
|
|
|
- from request URI ("Request-URI"), To header field ("To"),
|
|
|
- From header field ("From") or digest credentials
|
|
|
- ("Credentials")
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- lookup
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- usrloc
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- table name
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- attempt to translate request URI using user location database;
|
|
|
- returns false if no contact for user found;
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- loose_route
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- rr
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- none
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- process loose routes in requests
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- mf_process_maxfwd_header
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- maxfwd
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- default max_forwards value
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- return true, if request's max_forwards value has not
|
|
|
- reached zero yet; if none is included in the request,
|
|
|
- set it to value in parameter
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- proxy_authorize
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- realm, subscriber table
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- returns true if requests contains proper credentials, false
|
|
|
- otherwise
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- proxy_challenge
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- auth
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- realm, qop
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- challenge user to submit digest credentials; qop may be turned
|
|
|
- off for backwards compatibility with elderly implementations
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- record_route
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- rr
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- loose routing (1=on, 0=off)
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- record-route a request
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- replace
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- textops
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- RegExp, Substitute
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- find the first occurence of a string matching the regular
|
|
|
- expression in header or body and replace it with a substitute
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- replace_all
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- textops
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- RegExp, Substitute
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- find all occurences of a string matching the regular
|
|
|
- expression in header or body and replace it with a substitute
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- save
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- usrloc
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- table name
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- for use in registrar: save content of Contact header fields
|
|
|
- in user location database and reply with 200
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- search
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- textops
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- regular expression
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- search for a regular expression match in request header of body
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- sl_send_reply
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- sl
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- status code, reason phrase
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- reply a request statelessly
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- t_relay
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- tm
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- none
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- stateful forwarding to locations in current destination set
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- t_on_negative
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- tm
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- reply_route number
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- set reply_route block which shall be entered if stateful
|
|
|
- forwarding fails
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- t_replicate
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- tm
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- host, port number
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- replicate a request to a destination
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
-
|
|
|
-
|
|
|
- </tbody>
|
|
|
- </tgroup>
|
|
|
- </table>
|
|
|
- </section> <!-- modules -->
|
|
|
- <section id="fiforeference">
|
|
|
- <title>FIFO Commands Reference</title>
|
|
|
- <para>
|
|
|
- This section lists currently supported FIFO commands. Some of them are
|
|
|
- built-in in <application moreinfo="none">ser</application> core, whereas
|
|
|
- others are exported by modules. The most important exporters are now
|
|
|
- tm and usrloc module. tm FIFO commands allow users to initiate transactions
|
|
|
- without knowledge of underlying SIP stack. usrloc FIFO commands allow
|
|
|
- users to access in-memory user-location database. Note that that is the
|
|
|
- only way how to affect content of the data-base in real-time. Changes
|
|
|
- to MySql database do not affect in-memory table unless <application moreinfo="none">ser</application>
|
|
|
- is restarted.
|
|
|
- </para>
|
|
|
- <table>
|
|
|
-
|
|
|
- <title>FIFO Commands</title>
|
|
|
- <tgroup cols="4">
|
|
|
- <thead>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- Command
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Module
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Parameters
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Comments
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- </thead>
|
|
|
- <tbody>
|
|
|
- <row>
|
|
|
- <entry>
|
|
|
- ps
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- core
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- none
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- prints running <application moreinfo="none">ser</application> processes
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>which</entry>
|
|
|
- <entry>core</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>prints list of available FIFO commands</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>arg</entry>
|
|
|
- <entry>core</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>prints list of command-line arguments with which
|
|
|
- <application moreinfo="none">ser</application> was started</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>pwd</entry>
|
|
|
- <entry>core</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>prints <application moreinfo="none">ser</application>'s working
|
|
|
- directory</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>version</entry>
|
|
|
- <entry>core</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>prints version of <application moreinfo="none">ser</application></entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>uptime</entry>
|
|
|
- <entry>core</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>prints <application moreinfo="none">ser</application>'s running time</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>sl_stats</entry>
|
|
|
- <entry>sl</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>prints statistics for sl module</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>t_stats</entry>
|
|
|
- <entry>tm</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>print statistics for tm module</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>t_hash</entry>
|
|
|
- <entry>tm</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>print occupation of transaction table (mainly for debugging)</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>t_uac_dlg</entry>
|
|
|
- <entry>tm</entry>
|
|
|
- <entry>method, request URI, outbound URI (if none, empty line with a single dot),
|
|
|
- dot-line-terminated header fields, optionaly dot-line terminated message
|
|
|
- body.
|
|
|
- </entry>
|
|
|
-
|
|
|
- <entry>initiate a transaction.
|
|
|
- From and To header fields must be present in header field list,
|
|
|
- so does Content-Type if body is present. If CSeq, CallId and From-tag
|
|
|
- are not present, ephemeral values are generated. Content_length is
|
|
|
- calculated automatically if body present.
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_stats</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>print usrloc statistics</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_rm</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>table name, user name</entry>
|
|
|
- <entry>remove all user's contacts from user-location database</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_rm_contact</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>table name, user name, contact</entry>
|
|
|
- <entry>remove a user's contact from user-location database</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_dump</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>print content of in-memory user-location database</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_flush</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>none</entry>
|
|
|
- <entry>flush content of in-memory user-location cache in
|
|
|
- persistent database (MySQL)</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_add</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>table name, user name, contact, expiration, priority (q)</entry>
|
|
|
- <entry>insert a contact address in user-location database</entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry>ul_show_contact</entry>
|
|
|
- <entry>usrloc</entry>
|
|
|
- <entry>table, user name</entry>
|
|
|
- <entry>show user's contact addresses in user-location database</entry>
|
|
|
- </row>
|
|
|
- </tbody>
|
|
|
- </tgroup>
|
|
|
- </table>
|
|
|
- </section>
|
|
|
- <section>
|
|
|
- <title>Used Database Tables</title>
|
|
|
- <para>
|
|
|
- <application moreinfo="none">ser</application> includes MySQL support
|
|
|
- to guarantee data persistence across server reboots and storage
|
|
|
- of users' web environment. The data stored in
|
|
|
- the database include user profiles, access control lists, user location,
|
|
|
- etc. Note that users are not supposed to alter the data directly, as it
|
|
|
- could introduce inconsistency between data on persistence storage and
|
|
|
- in server's memory.
|
|
|
- The following list enumerates used tables and explains their purpose.
|
|
|
-
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- subscriber -- table of users. It includes user names and
|
|
|
- security credentials, as well as additional user information.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- reserved -- reserved user names. <application moreinfo="none">serweb</application>
|
|
|
- does not permit creation of accounts with name on this list.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- phonebook -- user's personal phonebooks. Accessible via
|
|
|
- <application moreinfo="none">serweb</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- pending -- table of unconfirmed subscription requests. Used by
|
|
|
- <application moreinfo="none">serweb</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- missed_calls -- table of missed calls. Can be fed by acc modules
|
|
|
- if mysql support is turned on. Displayed by <application moreinfo="none">serweb</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- location -- user contacts. Typically updated through
|
|
|
- <application moreinfo="none">ser</application>'r registrar
|
|
|
- functionality.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- grp -- group membership. Used by auth module to determine
|
|
|
- whether a user belongs to a group.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- event -- allows users to subscribe to additional services.
|
|
|
- Currently unused.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- aliases -- keeps track of alternative user names.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- active_sessions -- keeps track of currently active web sessions.
|
|
|
- For use by <application moreinfo="none">serweb</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- acc -- keeps track of accounted calls. Can be fed by acc module
|
|
|
- if mysql support is turned on. Displayed by <application moreinfo="none">serweb</application>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- config -- maintains attribute-value pairs for keeping various information.
|
|
|
- Currently not used.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- silo -- message store for instant messages which could not have been
|
|
|
- delivered.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- version -- keeps version number of each table definition.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
-
|
|
|
- </para>
|
|
|
- </section>
|
|
|
- </chapter> <!-- reference -->
|
|
|
|
|
|
<!-- TODO
|
|
|
|