Browse code

more exec examples, missed calls howto

Jiri Kuthan authored on 05/01/2003 23:00:01
Showing 1 changed files
... ...
@@ -13,6 +13,13 @@
13 13
 <!ENTITY accountingexample SYSTEM "../../examples/acc.cfg">
14 14
 <!ENTITY replicateexample SYSTEM "../../examples/replicate.cfg">
15 15
 <!ENTITY defscr SYSTEM "../../etc/ser.cfg">
16
+<!ENTITY execstep2 SYSTEM "../../examples/exec_s2.cfg">
17
+<!ENTITY execstep3 SYSTEM "../../examples/exec_s3.cfg">
18
+<!ENTITY execstep4 SYSTEM "../../examples/exec_s4.cfg">
19
+<!ENTITY execstep5 SYSTEM "../../examples/exec_s5.cfg">
20
+<!ENTITY execstep5b SYSTEM "../../examples/exec_s5b.cfg">
21
+<!ENTITY releasenotes SYSTEM "../../NEWS">
22
+<!ENTITY install SYSTEM "../../INSTALL">
16 23
 
17 24
 
18 25
 
... ...
@@ -24,7 +31,7 @@
24 31
 <?dbhtml filename="index.html">
25 32
 
26 33
    
27
-    <title>iptel.org SIP Express Router v0.8.10 -- Admin's Guide</title>
34
+    <title>iptel.org SIP Express Router v0.8.11 -- Admin's Guide</title>
28 35
     <bookinfo>
29 36
 	<authorgroup>
30 37
 	    <author>
... ...
@@ -87,10 +94,10 @@
87 94
 	    </para>
88 95
 	</abstract>
89 96
 	<releaseinfo>
90
-	    This documentation is continuously updated. For the latest and most complete 
91
-	    version, visit our site at 
97
+	    This documentation is continuously updated. For the latest  
98
+	    version visit our site at 
92 99
 	    <ulink url="http://www.iptel.org/ser/">http://www.iptel.org/ser</ulink>.
93
-	    Version of this document is $Revision$.
100
+	    $Revision$.
94 101
 	</releaseinfo>
95 102
     </bookinfo>
96 103
 
... ...
@@ -505,12 +512,25 @@
505 512
 		Most up-to-date information including latest and most complete version
506 513
 		of this documentation is always available at our website,
507 514
 		<ulink url="http://www.iptel.org/ser/">http://www.iptel.org/ser/</ulink>.
508
-		For information on how to install ser, read INSTALL.
509
-		SGML documentation is available in the 'doc' directory.
515
+		The site includes links to other important information about
516
+		<application moreinfo="none">ser</application>, such
517
+		as installation guidelines (INSTALL), download links,
518
+		development pages, programmer's manual, etc.
519
+	    </para>
520
+	    <para>
510 521
 		A SIP tutorial (slide set) is available at 
511 522
 		<ulink url="http://www.iptel.org/sip/">http://www.iptel.org/sip/</ulink> .
512 523
 	    </para>
513 524
 	</section> <!-- info -->
525
+
526
+	<section>
527
+	    <title>Release Notes</title>
528
+	    <literallayout format="linespecific" class="normal">
529
+&releasenotes;
530
+	    </literallayout>
531
+	</section> <!-- release notes -->
532
+
533
+
514 534
     </chapter> <!-- general -->
515 535
 
516 536
     <chapter>
... ...
@@ -524,7 +544,7 @@
524 544
 		hop of a request. It can be for example used to implement user 
525 545
 		location service or enforce static routing to a gateway. Real-world
526 546
 		deployments actually ask for quite complex routing logic, which
527
-		needs to reflex static routes to PSTN gateways, dynamic routes
547
+		needs to reflect static routes to PSTN gateways, dynamic routes
528 548
 		to registered users, authentication policy, capabilities of
529 549
 		SIP devices, etc.
530 550
 	    </para>
... ...
@@ -1591,7 +1611,7 @@ route{
1591 1611
 		<application>ser</application> features.
1592 1612
 	    </para>
1593 1613
 
1594
-	    <section>
1614
+	    <section id="defaultscript">
1595 1615
 		<title>Default Configuration Script</title>		
1596 1616
 		<para>
1597 1617
 		    The configuration script, <filename moreinfo="none">ser.cfg</filename>,
... ...
@@ -1668,7 +1688,7 @@ route{
1668 1688
 		</example>
1669 1689
 	    </section>
1670 1690
 
1671
-	    <section>
1691
+	    <section id="statefulua">
1672 1692
 		<title>Stateful User Agent</title>
1673 1693
 		<para>
1674 1694
 		    This examples shows how to make ser act as a stateful user
... ...
@@ -1791,7 +1811,7 @@ route{
1791 1811
 		</example>
1792 1812
 	    </section> <!-- exec example -->
1793 1813
 	    
1794
-	    <section>
1814
+	    <section id="replyprocessingsection">
1795 1815
 		<title>Reply Processing (Forward on Unavailable)</title>
1796 1816
 		<para>
1797 1817
 		    Many services depend on status of messages relayed
... ...
@@ -1887,7 +1907,7 @@ route{
1887 1907
 			There is also a utility <application moreinfo="none">
1888 1908
 			    scripts/harv_ser.sh</application> in <application moreinfo="none">
1889 1909
 			ser</application> distribution for post-processing
1890
-			of captures messages. It summarizes messages captured
1910
+			of captured messages. It summarizes messages captured
1891 1911
 			by reply status and user-agent header field.
1892 1912
 		    </para>
1893 1913
 		</answer>
... ...
@@ -1905,7 +1925,7 @@ route{
1905 1925
 		    tools available, using a simple, text-oriented tool
1906 1926
 		    such as <application>ngrep</application> makes the job very well thanks to SIP's textual nature.
1907 1927
 			</para>
1908
-		    <example>
1928
+		    <example id="usingngrep">
1909 1929
 			<title>Using <application>ngrep</application>
1910 1930
 			</title>
1911 1931
 			<para>In this example, all messages at port 5060
... ...
@@ -1953,41 +1973,70 @@ Warning: 392 127.0.0.1:5060 "Noisy feedback tells: pid=31604 req_src_ip=153.96.1
1953 1973
 		    </para>
1954 1974
 		</question>
1955 1975
 		<answer>
1956
-		    <para>
1957
-			A request may pass any number of proxy servers on
1958
-			its path to its destination. If an error occurs,
1959
-			it may be quite difficult to learn in which of
1960
-			the servers in the chain it originated and what
1961
-			was its cause. <application moreinfo="none">ser
1962
-			</application> does its best and displays extensive
1963
-			diagnostics information in SIP replies. This
1964
-			information is part of the warning header field,
1965
-			and contains the following facts:
1976
+			<para>
1977
+			    A request may pass any number of proxy servers on
1978
+			    its path to its destination. If an error occurs
1979
+			    in the chain, it is difficult for upstream troubleshooters
1980
+			    and/or users complaining to administrators to learn 
1981
+			    more about error circumstances. 
1982
+			    <application moreinfo="none">ser
1983
+			    </application> does its best and displays extensive
1984
+			    diagnostics information in SIP replies. It allows 
1985
+			    troubleshooters and/or users who report to troubleshooters
1986
+			    to gain additional knowledge about request processing
1987
+			    status. 
1988
+			    This extended debugging information is part of the warning 
1989
+			    header field. See <xref linkend="usingngrep"> for an illustration
1990
+			    of a reply that includes such a warning header field. The header
1991
+			    field contains the following pieces of information:
1966 1992
 			<itemizedlist>
1967 1993
 			    <listitem>
1968 1994
 				<para>
1969 1995
 				Server's IP Address -- good to identify
1970 1996
 				from which server in a chain the reply
1971
-				came
1997
+				came.
1972 1998
 				    </para>
1973 1999
 			    </listitem>
1974 2000
 			    <listitem>
1975
-				<para>
1976
-				    Incoming and outgoing URIs -- good to
1977
-				    learn for which URI the reply was
1978
-				    generated, as it may be rewritten
1979
-				    many times in the path
1980
-				</para>
2001
+				    <para>
2002
+					Incoming and outgoing URIs -- good to
2003
+					learn for which URI the reply was
2004
+					generated, as it may be rewritten
2005
+					many times in the path. Particularly
2006
+					useful for debugging of numbering plans.
2007
+				    </para>
1981 2008
 			    </listitem>
1982 2009
 			    <listitem>
1983 2010
 				<para>
1984
-				    Number of Via header fields in replied
1985
-				    request -- that helps in assessment of
1986
-				    request path length.
2011
+					Number of Via header fields in replied
2012
+					request -- that helps in assessment of
2013
+					request path length. Upstream clients would
2014
+					not know otherwise, how far away in terms
2015
+					of SIP hops their requests were replied.
1987 2016
 				</para>
1988 2017
 			    </listitem>
2018
+				<listitem>
2019
+				    <para>
2020
+					Server's process id. That is useful for
2021
+					debugging to discover situations when
2022
+					mutliple servers listen at the same
2023
+					address.
2024
+				    </para>
2025
+				</listitem>
2026
+				<listitem>
2027
+				    <para>
2028
+					IP address of previous SIP hop as seen by
2029
+					the SIP server.
2030
+				    </para>
2031
+				</listitem>
1989 2032
 			</itemizedlist>
1990 2033
 		    </para>
2034
+			<para>
2035
+			    If server administrator is not comfortable with
2036
+			    disclosing all this information, he can turn them
2037
+			    off using the <varname>sip_warning</varname> configuration
2038
+			    option.
2039
+			</para>
1991 2040
 		    <para>
1992 2041
 			A nice utility for debugging server chains is
1993 2042
 			<application moreinfo="none">sipsak</application>,
... ...
@@ -2243,12 +2292,9 @@ P-hint: OUTBOUND.			    </programlisting>
2243 2292
 		such as user management or controlling access
2244 2293
 		to PSTN gateways.
2245 2294
 	    </para>
2246
-	    <qandaset>
2247
-		<qandaentry>
2248
-		    <question>
2249
-			<para>User Management</para>
2250
-		    </question>
2251
-		    <answer>
2295
+	    <section>
2296
+		<title>User Management</title>
2297
+
2252 2298
 			<para>
2253 2299
 			    There are two tasks related to management of SIP users:
2254 2300
 			    maintaining user accounts and maintaining user contacts.
... ...
@@ -2325,15 +2371,10 @@ sip:666@gateway.foo.bar
2325 2371
 404 Username newuser in table location not found
2326 2372
 			    </screen>
2327 2373
 			</para>
2328
-		    </answer>
2329
-		</qandaentry>
2330
-		<qandaentry>
2331
-		    <question>
2332
-			<para>
2333
-			    User Aliases
2334
-			</para>
2335
-		    </question>
2336
-		    <answer>
2374
+	    </section> <!-- user management -->
2375
+	    <section>
2376
+		<title>User Aliases</title>
2377
+
2337 2378
 			<para>
2338 2379
 			    Frequently, it is desirable for a user to have multiple
2339 2380
 			    addresses in a domain. For example, a user with username "john.doe" wants to be
... ...
@@ -2412,13 +2453,9 @@ modparam("usrloc", "db_mode",   1)
2412 2453
 modparam("usrloc", "db_url","sql://ser:secret@dbhost/ser")
2413 2454
 			    </programlisting>
2414 2455
 			</para>
2415
-		    </answer>
2416
-		</qandaentry>
2417
-		<qandaentry>
2418
-		    <question>
2419
-			<para>Access Control (PSTN Gateway)</para>
2420
-		    </question>
2421
-		    <answer>
2456
+	    </section> <!-- user aliases -->
2457
+	    <section>
2458
+		<title>Access Control (PSTN Gateway)</title>
2422 2459
 			<para>
2423 2460
 			    It is sometimes important to exercise some sort of
2424 2461
 			    access control. A typical use case is when 
... ...
@@ -2489,15 +2526,9 @@ MySql Password:
2489 2526
 +------+-----+---------------------+
2490 2527
 			    </screen>
2491 2528
 			</para>
2492
-		    </answer>
2493
-		</qandaentry>
2494
-		<qandaentry>
2495
-		    <question>
2496
-			<para>
2497
-			    Accounting
2498
-			</para>
2499
-		    </question>
2500
-		    <answer>
2529
+	    </section> <!-- access control -->
2530
+	    <section>
2531
+		<title>Accounting</title>
2501 2532
 			<para>
2502 2533
 			    In some scenarios, like termination of calls in PSTN, SIP administrators
2503 2534
 			    may wish to keep track of placed calls. <application moreinfo="none">ser</application>
... ...
@@ -2527,13 +2558,10 @@ MySql Password:
2527 2558
 				</programlisting>
2528 2559
 			    </example>
2529 2560
 			</para>
2530
-		    </answer>
2531
-		</qandaentry>
2532
-		<qandaentry>
2533
-		    <question>
2534
-			<para>Reliability</para>
2535
-		    </question>
2536
-		    <answer>
2561
+	    </section> <!-- accounting -->
2562
+	    <section>
2563
+		<title>Reliability</title>
2564
+
2537 2565
 			<para>
2538 2566
 			    It is essential to guarantee continuous
2539 2567
 			    service operation even under erroneous conditions, 
... ...
@@ -2605,16 +2633,9 @@ MySql Password:
2605 2633
 				</programlisting>
2606 2634
 			    </example>
2607 2635
 			</para>
2608
-		    </answer>
2609
-		    
2610
-		</qandaentry>
2611
-		<qandaentry>
2612
-		    <question>
2613
-			<para>
2614
-			    Stateful versus Stateless Forwarding
2615
-			</para>
2616
-		    </question>
2617
-		    <answer>
2636
+	    </section> <!-- reliability -->
2637
+	    <section>
2638
+		<title>Stateful versus Stateless Forwarding</title>
2618 2639
 			<para>
2619 2640
 			    <application moreinfo="none">ser</application> allows both stateless
2620 2641
 			    and stateful request processing. This memo explains what are pros and cons of
... ...
@@ -2672,15 +2693,9 @@ MySql Password:
2672 2693
 				</listitem>
2673 2694
 			    </itemizedlist>
2674 2695
 			</para>
2675
-		    </answer>
2676
-		</qandaentry>
2677
-		<qandaentry>
2678
-		    <question>
2679
-			<para>
2680
-			    Serving Multiple Domains
2681
-			</para>
2682
-		    </question>
2683
-		    <answer>
2696
+	    </section> <!-- stateful vs. stateless -->
2697
+	    <section>
2698
+		<title>Serving Multiple Domains</title>
2684 2699
 			<para>
2685 2700
 			    <application moreinfo="none">ser</application> can be configured to
2686 2701
 			    serve multiple domains. To do so, you need to take the following steps:
... ...
@@ -2707,11 +2722,82 @@ MySql Password:
2707 2722
 				
2708 2723
 			    </orderedlist>
2709 2724
 			</para>
2710
-		    </answer>
2711
-		</qandaentry>
2712
-	    </qandaset>
2713
-	    
2714
-
2725
+	    </section> <!-- multiple domains -->
2726
+	    <section id="missedcalls">
2727
+		<title>Reporting Missed Calls</title>
2728
+			<para>
2729
+			    <application moreinfo="none">ser</application> can report missed
2730
+			    calls via <application moreinfo="none">syslog</application> facility
2731
+			    or to mysql. Mysql reporting can be utilized by 
2732
+			    <application moreinfo="none">ser</application>'s 
2733
+			    complementary web-interface, <application moreinfo="none">serweb</application>.
2734
+			    (See more in <xref linkend="serweb">).
2735
+			</para>
2736
+			<para>
2737
+			    Reporting on missed calls is enabled by acc module.
2738
+			    There are two cases, on which you want to report. The first
2739
+			    case is when a callee is off-line. The other case is when
2740
+			    a user is on-line, but call establishment fails. There
2741
+			    may be many failure reasons (call cancellation, inactive phone,
2742
+			    busy phone, server timer, etc.), all of them leading to
2743
+			    a negative (>=300) reply sent to caller. The acc module
2744
+			    can be configured to issue a missed-call report whenever
2745
+			    a transaction completes with a negative status. Two following
2746
+			    script fragment deals with both cases.
2747
+			</para>
2748
+			<para>
2749
+			    First, it reports
2750
+			    on calls missed due to off-line callee status
2751
+			    using the <command moreinfo="none">acc_request</command>
2752
+			    action. The action is wrapped in transactional
2753
+			    processing (<command moreinfo="none">t_newtran</command>)
2754
+			    to guarantee that reports are not
2755
+			    duplicated on receipt of retransmissions.
2756
+			    </para>
2757
+			<para>
2758
+			    Secondly, transaction to on-line users are marked
2759
+			    to be reported on failure. That is what the 
2760
+			    <command moreinfo="none">setflag(3)</command> action
2761
+			    is responsible for, along with the configuration option
2762
+			    "missed_flag". This option configures <application moreinfo="none">ser</application>
2763
+			    to report on all transactions, which were marked
2764
+			    with flag 3.			   
2765
+			    <programlisting format="linespecific">
2766
+loadmodule("modules/tm/tm.so");
2767
+loadmodule("modules/acc/acc.so");
2768
+....
2769
+# if a call is labeled using setflag(3) and is missed, it will
2770
+# be reported
2771
+...
2772
+modparam("acc", "missed_flag", 3 );
2773
+if (!lookup("location")) {
2774
+     # call invitations to off-line users are reported using the
2775
+     # acc_request action; to avoid duplicate reports on request
2776
+     # retransmissions, request is processed statefuly (t_newtran,
2777
+     # t_reply)
2778
+     if ((method=="INVITE" || method=="ACK") && t_newtran() ) {
2779
+          t_reply("404", "Not Found");
2780
+	  acc_request("404 Not Found");
2781
+          break;
2782
+     };
2783
+     # all other requests to off-line users are simply replied
2784
+     # statelessly and no reports are issued
2785
+    sl_send_reply("404", "Not Found");
2786
+    break;
2787
+} else {
2788
+     # user on-line; report on failed transactions; mark the
2789
+     # transaction for reporting using the same number as 
2790
+     # configured above; if the call is really missed, a report
2791
+     # will be issued
2792
+     setflag(3);
2793
+     # forward to user's current destination
2794
+     t_relay();
2795
+     break;
2796
+};
2797
+			    </programlisting>
2798
+			    
2799
+			</para>
2800
+	    </section> <!-- missed calls -->
2715 2801
 	</section> <!-- howtos -->
2716 2802
 
2717 2803
 	<section>
... ...
@@ -2752,6 +2838,7 @@ MySql Password:
2752 2838
 		<qandaentry>
2753 2839
 		    <question>
2754 2840
 			<para>
2841
+			    <anchor id="msmbug">
2755 2842
 			    Windows Messenger authentication fails.
2756 2843
 			</para>
2757 2844
 		    </question>
... ...
@@ -2800,29 +2887,34 @@ MySql Password:
2800 2887
 	<title>Application Writing</title>
2801 2888
 	<para>
2802 2889
 	    <application moreinfo="none">ser</application> offers several
2803
-	    methods to leverage and extend its abilities. They primarily
2804
-	    differ in how easy-to-use and powerful they are. The easiest
2805
-	    way is to couple <application moreinfo="none">ser</application>
2806
-	    with external applications via the <emphasis>exec</emphasis>
2807
-	    module. This module allows execution of logic and URI manipulation 
2808
-	    by external applications on request receipt. While very
2809
-	    simple, many useful services can be
2810
-	    implemented this way. External applications can be written in
2811
-	    any programming language and do not be aware of SIP at all.
2812
-	    They only care of URIs. For example, an external shell script
2813
-	    may send an email whenever a request for a user arrives.
2814
-	    <example>
2815
-		<title>Using External Scripts</title>
2816
-		<programlisting format="linespecific">
2817
-# send email if a request for johndoe arrives
2818
-if (uri=~"^sip:johndoe@") {
2819
-     exec_msg("echo 'body: call arrived'|mail -s 'call for you' johndoe");
2820
-}
2821
-		</programlisting>
2822
-	    </example>
2890
+	    ways to couple its functionality with applications. The coupling
2891
+	    is bidirectional: <application moreinfo="none">ser</application>
2892
+	    can utilize external applications and external applications can
2893
+	    utilize <application moreinfo="none">ser</application>. 
2894
+	    An example of the former direction would be an external program
2895
+	    determining a least-cost route for a called destination  using 
2896
+	    a pricing table. An example of the latter case
2897
+	    is a web application for server provisioning.
2898
+	    Such an application may want to send instant 
2899
+	    messages, query all current user's locations and monitor server
2900
+	    health. An existing web interface to <application moreinfo="none">ser</application>,
2901
+	    <application moreinfo="none">serweb</application>, actually
2902
+	    does all of it. 
2823 2903
 	</para>
2824 2904
 	<para>
2825
-	    The other extreme method for extending <application moreinfo="none">ser</application>
2905
+	    The easiest, language-independent way of using external logic 
2906
+	    from <application moreinfo="none">ser</application> is provided
2907
+	    by exec module. exec module allows <application moreinfo="none">ser</application>
2908
+	    to start external programs on receipt of a request. The
2909
+	    programs can execute arbitrary logic and/or affect routing of SIP
2910
+	    requests. A great benefit of this programming method is it
2911
+	    is language-independent. Programmers may use programming languages
2912
+	    that are effective or with which they are best familiar.
2913
+	    <xref linkend="usingexec"> gives additional examples illustrating 
2914
+	    use of the exec module.
2915
+	</para>
2916
+	<para>
2917
+	    Another method for extending <application moreinfo="none">ser</application>
2826 2918
 	    capabilities is to write new modules in C. This method takes
2827 2919
 	    deeper understanding of <application moreinfo="none">ser</application>
2828 2920
 	    internals but gains the highest flexibility. Modules can implement
... ...
@@ -2832,16 +2924,298 @@ if (uri=~"^sip:johndoe@") {
2832 2924
 	    programmer's handbook available from iptel.org website.
2833 2925
 	</para>
2834 2926
 	<para>
2835
-	    There is a middle way too, which allows easy service creation
2836
-	    without in-depth knowledge of <application moreinfo="none">ser</application>
2837
-	    internals. <application moreinfo="none">ser</application> allows
2838
-	    external applications to link via its built-in
2839
-	    <emphasis>application FIFO server</emphasis> described in the next section. 
2927
+	    To address needs of applications wishing to leverage
2928
+	    <application moreinfo="none">ser</application>,
2929
+	    <application moreinfo="none">ser</application> exports
2930
+	    parts of its functionality via its built-in
2931
+	    "Application FIFO server". This is a simple textual
2932
+	    interface that allows any external applications
2933
+	    to communicate with the server. It can be used to
2934
+	    send instant messages, manipulate user contacts,
2935
+	    watch server health, etc. Programs written in any
2936
+	    language (PHP, shell scripts, Perl, C, etc.) can
2937
+	    utilize this feature. How to use it is shown in
2938
+	    <xref linkend="fifoserver">.
2840 2939
 	</para>
2841
-	<section>
2940
+
2941
+
2942
+	<section id="usingexec">
2943
+	    <title>Using exec Module</title>
2944
+	    <para>
2945
+		
2946
+		The easiest way is to couple <application moreinfo="none">ser</application>
2947
+		with external applications via the <emphasis>exec</emphasis>
2948
+		module. This module allows execution of logic and URI manipulation 
2949
+		by external applications on request receipt. While very
2950
+		simple, many useful services can be
2951
+		implemented this way. External applications can be written in
2952
+		any programming language and do not be aware of SIP at all.
2953
+		<application moreinfo="none">ser</application> interacts with
2954
+		the application via standard input/output and environment 
2955
+		variables.
2956
+		
2957
+
2958
+	    </para>
2959
+	
2960
+
2961
+	    <para>
2962
+		For example, an external shell script
2963
+		may send an email whenever a request for a user arrives.
2964
+	    </para>
2965
+
2966
+	    <example>
2967
+		<title>Using exec: Step 1</title>
2968
+		<programlisting format="linespecific">
2969
+# send email if a request for user "jiri" arrives
2970
+if (uri=~"^sip:jiri@") {
2971
+     exec_msg("echo 'body: call arrived'|mail -s 'call for you' jiri");
2972
+}
2973
+		</programlisting>
2974
+	    </example> <!-- step 1 -->
2975
+	    <para>
2976
+		In this example, the <command moreinfo="none">exec_msg</command> 
2977
+		action starts an external shell. It passes a received SIP request
2978
+		to shell's input. In the shell, <command>mail</command> command
2979
+		is called to send a notification by e-mail.
2980
+		The script however features several simplifications:
2981
+		<orderedlist inheritnum="ignore" continuation="restarts">
2982
+		    <listitem>
2983
+			<para>
2984
+			    The email notification does not tell who was calling.
2985
+			</para>
2986
+		    </listitem>
2987
+		    <listitem>
2988
+			<para>
2989
+			    The logic is not general: it only supports one well-known user (jiri).
2990
+			</para>
2991
+		    </listitem>
2992
+		    <listitem>
2993
+			<para>
2994
+			    The logic is stateless. It will be executed on
2995
+			    every retransmission.
2996
+			</para>
2997
+		    </listitem>
2998
+		    <listitem>
2999
+			<para>
3000
+			    It is a script fragment not explaining the 
3001
+			    context. This particular example may be for
3002
+			    example used to report on missed calls.
3003
+			</para>
3004
+		    </listitem>
3005
+		</orderedlist>
3006
+		All of these simplifications are addressed step-by-step
3007
+		in the following examples.
3008
+	    </para>
3009
+	    <example> <!-- step 2: who called me -->
3010
+		<title>Using exec: Step 2, Who Called Me</title>
3011
+		<para>
3012
+		    This example shows how to display caller's address
3013
+		    in email notification. The trick is easy: process
3014
+		    request received on shell programm's input
3015
+		    and grep From header field.
3016
+		</para>
3017
+		<programlisting format="linespecific">
3018
+&execstep2;
3019
+		</programlisting>
3020
+		<para>
3021
+			The following two figures show an example SIP request and
3022
+			email notification generated on its receipt.
3023
+			
3024
+		    <screen format="linespecific">
3025
+
3026
+<![CDATA[
3027
+INVITE sip:jiri@iptel.org SIP/2.0
3028
+Via: SIP/2.0/UDP 195.37.77.100:5040
3029
+Max-Forwards: 10
3030
+From: "alice" <sip:alice@iptel.org>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
3031
+To: <sip:jiri@iptel.org>
3032
+Call-ID: d10815e0-bf17-4afa-8412-d9130a793d96@213.20.128.35
3033
+CSeq: 2 INVITE
3034
+Contact: <sip:123.20.128.35:9315>
3035
+Content-Type: application/sdp
3036
+Content-Length: 451
3037
+
3038
+--- SDP payload snipped ---
3039
+]]>
3040
+
3041
+		    </screen>
3042
+		
3043
+		    email received:
3044
+		
3045
+			<screen format="linespecific">
3046
+<![CDATA[
3047
+Date: Thu, 12 Dec 2002 14:25:02 +0100
3048
+From: root <root@cat.iptel.org>
3049
+To: jiri@cat.iptel.org
3050
+Subject: request for you
3051
+
3052
+From: "alice" <sip:alice@iptel.org>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
3053
+request received
3054
+]]>
3055
+		    </screen>
3056
+		</para>
3057
+		<para>
3058
+		    There is another way to learn values of request
3059
+		    header fields, simpler than use of <command moreinfo="none">grep</command>. 
3060
+		    <application moreinfo="none">ser</application>
3061
+		    parses header fields and passes their values in 
3062
+		    environment variables. Their names correspond
3063
+		    to header field names prefixed with "SIP_HF_".
3064
+		<programlisting format="linespecific">
3065
+# send email if a request for "jiri" arrives
3066
+if (uri=~"^sip:jiri@") {
3067
+     exec_msg("echo request received from $SIP_HF_FROM | mail -s 'request for you' jiri");
3068
+};
3069
+		</programlisting>
3070
+		    Moreover, several other values are passed in environment
3071
+		    variables. <varname>SIP_TID</varname> is a token uniquely identifying 
3072
+		    transaction, to which the request belongs. <varname>SIP_DID</varname>
3073
+		    includes to-tag, and is empty in requests creating a dialog.
3074
+		    <varname>SIP_SRCIP</varname> includes IP address, from which the
3075
+		    request was sent. <varname>SIP_RURI</varname> and <varname>SIP_ORURI</varname>
3076
+		    include current request-uri and original request-uri respectively,
3077
+		    <varname>SIP_USER</varname> and <varname>SIP_OUSER</varname> username
3078
+		    parts of these. The following listing shows environment variables
3079
+		    passed to a shell script on receipt of the previous message:
3080
+		    <programlisting format="linespecific">
3081
+<![CDATA[
3082
+SIP_HF_MAX_FORWARDS=10
3083
+SIP_HF_VIA=SIP/2.0/UDP 195.37.77.100:5040
3084
+SIP_HF_CSEQ=2 INVITE
3085
+SIP_HF_FROM="alice" <sip:alice@iptel.org>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
3086
+SIP_ORUI=sip:jiri@iptel.org
3087
+SIP_HF_CONTENT_LENGTH=451
3088
+SIP_TID=3b6b8295db0835815847b1f35f3b29b8
3089
+SIP_DID=
3090
+SIP_RURI=iptel.org
3091
+SIP_HF_TO=<sip:jiri@iptel.org>
3092
+SIP_OUSER=jiri
3093
+SIP_HF_CALLID=d10815e0-bf17-4afa-8412-d9130a793d96@213.20.128.35
3094
+SIP_SRCIP=195.37.77.100
3095
+SIP_HF_CONTENT_TYPE=application/sdp
3096
+SIP_HF_CONTACT=<sip:123.20.128.35:9315>
3097
+]]>
3098
+		    </programlisting>
3099
+				    
3100
+		</para>
3101
+	    </example> <!-- step 2, who called me -->
3102
+
3103
+
3104
+	    <example>  <!-- step 3,  make the script work for anyone -->
3105
+		<title>Using exec: step 3, Make The Script Work For Anyone</title>
3106
+		<para>
3107
+		    A drawback of the previous example is it works only
3108
+		    for one well-known user: request URI is matched against
3109
+		    his SIP address and notification is sent to his hard-wired email
3110
+		    address. In real scenarios, one would like
3111
+		    to enable such a service for all users without enumerating
3112
+		    their addresses in the script. The missing piece
3113
+		    is translation of user's SIP name to his email address.
3114
+		    This information is maintained in subscriber profiles,
3115
+		    stored in MySQL by <application moreinfo="none">ser</application>.
3116
+		    To translate the username to email address, the executed script
3117
+		    needs to query the MySQL database. That is what this example
3118
+		    shows. First, an SQL query is constructed which looks up
3119
+		    email address of user, for whom a request arrived. If the
3120
+		    query does not return a valid email address, the script
3121
+		    returns with an error status and <application moreinfo="none">ser</application>
3122
+		    script replies with "user does not exist". Otherwise
3123
+		    an email notification is sent.
3124
+		
3125
+		    <programlisting format="linespecific">
3126
+&execstep3;
3127
+		    </programlisting>
3128
+		</para>
3129
+	    </example> <!-- step 3 make the script work for anyone -->
3130
+	    <example> <!-- step 4, stateful processing -->
3131
+		<title>Adding Stateful Processing</title>
3132
+		<para>
3133
+		    The previously improved example still features a shortcoming.
3134
+		    When a message retransmission arrives due to a nework
3135
+		    mistake such as lost reply, the email notification is
3136
+		    executed again and again. That happens because the script
3137
+		    is stateless, i.e., no track of current transactions is
3138
+		    kept. The script does not know whether a request is
3139
+		    a new or a retransmitted one. Transaction management may
3140
+		    be introduced by use of tm module as described in
3141
+		    <xref linkend="statefulua">. In the script,
3142
+		    <command moreinfo="none">t_newtran</command> is first
3143
+		    called to absorb requests retransmission -- if they
3144
+		    occur, script does not continue. Then, as in the previous
3145
+		    example, an exec module action is called. Eventually,
3146
+		    a reply is sent statefully.
3147
+		    <note>
3148
+			<para>
3149
+			    Note carefuly: it is important that the stateful
3150
+			    reply processing (<command moreinfo="none">t_reply</command>)
3151
+			    is used as opposed to using stateless replies
3152
+			    (<command moreinfo="none">sl_send_reply</command>).
3153
+			    Otherwise, the outgoing reply would not affect
3154
+			    transactional context and would not be resent on
3155
+			    receipt of a request retransmission.
3156
+			</para>
3157
+		    </note>
3158
+		    <programlisting format="linespecific">
3159
+&execstep4;
3160
+		    </programlisting>
3161
+		    
3162
+		</para>
3163
+	    </example> <!-- step 4,  stateful processing -->
3164
+	    <example> <!-- step 5, full exec use -->
3165
+		<title>Full Example of exec Use</title>
3166
+		<para>
3167
+		    The last example iteration shows how to integrate the
3168
+		    email notification on missed calls with the default
3169
+		    <application moreinfo="none">ser</application> script
3170
+		    (see <xref linkend="defaultscript">). It generates an
3171
+		    email for every call invitation to an off-line user.
3172
+		    <programlisting format="linespecific">
3173
+&execstep5;
3174
+		    </programlisting>
3175
+		</para>
3176
+		    
3177
+		<para>
3178
+		    Production "missed calls" services may want to 
3179
+		    report on calls missed for other reasons than
3180
+		    being off-line too. Particularly, users may wish to be
3181
+		    reported calls missed due to call cancellation,
3182
+		    busy status or a downstream failure. Such missed
3183
+		    calls can be easily reported to syslog or mysql
3184
+		    using the acc module (see <xref linkend="missedcalls">).
3185
+		    The other, more general way, is to return to request
3186
+		    processing on receipt of a negative reply.
3187
+		    (see <xref linkend="replyprocessingsection">). Before
3188
+		    a request is forwarded, it is labeled to be
3189
+		    re-processed in a <command moreinfo="none">reply_route</command>
3190
+		    on receipt of a negative reply -- this is what
3191
+		    <command moreinfo="none">t_on_negative</command> action
3192
+		    is used for. It does not matter what caused the transaction
3193
+		    to fail -- it may be unresponsive downstream server,
3194
+		    server responding with 6xx, or server sending a 487
3195
+		    reply, because an INVITE was cancelled. When any such
3196
+		    circumstances occur (i.e., transaction does not complete
3197
+		    with a 2xx status code), <command moreinfo="none">reply_route</command>
3198
+		    is entered.
3199
+		</para>
3200
+		<para>
3201
+		    The following <application moreinfo="none">ser</application>
3202
+		    script reports missed calls in all possible cases.
3203
+		    It reports them when a user is off-line as well as when
3204
+		    a user is on-line, but INVITE transaction does not complete
3205
+		    successfully.
3206
+		    <programlisting format="linespecific">
3207
+&execstep5b;
3208
+		    </programlisting>
3209
+		</para>
3210
+		
3211
+	    </example> <!-- step 5, full exec use -->
3212
+
3213
+	</section> <!-- using exec -->
3214
+
3215
+	<section id="fifoserver">
2842 3216
 	    <title>Application FIFO Server</title>
2843 3217
 
2844
-	<para>
3218
+	    <para>
2845 3219
 	    Application FIFO server is a very powerful method to program
2846 3220
 	    SIP services. The most valuable benefit
2847 3221
 	    is it works with SIP-unaware applications
... ...
@@ -2858,7 +3232,7 @@ if (uri=~"^sip:johndoe@") {
2858 3232
 	    management utility. The command-line utility can browse
2859 3233
 	    server's in-memory user-location database, display 
2860 3234
 	    running processes and operational statistics.
2861
-	</para>
3235
+	    </para>
2862 3236
 	    <para>
2863 3237
 		The way the FIFO server works is similar to how 
2864 3238
 		<filename moreinfo="none">/proc</filename> filesystem works
... ...
@@ -3016,6 +3390,134 @@ EOF
3016 3390
 
3017 3391
 	</section> <!-- FIFO server -->
3018 3392
     </chapter>
3393
+
3394
+    <chapter id="complementaryapps">
3395
+	<title>Complementary Applications</title>
3396
+	<section id="serctl">
3397
+	    <title><application>serctl</application> command-line tool</title>
3398
+	    <para>
3399
+		<application>serctl</application> is a command-line utility which allows to
3400
+		perform most of management tasks needed to operate
3401
+		<application moreinfo="none">ser</application>: adding users, changing their passwords,
3402
+		watching server status, etc. Usage of utility is
3403
+		as follows:
3404
+
3405
+		<example>
3406
+		    <title><application>serctl</application> usage</title>
3407
+		    <programlisting format="linespecific">
3408
+
3409
+usage: 
3410
+           * subscribers *
3411
+ serctl add &lt;username&gt; &lt;password&gt; &lt;email&gt; .. add a new subscriber (*)
3412
+ serctl passwd &lt;username&gt; &lt;passwd&gt; ......... change user's password (*)
3413
+ serctl rm &lt;username&gt; ...................... delete a user (*)
3414
+ serctl mail &lt;username&gt; .................... send an email to a user
3415
+ serctl alias show [&lt;alias&gt;] ............... show aliases
3416
+ serctl alias rm &lt;alias&gt; ................... remove an alias
3417
+ serctl alias add &lt;alias&gt; &lt;uri&gt; ............ add an aliases 
3418
+
3419
+           * access control lists *
3420
+ serctl acl show [&lt;username&gt;] .............. show user membership
3421
+ serctl acl grant &lt;username&gt; &lt;group&gt; ....... grant user membership (*)
3422
+ serctl acl revoke &lt;username&gt; [&lt;group&gt;] .... grant user membership(s) (*)
3423
+
3424
+           * usrloc *
3425
+ serctl ul show [&lt;username&gt;]................ show in-RAM online users
3426
+ serctl ul rm &lt;username&gt; ................... delete user's UsrLoc entries
3427
+ serctl ul add &lt;username&gt; &lt;uri&gt; ............ introduce a permanent UrLoc entry
3428
+ serctl showdb [&lt;username&gt;] ................ show online users flushed in DB
3429
+
3430
+           * server health *
3431
+ serctl monitor ............................ show internal status
3432
+ serctl ps ................................. show runnig processes 
3433
+ serctl fifo ............................... send raw commands to FIFO
3434
+
3435
+   Commands labeled with (*) will prompt for a MySQL password.
3436
+   If the variable PW is set, the password will not be prompted.
3437
+
3438
+ </programlisting>
3439
+		</example>
3440
+	    </para>
3441
+	    <note>
3442
+		<para>
3443
+
3444
+		Prior to using the utility, you have to first 
3445
+		set the environment variable <constant>SIP_DOMAIN</constant>
3446
+		to locally appropriate value (e.g., "foo.com"). It is
3447
+		needed for calculation of user credentials, which depend
3448
+		    on SIP digest realm. 
3449
+		    (see also <link linkend="msmbug">MSM Authentication Issue</link>)
3450
+	        </para>
3451
+	    </note>
3452
+
3453
+	    <example>
3454
+		<title>Example Output of Server Watching Command 
3455
+		    <command moreinfo="none">sc monitor</command>
3456
+		</title>
3457
+		<programlisting format="linespecific">
3458
+
3459
+[cycle #: 2; if constant make sure server lives and fifo is on]
3460
+Server: Sip EXpress router(0.8.8 (i386/linux))
3461
+Now: Thu Sep 26 23:16:48 2002
3462
+Up Since: Thu Sep 26 12:35:27 2002
3463
+Up time: 38481 [sec]
3464
+
3465
+Transaction Statistics
3466
+Current: 0 (0 waiting) Total: 606 (0 local)       
3467
+Replied localy: 34      
3468
+Completion status 6xx: 0, 5xx: 1, 4xx: 86, 3xx: 0,2xx: 519      
3469
+
3470
+Stateless Server Statistics
3471
+200: 6218 202: 0 2xx: 0      
3472
+300: 0 301: 0 302: 0 3xx: 0      
3473
+400: 0 401: 7412 403: 2 404: 1258 407: 116 408: 0 483: 0 4xx: 25      500: 0 5xx: 0      
3474
+6xx: 0      
3475
+xxx: 0      
3476
+failures: 0      
3477
+
3478
+UsrLoc Stats
3479
+Domain Registered Expired
3480
+'aliases' 9 0
3481
+'location' 29 17
3482
+
3483
+		</programlisting>
3484
+
3485
+	    </example>
3486
+	</section>
3487
+
3488
+	<section id="serweb">
3489
+	    <title>Web User Provisioning -- <application>serweb</application></title>
3490
+	    <para>
3491
+		To make provisioning of user accounts convenient, 
3492
+		a web front-end to <application moreinfo="none">ser</application>,
3493
+		<application moreinfo="none">serweb</application> has been
3494
+		developed. <application moreinfo="none">serweb</application>,
3495
+		a PHP-written web application,
3496
+		allows users to apply for new <application moreinfo="none">ser</application>
3497
+		accounts, and maintain these.
3498
+		Users can manipulate their contacts, keep a phone-book
3499
+		with SIP addresses, change password, send instant SIP messages,
3500
+		and more. Administrators can manipulate any accounts and
3501
+		grant or revoke user privileges.
3502
+	    </para>
3503
+	    <para>
3504
+		<application moreinfo="none">serweb</application> is freely
3505
+		available from berlios site at
3506
+		<ulink url="http://developer.berlios.de/cvs/?group_id=500">
3507
+		http://developer.berlios.de/cvs/?group_id=500</ulink>. Installation
3508
+		takes unpacking tarball to a safe destination at web server
3509
+		(better not in the HTML tree) and configuring 
3510
+		<filename moreinfo="none">config.php</filename> accordingly
3511
+		to local conditions.
3512
+	    </para>
3513
+	    <para>
3514
+		Running <application moreinfo="none">serweb</application> can
3515
+		be seen at iptel.org's SIP site. Just create and use a SIP
3516
+		account at <ulink url="http://www.iptel.org/user/">http://www.iptel.org/user/</ulink>
3517
+	    </para>
3518
+	</section>
3519
+
3520
+    </chapter> <!-- serweb -->
3019 3521
     
3020 3522
     <chapter>
3021 3523
 	<title>Reference</title>
... ...
@@ -3663,97 +4165,6 @@ if (len_gt(1024)) {
3663 4165
 	    </itemizedlist>
3664 4166
 	</section>
3665 4167
 
3666
-	<section>
3667
-	    <title><application>serctl</application> command</title>
3668
-	    <para>
3669
-		<application>serctl</application> is a command-line utility which allows to
3670
-		perform most of management tasks needed to operate
3671
-		a server: adding users, changing their passwords,
3672
-		watching server status, etc. Usage of utility is
3673
-		as follows:
3674
-
3675
-		<example>
3676
-		    <title><application>serctl</application> usage</title>
3677
-		    <programlisting format="linespecific">
3678
-
3679
-usage: 
3680
-           * subscribers *
3681
- serctl add &lt;username&gt; &lt;password&gt; &lt;email&gt; .. add a new subscriber (*)
3682
- serctl passwd &lt;username&gt; &lt;passwd&gt; ......... change user's password (*)
3683
- serctl rm &lt;username&gt; ...................... delete a user (*)
3684
- serctl mail &lt;username&gt; .................... send an email to a user
3685
- serctl alias show [&lt;alias&gt;] ............... show aliases
3686
- serctl alias rm &lt;alias&gt; ................... remove an alias
3687
- serctl alias add &lt;alias&gt; &lt;uri&gt; ............ add an aliases 
3688
-
3689
-           * access control lists *
3690
- serctl acl show [&lt;username&gt;] .............. show user membership
3691
- serctl acl grant &lt;username&gt; &lt;group&gt; ....... grant user membership (*)
3692
- serctl acl revoke &lt;username&gt; [&lt;group&gt;] .... grant user membership(s) (*)
3693
-
3694
-           * usrloc *
3695
- serctl ul show [&lt;username&gt;]................ show in-RAM online users
3696
- serctl ul rm &lt;username&gt; ................... delete user's UsrLoc entries
3697
- serctl ul add &lt;username&gt; &lt;uri&gt; ............ introduce a permanent UrLoc entry
3698
- serctl showdb [&lt;username&gt;] ................ show online users flushed in DB
3699
-
3700
-           * server health *
3701
- serctl monitor ............................ show internal status
3702
- serctl ps ................................. show runnig processes 
3703
- serctl fifo ............................... send raw commands to FIFO
3704
-
3705
-   Commands labeled with (*) will prompt for a MySQL password.
3706
-   If the variable PW is set, the password will not be prompted.
3707
-
3708
- </programlisting>
3709
-		</example>
3710
-	    </para>
3711
-	    <note>
3712
-		<para>
3713
-
3714
-
3715
-		Prior to using the utility, you have to first 
3716
-		set the environment variable <constant>SIP_DOMAIN</constant>
3717
-		to locally appropriate value (e.g., "foo.com"). It is
3718
-		needed for calculation of user credentials, which depend
3719
-		on SIP digest realm.
3720
-	        </para>
3721
-	    </note>
3722
-
3723
-	    <example>
3724
-		<title>Example Output of Server Watching Command 
3725
-		    <command moreinfo="none">sc monitor</command>
3726
-		</title>
3727
-		<programlisting format="linespecific">
3728
-
3729
-[cycle #: 2; if constant make sure server lives and fifo is on]
3730
-Server: Sip EXpress router(0.8.8 (i386/linux))
3731
-Now: Thu Sep 26 23:16:48 2002
3732
-Up Since: Thu Sep 26 12:35:27 2002
3733
-Up time: 38481 [sec]
3734
-
3735
-Transaction Statistics
3736
-Current: 0 (0 waiting) Total: 606 (0 local)       
3737
-Replied localy: 34      
3738
-Completion status 6xx: 0, 5xx: 1, 4xx: 86, 3xx: 0,2xx: 519      
3739
-
3740
-Stateless Server Statistics
3741
-200: 6218 202: 0 2xx: 0      
3742
-300: 0 301: 0 302: 0 3xx: 0      
3743
-400: 0 401: 7412 403: 2 404: 1258 407: 116 408: 0 483: 0 4xx: 25      500: 0 5xx: 0      
3744
-6xx: 0      
3745
-xxx: 0      
3746
-failures: 0      
3747
-
3748
-UsrLoc Stats
3749
-Domain Registered Expired
3750
-'aliases' 9 0
3751
-'location' 29 17
3752
-
3753
-		</programlisting>
3754
-
3755
-	    </example>
3756
-	</section>
3757 4168
 
3758 4169
 
3759 4170
 
... ...
@@ -3899,20 +4310,7 @@ Domain Registered Expired
3899 4310
 		    </thead>
3900 4311
 
3901 4312
 		    <tbody>
3902
-			<row>
3903
-			    <entry>
3904
-				addRecordRoute
3905
-			    </entry>
3906
-			    <entry>
3907
-				rr
3908
-			    </entry>
3909
-			    <entry>
3910
-				none
3911
-			    </entry>
3912
-			    <entry>
3913
-				record-route request
3914
-			    </entry>
3915
-			</row>
4313
+
3916 4314
 			<row>
3917 4315
 			    <entry>
3918 4316
 				append_hf
... ...
@@ -3957,7 +4355,7 @@ Domain Registered Expired
3957 4355
 			</row>
3958 4356
 			<row>
3959 4357
 			    <entry>
3960
-				exec_uri
4358
+				exec_dset
3961 4359
 			    </entry>
3962 4360
 			    <entry>
3963 4361
 				exec
... ...
@@ -3970,6 +4368,21 @@ Domain Registered Expired
3970 4368
 				its output
3971 4369
 			    </entry>
3972 4370
 			</row>
4371
+			<row>
4372
+			    <entry>
4373
+				exec_msg
4374
+			    </entry>
4375
+			    <entry>
4376
+				exec
4377
+			    </entry>
4378
+			    <entry>
4379
+				command name
4380
+			    </entry>
4381
+			    <entry>
4382
+				execute an external command and pass received SIP request
4383
+				to its input
4384
+			    </entry>
4385
+			</row>
3973 4386
 			<row>
3974 4387
 			    <entry>
3975 4388
 				is_in_group
... ...
@@ -4031,6 +4444,20 @@ Domain Registered Expired
4031 4444
 				returns false if no contact for user found;
4032 4445
 			    </entry>
4033 4446
 			</row>
4447
+			<row>
4448
+			    <entry>
4449
+				loose_route
4450
+			    </entry>
4451
+			    <entry>
4452
+				rr
4453
+			    </entry>
4454
+			    <entry>
4455
+				none
4456
+			    </entry>
4457
+			    <entry>
4458
+				process loose routes in requests
4459
+			    </entry>
4460
+			</row>
4034 4461
 			<row>
4035 4462
 			    <entry>
4036 4463
 				mf_process_maxfwd_header
... ...
@@ -4085,17 +4512,16 @@ Domain Registered Expired
4085 4512
 			</row>
4086 4513
 			<row>
4087 4514
 			    <entry>
4088
-				rewriteFromRoute
4515
+				record_route
4089 4516
 			    </entry>
4090 4517
 			    <entry>
4091 4518
 				rr
4092 4519
 			    </entry>
4093 4520
 			    <entry>
4094
-				none
4521
+				loose routing (1=on, 0=off)
4095 4522
 			    </entry>
4096 4523
 			    <entry>
4097
-				strict routing: use Route header field if present in
4098
-				request
4524
+				record-route a request
4099 4525
 			    </entry>
4100 4526
 			</row>
4101 4527
 			<row>
... ...
@@ -4437,23 +4863,12 @@ Domain Registered Expired
4437 4863
     
4438 4864
     <!-- TODO
4439 4865
 
4440
-
4441
-    MISSING
4442
-    - modules
4443
-    - installation
4866
+    serweb
4444 4867
 
4445 4868
     FAQ: 
4446 4869
     - bandwidth, FW/NATs
4447 4870
 
4448
-    HOWTO
4449
-    - serving multiple domains
4450
-    - ACLs
4451
-    - when to use stateless versus stateful
4452
-
4453
-    PROGRAMMING TM
4454
-
4455 4871
 
4456
-    follow the mysql pattern, tehy have a very nice documentation
4457 4872
     -->
4458 4873
 
4459 4874
 </book>