Sfoglia il codice sorgente

Merge branch 'master' into drouting

* master: (728 commits)
  tm: suspended transaction was not always replied and freed
  core: fix EXTRA_DEBUG information about second via in parse_msg
  nathelper(k): fix for very long payload-type
  nathelper (k): fix for flag 'l'
  avpops: merge avpops modules
  according to Di-Shi are K's and ser's osp module more or less the same, whereas Kamailio's osp module should be more up2date than ser's module. Thus, ser's osp module will be removed and K's osp module will be used as common OSP module.
  remove shm_str_dup() from tls_util.[c|h] as it breaks compilation and is not used at all
  cfg framework: documentation for cfg_read_var*
  Add missed <sys/select.h> include.
  cfg framework: read variables by name with a handle
  domain: init db connection for RPC process
  presence: use event name from parsed structure
  core: parse_event - skip first ; for parameters
  select_core: fix @ruri.rn_user moving parsed ptr
  modules/lcr: fixed printing of lcr_id by lcr.dump_lcrs
  carrierroute: port from 1.5 branch, r5885
  siputils(k): port from 1.5 branch, r5880
  carrierroute: port from 1.5 branch, r5877
  carrierroute: port from 1.5 branch, r5876, remove dead code (double return)
  registrar(k): port from 1.5 branch, r5873
  ...
Raul Alexis Betancor Santana 16 anni fa
parent
commit
75837023e6
100 ha cambiato i file con 4888 aggiunte e 1197 eliminazioni
  1. 1 0
      .gitignore
  2. 116 98
      INSTALL
  3. 104 57
      Makefile
  4. 8 3
      Makefile.defs
  5. 4 4
      Makefile.rules
  6. 1 1
      Makefile.targets
  7. 106 2
      NEWS
  8. 43 0
      cfg.lex
  9. 101 5
      cfg.y
  10. 2 2
      cfg/cfg_ctx.c
  11. 4 0
      cfg/cfg_ctx.h
  12. 134 1
      cfg/cfg_select.c
  13. 24 0
      cfg/cfg_select.h
  14. 1 1
      config.h
  15. 23 7
      core_cmd.c
  16. 10 7
      dns_cache.c
  17. 39 0
      doc/cfg.txt
  18. 46 18
      doc/rpc/ser_rpc.txt
  19. 60 22
      doc/rpc/ser_rpc.xml
  20. 5 1
      docbook/entities.xml
  21. 3 3
      etc/dbtext.cfg
  22. 49 0
      etc/dictionary.radius
  23. 0 0
      etc/dictionary.sip-router
  24. 545 0
      etc/kamailio.cfg
  25. 12 12
      etc/nathelper.cfg
  26. 1 1
      etc/rules.m4
  27. 7 7
      etc/sip-router-basic.cfg
  28. 13 13
      etc/sip-router-oob.cfg
  29. 0 0
      etc/sip-router.cfg
  30. 23 23
      etc/sip-router.cfg.m4
  31. 17 17
      etc/sr
  32. 22 0
      etc/tls/README
  33. 88 0
      etc/tls/ca.conf
  34. 58 0
      etc/tls/request.conf
  35. 22 0
      etc/tls/rootCA/cacert.pem
  36. 56 0
      etc/tls/rootCA/certs/01.pem
  37. 1 0
      etc/tls/rootCA/index.txt
  38. 30 0
      etc/tls/rootCA/private/cakey.pem
  39. 1 0
      etc/tls/rootCA/serial
  40. 16 0
      etc/tls/user.conf
  41. 22 0
      etc/tls/user/user-calist.pem
  42. 56 0
      etc/tls/user/user-cert.pem
  43. 9 0
      etc/tls/user/user-cert_req.pem
  44. 9 0
      etc/tls/user/user-privkey.pem
  45. 242 0
      examples/kamailio/acc-mysql.cfg
  46. 71 0
      examples/kamailio/acc.cfg
  47. 224 0
      examples/kamailio/ctd.sh
  48. 30 0
      examples/kamailio/exec_s3.cfg
  49. 41 0
      examples/kamailio/exec_s4.cfg
  50. 68 0
      examples/kamailio/exec_s5.cfg
  51. 103 0
      examples/kamailio/flag_reply.cfg
  52. 67 0
      examples/kamailio/fork.cfg
  53. 31 0
      examples/kamailio/logging.cfg
  54. 146 0
      examples/kamailio/msilo.cfg
  55. 237 0
      examples/kamailio/nathelper.cfg
  56. 148 0
      examples/kamailio/pstn.cfg
  57. 33 0
      examples/kamailio/redirect.cfg
  58. 76 0
      examples/kamailio/replicate.cfg
  59. 65 0
      examples/kamailio/serial_183.cfg
  60. 11 0
      examples/kamailio/web_im/README
  61. 40 0
      examples/kamailio/web_im/click_to_dial.html
  62. 76 0
      examples/kamailio/web_im/click_to_dial.php
  63. 37 0
      examples/kamailio/web_im/send_im.html
  64. 77 0
      examples/kamailio/web_im/send_im.php
  65. 2 2
      io_wait.c
  66. 2 0
      lib/kmi/Makefile
  67. 3 3
      lib/kmi/attr.c
  68. 2 2
      lib/kmi/fmt.c
  69. 2 2
      lib/kmi/mi.c
  70. 49 0
      lib/kmi/mi_mem.h
  71. 5 6
      lib/kmi/tree.c
  72. 9 16
      lib/srdb1/schema/gw.xml
  73. 9 12
      lib/srdb1/schema/lcr.xml
  74. 8 1
      main.c
  75. 0 0
      modules/avpops/Makefile
  76. 0 0
      modules/avpops/README
  77. 0 0
      modules/avpops/avpops.c
  78. 0 0
      modules/avpops/avpops_db.c
  79. 0 0
      modules/avpops/avpops_db.h
  80. 0 0
      modules/avpops/avpops_impl.c
  81. 0 0
      modules/avpops/avpops_impl.h
  82. 0 0
      modules/avpops/avpops_parse.c
  83. 0 0
      modules/avpops/avpops_parse.h
  84. 0 0
      modules/avpops/doc/Makefile
  85. 0 0
      modules/avpops/doc/avpops.xml
  86. 0 0
      modules/avpops/doc/avpops_admin.xml
  87. 16 16
      modules/carrierroute/README
  88. 14 8
      modules/carrierroute/cr_fifo.c
  89. 15 15
      modules/carrierroute/doc/carrierroute_admin.xml
  90. 345 261
      modules/lcr/README
  91. 1 1
      modules/lcr/doc/lcr.xml
  92. 240 112
      modules/lcr/doc/lcr_admin.xml
  93. 0 2
      modules/lcr/hash.c
  94. 280 375
      modules/lcr/lcr_mod.c
  95. 6 4
      modules/lcr/lcr_mod.h
  96. 62 43
      modules/lcr/lcr_rpc.c
  97. 10 7
      modules/lcr/mi.c
  98. 5 4
      modules/mi_rpc/Makefile
  99. 84 0
      modules/mi_rpc/README
  100. 4 0
      modules/mi_rpc/doc/Makefile

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 # ignore autogenerated files
+autover.h
 cfg.tab.c
 cfg.tab.h
 lex.yy.c

+ 116 - 98
INSTALL

@@ -3,30 +3,30 @@ $Id$
 
      ===========================================
 
-     SIP Express Router (ser) Installation Notes
+     SIP Router (sip-router) Installation Notes
 
-             http://www.iptel.org/ser/
+             http://sip-router.org
 
      ===========================================
 
-  This memo gives you hints how to set up SER quickly. To 
-  understand how SER works and how to configure it properly,
-  read admin's guide available from SER website. We also
-  urge you to read latest ISSUES (available from SER website 
+  This memo gives you hints how to set up SIP Router quickly. To 
+  understand how SIP Router works and how to configure it properly,
+  read admin's guide available from SIP Router website. We also
+  urge you to read latest ISSUES (available from SIP Router website 
   too) and check for potential problems in this release.
   Users of previous releases are encouraged to read NEWS to
-  learn how to move to this new SER version.
+  learn how to move to this new SIP Router version.
   
 
 TOC
 
 1. Supported Architectures and Requirements
-2. Howto Build ser From Source Distribution
+2. Howto Build sip-router From Source Distribution
 3. Quick-Start Installation Guide
    A) Getting Help
    B) Disclaimers
    C) Quick Start
-   D) ser with Persistent Data Storage
+   D) sip-router with Persistent Data Storage
 4. Troubleshooting
 
 
@@ -35,10 +35,10 @@ TOC
 -------------------------------------------
 
 Supported operating systems: Linux, FreeBSD, NetBSD, OpenBSD, Solaris, Darwin
-Partially supported: Windows+Cygwin (core + static modules only, no IPv6,
- no TCP, no dynamic modules)
+Partially supported: Windows+Cygwin (core + static modules only, no
+  IPv6, no TCP, no dynamic modules)
 Supported architectures: i386, x86_64 (amd64), armv4l, sparc64, powerpc,
- powerpc64
+  powerpc64
 Experimental architectures: mips1, mips2, sparc32, alpha
 
 (for other architectures the Makefiles might need to be edited)
@@ -53,7 +53,7 @@ Requirements:
 - bison or yacc (Berkley yacc)
 - flex
 - GNU make (on Linux this is the standard "make", on *BSD and Solaris is
- called "gmake") version >= 3.80 (recommended 3.81).
+  called "gmake") version >= 3.80 (recommended 3.81).
 - sed and tr (used in the makefiles)
 - GNU tar ("gtar" on Solaris) and gzip if you want "make tar" to work
 - GNU install, BSD install or Solaris install if you want "make
@@ -61,9 +61,9 @@ Requirements:
 - libmysqlclient & libz (zlib) if you want mysql support (the mysql module)
 - libexpat if you want the jabber gateway support (the jabber module)
 - libxml2 if you want to compile the cpl-c (CPL support) or pa (presence) 
-modules
+   modules
 - libradiusclient-ng (> 5.0) if you need radius support (the auth_radius,
-group_radius, uri_radius and avp_radius modules)
+  group_radius, uri_radius and avp_radius modules)
 - libpq if you need postgres support (the postgres module)
 
 
@@ -84,7 +84,7 @@ OS Notes:
   NOTE: you'll need to add radiusclient_ng=4 to the gmake command line if you
   use the 0.4.* version.
   
-  Compile example (all the modules and ser in a tar.gz):
+  Compile example (all the modules and sip-router in a tar.gz):
      gmake bin radiusclient_ng=4 include_modules="mysql jabber cpl-c auth_radius group_radius uri_radius postgres pa"
 
   OpenBSD 3.7
@@ -95,7 +95,7 @@ OS Notes:
    http://download.berlios.de/radiusclient-ng/radiusclient-ng-0.5.1.tar.gz
    (you need to download and install it, since there is no "official" 
    openbsd port for it) for libradiusclient-ng 
-  Compile example (all the modules and ser in a tar.gz):
+  Compile example (all the modules and sip-router in a tar.gz):
      gmake bin include_modules="mysql jabber cpl-c auth_radius group_radius uri_radius pa"
 
   NetBSD 2.0
@@ -104,7 +104,7 @@ OS Notes:
   - libxml2-2.6.19 (/usr/pkgsrc/textproc/libxml2) for libxml2
   - radiusclient-ng-0.5.1 (see OpenBSD)
   
-  Compile example (all the modules and ser in a tar.gz):
+  Compile example (all the modules and sip-router in a tar.gz):
      gmake bin include_modules="mysql jabber cpl-c auth_radius group_radius uri_radius pa"
 
  Solaris 10
@@ -118,7 +118,7 @@ OS Notes:
   Needed packages:
   [TODO]
   
-  Compile example (all the modules and ser in a tar.gz):
+  Compile example (all the modules and sip-router in a tar.gz):
      gmake bin INSTALL=install include_modules="mysql jabber cpl-c auth_radius group_radius uri_radius postgres pa"
 
  Linux
@@ -131,20 +131,21 @@ OS Notes:
       - libxml2-dev for libxml2
       - libradiusclient-ng-dev for libradiusclient (you can download the 
       package from http://apt.sip-router.org/debian/dists/unstable/main/binary-i386/libradiusclient-ng-dev_0.5.1-0.5_i386.deb ).
-      NOTE: you can get up-to-date ser packages or libradiusclient packages
+      NOTE: you can get up-to-date sip-router packages or libradiusclient packages
       from http://apt.sip-router.org: add to your /etc/apt/sources.list the
       following lines:
          deb http://apt.sip-router.org/debian testing main contrib non-free
          deb http://apt.sip-router.org/debian unstable main contrib non-free
       and then: apt-get update; apt-get install libradiusclient-ng-dev
       (or, if you want to use the pre-built modules:
-       apt-get install ser ser-cpl-module ser-jabber-module ser-mysq-module ser-pa-module ser-postgres-module ser-radius-modules )
+       apt-get install sip-router sip-router-cpl-module sip-router-jabber-module sip-router-mysq-module sip-router-pa-module sip-router-postgres-module sip-router-radius-modules )
 
  Cygwin  (alpha state, partial support)
 
- make sure make, bison, flex, minires and minires-devel (needed for the resolver functions) are installed. 
+ make sure make, bison, flex, minires and minires-devel (needed for the
+ resolver functions) are installed.
  
- Only building ser's core and some static modules is supported for now.
+ Only building sip-router's core and some static modules is supported for now.
  Stuff known not to work:
            - IPv6 (cygwin doesn't support it yet)
            - TCP (the tcp code heavily depends on file descriptor passing 
@@ -153,20 +154,21 @@ OS Notes:
              backlinking doesn't work in windows by design)
 
 
-  Compile example (all the modules and ser in a tar.gz):
+  Compile example (all the modules and sip-router in a tar.gz):
      make bin include_modules="mysql jabber cpl-c auth_radius group_radius uri_radius postgres pa"
 
 
-2. Howto Build ser From Source Distribution
+2. Howto Build sip-router From Source Distribution
 -------------------------------------------
 
 (NOTE: if make doesn't work try gmake  instead)
 
-SER is split in four main parts: The core, the modules, the utilties, and scripts/examples
-When you build, you can decide to build only the core, the modules, both, or all.
+SIP Router is split in four main parts: The core, the modules, the
+utilties, and scripts/examples.  When you build, you can decide to build
+only the core, the modules, both, or all.
 
-Compile SER core only:
-make   #builds only ser core, equivalent to make ser
+Compile SIP Router core only:
+make   #builds only sip-router core, equivalent to make sip-router
 
 Compile modules except some explicitly excepted (see below)
 make modules  
@@ -183,11 +185,11 @@ avp_radius, postgres, pa.
 Including groups of modules (available in >0.9.x):
 Instead of compiling the default modules only, you can specify groups of
 modules to include, according to their status:
-standard - Modules in this group are considered a standard part of SER (due to widespread usage)
+standard - Modules in this group are considered a standard part of SIP Router (due to widespread usage)
     but they have no dependencies (note that some of these interplay with external systems.
     However, they don't have compile or link dependencies).
 
-standard-dep -  Modules in this group are considered a standard part of SER (due to widespread usage)
+standard-dep -  Modules in this group are considered a standard part of SIP Router (due to widespread usage)
     but they have dependencies that most be satisfied for compilation.
     NOTE! All presence modules (dialog, pa, presence_b2b, rls, xcap) have been included in this
     group due to interdependencies
@@ -224,14 +226,18 @@ You can also explicitly skip modules using skip_modules. Let's say you want all
  and standard-dep modules except domain:
 make group_include="standard standard-dep" skip_modules="domain" all
 
-NOTE!!! As this mechanism is very powerful, you may be uncertain which modules wwill be included.
-Just replace all (or modules) with print-modules and you will see which modules will be included
-and excluded, ex:
+NOTE!!! As this mechanism is very powerful, you may be uncertain which
+modules wwill be included.
+Just replace all (or modules) with print-modules and you will see which
+modules will be included and excluded, ex:
+
 make print-modules
+
 will show which modules are excluded by default.
 
-If you want to install or to build a binary package (a tar.gz with ser and
- the modules), substitute "all" in the above command with "install" or "bin".
+If you want to install or to build a binary package (a tar.gz with
+sip-router and the modules), substitute "all" in the above command with
+"install" or "bin".
 
 
 More compile examples:
@@ -421,22 +427,23 @@ make prefix=/usr/local  install
 
 Note: If you use prefix parameter in make install then you also need
 to use this parameter in previous make commands, i.e. make, make modules,
-or make all. If you fail to do this then SER will look for the default
+or make all. If you fail to do this then SIP Router will look for the default
 configuration file in a wrong directory, because the directory of the
-default configuration file is hard coded into ser during compile time. 
+default configuration file is hard coded into sip-router during compile time. 
 When you use a different prefix parameter when installing then the 
-directory hard coded in ser and the directory in which the file will be 
+directory hard coded in sip-router and the directory in which the file will be 
 installed by make install will not match. (You can specify exact location
-of the configuration file using -f parameter of ser).
+of the configuration file using -f parameter of sip-router).
 
 For example, if you do the following:
 make all
 make prefix=/ install
 
 Then the installation will put the default configuration file into
-/etc/ser/ser.cfg (because prefix is /), but ser will look for the file
-in /usr/local/etc/ser/ser.cfg (because there was no prefix parameter
-in make all and /usr/local is the default value of prefix).
+/etc/sip-router/sip-router.cfg (because prefix is /), but sip-router
+will look for the file in /usr/local/etc/sip-router/sip-router.cfg
+(because there was no prefix parameter make all and /usr/local is the
+default value of prefix).
 
 Workaround is trivial, use the same parameters in all make commands:
 make prefix=/ all
@@ -452,17 +459,18 @@ That applies to other make parameters as well (for example parameters
 
 A) Getting Help
 
-This guide gives you instructions on how to set up the SIP Express 
-Router (ser) on your box quickly. In case the default configuration
-does not fly, check documentation at ser site
-  http://www.iptel.org/ser/
-to learn how to configure SER for your site.
+This guide gives you instructions on how to set up the SIP Router
+(sip-router) on your box quickly. In case the default configuration
+does not fly, check documentation at sip-router site
+  http://sip-router.org
+to learn how to configure SIP Router for your site.
 
 If the documentation does not resolve your problem you may try contacting 
-our user forum by E-mail at [email protected] -- that is the mailing 
-list of ser community. To participate in the mailing list, subscribe at the 
-following web address:
-  http://lists.iptel.org/mailman/listinfo/serusers
+our user forum by E-mail at [email protected] -- that is the
+mailing list of ser community. To participate in the mailing list,
+subscribe at the following web address:
+
+  http://lists.sip-router.org/cgi-bin/mailman/listinfo
 
 To participate in our commercial support program, contact [email protected].
 The support program will provide you with most timely and accurate help
@@ -482,14 +490,19 @@ dependencies on MySQL which is needed for storing user credentials.)
 C) Quick Start
 
 The following step-by step guide gives you instructions how to install the 
-sql-free distribution of ser. If you need persistence and authentication, 
-then you have to install additional MySql support -- proceed to section D)
-after you are finished with C).
-
-1) Download an RPM or debian package from our site
-    http://www.iptel.org/ser
-If you don't use an rpm or debian based distribution, try our tar.gz'ed binaries
- (ser-$(version)_$(os)_$(arch).tar.gz, e.g: ser-0.8.8_linux_i386.tar.gz).
+sql-free distribution of sip-router. If you need persistence and
+authentication, then you have to install additional MySql support --
+proceed to section D) after you are finished with C).
+
+1) Download an RPM or debian package from site
+
+    ****** site not available yet
+
+If you don't use an rpm or debian based distribution, try our tar.gz'ed
+binaries
+
+  ******* not available yet
+
 If you use Solaris 8 you can try our solaris package.
 If you use Gentoo Linux you do not have to download a package.
 
@@ -499,13 +512,13 @@ RPM:
 debian:
     dpkg -i <package_name>
 gentoo:
-    emerge ser
+    emerge sip-router
 	(or if use only stable packets:
-	 ACCEPT_KEYWORDS="~x86" emerge ser)
+	 ACCEPT_KEYWORDS="~x86" emerge sip-router)
 tar.gz:
     cd /; tar zxvf <package_name>_os_arch.tar.gz
     (it will install in /usr/local/, and the configuration file in
-     /usr/local/etc/ser/ser.cfg)
+     /usr/local/etc/sip-router/sip-router.cfg)
 Solaris:
     gunzip <package_name>.gz ; pkgadd -d <package_name>
 *BSD:
@@ -513,15 +526,15 @@ Solaris:
     
 3) start the server
 RPM + gentoo:
-    /etc/init.d/ser start
+    /etc/init.d/sip-router start
 debian:
-    ser is started automatically after the install
-    (in case something fails you can start it with /etc/init.d/ser start)
+    sip-router is started automatically after the install
+    (in case something fails you can start it with /etc/init.d/sip-router start)
 tar.gz:
     the tar.gz does not include an init.d script, you'll have to create one of
     your own or adapt one from the source distribution (debian/init.d,
-    rpm/ser.init.*, gentoo/ser.init)
-    You can start ser directly with /usr/local/sbin/ser.
+    rpm/sip-router.init.*, gentoo/sip-router.init)
+    You can start sip-router directly with /usr/local/sbin/sip-router.
 Solaris:
     see tar.gz.
     
@@ -552,20 +565,23 @@ Solaris:
 
 
 
-D) ser with Persistent Data Storage
+D) sip-router with Persistent Data Storage
 
 The default configuration is very simple and features many simplifications. 
 In particular, it does not authenticate users and loses User Location database 
 on reboot. To provide persistence, keep user credentials and remember users' 
-locations across reboots, ser can be configured to use MySQL. Before you proceed, 
-you need to make sure MySQL is installed on your box. Your MySQL server must be 
-configured to deal with a large number of connection. To increase it, set the 
-following line in [mysqld] section of your configuration file:
+locations across reboots, ser can be configured to use MySQL. Before you
+proceed, you need to make sure MySQL is installed on your box. Your
+MySQL server must be configured to deal with a large number of
+connection. To increase it, set the following line in [mysqld] section
+of your configuration file:
 
    set-variable    = max_connections=500
 
-1) Download the package containing mysql support for ser from: 
-    http://www.iptel.org/ser/
+1) Download the package containing mysql support for sip-router from: 
+    
+    **** site not available yet
+
     (rpm and deb provided, most of the binary tar.gz distributions and the 
      solaris package include it; if it is not present you'll have to rebuild
      from the source).
@@ -576,23 +592,23 @@ following line in [mysqld] section of your configuration file:
     or
     dpkg -i <package_name>
 	or
-	emerge ser
+	emerge sip-router
 	(if do not want to put 'mysql' into your USE variable you can type:
-	 USE="mysql" emerge ser)
+	 USE="mysql" emerge sip-router)
 3) create MySQL tables
-	- if you have a previously installed SER on your system, use
-    	/usr/sbin/ser_mysql.sh reinstall 
-	  to convert your SER database into new structures
+	- if you have a previously installed SIP Router on your system, use
+    	/usr/sbin/sip-router_mysql.sh reinstall 
+	  to convert your SIP Router database into new structures
 	- otherwise, if this is your very first installation, use
-    	/usr/sbin/ser_mysql.sh create
-	  to create SER database structures
+    	/usr/sbin/sip-router_mysql.sh create
+	  to create SIP Router database structures
    (you will be prompted for password of MySql "root" user)
-4) configure ser to use SQL
-    uncomment all lines in configuration file ser.cfg which are related to 
+4) configure sip-router to use SQL
+    uncomment all lines in configuration file sip-router.cfg which are related to 
     authentication:
-    - loadmodule "/usr/lib/ser/modules/mysql.so"
-    - loadmodule "/usr/lib/ser/modules/auth.so"
-    - loadmodule "/usr/lib/ser/modules/auth_db.so"
+    - loadmodule "/usr/lib/sip-router/modules/mysql.so"
+    - loadmodule "/usr/lib/sip-router/modules/auth.so"
+    - loadmodule "/usr/lib/sip-router/modules/auth_db.so"
     - modparam("usrloc", "db_mode", 2)
     - modparam("auth", "calculate_ha1", yes)
     - modparam("auth_db", "password_column", "password")
@@ -609,7 +625,7 @@ following line in [mysqld] section of your configuration file:
         break;
       }
 6) restart the server
-    /etc/init.d/ser restart
+    /etc/init.d/sip-router restart
 7) you can now start  managing the server using the serctl utility; 
    you need to first set the environment variable SIP_DOMAIN to your 
    local SIP realm, e.g.,
@@ -633,17 +649,19 @@ 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.
 
-Q: SIP requests are replied by ser with "483 Too Many Hops" or 
+Q: SIP requests are replied by sip-router with "483 Too Many Hops" or 
    "513 Message Too Large"
 
 A: 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. A quick way to achieve that is to introduce a config
-   option to ser.cfg: alias=domainname, where domainname shall be replaced with
-   name of domain, which you wish to server and which appears in request-URIs.
+   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. A quick way to achieve that is to
+   introduce a config option to sip-router.cfg: alias=domainname, where
+   domainname shall be replaced with name of domain, which you wish to
+   server and which appears in request-URIs.

+ 104 - 57
Makefile

@@ -62,6 +62,8 @@
 #               $(MAKE) invocation (andrei)
 #  2009-04-22  don't rebuild config.mak or modules.lst if not needed
 #              (e.g. on clean) (andrei)
+#  2009-06-24  auto-generate autover.h, containing the REPO_VER macro, defined
+#               to the top git commit sha (if git is found) (andrei)
 #
 
 # check make version
@@ -77,7 +79,8 @@ endif
 
 
 auto_gen=lex.yy.c cfg.tab.c #lexx, yacc etc
-auto_gen_others=cfg.tab.h  # auto generated, non-c
+auto_gen_others=cfg.tab.h # auto generated, non-c
+auto_gen_keep=autover.h # auto generated, should be included in archives
 
 COREPATH=.
 #include  source related defs
@@ -89,8 +92,8 @@ include Makefile.targets
 #  an utility fails
 err_fail?=1
 
-# whether or not to install ser.cfg or just ser.cfg.default
-# (ser.cfg will never be overwritten by make install, this is usefull
+# whether or not to install $(MAIN_NAME).cfg or just $(MAIN_NAME).cfg.default
+# ($(MAIN_NAME).cfg will never be overwritten by make install, this is usefull
 #  when creating packages)
 skip_cfg_install?=
 
@@ -183,6 +186,7 @@ ifneq ($(group_include)$(cfg_group_include),)
 	exclude_modules?=
 else
 	# Old defaults for backwards compatibility
+	# excluded because they depend on external libraries
 	exclude_modules?= 		cpl mangler postgres jabber mysql cpl-c \
 							auth_radius uri_radius avp_radius \
 							acc_radius dialog pa rls presence_b2b xcap xmlrpc\
@@ -190,9 +194,15 @@ else
 							unixsock dbg print_lib auth_identity ldap \
 							db_berkeley db_mysql db_postgres db_oracle \
 							db_unixodbc memcached mi_xmlrpc \
-							nat_traversal perlvdb purple seas siptrace \
+							nat_traversal perl perlvdb purple seas siptrace \
 							snmpstats uac_redirect xmpp \
-							carrierroute misc_radius peering
+							carrierroute misc_radius peering \
+							dialplan lcr utils presence \
+							presence_dialoginfo presence_xml pua pua_bla \
+							pua_dialoginfo pua_usrloc pua_xmpp \
+							regex xcap_client
+	#excluded because they depend on external *.h files
+	exclude_modules+= h350
 	# excluded because they do not compile (remove them only after they are
 	#  fixed) -- andrei
 	exclude_modules+= avpops  bdb dbtext iptrtpproxy pa rls
@@ -338,7 +348,7 @@ utils_bin_install=	utils/gen_ha1/gen_ha1 utils/sercmd/sercmd
 utils_script_install=
 
 # This is the list of files to be installed into the arch-independent
-# shared directory (by default /usr/local/share/ser)
+# shared directory (by default /usr/local/share/$(MAIN_NAME))
 share_install= scripts/mysql/my_create.sql \
 			   scripts/mysql/my_data.sql   \
 			   scripts/mysql/my_drop.sql
@@ -387,8 +397,14 @@ modules_search_path=$(subst $(space),:,$(strip\
 						$(foreach m,$(modules_dirs),$($(m)_target))))
 		#				$(addprefix $(modules_target),$(modules_dirs))))
 
+# special depends for main.o
+main.d main.o: autover.h
 main.o: DEFS+=-DMODS_DIR='"$(modules_search_path)"'
 
+
+#special depends for core_cmd.o
+core_cmd.d core_cmd.o: autover.h
+
 include Makefile.shared
 
 ifeq ($(config_mak),1)
@@ -438,6 +454,30 @@ modules-cfg modules-list modules-lst:
 	rm -f modules.lst
 	$(MAKE) modules.lst
 
+ifneq ($(wildcard .git),)
+# if .git/ exists
+repo_ver=$(shell  RV=`git rev-parse --verify --short=6 HEAD 2>/dev/null`;\
+					[ -n "$$RV" ] && \
+					test -n "`git update-index --refresh --unmerged >/dev/null\
+							; git diff-index --name-only HEAD 2>/dev/null | \
+								grep -v Makefile`" &&\
+						RV="$$RV"-dirty; echo "$$RV")
+autover_h_dep=.git $(filter-out $(auto_gen), $(sources)) cfg.y cfg.lex
+else
+# else if .git/ does not exist
+repo_ver=
+autover_h_dep=
+endif
+
+
+autover.h: $(autover_h_dep)
+	@echo  "generating autover.h ..."
+	@echo "/* this file is autogenerated by make autover.h" >$@
+	@echo " * DO NOT EDIT IT" >>$@
+	@echo " */" >>$@
+	@echo "" >>$@
+	@echo "#define REPO_VER \"$(repo_ver)\"" >>$@
+
 .PHONY: all
 all: $(NAME) every-module
 
@@ -613,7 +653,7 @@ utils:
 	done; true
 
 
-dbg: ser
+dbg: sip-router
 	gdb -command debug.gdb
 
 .PHONY: tar
@@ -621,13 +661,14 @@ dbg: ser
 
 dist: tar
 
-tar: 
+tar: $(auto_gen_keep)
 	$(TAR) -C .. \
 		--exclude=$(notdir $(CURDIR))/test* \
 		--exclude=$(notdir $(CURDIR))/tmp* \
-		--exclude=$(notdir $(CURDIR))/debian/ser \
-		--exclude=$(notdir $(CURDIR))/debian/ser-* \
-		--exclude=$(notdir $(CURDIR))/ser_tls* \
+		--exclude=$(notdir $(CURDIR))/debian/$(MAIN_NAME) \
+		--exclude=$(notdir $(CURDIR))/debian/$(MAIN_NAME)-* \
+		--exclude=$(notdir $(CURDIR))/$(MAIN_NAME)_tls* \
+		--exclude=.git* \
 		--exclude=CVS* \
 		--exclude=.svn* \
 		--exclude=.cvsignore \
@@ -639,13 +680,14 @@ tar:
 		--exclude=*.[do] \
 		--exclude=*.so \
 		--exclude=*.il \
-		--exclude=$(notdir $(CURDIR))/ser \
+		--exclude=$(notdir $(CURDIR))/$(MAIN_NAME) \
 		--exclude=*.gz \
 		--exclude=*.bz2 \
 		--exclude=*.tar \
 		--exclude=*.patch \
 		--exclude=.\#* \
 		--exclude=*.swp \
+		--exclude=*.swo \
 		${tar_extra_args} \
 		-cf - $(notdir $(CURDIR)) | \
 			(mkdir -p tmp/_tar1; mkdir -p tmp/_tar2 ; \
@@ -660,10 +702,10 @@ tar:
 # binary dist. tar.gz
 .PHONY: bin
 bin:
-	mkdir -p tmp/ser/usr/local
-	$(MAKE) install basedir=tmp/ser $(mk_params)
-	$(TAR) -C tmp/ser/ -zcf ../$(NAME)-$(RELEASE)_$(OS)_$(ARCH).tar.gz .
-	rm -rf tmp/ser
+	mkdir -p tmp/$(MAIN_NAME)/usr/local
+	$(MAKE) install basedir=tmp/$(MAIN_NAME) $(mk_params)
+	$(TAR) -C tmp/$(MAIN_NAME)/ -zcf ../$(NAME)-$(RELEASE)_$(OS)_$(ARCH).tar.gz .
+	rm -rf tmp/$(MAIN_NAME)
 
 .PHONY: deb
 deb:
@@ -677,18 +719,18 @@ deb:
 
 .PHONY: sunpkg
 sunpkg:
-	mkdir -p tmp/ser
-	mkdir -p tmp/ser_sun_pkg
-	$(MAKE) install basedir=tmp/ser prefix=/usr/local $(mk_params)
+	mkdir -p tmp/$(MAIN_NAME)
+	mkdir -p tmp/$(MAIN_NAME)_sun_pkg
+	$(MAKE) install basedir=tmp/$(MAIN_NAME) prefix=/usr/local $(mk_params)
 	(cd pkg/solaris; \
-	pkgmk -r ../../tmp/ser/usr/local -o -d ../../tmp/ser_sun_pkg/ -v "$(RELEASE)" ;\
+	pkgmk -r ../../tmp/$(MAIN_NAME)/usr/local -o -d ../../tmp/$(MAIN_NAME)_sun_pkg/ -v "$(RELEASE)" ;\
 	cd ../..)
 	cat /dev/null > ../$(NAME)-$(RELEASE)-$(OS)-$(ARCH)-local
-	pkgtrans -s tmp/ser_sun_pkg/ ../$(NAME)-$(RELEASE)-$(OS)-$(ARCH)-local \
-		IPTELser
+	pkgtrans -s tmp/$(MAIN_NAME)_sun_pkg/ ../$(NAME)-$(RELEASE)-$(OS)-$(ARCH)-local \
+		IPTEL$(MAIN_NAME)
 	gzip -9 ../$(NAME)-$(RELEASE)-$(OS)-$(ARCH)-local
-	rm -rf tmp/ser
-	rm -rf tmp/ser_sun_pkg
+	rm -rf tmp/$(MAIN_NAME)
+	rm -rf tmp/$(MAIN_NAME)_sun_pkg
 
 
 .PHONY: install
@@ -698,8 +740,8 @@ install: install-bin install-every-module install-cfg \
 
 .PHONY: dbinstall
 dbinstall:
-	-@echo "Initializing ser database"
-	scripts/mysql/ser_mysql.sh create
+	-@echo "Initializing $(MAIN_NAME) database"
+	scripts/mysql/$(SCR_NAME)_mysql.sh create
 	-@echo "Done"
 
 .PHONY: README
@@ -743,32 +785,34 @@ $(man_prefix)/$(man_dir)/man5:
 # note: sed with POSIX.1 regex doesn't support |, + or ? (darwin, solaris ...) 
 install-cfg: $(cfg_prefix)/$(cfg_dir)
 		sed $(foreach m,$(modules_dirs),\
-				-e "s#/usr/[^:]*lib/ser/$(m)\([:/\"]\)#$($(m)_target)\1#g") \
-			< etc/ser-basic.cfg > $(cfg_prefix)/$(cfg_dir)ser.cfg.sample
-		chmod 644 $(cfg_prefix)/$(cfg_dir)ser.cfg.sample
+				-e "s#/usr/[^:]*lib/$(CFG_NAME)/$(m)\([:/\"]\)#$($(m)_target)\1#g") \
+			< etc/$(CFG_NAME)-basic.cfg > \
+			$(cfg_prefix)/$(cfg_dir)$(MAIN_NAME).cfg.sample
+		chmod 644 $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME).cfg.sample
 		if [ -z "${skip_cfg_install}" -a \
-				! -f $(cfg_prefix)/$(cfg_dir)ser.cfg ]; then \
-			mv -f $(cfg_prefix)/$(cfg_dir)ser.cfg.sample \
-				$(cfg_prefix)/$(cfg_dir)ser.cfg; \
+				! -f $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME).cfg ]; then \
+			mv -f $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME).cfg.sample \
+				$(cfg_prefix)/$(cfg_dir)$(MAIN_NAME).cfg; \
 		fi
 		sed $(foreach m,$(modules_dirs),\
-			-e "s#/usr/[^:]*lib/ser/$(m)\([:/\"]\)#$($(m)_target)\1#g") \
-			< etc/ser-oob.cfg \
-			> $(cfg_prefix)/$(cfg_dir)ser-advanced.cfg.sample
-		chmod 644 $(cfg_prefix)/$(cfg_dir)ser-advanced.cfg.sample
+			-e "s#/usr/[^:]*lib/$(CFG_NAME)/$(m)\([:/\"]\)#$($(m)_target)\1#g") \
+			< etc/$(CFG_NAME)-oob.cfg \
+			> $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME)-advanced.cfg.sample
+		chmod 644 $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME)-advanced.cfg.sample
 		if [ -z "${skip_cfg_install}" -a \
-				! -f $(cfg_prefix)/$(cfg_dir)ser-advanced.cfg ]; then \
-			mv -f $(cfg_prefix)/$(cfg_dir)ser-advanced.cfg.sample \
-				$(cfg_prefix)/$(cfg_dir)ser-advanced.cfg; \
+				! -f $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME)-advanced.cfg ]; \
+		then \
+			mv -f $(cfg_prefix)/$(cfg_dir)$(MAIN_NAME)-advanced.cfg.sample \
+				$(cfg_prefix)/$(cfg_dir)$(MAIN_NAME)-advanced.cfg; \
 		fi
 		# radius dictionary
-		$(INSTALL_TOUCH) $(cfg_prefix)/$(cfg_dir)/dictionary.ser
-		$(INSTALL_CFG) etc/dictionary.ser $(cfg_prefix)/$(cfg_dir)
+		$(INSTALL_TOUCH) $(cfg_prefix)/$(cfg_dir)/dictionary.$(CFG_NAME)
+		$(INSTALL_CFG) etc/dictionary.$(CFG_NAME) $(cfg_prefix)/$(cfg_dir)
 
 		# TLS configuration
 		$(INSTALL_TOUCH) $(cfg_prefix)/$(cfg_dir)/tls.cfg
 		$(INSTALL_CFG) modules/tls/tls.cfg $(cfg_prefix)/$(cfg_dir)
-		modules/tls/ser_cert.sh -d $(cfg_prefix)/$(cfg_dir)
+		modules/tls/$(SCR_NAME)_cert.sh -d $(cfg_prefix)/$(cfg_dir)
 
 install-bin: $(bin_prefix)/$(bin_dir) $(NAME)
 		$(INSTALL_TOUCH) $(bin_prefix)/$(bin_dir)/$(NAME)
@@ -833,8 +877,9 @@ install-utils: utils $(bin_prefix)/$(bin_dir)
 	# FIXME: This is a hack, this should be (and will be) done properly in
     # per-module Makefiles
 	sed -e "s#^DEFAULT_SCRIPT_DIR.*#DEFAULT_SCRIPT_DIR=\"$(share_prefix)/$(share_dir)\"#g" \
-		< scripts/mysql/ser_mysql.sh > $(bin_prefix)/$(bin_dir)/ser_mysql.sh
-	chmod 755 $(bin_prefix)/$(bin_dir)/ser_mysql.sh
+		< scripts/mysql/$(SCR_NAME)_mysql.sh > \
+			$(bin_prefix)/$(bin_dir)/$(MAIN_NAME)_mysql.sh
+	chmod 755 $(bin_prefix)/$(bin_dir)/$(MAIN_NAME)_mysql.sh
 
 
 install-modules-all: install-every-module install-every-module-doc
@@ -853,23 +898,25 @@ install-doc: $(doc_prefix)/$(doc_dir) install-every-module-doc
 	$(INSTALL_DOC) README $(doc_prefix)/$(doc_dir)
 
 
-install-ser-man: $(man_prefix)/$(man_dir)/man8 $(man_prefix)/$(man_dir)/man5
-		sed -e "s#/etc/ser/ser\.cfg#$(cfg_target)ser.cfg#g" \
+install-sr-man: $(man_prefix)/$(man_dir)/man8 $(man_prefix)/$(man_dir)/man5
+		sed -e "s#/etc/$(CFG_NAME)/$(CFG_NAME)\.cfg#$(cfg_target)$(MAIN_NAME).cfg#g" \
 			-e "s#/usr/sbin/#$(bin_target)#g" \
 			$(foreach m,$(modules_dirs),\
-				-e "s#/usr/lib/ser/$(m)\([^_]\)#$($(m)_target)\1#g") \
-			-e "s#/usr/share/doc/ser/#$(doc_target)#g" \
-			< ser.8 >  $(man_prefix)/$(man_dir)/man8/ser.8
-		chmod 644  $(man_prefix)/$(man_dir)/man8/ser.8
-		sed -e "s#/etc/ser/ser\.cfg#$(cfg_target)ser.cfg#g" \
+				-e "s#/usr/lib/$(CFG_NAME)/$(m)\([^_]\)#$($(m)_target)\1#g") \
+			-e "s#/usr/share/doc/$(CFG_NAME)/#$(doc_target)#g" \
+			< $(CFG_NAME).8 >  \
+							$(man_prefix)/$(man_dir)/man8/$(MAIN_NAME).8
+		chmod 644  $(man_prefix)/$(man_dir)/man8/$(MAIN_NAME).8
+		sed -e "s#/etc/$(CFG_NAME)/$(CFG_NAME)\.cfg#$(cfg_target)$(MAIN_NAME).cfg#g" \
 			-e "s#/usr/sbin/#$(bin_target)#g" \
 			$(foreach m,$(modules_dirs),\
-				-e "s#/usr/lib/ser/$(m)\([^_]\)#$($(m)_target)\1#g") \
-			-e "s#/usr/share/doc/ser/#$(doc_target)#g" \
-			< ser.cfg.5 >  $(man_prefix)/$(man_dir)/man5/ser.cfg.5
-		chmod 644  $(man_prefix)/$(man_dir)/man5/ser.cfg.5
+				-e "s#/usr/lib/$(CFG_NAME)/$(m)\([^_]\)#$($(m)_target)\1#g") \
+			-e "s#/usr/share/doc/$(CFG_NAME)/#$(doc_target)#g" \
+			< $(CFG_NAME).cfg.5 >  \
+			$(man_prefix)/$(man_dir)/man5/$(MAIN_NAME).cfg.5
+		chmod 644  $(man_prefix)/$(man_dir)/man5/$(MAIN_NAME).cfg.5
 
-install-man:  install-ser-man install-every-module-man
+install-man:  install-sr-man install-every-module-man
 
 
 
@@ -887,7 +934,7 @@ proper-libs realclean-libs distclean-libs maintainer-clean-libs:
 clean: clean-modules
 # clean utils on make clean
 clean: clean-utils
-# cleaning in libs always when cleaning ser
+# cleaning in libs always when cleaning sip-router
 clean: clean-libs
 
 # proper/distclean a.s.o modules, utils and libs too

+ 8 - 3
Makefile.defs

@@ -101,12 +101,17 @@ export makefile_defs
 $(info normal Makefile.defs exec)
 # main binary name
 MAIN_NAME=ser
+#prefix for various configs and scripts
+#config name/name-prefix for distributed configs
+CFG_NAME=sip-router
+#config name/name-prefix for distributed scripts
+SCR_NAME=sip-router
 
 #version number
 VERSION = 2
-PATCHLEVEL = 1
+PATCHLEVEL = 99
 SUBLEVEL =  0
-EXTRAVERSION = -dev23-make
+EXTRAVERSION = -dev01-serk
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
 			$(SUBLEVEL) )
@@ -1698,7 +1703,7 @@ export exported_vars
 # variable changeable only at configure time (once saved in config.mak they
 #  cannot be overwritten from environment or command line, unless make cfg
 #  is run)
-saved_fixed_vars:=	MAIN_NAME \
+saved_fixed_vars:=	MAIN_NAME  CFG_NAME SCR_NAME \
 		RELEASE OS ARCH \
 		C_DEFS DEFS_RM PROFILE CC LD MKDEP MKTAGS LDFLAGS C_INCLUDES \
 		MOD_LDFLAGS LIB_LDFLAGS LIB_SONAME LD_RPATH \

+ 4 - 4
Makefile.rules

@@ -7,9 +7,9 @@
 
 #
 # Uses: NAME, ALLDEP, CC, CFLAGS, C_DEFS, DEFS, C_INCLUDES, INCLUDES, LIBS, 
-#       MKDEP, auto_gen, 
-# auto_gen_others, depends, objs, extra_objs, static_modules, 
-# static_modules_path, LD_RPATH
+#       MKDEP, auto_gen, auto_gen_others, auto_gen_keep, 
+#       depends, objs, extra_objs, static_modules, static_modules_path,
+#       LD_RPATH
 # (all this must  be defined previously!,  see Makefile.defs & Makefile)
 # Optional: SER_LIBS - list of ser libraries that will be automatically
 #  built if necessary. Format: path/shortname, where shortname is the 
@@ -205,7 +205,7 @@ clean-utils:
 .PHONY: realclean
 .PHONY: maintainer-clean
 proper distclean realclean maintainer-clean: local-clean
-	-@rm -f $(depends) $(auto_gen) $(auto_gen_others) \
+	-@rm -f $(depends) $(auto_gen) $(auto_gen_others) $(auto_gen_keep) \
 			makecfg.lst 2>/dev/null
 
 maintainer-clean: clean-tmp

+ 1 - 1
Makefile.targets

@@ -35,7 +35,7 @@ doc_targets:=	README man install-doc install-man install-ser-man \
 # auxiliary: maintance, debugging, etc. (don't affect code/objects)
 aux_targets:=	TAGS tar dist cfg-defs cfg config config.mak print-modules \
 		dbg dbinstall librpath.lst makecfg.lst modules.lst modules-cfg \
-		modules-list modules-lst mk-install_dirs
+		modules-list modules-lst mk-install_dirs autover.h
 # other targets that don't produce code in the current directory ("external")
 ext_targets:=	every-module $(modules_dirs) libs utils \
 		install-cfg install-utils  install-modules-all install-every-module\

+ 106 - 2
NEWS

@@ -338,9 +338,14 @@ new config variables:
   sctp_socket_rcvbuf = number - size for the sctp socket receive buffer
   sctp_socket_sndbuf = number - size for the sctp socket send buffer
   sctp_autoclose = seconds - number of seconds before autoclosing an idle
-     assocation (default: 180 s).
+                   association (default: 180 s).
+                   Can be changed at runtime, but it will affect only new
+                   associations. E.g.:
+                   $ sercmd cfg.set_now_int sctp autoclose 120
   sctp_send_ttl = milliseconds - number of milliseconds before an unsent
-     message/chunk is dropped (default: 32000 ms or 32 s).
+                  message/chunk is dropped (default: 32000 ms or 32 s).
+                  Can be changed at runtime, e.g.:
+                  $ sercmd cfg.set_now_int sctp send_ttl 180000
   sctp_send_retries - how many times to attempt re-sending a message on a
                       re-opened association, if the sctp stack did give up
                       sending it (it's not related to sctp protocol level
@@ -349,6 +354,105 @@ new config variables:
                       machine. WARNING: use with care and low values (e.g.
                       1-3) to avoid "multiplying" traffic to unresponding 
                       hosts (default: 0).
+                      Can be changed at runtime.
+  sctp_assoc_tracking = yes/no - controls whether or not sctp associations
+     are tracked inside ser/sip-router. Turning it off would result in
+     less memory being used and slightly better performance, but it will also
+     disable some other features that depend on it (e.g. sctp_assoc_reuse).
+     Default: yes.
+     Can be changed at runtime (sercmd sctp assoc_tracking 0), but changes
+     will be allowed only if all the other features that depend on it are
+     turned off (for example it can be turned off only if first
+     sctp_assoc_reuse was turned off).
+     Note: turning sctp_assoc_tracking on/off will delete all the tracking
+     information for all the currently tracked associations and might introduce
+     a small temporary delay in the sctp processing if lots of associations
+     were tracked.
+     Config options depending on sctp_assoc_tracking being on:
+      sctp_assoc_reuse.
+  sctp_assoc_reuse = yes/no - controls sctp association reuse. For now only
+     association reuse for replies is affected by it. Default: yes.
+     Depends on sctp_assoc_tracking being on.
+     Note that even if turned off, if the port in via corresponds to the
+     source port of the association the request was sent on or if rport is
+     turned on (force_rport() or via containing a rport option), the
+     association will be automatically reused by the sctp stack.
+     Can be changed at runtime (sctp assoc_reuse), but it can be turned on
+     only if sctp_assoc_tracking is on.
+  sctp_max_assocs = number - maximum number of allowed open sctp associations.
+     -1 means maximum allowed by the OS. Default: -1.
+     Can be changed at runtime (e.g.:
+      sercmd cfg.set_now_int sctp max_assocs 10 ).
+     When the maximum associations number is exceeded and a new associations
+     is opened by a remote host, the association will be immediately closed.
+     However it is possible that some sip packets get through (especially if
+     they are sent early, as part of the 4-way handshake).
+     When ser/sip-router tries to open a new association and the max_assocs
+     is exceeded the exact behaviour depends on whether or not
+     sctp_assoc_tracking is on. If on, the send triggering the active open
+     will gracefully fail, before actually opening the new association and no
+     packet will be sent. However if sctp_assoc_tracking is off, the
+     association will first be opened and then immediately closed. In general
+     this means that the initial sip packet will be sent (as part of the 4-way
+     handshake).
+  sctp_srto_initial = milliseconds - initial value of the retr. timeout, used
+     in RTO calculations (default: OS specific).
+     Can be changed at runtime (sctp srto_initial) but it will affect only new
+     associations.
+  sctp_srto_max = milliseconds - maximum value of the retransmission timeout
+     (RTO) (default: OS specific).
+     WARNING: values lower then the sctp sack_delay will cause lots of
+     retransmissions and connection instability (see sctp_srto_min for more
+     details).
+     Can be changed at runtime (sctp srto_max) but it will affect only new
+     associations.
+  sctp_srto_min = milliseconds - minimum value of the retransmission timeout
+     (RTO) (default: OS specific).
+     WARNING: values lower then the sctp sack_delay of any peer might cause
+     retransmissions and possible interoperability problems. According to the
+     standard the sack_delay should be between 200 and 500 ms, so avoid trying
+     values lower then 500 ms unless you control all the possible sctp peers
+     and you do make sure their sack_delay is higher or their sack_freq is 1.
+     Can be changed at runtime (sctp srto_min) but it will affect only new
+     associations.
+  sctp_asocmaxrxt   = number - maximum retransmissions attempts per association
+     (default: OS specific). It should be set to sctp_pathmaxrxt * no. of
+     expected paths.
+     Can be changed at runtime (sctp asocmaxrxt) but it will affect only new
+     associations.
+  sctp_init_max_attempts = number - maximum INIT retransmission attempts
+     (default: OS specific).
+     Can be changed at runtime (sctp init_max_attempts).
+  sctp_init_max_timeo = milliseconds - maximum INIT retransmission timeout (RTO
+     max for INIT). Default: OS specific.
+     Can be changed at runtime (sctp init_max_timeo).
+  sctp_hbinterval = milliseconds - sctp heartbeat interval. Setting it to -1
+     will disable the heartbeats. Default: OS specific.
+     Can be changed at runtime (sctp hbinterval) but it will affect only new
+     associations.
+  sctp_pathmaxrxt = number - maximum retransmission attempts per path (see also
+     sctp_asocmaxrxt). Default: OS specific.
+     Can be changed at runtime (sctp pathmaxrxt) but it will affect only new
+     associations.
+  sctp_sack_delay = milliseconds - delay until an ACK is generated after
+     receiving a packet. Default: OS specific.
+     WARNING: a value higher then srto_min can cause a lot of retransmissions
+     (and strange problems). A value higher then srto_max will result in very
+     high connections instability. According to the standard the sack_delay
+     value should be between 200 and 500 ms.
+     Can be changed at runtime (sctp sack_delay) but it will affect only new
+     associations.
+  sctp_sack_freq = number - number of packets received before an ACK is sent
+     (without waiting for the sack_delay to expire).  Default: OS specific.
+     Note: on linux with lksctp up to and including 1.0.9 is not possible to
+     set this value (having it in the config will produce a warning on
+     startup).
+     Can be changed at runtime (sctp sack_freq) but it will affect only new
+     associations.
+  sctp_max_burst = number - maximum burst of packets that can be emitted by an
+     association. Default: OS specific.
+     Can be changed at runtime (sctp max_burst) but it will affect only new 
+     associations.
   server_id = number - A configurable unique server id that can be used to
                        discriminate server instances within a cluster of
                        servers when all other information, such as IP addresses

+ 43 - 0
cfg.lex

@@ -378,6 +378,21 @@ SCTP_SOCKET_SNDBUF	"sctp_socket_sndbuf"|"sctp_socket_send_buffer"
 SCTP_AUTOCLOSE	"sctp_autoclose"
 SCTP_SEND_TTL	"sctp_send_ttl"
 SCTP_SEND_RETRIES	"sctp_send_retries"
+SCTP_ASSOC_TRACKING	"sctp_assoc_tracking"
+SCTP_ASSOC_REUSE	"sctp_assoc_reuse"
+SCTP_MAX_ASSOCS		"sctp_max_assocs"
+SCTP_SRTO_INITIAL	"sctp_srto_initial"
+SCTP_SRTO_MAX		"sctp_srto_max"
+SCTP_SRTO_MIN		"sctp_srto_min"
+SCTP_ASOCMAXRXT		"sctp_asocmaxrxt"
+SCTP_INIT_MAX_ATTEMPTS		"sctp_init_max_attempts"
+SCTP_INIT_MAX_TIMEO			"sctp_init_max_timeo"
+SCTP_HBINTERVAL				"sctp_hbinterval"
+SCTP_PATHMAXRXT				"sctp_pathmaxrxt"
+SCTP_SACK_DELAY				"sctp_sack_delay"
+SCTP_SACK_FREQ				"sctp_sack_freq"
+SCTP_MAX_BURST				"sctp_max_burst"
+
 ADVERTISED_ADDRESS	"advertised_address"
 ADVERTISED_PORT		"advertised_port"
 DISABLE_CORE		"disable_core_dump"
@@ -715,6 +730,34 @@ EAT_ABLE	[\ \t\b\r]
 										return SCTP_SEND_TTL; }
 <INITIAL>{SCTP_SEND_RETRIES}	{ count(); yylval.strval=yytext;
 										return SCTP_SEND_RETRIES; }
+<INITIAL>{SCTP_ASSOC_TRACKING}	{ count(); yylval.strval=yytext;
+										return SCTP_ASSOC_TRACKING; }
+<INITIAL>{SCTP_ASSOC_REUSE}		{ count(); yylval.strval=yytext;
+										return SCTP_ASSOC_REUSE; }
+<INITIAL>{SCTP_MAX_ASSOCS}		{ count(); yylval.strval=yytext;
+										return SCTP_MAX_ASSOCS; }
+<INITIAL>{SCTP_SRTO_INITIAL}	{ count(); yylval.strval=yytext;
+										return SCTP_SRTO_INITIAL; }
+<INITIAL>{SCTP_SRTO_MAX}	{ count(); yylval.strval=yytext;
+										return SCTP_SRTO_MAX; }
+<INITIAL>{SCTP_SRTO_MIN}	{ count(); yylval.strval=yytext;
+										return SCTP_SRTO_MIN; }
+<INITIAL>{SCTP_ASOCMAXRXT}	{ count(); yylval.strval=yytext;
+										return SCTP_ASOCMAXRXT; }
+<INITIAL>{SCTP_INIT_MAX_ATTEMPTS}	{ count(); yylval.strval=yytext;
+										return SCTP_INIT_MAX_ATTEMPTS; }
+<INITIAL>{SCTP_INIT_MAX_TIMEO}	{ count(); yylval.strval=yytext;
+										return SCTP_INIT_MAX_TIMEO; }
+<INITIAL>{SCTP_HBINTERVAL}	{ count(); yylval.strval=yytext;
+										return SCTP_HBINTERVAL; }
+<INITIAL>{SCTP_PATHMAXRXT}	{ count(); yylval.strval=yytext;
+										return SCTP_PATHMAXRXT; }
+<INITIAL>{SCTP_SACK_DELAY}	{ count(); yylval.strval=yytext;
+										return SCTP_SACK_DELAY; }
+<INITIAL>{SCTP_SACK_FREQ}	{ count(); yylval.strval=yytext;
+										return SCTP_SACK_FREQ; }
+<INITIAL>{SCTP_MAX_BURST}	{ count(); yylval.strval=yytext;
+										return SCTP_MAX_BURST; }
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
 <INITIAL>{ADVERTISED_ADDRESS}	{	count(); yylval.strval=yytext;

+ 101 - 5
cfg.y

@@ -185,6 +185,12 @@
 	#define IF_STUN(x) warn("stun support not compiled in")
 #endif
 
+#ifdef USE_SCTP
+	#define IF_SCTP(x) x
+#else
+	#define IF_SCTP(x) warn("sctp support not compiled in")
+#endif
+
 
 extern int yylex();
 static void yyerror(char* s, ...);
@@ -439,6 +445,20 @@ static int case_check_default(struct case_stms* stms);
 %token SCTP_AUTOCLOSE
 %token SCTP_SEND_TTL
 %token SCTP_SEND_RETRIES
+%token SCTP_ASSOC_TRACKING
+%token SCTP_ASSOC_REUSE
+%token SCTP_MAX_ASSOCS
+%token SCTP_SRTO_INITIAL
+%token SCTP_SRTO_MAX
+%token SCTP_SRTO_MIN
+%token SCTP_ASOCMAXRXT
+%token SCTP_INIT_MAX_ATTEMPTS
+%token SCTP_INIT_MAX_TIMEO
+%token SCTP_HBINTERVAL
+%token SCTP_PATHMAXRXT
+%token SCTP_SACK_DELAY
+%token SCTP_SACK_FREQ
+%token SCTP_MAX_BURST
 %token ADVERTISED_ADDRESS
 %token ADVERTISED_PORT
 %token DISABLE_CORE
@@ -1214,7 +1234,7 @@ assign_stm:
 	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
 	| SCTP_SOCKET_RCVBUF EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_so_rcvbuf=$3;
+			sctp_default_cfg.so_rcvbuf=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1222,7 +1242,7 @@ assign_stm:
 	| SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
 	| SCTP_SOCKET_SNDBUF EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_so_sndbuf=$3;
+			sctp_default_cfg.so_sndbuf=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1230,7 +1250,7 @@ assign_stm:
 	| SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
 	| SCTP_AUTOCLOSE EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_autoclose=$3;
+			sctp_default_cfg.autoclose=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1238,7 +1258,7 @@ assign_stm:
 	| SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
 	| SCTP_SEND_TTL EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_send_ttl=$3;
+			sctp_default_cfg.send_ttl=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1246,12 +1266,88 @@ assign_stm:
 	| SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
 	| SCTP_SEND_RETRIES EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_send_retries=$3;
+			sctp_default_cfg.send_retries=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
 	}
 	| SCTP_SEND_RETRIES EQUAL error { yyerror("number expected"); }
+	| SCTP_ASSOC_TRACKING EQUAL NUMBER {
+		#ifdef USE_SCTP
+			#ifdef SCTP_CONN_REUSE
+				sctp_default_cfg.assoc_tracking=$3;
+			#else
+				if ($3)
+					warn("sctp association tracking/reuse (SCTP_CONN_REUSE) "
+							"support not compiled in");
+			#endif /* SCTP_CONN_REUSE */
+		#else
+			warn("sctp support not compiled in");
+		#endif /* USE_SCTP */
+	}
+	| SCTP_ASSOC_TRACKING EQUAL error { yyerror("number expected"); }
+	| SCTP_ASSOC_REUSE EQUAL NUMBER {
+		#ifdef USE_SCTP
+			#ifdef SCTP_CONN_REUSE
+				sctp_default_cfg.assoc_reuse=$3;
+			#else
+				if ($3)
+					warn("sctp association reuse (SCTP_CONN_REUSE) support"
+							" not compiled in");
+			#endif /* SCTP_CONN_REUSE */
+		#else
+			warn("sctp support not compiled in");
+		#endif /* USE_SCTP */
+	}
+	| SCTP_ASSOC_REUSE EQUAL error { yyerror("number expected"); }
+	| SCTP_MAX_ASSOCS EQUAL intno {
+			IF_SCTP(sctp_default_cfg.max_assocs=$3);
+	}
+	| SCTP_MAX_ASSOCS EQUAL error { yyerror("number expected"); }
+	| SCTP_SRTO_INITIAL EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.srto_initial=$3);
+	}
+	| SCTP_SRTO_INITIAL EQUAL error { yyerror("number expected"); }
+	| SCTP_SRTO_MAX EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.srto_max=$3);
+	}
+	| SCTP_SRTO_MAX EQUAL error { yyerror("number expected"); }
+	| SCTP_SRTO_MIN EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.srto_min=$3);
+	}
+	| SCTP_SRTO_MIN EQUAL error { yyerror("number expected"); }
+	| SCTP_ASOCMAXRXT EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.asocmaxrxt=$3);
+	}
+	| SCTP_ASOCMAXRXT EQUAL error { yyerror("number expected"); }
+	| SCTP_INIT_MAX_ATTEMPTS EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.init_max_attempts=$3);
+	}
+	| SCTP_INIT_MAX_ATTEMPTS EQUAL error { yyerror("number expected"); }
+	| SCTP_INIT_MAX_TIMEO EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.init_max_timeo=$3);
+	}
+	| SCTP_INIT_MAX_TIMEO EQUAL error { yyerror("number expected"); }
+	| SCTP_HBINTERVAL EQUAL intno {
+			IF_SCTP(sctp_default_cfg.hbinterval=$3);
+	}
+	| SCTP_HBINTERVAL EQUAL error { yyerror("number expected"); }
+	| SCTP_PATHMAXRXT EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.pathmaxrxt=$3);
+	}
+	| SCTP_PATHMAXRXT EQUAL error { yyerror("number expected"); }
+	| SCTP_SACK_DELAY EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.sack_delay=$3);
+	}
+	| SCTP_SACK_DELAY EQUAL error { yyerror("number expected"); }
+	| SCTP_SACK_FREQ EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.sack_freq=$3);
+	}
+	| SCTP_SACK_FREQ EQUAL error { yyerror("number expected"); }
+	| SCTP_MAX_BURST EQUAL NUMBER {
+			IF_SCTP(sctp_default_cfg.max_burst=$3);
+	}
+	| SCTP_MAX_BURST EQUAL error { yyerror("number expected"); }
 	| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
 	| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
 	| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }

+ 2 - 2
cfg/cfg_ctx.c

@@ -129,7 +129,7 @@ void cfg_notify_drivers(char *group_name, int group_name_len, cfg_def_t *def)
 static char	*temp_string = NULL;
 
 /* convert the value to the requested type */
-static int convert_val(unsigned int val_type, void *val,
+int convert_val(unsigned int val_type, void *val,
 			unsigned int var_type, void **new_val)
 {
 	static str	s;
@@ -482,7 +482,7 @@ static int cfg_var_size(cfg_mapping_t *var)
 		return sizeof(void *);
 
 	default:
-		LOG(L_CRIT, "BUG: cfg_var_sizeK(): unknown type: %u\n",
+		LOG(L_CRIT, "BUG: cfg_var_size(): unknown type: %u\n",
 			CFG_VAR_TYPE(var));
 		return 0;
 	}

+ 4 - 0
cfg/cfg_ctx.h

@@ -108,6 +108,10 @@ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name,
 /* notify the drivers about the new config definition */
 void cfg_notify_drivers(char *group_name, int group_name_len, cfg_def_t *def);
 
+/* convert the value to the requested type */
+int convert_val(unsigned int val_type, void *val,
+			unsigned int var_type, void **new_val);
+
 /* initialize the handle for cfg_get_group_next() */
 #define cfg_get_group_init(handle) \
 	(*(handle)) = (void *)cfg_group

+ 134 - 1
cfg/cfg_select.c

@@ -33,6 +33,7 @@
 #include "../select.h"
 #include "../ut.h"
 #include "cfg_struct.h"
+#include "cfg_ctx.h"
 #include "cfg_select.h"
 
 /* It may happen that the select calls cannot be fixed up before shmizing
@@ -200,7 +201,7 @@ int select_cfg_var(str *res, select_t *s, struct sip_msg *msg)
 	if (!group || !var) return -1;
 
 	/* use the module's handle to access the variable, so the variables
-	are read from private memory */
+	are read from the local config */
 	p = *(group->handle) + var->offset;
 
 	switch (CFG_VAR_TYPE(var)) {
@@ -220,6 +221,138 @@ int select_cfg_var(str *res, select_t *s, struct sip_msg *msg)
 		memcpy(res, p, sizeof(str));
 		break;
 
+	default:
+		LOG(L_DBG, "DEBUG: select_cfg_var(): unsupported variable type: %d\n",
+			CFG_VAR_TYPE(var));
+		return -1;
 	}
 	return 0;
 }
+
+/* fix-up function for read_cfg_var()
+ *
+ * return value:
+ * >0 - success
+ *  0 - the variable has not been declared yet, but it will be automatically
+ *	fixed-up later.
+ * <0 - error
+ */
+int read_cfg_var_fixup(char *gname, char *vname, struct cfg_read_handle *read_handle)
+{
+	cfg_group_t	*group;
+	cfg_mapping_t	*var;
+	str		group_name, var_name;
+
+	if (!gname || !vname || !read_handle)
+		return -1;
+
+	group_name.s = gname;
+	group_name.len = strlen(gname);
+	var_name.s = vname;
+	var_name.len = strlen(vname);
+
+	/* look-up the group and the variable */
+	if (cfg_lookup_var(&group_name, &var_name, &group, &var)) {
+		if (cfg_shmized) {
+			LOG(L_ERR, "ERROR: read_cfg_var_fixup(): unknown variable: %.*s.%.*s\n",
+				group_name.len, group_name.s,
+				var_name.len, var_name.s);
+			return -1;
+		}
+		/* The variable was not found, add it to the non-fixed select list.
+		 * So we act as if the fixup was successful, and we retry it later */
+		if (cfg_new_select(&group_name, &var_name,
+					&read_handle->group, &read_handle->var))
+			return -1;
+
+		LOG(L_DBG, "DEBUG: read_cfg_var_fixup(): cfg read fixup is postponed: %.*s.%.*s\n",
+			group_name.len, group_name.s,
+			var_name.len, var_name.s);
+
+		read_handle->group = NULL;
+		read_handle->var = NULL;
+		return 0;
+	}
+
+	read_handle->group = (void *)group;
+	read_handle->var = (void *)var;
+	return 1;
+}
+
+/* read the value of a variable via a group and variable name previously fixed up
+ * Returns the type of the variable
+ */
+unsigned int read_cfg_var(struct cfg_read_handle *read_handle, void **val)
+{
+	cfg_group_t	*group;
+	cfg_mapping_t	*var;
+	void		*p;
+	static str	s;
+
+	if (!val || !read_handle || !read_handle->group || !read_handle->var)
+		return 0;
+
+	group = (cfg_group_t *)(read_handle->group);
+	var = (cfg_mapping_t *)(read_handle->var);
+
+	/* use the module's handle to access the variable, so the variables
+	are read from the local config */
+	p = *(group->handle) + var->offset;
+
+	switch (CFG_VAR_TYPE(var)) {
+	case CFG_VAR_INT:
+		*val = (void *)(long)*(int *)p;
+		break;
+
+	case CFG_VAR_STRING:
+		*val = (void *)*(char **)p;
+		break;
+
+	case CFG_VAR_STR:
+		memcpy(&s, p, sizeof(str));
+		*val = (void *)&s;
+		break;
+
+	case CFG_VAR_POINTER:
+		*val = *(void **)p;
+		break;
+
+	}
+	return CFG_VAR_TYPE(var);
+}
+
+/* wrapper function for read_cfg_var() -- convert the value to integer
+ * returns -1 on error, 0 on success
+ */
+int read_cfg_var_int(struct cfg_read_handle *read_handle, int *val)
+{
+	unsigned int	type;
+	void		*v1, *v2;
+
+	if ((type = read_cfg_var(read_handle, &v1)) == 0)
+		return -1;
+
+	if (convert_val(type, v1, CFG_INPUT_INT, &v2))
+		return -1;
+
+	*val = (int)(long)(v2);
+	return 0;
+}
+
+/* wrapper function for read_cfg_var() -- convert the value to str
+ * returns -1 on error, 0 on success
+ */
+int read_cfg_var_str(struct cfg_read_handle *read_handle, str *val)
+{
+	unsigned int	type;
+	void		*v1, *v2;
+
+	if ((type = read_cfg_var(read_handle, &v1)) == 0)
+		return -1;
+
+	if (convert_val(type, v1, CFG_INPUT_STR, &v2))
+		return -1;
+
+	*val = *(str *)(v2);
+	return 0;
+}

+ 24 - 0
cfg/cfg_select.h

@@ -34,6 +34,11 @@
 
 #include "../select.h"
 
+struct cfg_read_handle {
+	void	*group;
+	void	*var;
+};
+
 /* free the list of not yet fixed selects */
 void cfg_free_selects();
 
@@ -42,4 +47,23 @@ int cfg_fixup_selects();
 
 int select_cfg_var(str *res, select_t *s, struct sip_msg *msg);
 
+/* fix-up function for read_cfg_var()
+ *
+ * return value:
+ * >0 - success
+ *  0 - the variable has not been declared yet, but it will be automatically
+ *	fixed-up later.
+ * <0 - error
+ */
+int read_cfg_var_fixup(char *gname, char *vname, struct cfg_read_handle *read_handle);
+
+/* read the value of a variable via a group and variable name previously fixed up
+ * Returns the type of the variable
+ */
+unsigned int read_cfg_var(struct cfg_read_handle *read_handle, void **val);
+
+/* wrapper functions for read_cfg_var() -- convert the value to the requested format */
+int read_cfg_var_int(struct cfg_read_handle *read_handle, int *val);
+int read_cfg_var_str(struct cfg_read_handle *read_handle, str *val);
+
 #endif /* _CFG_SELECT_H */

+ 1 - 1
config.h

@@ -44,7 +44,7 @@
 #define SIP_PORT  5060
 #define SIPS_PORT 5061
 
-#define CFG_FILE CFG_DIR "ser.cfg"
+#define CFG_FILE CFG_DIR "sip-router.cfg"
 
 #define TLS_PKEY_FILE "cert.pem" 
 #define TLS_CERT_FILE "cert.pem"

+ 23 - 7
core_cmd.c

@@ -28,6 +28,7 @@
 #include <time.h>
 #include <sys/types.h>
 #include <signal.h>
+#include "autover.h"
 #include "mem/mem.h"
 #include "mem/shm_mem.h"
 #include "sr_module.h"
@@ -298,7 +299,7 @@ static const char* core_version_doc[] = {
 
 static void core_version(rpc_t* rpc, void* c)
 {
-	rpc->add(c, "s", SERVER_HDR);
+	rpc->add(c, "s", SERVER_HDR " " REPO_VER );
 }
 
 
@@ -626,16 +627,31 @@ static void core_sctp_options(rpc_t* rpc, void* c)
 {
 #ifdef USE_SCTP
 	void *handle;
-	struct sctp_cfg_options t;
+	struct cfg_group_sctp t;
 
 	if (!sctp_disable){
 		sctp_options_get(&t);
 		rpc->add(c, "{", &handle);
-		rpc->struct_add(handle, "dddd",
-			"sctp_autoclose",		t.sctp_autoclose,
-			"sctp_send_ttl",	t.sctp_autoclose,
-			"sctp_socket_rcvbuf",	t.sctp_so_rcvbuf,
-			"sctp_socket_sndbuf",	t.sctp_so_sndbuf
+		rpc->struct_add(handle, "ddddddddddddddddddd",
+			"sctp_socket_rcvbuf",	t.so_rcvbuf,
+			"sctp_socket_sndbuf",	t.so_sndbuf,
+			"sctp_autoclose",		t.autoclose,
+			"sctp_send_ttl",	t.send_ttl,
+			"sctp_send_retries",	t.send_retries,
+			"sctp_assoc_tracking",	t.assoc_tracking,
+			"sctp_assoc_reuse",	t.assoc_reuse,
+			"sctp_max_assocs", t.max_assocs,
+			"sctp_srto_initial",	t.srto_initial,
+			"sctp_srto_max",		t.srto_max,
+			"sctp_srto_min",		t.srto_min,
+			"sctp_asocmaxrxt",	t.asocmaxrxt,
+			"sctp_init_max_attempts",	t.init_max_attempts,
+			"sctp_init_max_timeo",t.init_max_timeo,
+			"sctp_hbinterval",	t.hbinterval,
+			"sctp_pathmaxrxt",	t.pathmaxrxt,
+			"sctp_sack_delay",	t.sack_delay,
+			"sctp_sack_freq",	t.sack_freq,
+			"sctp_max_burst",	t.max_burst
 		);
 	}else{
 		rpc->fault(c, 500, "sctp support disabled");

+ 10 - 7
dns_cache.c

@@ -1866,7 +1866,7 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
 	if (type==T_A){
 		if ((ip=str2ip(name))!=0){
 				e=dns_cache_mk_ip_entry(name, ip);
-				if (e)
+				if (likely(e))
 					atomic_set(&e->refcnt, 1);/* because we ret. a ref. to it*/
 				goto end; /* we do not cache obvious stuff */
 		}
@@ -1875,7 +1875,7 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
 	else if (type==T_AAAA){
 		if ((ip=str2ip6(name))!=0){
 				e=dns_cache_mk_ip_entry(name, ip);
-				if (e)
+				if (likely(e))
 					atomic_set(&e->refcnt, 1);/* because we ret. a ref. to it*/
 				goto end;/* we do not cache obvious stuff */
 		}
@@ -1897,12 +1897,12 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
 	if (records){
 #ifdef CACHE_RELEVANT_RECS_ONLY
 		e=dns_cache_mk_rd_entry(name, type, &records);
-		if (e){
+		if (likely(e)){
 			l=e;
 			e=dns_get_related(l, type, &records);
 			/* e should contain the searched entry (if found) and l
 			 * all the entries (e and related) */
-			if (e){
+			if (likely(e)){
 				atomic_set(&e->refcnt, 1); /* 1 because we return a
 												ref. to it */
 			}else{
@@ -1943,9 +1943,12 @@ inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
 #endif
 		free_rdata_list(records);
 	}else if (cfg_get(core, core_cfg, dns_neg_cache_ttl)){
-		e=dns_cache_mk_bad_entry(name, type, cfg_get(core, core_cfg, dns_neg_cache_ttl), DNS_BAD_NAME);
-		atomic_set(&e->refcnt, 1); /* 1 because we return a ref. to it */
-		dns_cache_add(e); /* refcnt++ inside*/
+		e=dns_cache_mk_bad_entry(name, type, 
+				cfg_get(core, core_cfg, dns_neg_cache_ttl), DNS_BAD_NAME);
+		if (likely(e)) {
+			atomic_set(&e->refcnt, 1); /* 1 because we return a ref. to it */
+			dns_cache_add(e); /* refcnt++ inside*/
+		}
 		goto end;
 	}
 #ifndef CACHE_RELEVANT_RECS_ONLY

+ 39 - 0
doc/cfg.txt

@@ -166,6 +166,45 @@ cfg_get(foo, cfg_handle, s)
 cfg_get(foo, cfg_handle, p)
 
 
+It is also possible to access the variables of other modules or the core in two
+different ways:
+
+1) Include the header file of the other module/core that declares the cfg_group_*
+structure and the handle for it. Than use the handle of that module/core to access
+the variable:
+
+cfg_get(bar, cfg_handle_of_bar, j);
+
+2) Access the variables by their group and variable name:
+
+#include "../../cfg/cfg_select.h"
+
+struct cfg_read_handle var_bar_j;
+
+in the module init function:
+static int mod_init(void)
+{
+	if ((read_cfg_var_fixup("bar", "j", &var_bar_j)) < 0)
+		return -1;
+	/* Note that the variable may or may not exist at this point
+	 * depending on the module loading order. The fixup will still
+	 * be successful but the variable cannot be read if it has not been
+	 * declared yet. If the variable will not be declared at all
+	 * SER will fail to start
+	 */
+}
+
+int	j;
+if ((cfg_read_var_int(&var_bar_j, &j)) < 0) { error... }
+
+or similarly,
+str	s;
+if ((cfg_read_var_str(&var_bar_j, &s)) < 0) { error... }
+
+2) is a bit slower than 1) because the first solution returns the pointer directly
+to the variable, but 2) supports also the variables declared in the script that are
+not known at compile time.
+
 3. Using the framework in the core
 ===============================================================================
 

+ 46 - 18
doc/rpc/ser_rpc.txt

@@ -238,12 +238,23 @@ add("sd", string_param, int_param);
    be of type struct again). Corresponding character in the formatting
    string is "{".
 
+   Optional parameters.  Optional parameters can be used, but only in the
+   scan function. For optional parameters the scan function will not
+   automatically generate a rpc fault if the input ends. Note that in this
+   case the scan will still return a negative value (minus the number of
+   parameters successfully read). Optional parameters can be marked in the
+   format string by preceding the first optional parameter type with a
+   "*". All the parameters following a "*" are considered to be optional.
+   For example for the format string "ds*dds", the last 3 parameters (2
+   ints and a string) are optional.
+
    Table 1. Data Type Overview
-   Name    Formating String Char C-Style Variable
-   Integer d                     int
-   Float   f                     double
-   String  s                     char*
-   String  S                     str
+Name              Formating String Char C-Style Variable
+Integer           d                     int
+Float             f                     double
+String            s                     char*
+String            S                     str
+Optional modifier *                     marks all further parameters as optional
 
 1.2.3. Getting Parameters
 
@@ -265,19 +276,29 @@ Note
    set. The function accepts variable number of parameters. The first
    parameter is the formatting string that determines the type of the
    parameters to be retrieved. Each parameter is represented by exactly
-   one character in the string. The variable part of parameters must
-   contain as many pointers to C variables as there are formatting
-   characters in the formatting string.
+   one parameter type character in the string. The variable part of
+   parameters must contain as many pointers to C variables as there are
+   formatting non-modifiers characters in the formatting string. The
+   formatting string can also contain a "*" modifier that does not have a
+   correspondent in the variable part of the parameters. The meaning of
+   "*" is that any further parameters (defined by other type characters in
+   the formatting string) are optional (they can be missing in the input
+   and no rpc fault will automatically be generated).
 
 Warning
 
    The function will crash if you fail to provide enough parameters.
 
-   The function indicates success by returning 0. When a failure occurs
-   (incorrect parameter type or no more parameters in the parameter set)
-   then the function will return -1 and it will also automatically change
-   the reply that will be sent to the caller to indicate that a failure
-   has occurred on the server. Prototype of the function is:
+   The function returns the number of parameters read on success (a number
+   greater or equal 0) and - (minus) the number of parameters read on
+   error (for example for an error after reading 2 parameters it will
+   return -2). When a failure occurs (incorrect parameter type or no more
+   parameters in the parameter set) the function will return a negative
+   number (- number of parameters read so far) and it will also
+   automatically change the reply that will be sent to the caller to
+   indicate that a failure has occurred on the server (unless the "*" is
+   used and the error is lack of more parameters). The prototype of the
+   function is:
 int scan(char* fmt, ...)
 
    It is possible to either call the function once to scan all the
@@ -293,11 +314,17 @@ rpc->scan("f", &double_val);
 1.2.3.2. struct_scan
 
    Function struct_scan can be used to retrieve named attributes from a
-   parameter of type structure. When retrieving a structure parameter from
-   the parameter set:
+   parameter of type structure.
+
+Note
+
+   This function is obsolete and not implemented by all the rpc transports
+   (e.g.: ctl / binrpc). Consider using the normal scan instead.
+
+   When retrieving a structure parameter from the parameter set:
 rpc->scan("{", &handle);
 
-   The corresponding variable (named handlein the example above) will
+   The corresponding variable (named handle in the example above) will
    contain the index of the structure parameter within the parameter set,
    but the index cannot be used to retrieve the contents of the structure.
    To retrieve the contents of the structure you can use function
@@ -308,8 +335,9 @@ rpc->struct_scan(handle, "sd", "str_attr", &str_val, "int_attr", &int_val);
    parameters. First parameter in each pair is the name of the attribute
    to retrieve (string) and the second parameter in each pair is the
    pointer to the variable to store the value of the parameter. The
-   function returns 0 on success and -1 on an error (just like scan
-   function). The function also indicates an error if a requested
+   function returns the number of parameters (name value pairs) read on
+   success and - number of parameters read so far on an error (just like
+   the scan function). The function also indicates an error if a requested
    attribute is missing in the structure.
 
    Example 3. Retrieving Parameters

+ 60 - 22
doc/rpc/ser_rpc.xml

@@ -31,11 +31,11 @@
 	<para>
 		The RPC transports are implemented by writting a RPC
 		transport module. The most used transport modules are
-		<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=modules_s/ctl/README'>
+		<ulink url='http://sip-router.org/docbook/sip-router/branch/master/modules_s/ctl/ctl.html'>
 		<emphasis>ctl</emphasis>
 		</ulink>
 		and
-		<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=modules_s/xmlrpc/README'>
+		<ulink url='http://sip-router.org/docbook/sip-router/branch/master/modules_s/xmlrpc/xmlrpc.html'>
 		<emphasis>xmlrpc</emphasis>
 		</ulink>.
 		The first one implements a ser-proprietary fast and space efficient
@@ -313,6 +313,22 @@ add("sd", string_param, int_param);
 		    formatting string is "{".
 		</para>
 	    </formalpara>
+		<formalpara>
+		<title>Optional parameters</title>
+		<para>
+			Optional parameters can be used, but only in the
+			<function>scan</function> function.  For optional parameters the
+			<function>scan</function> function will not automatically generate
+			a rpc fault if the input ends. Note that in this case the
+			<function>scan</function> will still return a negative value
+			(minus the number of parameters successfully read).
+			Optional parameters can be marked in the format string by
+			preceding the first optional parameter type with a "*".
+			All the parameters following a "*" are considered to be optional.
+			For example for the format string "ds*dds", the last 3 parameters
+			(2 ints and a string) are optional.
+		</para>
+		</formalpara>
 	    <table>
 		<title>Data Type Overview</title>
 		<tgroup cols="3">
@@ -342,6 +358,11 @@ add("sd", string_param, int_param);
 			    <entry>S</entry>
 			    <entry>str</entry>
 			</row>
+			<row>
+				<entry>Optional modifier</entry>
+				<entry>*</entry>
+				<entry>marks all further parameters as optional</entry>
+			</row>
 		    </tbody>
 		</tgroup>
 	    </table>
@@ -373,22 +394,33 @@ add("sd", string_param, int_param);
 		    variable number of parameters. The first parameter is the
 		    formatting string that determines the type of the
 		    parameters to be retrieved. Each parameter is represented by
-		    exactly one character in the string. The variable part of
-		    parameters must contain as many pointers to C variables as
-		    there are formatting characters in the formatting
-		    string.
+		    exactly one parameter type character in the string.
+			The variable part of parameters must contain as many pointers to C
+			variables as there are formatting non-modifiers characters in the
+			formatting string.
+			The formatting string can also contain a "*" modifier that does not
+			have a correspondent in the variable part of the parameters. The
+			meaning of "*" is that any further parameters (defined by other
+			type characters in the formatting string) are optional (they
+			can be missing in the input and no rpc fault will automatically
+			be generated).
 		    <warning>
 			<para>
 			    The function will crash if you fail to provide
 			    enough parameters.
 			</para>
 		    </warning>
-		    The function indicates success by returning 0. When a
-		    failure occurs (incorrect parameter type or no more
-		    parameters in the parameter set) then the function will
-		    return -1 and it will also automatically change the reply
-		    that will be sent to the caller to indicate that a failure
-		    has occurred on the server. Prototype of the function is:
+			The function returns the number of parameters read on success
+			(a number greater or equal 0) and - (minus) the number of
+			parameters read on error (for example for an error after 
+			reading 2 parameters it will return -2).
+			When a failure occurs (incorrect parameter type or no more
+			parameters in the parameter set) the function will
+			return a negative number (- number of parameters read so far)
+			and it will also automatically change the reply that will be
+			sent to the caller to indicate that a failure has occurred on 
+			the server (unless the "*" is used and the error is lack
+			of more parameters). The prototype of the function is:
 		    <programlisting>
 int scan(char* fmt, ...)
 		    </programlisting>
@@ -409,15 +441,20 @@ rpc->scan("f", &amp;double_val);
 	    <section>
 		<title><function>struct_scan</function></title>
 		<para>
-		    Function <function>struct_scan</function> can be used to
-		    retrieve named attributes from a parameter of type
-		    structure. When retrieving a structure parameter from the
-		    parameter set:
+			Function <function>struct_scan</function> can be used to
+			retrieve named attributes from a parameter of type
+			structure.
+			<note>This function is obsolete and not implemented by all the
+			rpc transports (e.g.: ctl / binrpc). Consider using the normal
+			<function>scan</function> instead.
+			</note>
+			When retrieving a structure parameter from the
+			parameter set:
 		    <programlisting>
 rpc->scan("{", &amp;handle);
 		    </programlisting>
 		    The corresponding variable (named 
-		    <varname>handle</varname>in the example above) will contain
+		    <varname>handle</varname> in the example above) will contain
 		    the index of the structure parameter within the parameter
 		    set, but the index cannot be used to retrieve the contents
 		    of the structure. To retrieve the contents of the structure
@@ -430,10 +467,11 @@ rpc->struct_scan(handle, "sd", "str_attr", &amp;str_val, "int_attr", &amp;int_va
 		    pairs of parameters. First parameter in each pair is the
 		    name of the attribute to retrieve (string) and the second
 		    parameter in each pair is the pointer to the variable to
-		    store the value of the parameter. The function returns 0 on
-		    success and -1 on an error (just like
-		    <function>scan</function> function). The function also
-		    indicates an error if a requested attribute is missing in
+		    store the value of the parameter. The function returns the
+			number of parameters (name value pairs) read on
+		    success and - number of parameters read so far on an error
+			(just like the <function>scan</function> function). The function
+			also indicates an error if a requested attribute is missing in
 		    the structure.
 		</para>
 	    </section>
@@ -797,7 +835,7 @@ static void rpc_register(rpc_t* rpc)
 <section id="rpc.xmlrpc_examples">
 	<title>Examples using xmlrpc</title>
 	<para>See the <varname>xmlrpc</varname> module documentation:
-	<ulink url='http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sip-router;a=blob;f=modules_s/xmlrpc/README'>modules_s/xmlrpc/README</ulink>.
+	<ulink url='http://sip-router.org/docbook/sip-router/branch/master/modules_s/xmlrpc/xmlrpc.html'>modules_s/xmlrpc/README</ulink>.
 	</para>
 </section>
 

+ 5 - 1
docbook/entities.xml

@@ -7,6 +7,10 @@
 <!ENTITY kamailioname "Kamailio SIP Server Platform">
 <!ENTITY kamailioconfig "kamailio.cfg">
 
+<!ENTITY siprouter "SIP Router">
+<!ENTITY siproutername "SIP Router Project">
+<!ENTITY siprouterconfig "sip-router.cfg">
+
 <!ENTITY kamwiki "http://www.kamailio.org/dokuwiki/">
 <!ENTITY kamwikilink "<ulink url='&kamwiki;'>&kamwiki;</ulink>">
 
@@ -84,4 +88,4 @@
 <!ENTITY rfc2543 "<ulink url='http://www.ietf.org/rfc/rfc2543.txt'>RFC2543</ulink>">
 
 <!ENTITY vsname "Voice Sistem SRL">
-<!ENTITY voicesystem "<ulink url='http://www.voice-system.ro'>voice-system.ro</ulink>">
+<!ENTITY voicesystem "<ulink url='http://www.voice-system.ro'>voice-system.ro</ulink>">

+ 3 - 3
etc/dbtext.cfg

@@ -21,7 +21,7 @@ dns=no           # (cmd. line: -r)
 rev_dns=no      # (cmd. line: -R)
 port=5060
 children=4
-fifo="/tmp/ser_fifo"
+fifo="/tmp/sip-router_fifo"
 
 # ------------------ module loading ----------------------------------
 
@@ -49,8 +49,8 @@ loadmodule "./modules/auth_db/auth_db.so"
 # Uncomment this if you want to use SQL database 
 # for persistent storage and comment the previous line
 modparam("usrloc", "db_mode", 1)
-modparam("usrloc", "db_url", "/home/janakj/ser")
-modparam("auth_db", "db_url", "/home/janakj/ser")
+modparam("usrloc", "db_url", "/home/janakj/sip-router")
+modparam("auth_db", "db_url", "/home/janakj/sip-router")
 
 # -- auth params --
 # Uncomment if you are using auth module

+ 49 - 0
etc/dictionary.radius

@@ -0,0 +1,49 @@
+#
+# $Id$
+#
+# SIP RADIUS attributes
+#
+# Proprietary indicates an attribute that hasn't
+# been standardized
+#
+#
+# NOTE: All standard (IANA registered) attributes are 
+#       defined in the default dictionary of the 
+#       radiusclient-ng library.
+#
+
+
+#### Attributes ###
+ATTRIBUTE Sip-Uri-User         208  string     # Proprietary, auth_radius
+ATTRIBUTE Sip-Group            211  string     # Proprietary, group_radius
+ATTRIBUTE Sip-Rpid             213  string     # Proprietary, auth_radius
+ATTRIBUTE SIP-AVP              225  string     # Proprietary, avp_radius
+
+### Acct-Status-Type Values ###
+#VALUE Acct-Status-Type   Failed           15   # RFC2866, acc
+
+### Service-Type Values ###
+#VALUE Service-Type       Call-Check       10   # RFC2865, uri_radius
+VALUE Service-Type       Group-Check      12   # Proprietary, group_radius
+##VALUE Service-Type       Sip-Session      15   # Schulzrinne, acc, auth_radius
+VALUE Service-Type       SIP-Caller-AVPs  30   # Proprietary, avp_radius
+VALUE Service-Type       SIP-Callee-AVPs  31   # Proprietary, avp_radius
+
+### Sip-Method Values ###
+VALUE Sip-Method         Undefined      0
+VALUE Sip-Method         Invite         1
+VALUE Sip-Method         Cancel         2
+VALUE Sip-Method         Ack            4
+VALUE Sip-Method         Bye            8
+VALUE Sip-Method         Info           16
+VALUE Sip-Method         Options        32
+VALUE Sip-Method         Update         64
+VALUE Sip-Method         Register       128
+VALUE Sip-Method         Message        256
+VALUE Sip-Method         Subscribe      512
+VALUE Sip-Method         Notify         1024
+VALUE Sip-Method         Prack          2048
+VALUE Sip-Method         Refer          4096
+VALUE Sip-Method         Other          8192
+
+

+ 0 - 0
etc/dictionary.ser → etc/dictionary.sip-router


+ 545 - 0
etc/kamailio.cfg

@@ -0,0 +1,545 @@
+#
+# $Id$
+#
+# Kamailio (OpenSER) SIP Server - basic configuration script
+#     - web: http://www.kamailio.org
+#     - svn: http://openser.svn.sourceforge.net/viewvc/openser/
+#
+# Direct your questions about this file to: <[email protected]>
+#
+# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php
+# for an explanation of possible statements, functions and parameters.
+#
+# There are comments showing how to enable different features in th econfig
+# file. Such commented code starts with #X# where X is a letter to identify
+# a feature. Delete entire #X# if you want to enable that feature. Next are
+# sed commands that help you enable such features.
+#
+# *** To enamble mysql execute:
+#     sed -i 's/#m#//g' kamailio.cfg
+#
+# *** To enamble authentication execute:
+#     - enable mysql
+#     sed -i 's/#a#//g' kamailio.cfg
+#     - add users using 'kamctl'
+#
+# *** To enamble persistent user location execute:
+#     - enable mysql
+#     sed -i 's/#u#//g' kamailio.cfg
+#
+# *** To enamble presence server execute:
+#     - enable mysql
+#     sed -i 's/#p#//g' kamailio.cfg
+#
+# *** To enamble nat traversal execute:
+#     sed -i 's/#n#//g' kamailio.cfg
+#     - install RTPProxy: http://www.rtpproxy.org
+#     - start RTPProxy:
+#        rtpproxy -l _your_public_ip_ -s udp:localhost:7722
+#
+# *** To enhance accounting execute:
+#     - enable mysql
+#     sed -i 's/#c#//g' kamailio.cfg
+#     - add following columns to database
+# ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
+# ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
+# ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
+# ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
+# ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
+# ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
+# ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
+# ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
+# ALTER TABLE missed_call ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
+# ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
+#
+
+
+####### Global Parameters #########
+
+debug=3
+log_stderror=no
+log_facility=LOG_LOCAL0
+
+fork=yes
+children=4
+
+/* uncomment the following lines to enable debugging */
+#debug=6
+#fork=no
+#log_stderror=yes
+
+/* uncomment the next line to disable TCP (default on) */
+#disable_tcp=yes
+
+/* uncomment the next line to enable the auto temporary blacklisting of 
+   not available destinations (default disabled) */
+#disable_dns_blacklist=no
+
+/* uncomment the next line to enable IPv6 lookup after IPv4 dns 
+   lookup failures (default disabled) */
+#dns_try_ipv6=yes
+
+/* uncomment the next line to disable the auto discovery of local aliases
+   based on revers DNS on IPs (default on) */
+#auto_aliases=no
+
+/* uncomment the following lines to enable TLS support  (default off) */
+#disable_tls = no
+#listen = tls:your_IP:5061
+#tls_verify_server = 1
+#tls_verify_client = 1
+#tls_require_client_certificate = 0
+#tls_method = TLSv1
+#tls_certificate = "/usr/local/etc/kamailio/tls/user/user-cert.pem"
+#tls_private_key = "/usr/local/etc/kamailio/tls/user/user-privkey.pem"
+#tls_ca_list     = "/usr/local/etc/kamailio/tls/user/user-calist.pem"
+
+
+port=5060
+
+/* uncomment and configure the following line if you want Kamailio to 
+   bind on a specific interface/port/proto (default bind on all available) */
+#listen=udp:192.168.1.2:5060
+
+
+####### Modules Section ########
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+/* uncomment next line for MySQL DB support */
+#m#loadmodule "db_mysql.so"
+loadmodule "mi_fifo.so"
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "pv.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "uri_db.so"
+loadmodule "siputils.so"
+loadmodule "xlog.so"
+loadmodule "acc.so"
+/* uncomment next lines for MySQL based authentication support 
+   NOTE: a DB (like db_mysql) module must be also loaded */
+#a#loadmodule "auth.so"
+#a#loadmodule "auth_db.so"
+/* uncomment next line for aliases support
+   NOTE: a DB (like db_mysql) module must be also loaded */
+#loadmodule "alias_db.so"
+/* uncomment next line for multi-domain support
+   NOTE: a DB (like db_mysql) module must be also loaded
+   NOTE: be sure and enable multi-domain support in all used modules
+         (see "multi-module params" section ) */
+#loadmodule "domain.so"
+/* uncomment the next two lines for presence server support
+   NOTE: a DB (like db_mysql) module must be also loaded */
+#p#loadmodule "presence.so"
+#p#loadmodule "presence_xml.so"
+
+#n#loadmodule "nathelper.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+
+# ----- mi_fifo params -----
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+
+# ----- rr params -----
+# add value to ;lr param to cope with most of the UAs
+modparam("rr", "enable_full_lr", 1)
+# do not append from tag to the RR (no need for this script)
+modparam("rr", "append_fromtag", 0)
+
+
+# ----- rr params -----
+modparam("registrar", "method_filtering", 1)
+/* uncomment the next line to disable parallel forking via location */
+# modparam("registrar", "append_branches", 0)
+/* uncomment the next line not to allow more than 10 contacts per AOR */
+#modparam("registrar", "max_contacts", 10)
+
+
+# ----- uri_db params -----
+/* by default we disable the DB support in the module as we do not need it
+   in this configuration */
+modparam("uri_db", "use_uri_table", 0)
+modparam("uri_db", "db_url", "")
+
+
+# ----- acc params -----
+/* what sepcial events should be accounted ? */
+modparam("acc", "early_media", 1)
+modparam("acc", "report_ack", 1)
+modparam("acc", "report_cancels", 1)
+/* by default ww do not adjust the direct of the sequential requests.
+   if you enable this parameter, be sure the enable "append_fromtag"
+   in "rr" module */
+modparam("acc", "detect_direction", 0)
+/* account triggers (flags) */
+modparam("acc", "failed_transaction_flag", 3)
+modparam("acc", "log_flag", 1)
+modparam("acc", "log_missed_flag", 2)
+modparam("acc", "log_extra", 
+	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
+/* uncomment the following lines to enable DB accounting also */
+#c#modparam("acc", "db_flag", 1)
+#c#modparam("acc", "db_missed_flag", 2)
+#c#modparam("acc", "db_url",
+#c#	"mysql://openser:openserrw@localhost/openser")
+#c#modparam("acc", "db_extra",
+#c#	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
+
+
+# ----- usrloc params -----
+/* uncomment the following lines if you want to enable DB persistency
+   for location entries */
+#u#modparam("usrloc", "db_mode",   2)
+#u#modparam("usrloc", "db_url",
+#u#	"mysql://openser:openserrw@localhost/openser")
+
+# ----- auth_db params -----
+/* uncomment the following lines if you want to enable the DB based
+   authentication */
+#a#modparam("auth_db", "calculate_ha1", yes)
+#a#modparam("auth_db", "password_column", "password")
+#a#modparam("auth_db", "db_url",
+#a#	"mysql://openser:openserrw@localhost/openser")
+#a#modparam("auth_db", "load_credentials", "")
+
+
+# ----- alias_db params -----
+/* uncomment the following lines if you want to enable the DB based
+   aliases */
+#modparam("alias_db", "db_url",
+#	"mysql://openser:openserrw@localhost/openser")
+
+
+# ----- domain params -----
+/* uncomment the following lines to enable multi-domain detection
+   support */
+#modparam("domain", "db_url",
+#	"mysql://openser:openserrw@localhost/openser")
+#modparam("domain", "db_mode", 1)   # Use caching
+
+
+# ----- multi-module params -----
+/* uncomment the following line if you want to enable multi-domain support
+   in the modules (dafault off) */
+#modparam("alias_db|auth_db|usrloc|uri_db", "use_domain", 1)
+
+
+# ----- presence params -----
+/* uncomment the following lines if you want to enable presence */
+#p#modparam("presence|presence_xml", "db_url",
+#p#	"mysql://openser:openserrw@localhost/openser")
+#p#modparam("presence_xml", "force_active", 1)
+#p#modparam("presence", "server_address", "sip:192.168.1.2:5060")
+
+# -- nathelper
+#n#modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:7722")
+#n#modparam("nathelper", "natping_interval", 30)
+#n#modparam("nathelper", "ping_nated_only", 1)
+#n#modparam("nathelper", "sipping_bflag", 7)
+#n#modparam("nathelper", "sipping_from", "sip:[email protected]")
+#n#modparam("registrar|nathelper", "received_avp", "$avp(i:80)")
+#n#modparam("usrloc", "nat_bflag", 6)
+
+####### Routing Logic ########
+
+
+# main request routing logic
+
+route{
+
+	if (!mf_process_maxfwd_header("10")) {
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	}
+
+	# NAT detection
+	route(4);
+
+	if (has_totag()) {
+		# sequential request withing a dialog should
+		# take the path determined by record-routing
+		if (loose_route()) {
+			if (is_method("BYE")) {
+				setflag(1); # do accounting ...
+				setflag(3); # ... even if the transaction fails
+			}
+			route(1);
+		} else {
+			if (is_method("SUBSCRIBE") && uri == myself) {
+				# in-dialog subscribe requests
+				route(2);
+				exit;
+			}
+			if ( is_method("ACK") ) {
+				if ( t_check_trans() ) {
+					# non loose-route, but stateful ACK; must be an ACK after a 487 or e.g. 404 from upstream server
+					t_relay();
+					exit;
+				} else {
+					# ACK without matching transaction ... ignore and discard.\n");
+					exit;
+				}
+			}
+			sl_send_reply("404","Not here");
+		}
+		exit;
+	}
+
+	#initial requests
+
+	# CANCEL processing
+	if (is_method("CANCEL"))
+	{
+		if (t_check_trans())
+			t_relay();
+		exit;
+	}
+
+	t_check_trans();
+
+	# authentication
+	route(3);
+
+	# record routing for dialog forming requests (in case they are routed)
+	if (is_method("INVITE|SUBSCRIBE"))
+		record_route();
+
+	# account only INVITEs
+	if (is_method("INVITE")) {
+		setflag(1); # do accounting
+	}
+	if (!uri==myself)
+	/* replace with following line if multi-domain support is used */
+	##if (!is_uri_host_local())
+	{
+		append_hf("P-hint: outbound\r\n"); 
+		# if you have some interdomain connections via TLS
+		##if($rd=="tls_domain1.net") {
+		##	t_relay("tls:domain1.net");
+		##	exit;
+		##} else if($rd=="tls_domain2.net") {
+		##	t_relay("tls:domain2.net");
+		##	exit;
+		##}
+		route(1);
+	}
+
+	# requests for my domain
+
+	if( is_method("PUBLISH|SUBSCRIBE"))
+		route(2);
+
+	if (is_method("REGISTER"))
+	{
+		if (!save("location"))
+			sl_reply_error();
+
+		exit;
+	}
+
+	if ($rU==NULL) {
+		# request with no Username in RURI
+		sl_send_reply("484","Address Incomplete");
+		exit;
+	}
+
+	# apply DB based aliases (uncomment to enable)
+	##alias_db_lookup("dbaliases");
+
+	if (!lookup("location")) {
+		switch ($retcode) {
+			case -1:
+			case -3:
+				t_newtran();
+				t_reply("404", "Not Found");
+				exit;
+			case -2:
+				sl_send_reply("405", "Method Not Allowed");
+				exit;
+		}
+	}
+
+	# when routing via usrloc, log the missed calls also
+	setflag(2);
+
+	route(1);
+}
+
+
+route[1] {
+#n#	if (check_route_param("nat=yes")) {
+#n#		setbflag(6);
+#n#	}
+#n#	if (isflagset(5) || isbflagset(6)) {
+#n#		route(5);
+#n#	}
+
+	/* example how to enable some additional event routes */
+	if (is_method("INVITE")) {
+		#t_on_branch("1");
+		t_on_reply("1");
+		t_on_failure("1");
+	}
+
+	if (!t_relay()) {
+		sl_reply_error();
+	}
+	exit;
+}
+
+
+# Presence route
+/* uncomment the whole following route for enabling presence server */
+route[2]
+{
+#p#	if (!t_newtran())
+#p#	{
+#p#		sl_reply_error();
+#p#		exit;
+#p#	};
+#p#
+#p#	if(is_method("PUBLISH"))
+#p#	{
+#p#		handle_publish();
+#p#		t_release();
+#p#	}
+#p#	else
+#p#	if( is_method("SUBSCRIBE"))
+#p#	{
+#p#		handle_subscribe();
+#p#		t_release();
+#p#	}
+#p#	exit;
+	
+	# if presence enabled, this part will not be executed
+	if (is_method("PUBLISH") || $rU==null)
+	{
+		sl_send_reply("404", "Not here");
+		exit;
+	}
+	return;
+}
+
+# Authentication route
+/* uncomment the whole following route for enabling authentication */
+route[3] {
+#a#	if (is_method("REGISTER"))
+#a#	{
+#a#		# authenticate the REGISTER requests (uncomment to enable auth)
+#a#		if (!www_authorize("", "subscriber"))
+#a#		{
+#a#			www_challenge("", "0");
+#a#			exit;
+#a#		}
+#a#
+#a#		if ($au!=$tU) 
+#a#		{
+#a#			sl_send_reply("403","Forbidden auth ID");
+#a#			exit;
+#a#		}
+#a#	} else {
+#a#		# authenticate if from local subscriber (uncomment to enable auth)
+#a#		if (from_uri==myself)
+#a#		{
+#a#			if (!proxy_authorize("", "subscriber")) {
+#a#				proxy_challenge("", "0");
+#a#				exit;
+#a#			}
+#a#			if (is_method("PUBLISH"))
+#a#			{
+#a#				if ($au!=$tU) {
+#a#					sl_send_reply("403","Forbidden auth ID");
+#a#					exit;
+#a#				}
+#a#			} else {
+#a#				if ($au!=$fU) {
+#a#					sl_send_reply("403","Forbidden auth ID");
+#a#					exit;
+#a#				}
+#a#			}
+#a#
+#a#			consume_credentials();
+#a#			# caller authenticated
+#a#		}
+#a#	}
+	return;
+}
+
+# Caller NAT detection route
+/* uncomment the whole following route for enabling Caller NAT Detection */
+route[4]{
+#n#	force_rport();
+#n#	if (nat_uac_test("19")) {
+#n#		if (method=="REGISTER") {
+#n#			fix_nated_register();
+#n#		} else {
+#n#			fix_nated_contact();
+#n#		}
+#n#		setflag(5);
+#n#	}
+	return;
+}
+
+# RTPProxy control
+/* uncomment the whole following route for enabling RTPProxy Control */
+route[5] {
+#n#	if (is_method("BYE")) {
+#n#		unforce_rtp_proxy();
+#n#	} else if (is_method("INVITE")){
+#n#		force_rtp_proxy();
+#n#	}
+#n#	if (!has_totag()) add_rr_param(";nat=yes");
+	return;
+}
+
+branch_route[1] {
+	xdbg("new branch at $ru\n");
+}
+
+
+onreply_route[1] {
+	xdbg("incoming reply\n");
+
+#n#	if ((isflagset(5) || isbflagset(6)) && status=~"(183)|(2[0-9][0-9])") {
+#n#		force_rtp_proxy();
+#n#	}
+#n#	if (isbflagset(6)) {
+#n#		fix_nated_contact();
+#n#	}
+}
+
+
+failure_route[1] {
+#n#	if (is_method("INVITE")
+#n#			&& (isbflagset(6) || isflagset(5))) {
+#n#		unforce_rtp_proxy();
+#n#	}
+
+	if (t_was_cancelled()) {
+		exit;
+	}
+
+	# uncomment the following lines if you want to block client 
+	# redirect based on 3xx replies.
+	##if (t_check_status("3[0-9][0-9]")) {
+	##t_reply("404","Not found");
+	##	exit;
+	##}
+
+	# uncomment the following lines if you want to redirect the failed 
+	# calls to a different new destination
+	##if (t_check_status("486|408")) {
+	##	sethostport("192.168.2.100:5060");
+	##	append_branch();
+	##	# do not set the missed call flag again
+	##	t_relay();
+	##}
+}

+ 12 - 12
etc/nathelper.cfg

@@ -33,28 +33,28 @@ dns=no           # (cmd. line: -r)
 rev_dns=no      # (cmd. line: -R)
 port=5060
 children=4
-fifo="/tmp/ser_fifo"
+fifo="/tmp/sip-router_fifo"
 
 # ------------------ module loading ----------------------------------
 
 # Uncomment this if you want to use SQL database
-#loadmodule "/usr/local/lib/ser/modules/mysql.so"
+#loadmodule "/usr/local/lib/sip-router/modules/mysql.so"
 
-loadmodule "/usr/local/lib/ser/modules/sl.so"
-loadmodule "/usr/local/lib/ser/modules/tm.so"
-loadmodule "/usr/local/lib/ser/modules/rr.so"
-loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
-loadmodule "/usr/local/lib/ser/modules/usrloc.so"
-loadmodule "/usr/local/lib/ser/modules/registrar.so"
-loadmodule "/usr/local/lib/ser/modules/textops.so"
+loadmodule "/usr/local/lib/sip-router/modules/sl.so"
+loadmodule "/usr/local/lib/sip-router/modules/tm.so"
+loadmodule "/usr/local/lib/sip-router/modules/rr.so"
+loadmodule "/usr/local/lib/sip-router/modules/maxfwd.so"
+loadmodule "/usr/local/lib/sip-router/modules/usrloc.so"
+loadmodule "/usr/local/lib/sip-router/modules/registrar.so"
+loadmodule "/usr/local/lib/sip-router/modules/textops.so"
 
 # Uncomment this if you want digest authentication
 # mysql.so must be loaded !
-#loadmodule "/usr/local/lib/ser/modules/auth.so"
-#loadmodule "/usr/local/lib/ser/modules/auth_db.so"
+#loadmodule "/usr/local/lib/sip-router/modules/auth.so"
+#loadmodule "/usr/local/lib/sip-router/modules/auth_db.so"
 
 # !! Nathelper
-loadmodule "/usr/local/lib/ser/modules/nathelper.so"
+loadmodule "/usr/local/lib/sip-router/modules/nathelper.so"
 
 # ----------------- setting module-specific parameters ---------------
 

+ 1 - 1
etc/rules.m4

@@ -3,7 +3,7 @@
 #
 # (c) 2003 iptel.org
 #
-# Rules to process ser.cfg templates
+# Rules to process sip-router.cfg templates
 #
 
 #id generator, usage: gen_id(`name'))

+ 7 - 7
etc/ser-basic.cfg → etc/sip-router-basic.cfg

@@ -3,7 +3,7 @@
 #
 # This a very basic config file w aliases and anamed route but
 # w/o authentication, accounting, database, multi-domain support etc.
-# Please refer to ser.cfg for a more complete example
+# Please refer to sip-router.cfg for a more complete example
 #
 
 # ----------- global configuration parameters ------------------------
@@ -23,8 +23,8 @@ dns=no          # (cmd. line: -r)
 rev_dns=no      # (cmd. line: -R)
 #port=5060
 #children=4
-#user=ser
-#group=ser
+#user=sip-router
+#group=sip-router
 #disable_core=yes #disables core dumping
 #open_fd_limit=1024 # sets the open file descriptors limit
 #mhomed=yes  # usefull for multihomed hosts, small performance penalty
@@ -36,7 +36,7 @@ rev_dns=no      # (cmd. line: -R)
 # ------------------ module loading ----------------------------------
 
 #loadpath "modules:modules_s"
-loadpath "/usr/lib/ser/modules:/usr/lib/ser/modules_s"
+loadpath "/usr/lib/sip-router/modules:/usr/lib/sip-router/modules_s"
 
 loadmodule "sl"
 loadmodule "tm"
@@ -59,11 +59,11 @@ modparam("usrloc", "db_mode",   0)
 modparam("rr", "enable_full_lr", 1)
 
 # ctl params
-# by default ctl listens on unixs:/tmp/ser_ctl if no other address is
+# by default ctl listens on unixs:/tmp/sip-router_ctl if no other address is
 # specified in modparams; this is also the default for sercmd
-modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl")
+modparam("ctl", "binrpc", "unixs:/tmp/sip-router_ctl")
 # listen on the "standard" fifo for backward compatibility
-modparam("ctl", "fifo", "fifo:/tmp/ser_fifo")
+modparam("ctl", "fifo", "fifo:/tmp/sip-router_fifo")
 # listen on tcp, localhost
 #modparam("ctl", "binrpc", "tcp:localhost:2046")
 

+ 13 - 13
etc/ser-oob.cfg → etc/sip-router-oob.cfg

@@ -16,7 +16,7 @@
 # multicast).
 #
 # If you look for a simpler version with a lot less dependencies
-# please refer to the ser-basic.cfg file in your SER distribution.
+# please refer to the sip-router-basic.cfg file in your SER distribution.
 #
 # Requirements:
 # ---------------
@@ -59,7 +59,7 @@
 # script, according to values entered by user at installation time in
 # debconf configuration. These values are then applied automatically to
 # this file each time the 'ser-oob' package is upgraded or reconfigured by
-# calling 'dpkg-reconfigure ser-oob'.
+# calling 'dpkg-reconfigure sip-router-oob'.
 #
 # The parts of this configuration file that may be altered by debconf are
 # enclosed between '#DEBCONF-something-START' and '#DEBCONF-something-END'
@@ -133,7 +133,7 @@ server_id=0
 #DEBCONF-SERVERID-END
 
 # Uncomment these lines to enter debugging mode or start SER with
-# ser -ED
+# sip-router -ED
 #
 #fork=no
 #log_stderror=yes
@@ -143,8 +143,8 @@ dns=no                  # (cmd. line: -r)
 rev_dns=no              # (cmd. line: -R)
 #port=5060
 #children=4
-#user=ser
-#group=ser
+#user=sip-router
+#group=sip-router
 #disable_core=yes       # disables core dumping
 open_files_limit=20480  # sets the open file descriptors limit
 #mhomed=yes             # usefull for multihomed hosts, small performance
@@ -195,7 +195,7 @@ dns_cache_min_ttl=60
 dns_cache_max_ttl=86400 # 1 day
 dns_cache_mem=2048 # 2 MB
 dns_cache_gc_interval=60  # garbage collection every minute
-# ser 2.1 specific options
+# sip-router 2.1 specific options
 # dns_try_naptr=yes
 # dns_srv_lb=yes  # srv based load balancing
 # dns_udp_pref=3  # prefer udp (when resolving naptr record)
@@ -210,7 +210,7 @@ use_dst_blacklist=on
 dst_blacklist_mem=1024 # 1 MB
 dst_blacklist_expire=300  # blacklist default time
 dst_blacklist_gc_interval=150 # 2.5 min
-# for ser 2.1 to the above add tm blst_503* parameters and/or use the
+# for sip-router 2.1 to the above add tm blst_503* parameters and/or use the
 # blst module (see NEWS)
 
 # ------------------- TCP Parameters ----------------------------------------
@@ -255,7 +255,7 @@ rtp_proxy.enabled = "detect" desc "indicates whether the RTP Proxy is enabled or
 # ------------------ Module Loading -----------------------------------------
 
 #loadpath "modules:modules_s"
-loadpath "/usr/lib/ser/modules:/usr/lib/ser/modules_s"
+loadpath "/usr/lib/sip-router/modules:/usr/lib/sip-router/modules_s"
 
 # load a SQL database for authentication, domains, user AVPs etc.
 loadmodule "db_mysql"
@@ -316,12 +316,12 @@ avpflags
 #
 #DEBCONF-DBURL-START
 modparam("speeddial|auth_db|usrloc|domain|uri_db|gflags|avp_db|db_ops",
-         "db_url", "mysql://ser:[email protected]/ser")
+         "db_url", "mysql://sip-router:[email protected]/sip-router")
 #DEBCONF-DBURL-END
 
 # specify the path to your database for accounting
 #DEBCONF-DBURLACC-START
-modparam("acc_db", "db_url", "mysql://ser:[email protected]/ser")
+modparam("acc_db", "db_url", "mysql://sip-router:[email protected]/sip-router")
 #DEBCONF-DBURLACC-END
 
 
@@ -429,11 +429,11 @@ modparam("domain", "load_domain_attrs", 1)
 
 # -- ctl --
 
-# By default, ctl listens on unixs:/tmp/ser_ctl if no other address is
+# By default, ctl listens on unixs:/tmp/sip-router_ctl if no other address is
 # specified in modparams; this is also the default for sercmd.
-modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl")
+modparam("ctl", "binrpc", "unixs:/tmp/sip-router_ctl")
 # Listen on the "standard" fifo for backward compatibility.
-modparam("ctl", "fifo", "fifo:/tmp/ser_fifo")
+modparam("ctl", "fifo", "fifo:/tmp/sip-router_fifo")
 # Listen on tcp on localhost.
 #modparam("ctl", "binrpc", "tcp:localhost:2046")
 

+ 0 - 0
etc/ser.cfg → etc/sip-router.cfg


+ 23 - 23
etc/ser.cfg.m4 → etc/sip-router.cfg.m4

@@ -18,7 +18,7 @@ declare(failure, PSTN_FAILURE, _1_FAILURE)
 #
 # $Id$
 #
-# ser.cfg m4 template
+# sip-router.cfg m4 template
 #
 
 #
@@ -30,14 +30,14 @@ declare(failure, PSTN_FAILURE, _1_FAILURE)
 fork=yes
 port=5060
 log_stderror=no
-fifo="/tmp/ser_fifo"
+fifo="/tmp/sip-router_fifo"
 
 # uncomment to enter testing mode
 /*
 fork=no
 port=5064
 log_stderror=yes
-fifo="/tmp/ser_fifox"
+fifo="/tmp/sip-router_fifox"
  */
 
 debug=3
@@ -54,26 +54,26 @@ children=16
 # decimal value in there, e.g. dec(rw|rw|rw)=dec(666)=438
 fifo_mode=0666
 
-loadmodule "/usr/local/lib/ser/modules/tm.so"
-loadmodule "/usr/local/lib/ser/modules/sl.so"
-loadmodule "/usr/local/lib/ser/modules/acc.so"
-loadmodule "/usr/local/lib/ser/modules/rr.so"
-loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
-loadmodule "/usr/local/lib/ser/modules/mysql.so"
-loadmodule "/usr/local/lib/ser/modules/usrloc.so"
-loadmodule "/usr/local/lib/ser/modules/registrar.so"
-loadmodule "/usr/local/lib/ser/modules/auth.so"
-loadmodule "/usr/local/lib/ser/modules/auth_db.so"
-loadmodule "/usr/local/lib/ser/modules/textops.so"
-loadmodule "/usr/local/lib/ser/modules/uri.so"
-loadmodule "/usr/local/lib/ser/modules/group.so"
-loadmodule "/usr/local/lib/ser/modules/msilo.so"
-loadmodule "/usr/local/lib/ser/modules/nathelper.so"
-loadmodule "/usr/local/lib/ser/modules/enum.so"
-loadmodule "/usr/local/lib/ser/modules/domain.so"
-#loadmodule "/usr/local/lib/ser/modules/permissions.so"
-
-modparam("usrloc|acc|auth_db|group|msilo", "db_url", "sql://ser:heslo@localhost/ser")
+loadmodule "/usr/local/lib/sip-router/modules/tm.so"
+loadmodule "/usr/local/lib/sip-router/modules/sl.so"
+loadmodule "/usr/local/lib/sip-router/modules/acc.so"
+loadmodule "/usr/local/lib/sip-router/modules/rr.so"
+loadmodule "/usr/local/lib/sip-router/modules/maxfwd.so"
+loadmodule "/usr/local/lib/sip-router/modules/mysql.so"
+loadmodule "/usr/local/lib/sip-router/modules/usrloc.so"
+loadmodule "/usr/local/lib/sip-router/modules/registrar.so"
+loadmodule "/usr/local/lib/sip-router/modules/auth.so"
+loadmodule "/usr/local/lib/sip-router/modules/auth_db.so"
+loadmodule "/usr/local/lib/sip-router/modules/textops.so"
+loadmodule "/usr/local/lib/sip-router/modules/uri.so"
+loadmodule "/usr/local/lib/sip-router/modules/group.so"
+loadmodule "/usr/local/lib/sip-router/modules/msilo.so"
+loadmodule "/usr/local/lib/sip-router/modules/nathelper.so"
+loadmodule "/usr/local/lib/sip-router/modules/enum.so"
+loadmodule "/usr/local/lib/sip-router/modules/domain.so"
+#loadmodule "/usr/local/lib/sip-router/modules/permissions.so"
+
+modparam("usrloc|acc|auth_db|group|msilo", "db_url", "sql://sip-router:heslo@localhost/sip-router")
 
 # -- usrloc params --
 /* 0 -- dont use mysql, 1 -- write_through, 2--write_back */

+ 17 - 17
etc/sr

@@ -10,19 +10,19 @@
 # chkconfig: 2345 20 80
 # description: controls execution of SIP router
 # processname: sr
-# config: /etc/ser/iptel.cfg
+# config: /etc/sip-router/iptel.cfg
 
 # Source function library.
 . /etc/rc.d/init.d/functions
 
-# we use a ser symlink -- that allows us to have a different name
-# in process table so that killalls does not start other sers
+# we use a sip-router symlink -- that allows us to have a different name
+# in process table so that killalls does not start other sip-routers
 # run from somewhere else
 
 BINNAME=sr
 HM=/home/srouter
 SERDIR=$HM/sip_router
-ETC=/etc/ser/iptel.cfg
+ETC=/etc/sip-router/iptel.cfg
 PIDFILE=/var/run/sr.pid
 [email protected]
 USR=510
@@ -38,9 +38,9 @@ MYDIR=$HM/core
 CORE=$MYDIR/core
 TMP=/tmp/srcore.$$
 
-ser_start() {
+sip-router_start() {
 	if [ -r $BIN -a -r $CORE ] ; then
-		echo "before startup ser core found on `date` at $HOSTNAME" > $TMP
+		echo "before startup sip-router core found on `date` at $HOSTNAME" > $TMP
 		echo "----------------------------------" >> $TMP
 		DATE=`date "+%Y-%m-%d--%H-%M"`
 		NEWCORE=$MYDIR/core.$DATE
@@ -48,8 +48,8 @@ ser_start() {
 		echo core stored in $NEWCORE >> $TMP
 		gdb $BIN $NEWCORE -x test/bt.gdb -batch >> $TMP
 		chmod a+r $NEWCORE
-		cd $SERDIR; tar czf $MYDIR/ser.$DATE.tgz .
-		mail -s "ser core found" $NOTIFY < $TMP
+		cd $SERDIR; tar czf $MYDIR/sip-router.$DATE.tgz .
+		mail -s "sip-router core found" $NOTIFY < $TMP
 		rm -f $TMP
 	fi
 	cd $MYDIR
@@ -60,7 +60,7 @@ ser_start() {
 	echo
 }
 
-ser_stop() {
+sip-router_stop() {
 	echo "Stopping SIP router: "
 	killproc $BINNAME
 	RETVAL=$?
@@ -69,14 +69,14 @@ ser_stop() {
 
 monit_start() {
    echo "Command Monit to start Ser..."
-   ${MONIT} -c ${MONITRC} start ser
+   ${MONIT} -c ${MONITRC} start sip-router
    RETVAL=$?
    echo
 }
 
 monit_stop() {
    echo "Command Monit to stop Ser..."
-   ${MONIT} -c ${MONITRC} stop ser
+   ${MONIT} -c ${MONITRC} stop sip-router
    RETVAL=$?
    echo
 }
@@ -84,15 +84,15 @@ monit_stop() {
 # See how we were called.
 case "$1" in
   serstart)
-	ser_start
+	sip-router_start
 	;;
-  serstop)
-    ser_stop
+  sip-routerstop)
+    sip-router_stop
 	;;
-  serrestart)
-	ser_stop
+  sip-routerrestart)
+	sip-router_stop
 	echo
-	ser_start
+	sip-router_start
 	;;
   start)
     monit_start

+ 22 - 0
etc/tls/README

@@ -0,0 +1,22 @@
+
+
+This directory contains an already generated TLS certificate that can be
+used in your OpenSER configuration. It's a generic certificate with the 
+main purpose of serving as example and for testings.
+
+IMPORTANT: it's not a trustable certificate - the CA is also an example.
+
+All TLS configuration file may be found in "user" directory. If you want to
+generate your own certificate, you may find in the "rootCA" directory the 
+root CA to sign your request with. Use "kamctl tls userCERT" command to
+create a new certificate; the rootCA password is "openser".
+
+What is the purpose of these default CA and certificate? First to make an 
+out-of-the box TLS configuration for users not so familiar with SSL/TLS.
+Second, to give access to the same CA root to a large community in order to
+encourage testings and interconnections via TLS with minimum of troubles.
+
+For any questions, please address to :
+	[email protected] (if you want to keep your question private)
+	[email protected] (public mailing list)
+

+ 88 - 0
etc/tls/ca.conf

@@ -0,0 +1,88 @@
+#
+# Default configuration to use  when one
+# is not provided on the command line.
+#
+[ ca ]
+default_ca = local_ca
+
+
+#
+# Default location  of  directories  and
+# files needed to generate certificates.
+#
+[ local_ca ]
+dir              = ./rootCA
+certificate      = $dir/cacert.pem
+database         = $dir/index.txt
+new_certs_dir    = $dir/certs
+private_key      = $dir/private/cakey.pem
+serial           = $dir/serial
+
+
+#
+# Default   expiration   and  encryption
+# policies for certificates.
+#
+default_crl_days = 365
+default_days     = 1825
+default_md       = sha1
+
+policy = local_ca_policy
+x509_extensions = local_ca_extensions
+
+
+#
+# Default policy to use  when generating
+# server   certificates.  The  following
+# fields  must  be defined in the server
+# certificate.
+#
+[ local_ca_policy ]
+commonName             = supplied
+stateOrProvinceName    = supplied
+countryName            = supplied
+emailAddress           = supplied
+organizationName       = supplied
+organizationalUnitName = supplied
+
+
+#
+# x509 extensions to use when generating
+# server certificates.
+#
+[ local_ca_extensions ]
+#subjectAltName      = DNS:altname.somewhere.com
+basicConstraints    = CA:false
+nsCertType          = server
+
+
+#
+# The   default   policy   to  use  when
+# generating the root certificate.
+#
+[ req ]
+default_bits        = 2048
+default_keyfile     = ./private/cakey.pem
+default_md          = sha1
+
+prompt              = no
+distinguished_name  = root_ca_distinguished_name
+x509_extensions     = root_ca_extensions
+
+
+#
+# Root  Certificate  Authority   distin-
+# guished name.  Changes these fields to
+# your local environment.
+#
+[ root_ca_distinguished_name ]
+commonName          = Your_NAME          # please update
+stateOrProvinceName = Your_STATE         # please update
+countryName         = CO                 # please update
+emailAddress        = YOUR_EMAIL         # please update
+organizationName    = YOUR_ORG_NAME      # please update
+
+[ root_ca_extensions ]
+basicConstraints    = CA:true
+subjectAltName      = email:copy
+issuerAltName       = issuer:copy

+ 58 - 0
etc/tls/request.conf

@@ -0,0 +1,58 @@
+#
+# Default configuration to use  when one
+# is not provided on the command line.
+#
+[ ca ]
+default_ca     = CA_request
+
+
+#
+# Default location  of  directories  and
+# files needed to generate certificates.
+#
+[ CA_request ]
+dir            = ./rootCA
+database       = $dir/index.txt
+new_certs_dir  = $dir/certs
+
+certificate    = $dir/cacert.pem
+serial         = $dir/serial
+private_key    = $dir/private/cakey.pem
+
+
+#
+# Default   expiration   and  encryption
+# policies for certificates.
+#
+default_days     = 365
+default_crl_days = 1825
+default_md       = sha1
+
+policy           = req_policy
+
+
+#
+# Information to be moved from 
+# request to the certificate
+#
+nameopt          = ca_default
+certopt          = ca_default
+copy_extensions  = copy
+x509_extensions     = cert_extensions
+
+
+#
+# The   default   policy   to  use  when
+# generating the certificate.
+#
+[ req_policy ]
+countryName            = supplied
+stateOrProvinceName    = optional
+organizationName       = supplied
+organizationalUnitName = optional
+commonName             = supplied
+emailAddress           = supplied
+
+[ cert_extensions ]
+basicConstraints    = CA:false
+

+ 22 - 0
etc/tls/rootCA/cacert.pem

@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDlTCCAn2gAwIBAgIJAIajPSGooWsRMA0GCSqGSIb3DQEBBQUAMGQxEDAOBgNV
+BAMTB09wZW5TRVIxDDAKBgNVBAgTA1NJUDELMAkGA1UEBhMCSVAxHzAdBgkqhkiG
+9w0BCQEWEHRlYW1Ab3BlbnNlci5vcmcxFDASBgNVBAoTC29wZW5zZXIub3JnMB4X
+DTA1MTAyODE5MDk0NFoXDTA2MTAyODE5MDk0NFowZDEQMA4GA1UEAxMHT3BlblNF
+UjEMMAoGA1UECBMDU0lQMQswCQYDVQQGEwJJUDEfMB0GCSqGSIb3DQEJARYQdGVh
+bUBvcGVuc2VyLm9yZzEUMBIGA1UEChMLb3BlbnNlci5vcmcwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCtOHaQSReSuBpet7hGSJtAtqoKzPYpYdoIijiw
+9tlB/ODBFWjz583MKJuUxIWt7cqnUheBNgBGvrtZYVB6bUxjyTS4m3g8NrrIcWuw
+ASTYqYWRmdWbiyLraC6MeoNd8fUG50kbfZa6fh/pkBzZDQb/4Z1cfqIEJ4VpVTLO
+CRDreGNfTmG1BREtX+DnzGiKKpGCJVUs/ffX+pTViVC9Y9TDwinJyV9fdtwtI42U
+pAxJA+iiG1oOTuk5yjxKOkxKlHju4DIKND3XnPriU3cjdh/93XhMQDxb/jNZhL6R
+Y/XhcEsS567ZL3VMUw2VxaDiA+exjAaS/wA8b/rHR8af8+svAgMBAAGjSjBIMAwG
+A1UdEwQFMAMBAf8wGwYDVR0RBBQwEoEQdGVhbUBvcGVuc2VyLm9yZzAbBgNVHRIE
+FDASgRB0ZWFtQG9wZW5zZXIub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAabH/C3EiJ
+1Dc3uq9KlF7hp2OODAI4928Yy6+pzcbppGoOhAzmDaEoXmlhIMomgeoD031rsESg
++WNavXs2IFCD0U4ocpCa7L0AKDYr8U+5lUtEi7DzXYkqNW17TB+HxkaQVdzvhGrh
++R3WasX0AIc+inxvgkXgzjm5M6IyRUE0FK3wDcACNfnjrDzzXVvdccrM0ZpCFr5T
+NWJjQYpGcqDB1HDXVBMPFxQ7XyqKOTOgDCMh4J9g9Ye8eL8uukKJx1eEjHoG4RbM
+uQmCYQcCWO0Z/oqiI0FObzsZigf8Xoi9GjK2RjdPEukG3QOflnAm7IjPOLMGzFBn
+peqgBkp+jZv5
+-----END CERTIFICATE-----

+ 56 - 0
etc/tls/rootCA/certs/01.pem

@@ -0,0 +1,56 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: CN=OpenSER, ST=SIP, C=IP/[email protected], O=openser.org
+        Validity
+            Not Before: Oct 28 19:16:29 2005 GMT
+            Not After : Oct 28 19:16:29 2006 GMT
+        Subject: C=IP, ST=SIP, O=OpenSER project, OU=OpenSER TLS tester, CN=OpenSER/[email protected]
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (512 bit)
+                Modulus (512 bit):
+                    00:b6:13:f8:54:99:2a:c3:39:2d:fa:b0:5a:cc:4d:
+                    ca:8b:d0:53:9d:c9:59:ce:17:1e:ba:0a:8e:82:eb:
+                    9b:c2:69:33:93:3a:b1:68:aa:da:40:bd:de:b5:6f:
+                    c2:5e:99:72:59:f4:68:75:4c:01:05:94:1b:ba:1d:
+                    f2:bb:10:67:d7
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+    Signature Algorithm: sha1WithRSAEncryption
+        3d:41:b5:28:a4:10:c7:c8:de:29:6f:2e:ed:a8:30:28:2f:9e:
+        3c:a9:95:c4:df:73:7b:2e:1c:51:84:a2:bd:ff:56:94:6f:5b:
+        ac:e2:8f:77:31:74:82:29:8d:e7:a8:c7:da:14:7d:6c:62:dc:
+        2f:2e:70:0c:eb:53:67:fa:1b:0a:e5:e8:58:41:5e:dd:84:3d:
+        3d:22:c2:c3:b5:69:e5:11:86:2a:a6:4c:f3:07:98:00:f5:cf:
+        c8:f1:ea:a3:62:f6:40:ef:08:74:93:de:5b:f2:dc:01:dc:0f:
+        2a:81:e3:03:56:d1:ef:ca:22:fc:18:29:4f:b0:45:b1:d0:30:
+        6b:63:1b:72:ef:9d:ae:bf:ef:b3:0d:fa:39:49:25:48:46:6d:
+        68:a1:12:7a:23:1e:ba:53:8e:a5:a2:38:8e:3b:0f:df:b1:b6:
+        1e:61:69:80:57:c1:f1:8d:62:69:e0:85:e9:6b:e0:10:4d:37:
+        b0:3e:98:cc:b5:b5:ea:db:2f:a2:02:51:85:27:1d:65:74:2e:
+        e3:f4:1f:0c:52:3e:f8:86:6b:50:f1:38:1d:23:97:53:3c:84:
+        03:4e:25:a0:66:3a:16:aa:94:77:f2:c8:65:db:ce:c7:0d:c2:
+        44:7a:8e:af:ee:c5:bc:4e:aa:2f:29:c5:02:33:ea:c7:78:76:
+        02:d4:b4:ca
+-----BEGIN CERTIFICATE-----
+MIICqjCCAZKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMRAwDgYDVQQDEwdPcGVu
+U0VSMQwwCgYDVQQIEwNTSVAxCzAJBgNVBAYTAklQMR8wHQYJKoZIhvcNAQkBFhB0
+ZWFtQG9wZW5zZXIub3JnMRQwEgYDVQQKEwtvcGVuc2VyLm9yZzAeFw0wNTEwMjgx
+OTE2MjlaFw0wNjEwMjgxOTE2MjlaMIGFMQswCQYDVQQGEwJJUDEMMAoGA1UECBMD
+U0lQMRgwFgYDVQQKEw9PcGVuU0VSIHByb2plY3QxGzAZBgNVBAsTEk9wZW5TRVIg
+VExTIHRlc3RlcjEQMA4GA1UEAxMHT3BlblNFUjEfMB0GCSqGSIb3DQEJARYQdGVh
+bUBvcGVuc2VyLm9yZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC2E/hUmSrDOS36
+sFrMTcqL0FOdyVnOFx66Co6C65vCaTOTOrFoqtpAvd61b8JemXJZ9Gh1TAEFlBu6
+HfK7EGfXAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBAD1B
+tSikEMfI3ilvLu2oMCgvnjyplcTfc3suHFGEor3/VpRvW6zij3cxdIIpjeeox9oU
+fWxi3C8ucAzrU2f6Gwrl6FhBXt2EPT0iwsO1aeURhiqmTPMHmAD1z8jx6qNi9kDv
+CHST3lvy3AHcDyqB4wNW0e/KIvwYKU+wRbHQMGtjG3Lvna6/77MN+jlJJUhGbWih
+EnojHrpTjqWiOI47D9+xth5haYBXwfGNYmnghelr4BBNN7A+mMy1terbL6ICUYUn
+HWV0LuP0HwxSPviGa1DxOB0jl1M8hANOJaBmOhaqlHfyyGXbzscNwkR6jq/uxbxO
+qi8pxQIz6sd4dgLUtMo=
+-----END CERTIFICATE-----

+ 1 - 0
etc/tls/rootCA/index.txt

@@ -0,0 +1 @@
+V	061028191629Z		01	unknown	/C=IP/ST=SIP/O=OpenSER project/OU=OpenSER TLS tester/CN=OpenSER/[email protected]

+ 30 - 0
etc/tls/rootCA/private/cakey.pem

@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,4FF5A11F3774B0A0
+
+55A4nhjLcx9PgAAnxRoYwkzCtM1D/2Rb3cLtUo6GTG8E+RzsKgo9PIZDDSDJAy9k
+39UXsC69C7jxmqP7oBQgU8M15yAKQwX9zIsi82tRb/oh58f331fK3vtCzvZrJCwQ
+5ZWUcmLCrtxVoDj2N9pItB3OizHcUYGmPVxhwWzLyA0Wnq5/EScVaIVEEUQUHZtU
+3iJCTUkgc8tFDsFAXEyfO9Y5MabQ3AKSYBgUklGJs0+4facYyCgfYWDwuoanxveQ
+2XIVtv2dcV0WOklGA/G+2tfwtRa0G0GBl4Jf49/bv2fONrhGX4KE4aJb7jp8LTZA
+nFokO8L/OPHQQDatZ4r9gqIJMzY8uMtzRdkccZvV+xecDieZ6PN4MW36s/AzMp3q
+oS72x413GSlDOLlrmDyy7NWo81yD5aYUCgoW6QOOtDCMwFGIJ+lEbt7vPasVp0GJ
+Qpsni2Kz7knpjZJHoAyARfm7rPX9Dsk60A16Up9/4LHyy2vsNfD8uXwRcYSTx3nF
+d5ClZYtwQp88cfe2qK2L5pegN+YoghXukE191OruZ3cU/ialPqGHefHTd46JyWsZ
+k1k0IxXwyAyLbWcFRJ0IKogYK/p/Jz2vAggGS/4utH6OWPkDObo6mclKO3nQk/AK
+YGtcAvbN+MOB9US6v/gqHSbh3FvjKtdeSdzkgOqJD0v9sYoshk9XlAcMKljPAqxt
+QuFlsNC221z9jpIPVWDoHiufVtuX2/qif0cYhy0T3ey1crgZ1Wf5Xt2VxRk8xCGs
+FN5bOmpQcFHhEAmeBS0/cRTM+P0RZ0qLoJUWgedxF9UHweNgpu/JgE8ReF7xIfbV
+OHi2ZEziydYuqAQaLi5rDditDJVz+8lnH9k8qWk9WKbFE+Oz/7i5/f10t+062aC2
+0pTg6dptI/X49p0TWuxrI/UTqQjreauTaNaR32pOZlKuCWngtcxLTg/XGfTahsLN
+EUKEdQk4T/2OzCICwStkwlayjs+O2osNEE2n79e9IxPG/L7KzWA4RF6dwuJ2Zh5J
+8xF/dAiL9C7EBIOQsPxLpjqQUUipedophsndkR5ADP4R3a97d2ZVsk6N0gGMfXHH
+6UghbSAcDQ3xj1eSBXYmb2cq36A0g6j3B9Clkh0yO07H7C6jlHeUbGw/5uaa69pX
+H9kyPDpPP/sJ26jIBDCC1hzWX2v3/wl7CZRBgf9OQ6lY3x1Mk6eQbxW+G0itI5T2
+MNWV0ae8Nr+vAi9OVmVUo3s0D2kUGtMRXC0ECwJUhXq68GDfLUy9y0ixeVrLnkix
+P1OHIu7VLawDvhWx+qQJRI6i0apAEWPTw+A9DiiwtrmILDTQJJWDHky+lja3zkt1
+heVVfeSuyPeS/EgzQgN2kkpr+3ZgNcLSRuKpFdpN2olSyxXt+fRcTj0kluZqJkBn
+7UpojLvzl6ODLZvIYFhHPrlZGVPer+YyuEQGt8Ni4NgFooJmOhzNlUOMQtEvo3kO
+lsll1jPUGO/5TIxoteHepTT/2nLhlbd2g6xsMNEMqqzmH/Q7OnLknI8IVE7AjkEv
+u138yr3yQfdZ+Q9/KDL9RICy/swCZct/dyIhZ6u6NGun2v6Kzzb3lw==
+-----END RSA PRIVATE KEY-----

+ 1 - 0
etc/tls/rootCA/serial

@@ -0,0 +1 @@
+02

+ 16 - 0
etc/tls/user.conf

@@ -0,0 +1,16 @@
+#
+# LocalServer.conf
+#
+
+[ req ]
+prompt = no
+distinguished_name = server_distinguished_name
+
+[ server_distinguished_name ]
+commonName             = somename.somewhere.com               # please update
+stateOrProvinceName    = Some State                           # please update
+countryName            = XY                                   # please update
+emailAddress           = [email protected]          # please update
+organizationName       = My Large Organization Name           # please update
+organizationalUnitName = My Subunit of Large Organization     # please update
+

+ 22 - 0
etc/tls/user/user-calist.pem

@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDlTCCAn2gAwIBAgIJAIajPSGooWsRMA0GCSqGSIb3DQEBBQUAMGQxEDAOBgNV
+BAMTB09wZW5TRVIxDDAKBgNVBAgTA1NJUDELMAkGA1UEBhMCSVAxHzAdBgkqhkiG
+9w0BCQEWEHRlYW1Ab3BlbnNlci5vcmcxFDASBgNVBAoTC29wZW5zZXIub3JnMB4X
+DTA1MTAyODE5MDk0NFoXDTA2MTAyODE5MDk0NFowZDEQMA4GA1UEAxMHT3BlblNF
+UjEMMAoGA1UECBMDU0lQMQswCQYDVQQGEwJJUDEfMB0GCSqGSIb3DQEJARYQdGVh
+bUBvcGVuc2VyLm9yZzEUMBIGA1UEChMLb3BlbnNlci5vcmcwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCtOHaQSReSuBpet7hGSJtAtqoKzPYpYdoIijiw
+9tlB/ODBFWjz583MKJuUxIWt7cqnUheBNgBGvrtZYVB6bUxjyTS4m3g8NrrIcWuw
+ASTYqYWRmdWbiyLraC6MeoNd8fUG50kbfZa6fh/pkBzZDQb/4Z1cfqIEJ4VpVTLO
+CRDreGNfTmG1BREtX+DnzGiKKpGCJVUs/ffX+pTViVC9Y9TDwinJyV9fdtwtI42U
+pAxJA+iiG1oOTuk5yjxKOkxKlHju4DIKND3XnPriU3cjdh/93XhMQDxb/jNZhL6R
+Y/XhcEsS567ZL3VMUw2VxaDiA+exjAaS/wA8b/rHR8af8+svAgMBAAGjSjBIMAwG
+A1UdEwQFMAMBAf8wGwYDVR0RBBQwEoEQdGVhbUBvcGVuc2VyLm9yZzAbBgNVHRIE
+FDASgRB0ZWFtQG9wZW5zZXIub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAabH/C3EiJ
+1Dc3uq9KlF7hp2OODAI4928Yy6+pzcbppGoOhAzmDaEoXmlhIMomgeoD031rsESg
++WNavXs2IFCD0U4ocpCa7L0AKDYr8U+5lUtEi7DzXYkqNW17TB+HxkaQVdzvhGrh
++R3WasX0AIc+inxvgkXgzjm5M6IyRUE0FK3wDcACNfnjrDzzXVvdccrM0ZpCFr5T
+NWJjQYpGcqDB1HDXVBMPFxQ7XyqKOTOgDCMh4J9g9Ye8eL8uukKJx1eEjHoG4RbM
+uQmCYQcCWO0Z/oqiI0FObzsZigf8Xoi9GjK2RjdPEukG3QOflnAm7IjPOLMGzFBn
+peqgBkp+jZv5
+-----END CERTIFICATE-----

+ 56 - 0
etc/tls/user/user-cert.pem

@@ -0,0 +1,56 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: CN=OpenSER, ST=SIP, C=IP/[email protected], O=openser.org
+        Validity
+            Not Before: Oct 28 19:16:29 2005 GMT
+            Not After : Oct 28 19:16:29 2006 GMT
+        Subject: C=IP, ST=SIP, O=OpenSER project, OU=OpenSER TLS tester, CN=OpenSER/[email protected]
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (512 bit)
+                Modulus (512 bit):
+                    00:b6:13:f8:54:99:2a:c3:39:2d:fa:b0:5a:cc:4d:
+                    ca:8b:d0:53:9d:c9:59:ce:17:1e:ba:0a:8e:82:eb:
+                    9b:c2:69:33:93:3a:b1:68:aa:da:40:bd:de:b5:6f:
+                    c2:5e:99:72:59:f4:68:75:4c:01:05:94:1b:ba:1d:
+                    f2:bb:10:67:d7
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+    Signature Algorithm: sha1WithRSAEncryption
+        3d:41:b5:28:a4:10:c7:c8:de:29:6f:2e:ed:a8:30:28:2f:9e:
+        3c:a9:95:c4:df:73:7b:2e:1c:51:84:a2:bd:ff:56:94:6f:5b:
+        ac:e2:8f:77:31:74:82:29:8d:e7:a8:c7:da:14:7d:6c:62:dc:
+        2f:2e:70:0c:eb:53:67:fa:1b:0a:e5:e8:58:41:5e:dd:84:3d:
+        3d:22:c2:c3:b5:69:e5:11:86:2a:a6:4c:f3:07:98:00:f5:cf:
+        c8:f1:ea:a3:62:f6:40:ef:08:74:93:de:5b:f2:dc:01:dc:0f:
+        2a:81:e3:03:56:d1:ef:ca:22:fc:18:29:4f:b0:45:b1:d0:30:
+        6b:63:1b:72:ef:9d:ae:bf:ef:b3:0d:fa:39:49:25:48:46:6d:
+        68:a1:12:7a:23:1e:ba:53:8e:a5:a2:38:8e:3b:0f:df:b1:b6:
+        1e:61:69:80:57:c1:f1:8d:62:69:e0:85:e9:6b:e0:10:4d:37:
+        b0:3e:98:cc:b5:b5:ea:db:2f:a2:02:51:85:27:1d:65:74:2e:
+        e3:f4:1f:0c:52:3e:f8:86:6b:50:f1:38:1d:23:97:53:3c:84:
+        03:4e:25:a0:66:3a:16:aa:94:77:f2:c8:65:db:ce:c7:0d:c2:
+        44:7a:8e:af:ee:c5:bc:4e:aa:2f:29:c5:02:33:ea:c7:78:76:
+        02:d4:b4:ca
+-----BEGIN CERTIFICATE-----
+MIICqjCCAZKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMRAwDgYDVQQDEwdPcGVu
+U0VSMQwwCgYDVQQIEwNTSVAxCzAJBgNVBAYTAklQMR8wHQYJKoZIhvcNAQkBFhB0
+ZWFtQG9wZW5zZXIub3JnMRQwEgYDVQQKEwtvcGVuc2VyLm9yZzAeFw0wNTEwMjgx
+OTE2MjlaFw0wNjEwMjgxOTE2MjlaMIGFMQswCQYDVQQGEwJJUDEMMAoGA1UECBMD
+U0lQMRgwFgYDVQQKEw9PcGVuU0VSIHByb2plY3QxGzAZBgNVBAsTEk9wZW5TRVIg
+VExTIHRlc3RlcjEQMA4GA1UEAxMHT3BlblNFUjEfMB0GCSqGSIb3DQEJARYQdGVh
+bUBvcGVuc2VyLm9yZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC2E/hUmSrDOS36
+sFrMTcqL0FOdyVnOFx66Co6C65vCaTOTOrFoqtpAvd61b8JemXJZ9Gh1TAEFlBu6
+HfK7EGfXAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBAD1B
+tSikEMfI3ilvLu2oMCgvnjyplcTfc3suHFGEor3/VpRvW6zij3cxdIIpjeeox9oU
+fWxi3C8ucAzrU2f6Gwrl6FhBXt2EPT0iwsO1aeURhiqmTPMHmAD1z8jx6qNi9kDv
+CHST3lvy3AHcDyqB4wNW0e/KIvwYKU+wRbHQMGtjG3Lvna6/77MN+jlJJUhGbWih
+EnojHrpTjqWiOI47D9+xth5haYBXwfGNYmnghelr4BBNN7A+mMy1terbL6ICUYUn
+HWV0LuP0HwxSPviGa1DxOB0jl1M8hANOJaBmOhaqlHfyyGXbzscNwkR6jq/uxbxO
+qi8pxQIz6sd4dgLUtMo=
+-----END CERTIFICATE-----

+ 9 - 0
etc/tls/user/user-cert_req.pem

@@ -0,0 +1,9 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBQDCB6wIBADCBhTEQMA4GA1UEAxMHT3BlblNFUjEMMAoGA1UECBMDU0lQMQsw
+CQYDVQQGEwJJUDEfMB0GCSqGSIb3DQEJARYQdGVhbUBvcGVuc2VyLm9yZzEYMBYG
+A1UEChMPT3BlblNFUiBwcm9qZWN0MRswGQYDVQQLExJPcGVuU0VSIFRMUyB0ZXN0
+ZXIwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAthP4VJkqwzkt+rBazE3Ki9BTnclZ
+zhceugqOguubwmkzkzqxaKraQL3etW/CXplyWfRodUwBBZQbuh3yuxBn1wIDAQAB
+oAAwDQYJKoZIhvcNAQEFBQADQQA0mFBhg/bbxznLbLcc2nQo0022x0HeT3Qxl0lm
+SlIvfG2YphvBYuc54HFjqHfRNrmckAVoSrVpEpcVXSO/g+L6
+-----END CERTIFICATE REQUEST-----

+ 9 - 0
etc/tls/user/user-privkey.pem

@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBALYT+FSZKsM5LfqwWsxNyovQU53JWc4XHroKjoLrm8JpM5M6sWiq
+2kC93rVvwl6Zcln0aHVMAQWUG7od8rsQZ9cCAwEAAQJBALCEy8u4cmyxkpHnRx+q
+iyLg5S+jdR0H7RIQCfmC0Y63LFIAsXasHQorV83r2br4eRRaeU87CsVLXdBUjvbe
+ywECIQDaq7ojtDBTGhNKILZ9CBOTk18jDdHgTJAC7ZpGvdGt+QIhANUpE9j5JWqA
+kIcR55eSJXmjoKB1IGnTz0kaMB/8B3hPAiEAw0351IXNW4vAisao9wdNpNNNd5uS
+RklbnqHk1yYWrtECIEXqi1AHqHYeZUloXgYhMZmMSgtXX6JWjw7zQAW9rNWRAiBe
+Xmwo0k9fY/KawVSsnY4rgYqk6PDWK98jl5/x/veDZA==
+-----END RSA PRIVATE KEY-----

+ 242 - 0
examples/kamailio/acc-mysql.cfg

@@ -0,0 +1,242 @@
+# $Id$
+#
+# Sample config for MySQL accouting with Kamailio 1.2.0
+#
+# - mysql module must be compiled and installed
+#
+# - new columns have to be added since by default only few are recorded
+# - here are full SQL statements to create acc and missed_calls tables
+#
+# CREATE TABLE `acc` (
+#   `id` int(10) unsigned NOT NULL auto_increment,
+#   `method` varchar(16) NOT NULL default '',
+#   `from_tag` varchar(64) NOT NULL default '',
+#   `to_tag` varchar(64) NOT NULL default '',
+#   `callid` varchar(128) NOT NULL default '',
+#   `sip_code` char(3) NOT NULL default '',
+#   `sip_reason` varchar(32) NOT NULL default '',
+#   `time` datetime NOT NULL default '0000-00-00 00:00:00',
+#   `src_ip` varchar(64) NOT NULL default '',
+#   `dst_user` varchar(64) NOT NULL default '',
+#   `dst_domain` varchar(128) NOT NULL default '',
+#   `src_user` varchar(64) NOT NULL default '',
+#   `src_domain` varchar(128) NOT NULL default '',
+#   INDEX acc_callid (`callid`),
+#   PRIMARY KEY  (`id`)
+# );
+#
+# CREATE TABLE `missed_calls` (
+#   `id` int(10) unsigned NOT NULL auto_increment,
+#   `method` varchar(16) NOT NULL default '',
+#   `from_tag` varchar(64) NOT NULL default '',
+#   `to_tag` varchar(64) NOT NULL default '',
+#   `callid` varchar(128) NOT NULL default '',
+#   `sip_code` char(3) NOT NULL default '',
+#   `sip_reason` varchar(32) NOT NULL default '',
+#   `time` datetime NOT NULL default '0000-00-00 00:00:00',
+#   `src_ip` varchar(64) NOT NULL default '',
+#   `dst_user` varchar(64) NOT NULL default '',
+#   `dst_domain` varchar(128) NOT NULL default '',
+#   `src_user` varchar(64) NOT NULL default '',
+#   `src_domain` varchar(128) NOT NULL default '',
+#   INDEX acc_callid (`callid`),
+#   PRIMARY KEY  (`id`)
+# );
+#
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3            # debug level (cmd line: -dddddddddd)
+fork=yes
+log_stderror=no    # (cmd line: -E)
+
+/* Uncomment these lines to enter debugging mode 
+fork=no
+log_stderror=yes
+*/
+
+check_via=no	# (cmd. line: -v)
+dns=no          # (cmd. line: -r)
+rev_dns=no      # (cmd. line: -R)
+port=5060
+children=4
+
+#
+# uncomment the following lines for TLS support
+#disable_tls = 0
+#listen = tls:your_IP:5061
+#tls_verify_server = 1
+#tls_verify_client = 1
+#tls_require_client_certificate = 0
+#tls_method = TLSv1
+#tls_certificate = "/usr/local/etc/kamailio/tls/user/user-cert.pem"
+#tls_private_key = "/usr/local/etc/kamailio/tls/user/user-privkey.pem"
+#tls_ca_list = "/usr/local/etc/kamailio/tls/user/user-calist.pem"
+
+# ------------------ module loading ----------------------------------
+
+# set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+# Uncomment this if you want to use SQL database
+# - MySQL loaded for accounting as well
+loadmodule "db_mysql.so"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "acc.so"
+loadmodule "mi_fifo.so"
+
+# Uncomment this if you want digest authentication
+# db_mysql.so must be loaded !
+#loadmodule "auth.so"
+#loadmodule "auth_db.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- mi_fifo params --
+
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# -- usrloc params --
+
+#modparam("usrloc", "db_mode",   0)
+
+# Uncomment this if you want to use SQL database 
+# for persistent storage and comment the previous line
+modparam("usrloc", "db_mode", 2)
+
+# -- auth params --
+# Uncomment if you are using auth module
+#
+#modparam("auth_db", "calculate_ha1", yes)
+#
+# If you set "calculate_ha1" parameter to yes (which true in this config), 
+# uncomment also the following parameter)
+#
+#modparam("auth_db", "password_column", "password")
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# -- acc params --
+modparam("acc", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
+# flag to record to db
+modparam("acc", "db_flag", 1)
+modparam("acc", "db_missed_flag", 2)
+# flag to log to syslog
+modparam("acc", "log_flag", 1)
+modparam("acc", "log_missed_flag", 2)
+# use extra accounting to record caller and callee username/domain
+# - take them from From URI and R-URI
+modparam("acc", "log_extra", "src_user=$fU;src_domain=$fd;dst_user=$rU;dst_domain=$rd")
+modparam("acc", "db_extra", "src_user=$fU;src_domain=$fd;dst_user=$rU;dst_domain=$rd")
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	# initial sanity checks -- messages with
+	# max_forwards==0, or excessively long requests
+	if (!mf_process_maxfwd_header("10")) {
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	};
+
+	if (msg:len >=  2048 ) {
+		sl_send_reply("513", "Message too big");
+		exit;
+	};
+
+	# we record-route all messages -- to make sure that
+	# subsequent messages will go through our proxy; that's
+	# particularly good if upstream and downstream entities
+	# use different transport protocol
+	if (!is_method("REGISTER"))
+		record_route();
+
+	# subsequent messages withing a dialog should take the
+	# path determined by record-routing
+	if (loose_route()) {
+		# mark routing logic in request
+		append_hf("P-hint: rr-enforced\r\n");
+		if(is_method("BYE")) {
+			# account BYE for STOP record
+			setflag(1);
+		}
+		route(1);
+	};
+
+	# account all calls
+	if(is_method("INVITE")) {
+		# set accounting on for INVITE (success or missed call)
+		setflag(1);
+		setflag(2);
+	}
+
+	if (!uri==myself) {
+		# mark routing logic in request
+		append_hf("P-hint: outbound\r\n"); 
+		# if you have some interdomain connections via TLS
+		#if(uri=~"@tls_domain1.net") {
+		#	t_relay("tls:domain1.net");
+		#	exit;
+		#} else if(uri=~"@tls_domain2.net") {
+		#	t_relay("tls:domain2.net");
+		#	exit;
+		#}
+		route(1);
+	};
+
+	# if the request is for other domain use UsrLoc
+	# (in case, it does not work, use the following command
+	# with proper names and addresses in it)
+	if (uri==myself) {
+
+		if (is_method("REGISTER")) {
+
+			# Uncomment this if you want to use digest authentication
+			#if (!www_authorize("kamailio.org", "subscriber")) {
+			#	www_challenge("kamailio.org", "0");
+			#	exit;
+			#};
+
+			save("location");
+			exit;
+		};
+
+		if (!uri==myself) {
+			append_hf("P-hint: outbound alias\r\n"); 
+			route(1);
+		};
+
+		# native SIP destinations are handled using our USRLOC DB
+		if (!lookup("location")) {
+			sl_send_reply("404", "Not Found");
+			exit;
+		};
+		append_hf("P-hint: usrloc applied\r\n"); 
+	};
+
+	route(1);
+}
+
+
+route[1] {
+	# send it out now; use stateful forwarding as it works reliably
+	# even for UDP2TCP
+	if (!t_relay()) {
+		sl_reply_error();
+	};
+	exit;
+}
+

+ 71 - 0
examples/kamailio/acc.cfg

@@ -0,0 +1,71 @@
+#
+# $Id$
+#
+# example: accounting calls to nummerical destinations
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "tm.so"
+loadmodule "acc.so"
+loadmodule "sl.so"
+loadmodule "maxfwd.so"
+loadmodule "rr.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- acc params --
+# set the reporting log level
+modparam("acc", "log_level", 1)
+# number of flag, which will be used for accounting; if a message is
+# labeled with this flag, its completion status will be reported
+modparam("acc", "log_flag", 1 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	/* ********* ROUTINE CHECKS  ********************************** */
+
+	# filter too old messages
+	if (!mf_process_maxfwd_header("10")) {
+		log("LOG: Too many hops\n");
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	};
+	if (msg:len >=  2048 ) {
+		sl_send_reply("513", "Message too big");
+		exit;
+	};
+
+    #  Process record-routing
+    if (loose_route()) { 
+		# label BYEs for accounting
+		if (method=="BYE") 
+			setflag(1);
+		t_relay();
+		exit;
+	};
+
+
+	# labeled all transaction for accounting
+	setflag(1);
+
+	# record-route INVITES to make sure BYEs will visit our server too
+	if (method=="INVITE") record_route();
+
+	# forward the request statefuly now; (we need *stateful* forwarding,
+	# because the stateful mode correlates requests with replies and
+	# drops retranmissions; otherwise, we would have to report on
+	# every single message received)
+	if (!t_relay()) {
+		sl_reply_error(); 
+		exit; 
+	};
+
+}

+ 224 - 0
examples/kamailio/ctd.sh

@@ -0,0 +1,224 @@
+#!/bin/sh
+#
+# $Id$
+#
+# Usage: ctd.sh $FROM $TARGET
+# 
+# click-to-dial example using REFER
+#----------------------------------
+#
+# About:
+# ------
+# this script initiates a call from SIP user $FROM to SIP
+# user $TARGET; it works as follows: a dummy user invites
+# $FROM to a dummy "call on hold"; as soon as it is set up, the
+# dummy user transfers $FROM to $TARGET  (REFER transaction)
+# and terminates the dummy session established previously
+# (BYE transaction). Note: the "dummy call" is used to
+# make $FROM accept $REFER -- most of SIP phones do not
+# accept REFER if no call has not been established yet.
+#
+# Requirements: 
+# -------------
+# - SER with FIFO server turned on and TM module loaded
+#
+# Limitations: 
+# ------------
+# it only works with UAs supporting REFER; it has been tested 
+# with Cisco 7960, Mitel 5055, Grandstream and Pingtel; Windows 
+# Messenger does not support REFER. Never tested on solaris. 
+# Some cisco 7960 images don't work (in particular, POS30202
+# doesnt, POS3-03-8-21 does)
+#
+# History:
+# --------
+# 2003-03-01 bug_fix: route set reversed
+# 2003-02-27 dialog support completed (jiri)
+# 2003-04-28 dialog info precomputed in SER (jiri)
+# 2007-04-06 updated for Kamailio 1.2.0+ (daniel)
+
+#--------------------------------
+# config: who with whom
+# address of the final destination to which we want to transfer
+# initial CSeq and CallId
+if [ -z "$2" ]; then
+	TARGET="sip:[email protected]"
+	echo "destination unspecified -- taking default value $TARGET"
+else
+	TARGET="$2"
+fi
+# address of user wishing to initiate conversation
+if [ -z "$1" ] ; then
+	URI="sip:[email protected]"
+	echo "caller unspecified -- taking default value $URI"
+else
+	URI="$1"
+fi
+
+#---------------------------------
+# fixed config data
+FIFO="/tmp/kamailio_fifo"
+# address of controller
+FROM="<sip:[email protected]>"
+CSEQ="1"
+CALLIDNR=`date '+%s'`$$
+CALLID="${CALLIDNR}.fifouacctd"
+name="ctd_fifo_$$"
+fifo_reply="/tmp/$name"
+dlg="/tmp/$CALLID.dlg"
+FIXED_DLG="From: $FROM;tag=$CALLIDNR\r\nCall-ID: $CALLID\r\nContact: <sip:caller@!!>\r\n"
+#----------------------------------
+
+# generate parts of FIFO-request essential to forming
+# subsequent in-dialog reuqests
+# 
+# limitations: parsing broken if <> in display names or
+# line-folding used
+filter_fl()
+{
+
+awk -F ' ' '
+BEGIN { IGNORECASE=1; line=0; eoh=0;ret=1 }
+END { exit ret; }
+
+{line++; }
+
+# line 2: status code
+line==2 && /^2[0-9][0-9] / { ret=0;next; }
+line==2 && /^[3-6][0-9][0-9] / { print; print $0 > "/dev/stderr"; next; }
+line==2 { print "reply error"; print; next; } 
+
+# skip body
+/^$/ { eoh=1 }
+eoh==1 { next }
+
+# uri and outbound uri at line 2,3: copy and paste
+line==3 { print $0; next; }
+line==4 { print $0; print "."; printf("\""); next; }
+# line 5: Route; empty if ".", copy and paste otherwise
+line==5 && /^\.$/ { next; }
+# if non-empty, copy and paste it
+line==5 { printf("%s\n", $0); next; }
+# filter out to header field for use in next requests
+/^(To|t):/ { printf("%s\n", $0); next; }
+# anything else will be ignored
+{next} 
+	' # end of awk script
+} # end of filter_fl
+
+#---------------------------
+# main
+
+# set up exit cleaner
+trap "rm -f $dlg $fifo_reply; exit 1" 0
+
+# set up FIFO communication
+
+if [ ! -w $FIFO ] ; then # can I write to FIFO server?
+	echo "Error opening ser's FIFO $FIFO"
+	exit 1
+fi
+mkfifo $fifo_reply # create a reply FIFO
+if [ $? -ne 0 ] ; then
+	echo "error opening reply fifo $fifo_reply"
+	exit 1
+fi
+chmod a+w $fifo_reply
+# start reader now so that it is ready for replies
+# immediately after a request is out
+
+cat < $fifo_reply | filter_fl > $dlg  &
+fifo_job="$!"
+
+# initiate dummy INVITE with pre-3261 "on-hold"
+# (note the dots -- they mean in order of appearance:
+# outbound uri, end of headers, end of body; eventualy
+# the FIFO request must be terminated with an empty line)
+#cat <<EOF
+cat > $FIFO <<EOF
+:t_uac_dlg:$name
+INVITE 
+$URI
+.
+.
+"`printf "${FIXED_DLG}To: <$URI>\r\nCSeq: $CSEQ INVITE\r\nContent-Type: application/sdp\r\n"`
+"
+"`printf "v=0\r\no=click-to-dial 0 0 IN IP4 0.0.0.0\r\ns=session\r\nc=IN IP4 0.0.0.0\r\nb=CT:1000\r\nt=0 0\r\nm=audio 9 RTP/AVP 8 0\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:0 PCMU/8000\r\n"`
+"
+
+EOF
+#exit
+
+# wait for reply 
+wait $fifo_job # returns completion status of filter_fl
+if [ "$?" -ne "0" ] ; then
+	echo "invitation failed"
+	exit 1
+fi
+
+echo "invitation succeeded"
+
+# proceed to REFER now
+if [ \! -r $dlg ] ; then
+	echo "dialog broken"
+	exit 1
+fi
+CSEQ=`expr $CSEQ + 1`
+
+# start reader now so that it is ready for replies
+# immediately after a request is out
+
+cat < $fifo_reply | filter_fl > /dev/null  &
+fifo_job="$!"
+
+# dump the REFER request to FIFO server 
+cat > $FIFO <<EOF
+:t_uac_dlg:$name
+REFER
+`cat $dlg; printf "${FIXED_DLG}CSeq: $CSEQ REFER\r\nReferred-By: $FROM\r\nRefer-To: $TARGET\r\n"`
+"
+
+EOF
+
+# report REFER status
+wait $fifo_job
+ref_ret="$?"
+
+if [ "$ref_ret" -ne "0" ] ; then
+	echo "refer failed"
+else
+	echo "refer succeeded"
+fi
+
+
+# well, URI is trying to call TARGET but still maintains the
+# dummy call we established with previous INVITE transaction:
+# tear it down
+
+
+# dump the BYE request to FIFO server 
+CSEQ=`expr $CSEQ + 1`
+cat < $fifo_reply | filter_fl > /dev/null  &
+fifo_job="$!"
+cat > $FIFO <<EOF
+:t_uac_dlg:$name
+BYE
+`cat $dlg; printf "${FIXED_DLG}CSeq: $CSEQ BYE\r\n"`
+"
+
+EOF
+
+# report BYE status
+wait $fifo_job
+ret="$?"
+
+if [ "$ret" -ne "0" ] ; then
+	echo "bye failed"
+	exit 1
+fi
+echo "bye succeeded"
+
+# clean-up
+trap 0
+rm -f $dlg $fifo_reply
+exit $ref_ret

+ 30 - 0
examples/kamailio/exec_s3.cfg

@@ -0,0 +1,30 @@
+#
+# $Id$
+#
+# email notification to email address from mysql database
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "exec.so"
+loadmodule "sl.so"
+
+# send email if a request arrives
+route[0] {
+     if (!exec_msg('
+	QUERY="select email_address from subscriber 
+		where user=\"$$SIP_OUSER\"";
+	EMAIL=`mysql  -Bsuser -pheslo -e "$$QUERY" kamailio`;
+	if [ -z "$$EMAIL" ] ; then exit 1; fi ;
+	echo "SIP request received from $$SIP_HF_FROM for $$SIP_OUSER" |
+	mail -s "request for you" $$EMAIL ')) {
+		# exec returned error ... user does not exist
+		sl_send_reply("404", "User does not exist");
+	} else {
+		sl_send_reply("600", "No messages for this user");
+	};
+		
+}

+ 41 - 0
examples/kamailio/exec_s4.cfg

@@ -0,0 +1,41 @@
+#
+# $Id$
+#
+# email notification to email address from mysql database
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+loadmodule "exec.so"
+loadmodule "sl.so"
+loadmodule "tm.so"
+
+# send email if a request arrives; process statefully
+# to avoid multiple execution on request retransmissions
+route[0] {
+	# stop script processing if transaction exists
+	if ( !t_newtran()) {
+		sl_reply_error();
+		return;
+	};
+
+  	if (!exec_msg('
+		QUERY="select email_address from subscriber 
+			where user=\"$$SIP_OUSER\"";
+		EMAIL=`mysql  -Bsuser -pheslo -e "$$QUERY" ser`;
+		if [ -z "$EMAIL" ] ; then exit 1; fi ;
+		echo "SIP request received from $$SIP_HF_FROM for $$SIP_OUSER" |
+		mail -s "request for you" $$EMAIL ')) 
+	{
+		# exec returned error ... user does not exist
+		# send a stateful reply
+		t_reply("404", "User does not exist");
+	} else {
+		t_reply("600", "No messages for this user");
+	};
+		
+}

+ 68 - 0
examples/kamailio/exec_s5.cfg

@@ -0,0 +1,68 @@
+#
+# $Id$
+#
+# simple quick-start config script
+#
+
+# ----------- global configuration parameters ------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "exec.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+route{
+	# uri for my domain ?
+	if (uri==myself) {
+
+		if (method=="REGISTER") {
+			save("location");
+			return;
+		};
+
+		# native SIP destinations are handled using our USRLOC DB
+		if (!lookup("location")) {
+			# proceed to email notification
+			if (method=="INVITE") route(1)
+			else sl_send_reply("404", "Not Found");
+			exit;
+		};
+	};
+	# user found, forward to his current uri now
+	if (!t_relay()) {
+		sl_reply_error();
+	};
+}
+
+/* handling of missed calls */
+route[1] {
+	# don't continue if it is a retransmission
+	if ( !t_newtran()) {
+		sl_reply_error();
+		exit;
+	};
+	# external script: lookup user, if user exists, send 
+	# an email notification to him
+    if (!exec_msg('
+		QUERY="select email_address from subscriber 
+			where user=\"$$SIP_OUSER\"";
+		EMAIL=`mysql  -Bsuser -pheslo -e "$$QUERY" ser`;
+		if [ -z "$$EMAIL" ] ; then exit 1; fi ;
+		echo "SIP request received from $$SIP_HF_FROM for $$SIP_OUSER" |
+		mail -s "request for you" $$EMAIL ')) 
+	{
+		# exec returned error ... user does not exist
+		# send a stateful reply
+		t_reply("404", "User does not exist");
+	} else {
+		t_reply("600", "No messages for this user");
+	};
+	exit;
+}

+ 103 - 0
examples/kamailio/flag_reply.cfg

@@ -0,0 +1,103 @@
+#
+# $Id$
+#
+# simple quick-start config script
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3         # debug level (cmd line: -dddddddddd)
+fork=yes
+log_stderror=no	# (cmd line: -E)
+
+fork=no
+log_stderror=yes
+
+check_via=no	# (cmd. line: -v)
+dns=no           # (cmd. line: -r)
+rev_dns=no      # (cmd. line: -R)
+children=4
+
+port=5060
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+# Uncomment this if you want to use SQL database
+#loadmodule "db_mysql.so"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "mi_fifo.so"
+
+# Uncomment this if you want digest authentication
+# mysql.so must be loaded !
+#loadmodule "auth.so"
+#loadmodule "auth_db.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- mi_fifo params --
+
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# -- usrloc params --
+
+modparam("usrloc", "db_mode",   0)
+
+# Uncomment this if you want to use SQL database 
+# for persistent storage and comment the previous line
+#modparam("usrloc", "db_mode", 2)
+
+# -- auth params --
+# Uncomment if you are using auth module
+#
+#modparam("auth_db", "calculate_ha1", yes)
+#
+# If you set "calculate_ha1" parameter to yes (which true in this config), 
+# uncomment also the following parameter)
+#
+#modparam("auth_db", "password_column", "password")
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+	setflag(1);
+	t_on_failure("1");
+	t_on_reply("1");
+	log(1, "message received\n");
+	t_relay("udp:kamailio.org:5060");
+}
+
+onreply_route[1]
+{
+	if (isflagset(1)) {
+		log(1, "onreply: flag set\n");
+	} else {
+		log(1, "onreply: flag unset\n");
+	};
+}
+
+failure_route[1] 
+{
+	if (isflagset(1)) {
+		log(1, "failure: flag set\n");
+	} else {
+		log(1, "failure: flag unset\n");
+	};
+}
+

+ 67 - 0
examples/kamailio/fork.cfg

@@ -0,0 +1,67 @@
+#
+# $Id$
+#
+# example script showing both types of forking;
+# incoming message is forked in parallel to
+# 'nobody' and 'parallel', if no positive reply
+# appears with final_response timer, nonsense
+# is retried (serial forking); than, destination
+# 'foo' is given last chance
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- tm params --
+# set time for which ser will be waiting for a final response;
+# fr_inv_timer sets value for INVITE transactions, fr_timer
+# for all others
+modparam("tm", "fr_inv_timer", 15 )
+modparam("tm", "fr_timer", 10 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+	# for testing purposes, simply okay all REGISTERs
+	if (method=="REGISTER") {
+		log("REGISTER");
+		sl_send_reply("200", "ok");
+		exit;
+	};
+	# try these two destinations first in parallel; the second
+	# destination is targeted to sink port -- that will make ser
+	# wait until timer hits
+	seturi("sip:[email protected]");
+	append_branch("sip:[email protected]:9");
+	# if we do not get a positive reply, continue at reply_route[1]
+	t_on_failure("1");
+	# forward the request to all destinations in destination set now 
+	t_relay();
+}
+
+failure_route[1] {
+	# forwarding failed -- try again at another destination 
+	append_branch("sip:[email protected]");
+	log(1,"first redirection\n");
+	# if this alternative destination fails too, proceed to reply_route[2] 
+	t_on_failure("2");
+	t_relay();
+}
+
+failure_route[2] {
+	# try out the last resort destination
+	append_branch("sip:[email protected]");
+	log(1, "second redirection\n");
+	# we no more call t_on_negative here; if this destination
+	# fails too, transaction will complete
+	t_relay();
+}

+ 31 - 0
examples/kamailio/logging.cfg

@@ -0,0 +1,31 @@
+#
+# $Id$
+#
+# logging example
+#
+
+# ------------------ module loading ----------------------------------
+
+fork=no
+port=5060
+log_stderror=yes
+debug=3
+
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+	# for testing purposes, simply okay all REGISTERs
+	if (method=="REGISTER") {
+		log(1, "REGISTER received\n");
+	} else {
+		log(1, "non-REGISTER received\n");
+	};
+	if (uri=~"sip:.*[@:]siphub.net") {
+		log(1, "request for siphub.net received\n");
+	} else {
+		log(1, "request for other domain received\n");
+	};
+}

+ 146 - 0
examples/kamailio/msilo.cfg

@@ -0,0 +1,146 @@
+#
+# MSILO usage example
+#
+# $ID: daniel $
+#
+
+
+
+children=2
+check_via=no      # (cmd. line: -v)
+dns=off           # (cmd. line: -r)
+rev_dns=off       # (cmd. line: -R)
+
+
+# ------------------ module loading ----------------------------------
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "textops.so"
+
+loadmodule "sl.so"
+loadmodule "db_mysql.so"
+loadmodule "maxfwd.so"
+loadmodule "tm.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "msilo.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- registrar params --
+
+modparam("registrar", "default_expires", 120)
+
+# -- registrar params --
+
+modparam("usrloc", "db_mode", 0)
+
+# -- msilo params --
+
+modparam("msilo", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
+
+# -- tm params --
+
+modparam("tm", "fr_timer", 10 )
+modparam("tm", "fr_inv_timer", 15 )
+modparam("tm", "wt_timer", 10 )
+
+
+route{
+	if ( !mf_process_maxfwd_header("10") )
+	{
+		sl_send_reply("483","To Many Hops");
+		exit;
+	};
+
+
+	if (uri==myself) {
+		# for testing purposes, simply okay all REGISTERs
+		# is_method("XYZ") is faster than (method=="XYZ")
+		#  but requires textops module
+		if (is_method("REGISTER"))
+		{
+			save("location");
+			log("REGISTER received -> dumping messages with MSILO\n");
+
+			# MSILO - dumping user's offline messages
+			if (m_dump())
+			{
+				log("MSILO: offline messages dumped - if they were\n");
+			}else{
+				log("MSILO: no offline messages dumped\n");
+			};
+			exit;
+		};
+
+		# backup r-uri for m_dump() in case of delivery failure
+		$avp(i:11) = $ru;
+
+		# domestic SIP destinations are handled using our USRLOC DB
+		
+		if(!lookup("location")) 
+		{
+			if (! t_newtran())
+			{
+				sl_reply_error();
+				exit;
+			};
+			# we do not care about anything else but MESSAGEs
+			if (!is_method("MESSAGE"))
+			{
+				if (!t_reply("404", "Not found")) 
+				{
+					sl_reply_error();
+				};
+				exit;
+			};
+			log("MESSAGE received -> storing using MSILO\n");
+			# MSILO - storing as offline message
+			if (m_store("$ru"))
+			{
+				log("MSILO: offline message stored\n");
+				if (!t_reply("202", "Accepted")) 
+				{
+					sl_reply_error();
+				};
+			}else{
+				log("MSILO: offline message NOT stored\n");
+				if (!t_reply("503", "Service Unavailable")) 
+				{
+					sl_reply_error();
+				};
+			};
+			exit;
+		};
+		# if the downstream UA does not support MESSAGE requests
+		# go to failure_route[1]
+		t_on_failure("1");
+		t_relay();
+		exit;
+	};
+
+	# forward anything else
+	t_relay();
+}
+
+failure_route[1] {
+	# forwarding failed -- check if the request was a MESSAGE 
+	if (!is_method("MESSAGE"))
+	{
+		exit;
+	};
+	
+	log(1,"MSILO: the downstream UA does not support MESSAGE requests ...\n");
+	# we have changed the R-URI with the contact address -- ignore it now
+	if (m_store("$avp(i:11)"))
+	{
+		log("MSILO: offline message stored\n");
+		t_reply("202", "Accepted"); 
+	}else{
+		log("MSILO: offline message NOT stored\n");
+		t_reply("503", "Service Unavailable");
+	};
+}
+
+

+ 237 - 0
examples/kamailio/nathelper.cfg

@@ -0,0 +1,237 @@
+#
+# $Id$
+#
+# simple quick-start config script including nathelper support
+
+# This default script includes nathelper support. To make it work
+# you will also have to install Maxim's RTP proxy. The proxy is enforced
+# if one of the parties is behind a NAT.
+#
+# If you have an endpoing in the public internet which is known to
+# support symmetric RTP (Cisco PSTN gateway or voicemail, for example),
+# then you don't have to force RTP proxy. If you don't want to enforce
+# RTP proxy for some destinations than simply use t_relay() instead of
+# route(1)
+#
+# Sections marked with !! Nathelper contain modifications for nathelper
+#
+# NOTE !! This config is EXPERIMENTAL !
+#
+# ----------- global configuration parameters ------------------------
+
+debug=3         # debug level (cmd line: -dddddddddd)
+fork=yes
+log_stderror=no	# (cmd line: -E)
+
+/* Uncomment these lines to enter debugging mode 
+fork=no
+log_stderror=yes
+*/
+
+check_via=no	# (cmd. line: -v)
+dns=no           # (cmd. line: -r)
+rev_dns=no      # (cmd. line: -R)
+port=5060
+children=4
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+# Uncomment this if you want to use SQL database
+#loadmodule "mysql.so"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "mi_fifo.so"
+
+# Uncomment this if you want digest authentication
+# db_mysql.so must be loaded !
+#loadmodule "auth.so"
+#loadmodule "auth_db.so"
+
+# !! Nathelper
+loadmodule "nathelper.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- mi_fifo params --
+
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# -- usrloc params --
+
+modparam("usrloc", "db_mode",   0)
+
+# Uncomment this if you want to use SQL database 
+# for persistent storage and comment the previous line
+#modparam("usrloc", "db_mode", 2)
+
+# -- auth params --
+# Uncomment if you are using auth module
+#
+#modparam("auth_db", "calculate_ha1", yes)
+#
+# If you set "calculate_ha1" parameter to yes (which true in this config), 
+# uncomment also the following parameter)
+#
+#modparam("auth_db", "password_column", "password")
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# !! Nathelper
+modparam("usrloc","nat_bflag",6)
+modparam("nathelper","sipping_bflag",8)
+modparam("nathelper", "ping_nated_only", 1)   # Ping only clients behind NAT
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	# initial sanity checks -- messages with
+	# max_forwards==0, or excessively long requests
+	if (!mf_process_maxfwd_header("10")) {
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	};
+	if (msg:len >=  2048 ) {
+		sl_send_reply("513", "Message too big");
+		exit;
+	};
+
+	# !! Nathelper
+	# Special handling for NATed clients; first, NAT test is
+	# executed: it looks for via!=received and RFC1918 addresses
+	# in Contact (may fail if line-folding is used); also,
+	# the received test should, if completed, should check all
+	# vias for rpesence of received
+	if (nat_uac_test("3")) {
+		# Allow RR-ed requests, as these may indicate that
+		# a NAT-enabled proxy takes care of it; unless it is
+		# a REGISTER
+
+		if (is_method("REGISTER") || !is_present_hf("Record-Route")) {
+		    log("LOG: Someone trying to register from private IP, rewriting\n");
+
+		    # This will work only for user agents that support symmetric
+		    # communication. We tested quite many of them and majority is
+		    # smart enough to be symmetric. In some phones it takes a configuration
+		    # option. With Cisco 7960, it is called NAT_Enable=Yes, with kphone it is
+		    # called "symmetric media" and "symmetric signalling".
+
+		    fix_nated_contact(); # Rewrite contact with source IP of signalling
+		    if ( is_method("INVITE") ) {
+		        fix_nated_sdp("1"); # Add direction=active to SDP
+		    };
+		    force_rport(); # Add rport parameter to topmost Via
+		    setbflag(6);    # Mark as NATed
+			
+			# if you want sip nat pinging
+			# setbflag(8);
+		};
+	};
+
+	# we record-route all messages -- to make sure that
+	# subsequent messages will go through our proxy; that's
+	# particularly good if upstream and downstream entities
+	# use different transport protocol
+	if (!is_method("REGISTER")) record_route();
+
+	# subsequent messages withing a dialog should take the
+	# path determined by record-routing
+	if (loose_route()) {
+		# mark routing logic in request
+		append_hf("P-hint: rr-enforced\r\n"); 
+		route(1);
+		exit;
+	};
+
+	if (!uri==myself) {
+		# mark routing logic in request
+		append_hf("P-hint: outbound\r\n"); 
+		route(1);
+		exit;
+	};
+
+	# if the request is for other domain use UsrLoc
+	# (in case, it does not work, use the following command
+	# with proper names and addresses in it)
+	if (uri==myself) {
+
+		if (method=="REGISTER") {
+
+# Uncomment this if you want to use digest authentication
+#			if (!www_authorize("siphub.org", "subscriber")) {
+#				www_challenge("siphub.org", "0");
+#				return;
+#			};
+
+			save("location");
+			exit;
+		};
+
+		lookup("aliases");
+		if (!uri==myself) {
+			append_hf("P-hint: outbound alias\r\n"); 
+			route(1);
+			exit;
+		};
+
+		# native SIP destinations are handled using our USRLOC DB
+		if (!lookup("location")) {
+			sl_send_reply("404", "Not Found");
+			exit;
+		};
+	};
+	append_hf("P-hint: usrloc applied\r\n"); 
+	route(1);
+}
+
+route[1] 
+{
+	# !! Nathelper
+	if (uri=~"[@:](192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" && !search("^Route:")){
+		sl_send_reply("479", "We don't forward to private IP addresses");
+		exit;
+	};
+
+	# if client or server know to be behind a NAT, enable relay
+	if (isbflagset(6)) {
+		force_rtp_proxy();
+	};
+
+	# NAT processing of replies; apply to all transactions (for example,
+	# re-INVITEs from public to private UA are hard to identify as
+	# NATed at the moment of request processing); look at replies
+	t_on_reply("1");
+
+	# send it out now; use stateful forwarding as it works reliably
+	# even for UDP2TCP
+	if (!t_relay()) {
+		sl_reply_error();
+	};
+}
+
+# !! Nathelper
+onreply_route[1] {
+	# NATed transaction ?
+	if (isbflagset(6) && status =~ "(183)|2[0-9][0-9]") {
+		fix_nated_contact();
+		force_rtp_proxy();
+	# otherwise, is it a transaction behind a NAT and we did not
+	# know at time of request processing ? (RFC1918 contacts)
+	} else if (nat_uac_test("1")) {
+		fix_nated_contact();
+	};
+}
+

+ 148 - 0
examples/kamailio/pstn.cfg

@@ -0,0 +1,148 @@
+#
+# $Id$
+#
+# example: ser configured as PSTN gateway guard; PSTN gateway is located
+# at 192.168.0.10
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "acc.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "db_mysql.so"
+loadmodule "auth.so"
+loadmodule "auth_db.so"
+loadmodule "group.so"
+loadmodule "uri.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+modparam("auth_db", "db_url","mysql://kamailio:kamailiorw@localhost/kamailio")
+modparam("auth_db", "calculate_ha1", yes)
+modparam("auth_db", "password_column", "password")
+
+# -- acc params --
+modparam("acc", "log_level", 1)
+# that is the flag for which we will account -- don't forget to
+# set the same one :-)
+modparam("acc", "log_flag", 1 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	/* ********* ROUTINE CHECKS  ********************************** */
+
+	# filter too old messages
+	if (!mf_process_maxfwd_header("10")) {
+		log("LOG: Too many hops\n");
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	};
+	if (msg:len >=  2048 ) {
+		sl_send_reply("513", "Message too big");
+		exit;
+	};
+
+	/* ********* RR ********************************** */
+
+	/* grant Route routing if route headers present */
+	if (loose_route()) { t_relay(); exit; };
+	
+	/* record-route INVITEs -- all subsequent requests must visit us */
+	if (method=="INVITE") {
+		record_route();
+	};
+
+	# now check if it really is a PSTN destination which should be handled
+	# by our gateway; if not, and the request is an invitation, drop it --
+	# we cannot terminate it in PSTN; relay non-INVITE requests -- it may
+	# be for example BYEs sent by gateway to call originator
+	if (!uri=~"sip:\+?[0-9]+@.*") {
+		if (method=="INVITE") {
+			sl_send_reply("403", "Call cannot be served here");
+		} else {
+			forward();
+		};
+		exit;
+	}; 
+
+	# account completed transactions via syslog
+	setflag(1);
+
+	# free call destinations ... no authentication needed
+	if ( is_user_in("Request-URI", "free-pstn")  /* free destinations */
+			||  uri=~"sip:[79][0-9][0-9][0-9]@.*"  /* local PBX */
+			|| uri=~"sip:98[0-9][0-9][0-9][0-9]") {
+		log("free call");
+	} else if (src_ip==192.168.0.10) {
+		# our gateway doesn't support digest authentication;
+		# verify that a request is coming from it by source
+		# address
+		log("gateway-originated request");
+	} else {
+		# in all other cases, we need to check the request against
+		# access control lists; first of all, verify request
+		# originator's identity
+
+		if (!proxy_authorize(	"gateway" /* realm */,
+				"subscriber" /* table name */))  {
+			proxy_challenge( "gateway" /* realm */, "0" /* no qop */ );
+			exit;
+		};
+
+		# authorize only for INVITEs -- RR/Contact may result in weird
+		# things showing up in d-uri that would break our logic; our
+		# major concern is INVITE which causes PSTN costs 
+
+		if (method=="INVITE") {
+
+			# does the authenticated user have a permission for local
+			# calls (destinations beginning with a single zero)? 
+			# (i.e., is he in the "local" group?)
+			if (uri=~"sip:0[1-9][0-9]+@.*") {
+				if (!is_user_in("credentials", "local")) {
+					sl_send_reply("403", "No permission for local calls"); 
+					exit;
+				};
+			# the same for long-distance (destinations begin with two zeros")
+			} else if (uri=~"sip:00[1-9][0-9]+@.*") {
+				if (!is_user_in("credentials", "ld")) {
+					sl_send_reply("403", " no permission for LD ");
+					exit;
+				};
+			# the same for international calls (three zeros)
+			} else if (uri=~"sip:000[1-9][0-9]+@.*") {
+				if (!is_user_in("credentials", "int")) {
+					sl_send_reply("403", "International permissions needed");
+					exit;
+				};
+			# everything else (e.g., interplanetary calls) is denied
+			} else {
+				sl_send_reply("403", "Forbidden");
+				exit;
+			};
+
+		}; # INVITE to authorized PSTN
+
+	}; # authorized PSTN
+
+	# if you have passed through all the checks, let your call go to GW!
+
+	rewritehostport("192.168.0.10:5060");
+
+	# forward the request now
+	if (!t_relay()) {
+		sl_reply_error(); 
+		exit; 
+	};
+
+}

+ 33 - 0
examples/kamailio/redirect.cfg

@@ -0,0 +1,33 @@
+#
+# $Id$
+#
+# this example shows use of ser as stateless redirect server
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "sl.so"
+
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+	# for testing purposes, simply okay all REGISTERs
+	if (method=="REGISTER") {
+		log("REGISTER");
+		sl_send_reply("200", "ok");
+		return;
+	};
+	# rewrite current URI, which is always part of destination ser
+	rewriteuri("sip:[email protected]:9");
+	# append one more URI to the destination ser
+	append_branch("sip:[email protected]:9");
+	# redirect now
+	sl_send_reply("300", "Redirect");
+}
+

+ 76 - 0
examples/kamailio/replicate.cfg

@@ -0,0 +1,76 @@
+#
+# $Id$
+#
+# demo script showing how to set-up usrloc replication
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3          # debug level (cmd line: -dddddddddd)
+fork=no
+log_stderror=yes # (cmd line: -E)
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "db_mysql.so"
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "auth.so"
+loadmodule "auth_db.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# digest generation secret; use the same in backup server;
+# also, make sure that the backup server has sync'ed time
+modparam("auth", "secret", "alsdkhglaksdhfkloiwr")
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	# initial sanity checks -- messages with
+	# max_forwars==0, or excessively long requests
+	if (!mf_process_maxfwd_header("10")) {
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	};
+	if (msg:len >=  2048 ) {
+		sl_send_reply("513", "Message too big");
+		exit;
+	};
+
+	# if the request is for other domain use UsrLoc
+	# (in case, it does not work, use the following command
+	# with proper names and addresses in it)
+	if (uri==myself) {
+
+		if (method=="REGISTER") {
+
+			# verify credentials
+			if (!www_authorize("foo.bar", "subscriber")) {
+				www_challenge("foo.bar", "0");
+				exit;
+			};
+
+			# if ok, update contacts and ...
+			save("location");
+			# ... if this REGISTER is not a replica from our
+			# peer server, replicate to the peer server
+			if (!src_ip==backup.foo.bar) {
+				t_replicate("sip:backup.foo.bar:5060");
+			};
+			exit;
+		};
+		# do whatever else appropriate for your domain
+		log("non-REGISTER\n");
+	};
+}
+

+ 65 - 0
examples/kamailio/serial_183.cfg

@@ -0,0 +1,65 @@
+#
+# $Id$
+#
+# this example shows how to use forking on failure
+#
+
+log_stderror=1
+fork=no
+listen=192.168.2.16
+debug=3
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+# Uncomment this if you want to use SQL database
+loadmodule "tm.so"
+loadmodule "sl.so"
+loadmodule "maxfwd.so"
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	# initial sanity checks -- messages with
+	# max_forwards==0, or excessively long requests
+	if (!mf_process_maxfwd_header("10")) {
+		sl_send_reply("483","Too Many Hops");
+		exit;
+	};
+	if (msg:len >=  2048 ) {
+		sl_send_reply("513", "Message too big");
+		exit;
+	};
+
+	/* skip register for testing purposes */
+	if (method=="REGISTER") { sl_send_reply("200", "ok"); exit; };
+
+	if (!method=="ACK")
+		log(1, "forwarding now to primary destination\n");
+	if (method=="INVITE") {
+		rewriteuri("sip:[email protected]:5064");
+		# if transaction broken, try other an alternative
+		# route
+		t_on_failure("1");
+		# if a provisional came, stop alternating
+		t_on_reply("1");
+	};
+	t_relay();
+}
+
+failure_route[1] {
+	log(1, "trying at alternate destination\n");
+	append_branch("sip:[email protected]:5064");
+	t_relay();
+}
+
+onreply_route[1] {
+	log(1, "reply came in\n");
+	if (status=~"18[0-9]")  {
+		log(1, "provisional -- resetting negative failure\n");
+		t_on_failure("0");
+	};
+}

+ 11 - 0
examples/kamailio/web_im/README

@@ -0,0 +1,11 @@
+#
+# $Id$
+#
+
+This examle illustrate how to use ser's FIFO interface
+to initate sending an instant message from a webpage.
+
+To enable this example, you need
+- web server with PHP support
+- install the example webpages on the server
+- have running ser with enabled fifo

+ 40 - 0
examples/kamailio/web_im/click_to_dial.html

@@ -0,0 +1,40 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Click-To-Dial
+</title>
+</header>
+
+<body>
+<h1>
+Click-To-Dial (using REFER)
+</h1>
+
+<i>Unfortunately, this example does not work. The reason is use of
+REFER for third-party call-control has not been standardized due
+to resistance of proponents of B2BUA use (which is somewhat bloated
+and not always operational).
+</i>
+
+<form method=POST action=click_to_dial.php>
+<table>
+<tr>
+<td>
+Caller's SIP Address
+<td>
+<input name=caller>
+<tr>
+<td>
+Callee's SIP Address
+<td>
+<input name=callee>
+<tr>
+<td>Click to dial
+<td>
+<input type=submit value=now>
+</table>
+</form>
+
+
+</body>

+ 76 - 0
examples/kamailio/web_im/click_to_dial.php

@@ -0,0 +1,76 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Click-To-Dial
+</title>
+</header>
+
+<body>
+<h1>
+Click-To-Dial
+</h1>
+
+<?php
+
+/* config values */
+$web_contact="sip:[email protected]";
+$fifo="/tmp/kamailio_fifo";
+$signature="web_dialer_0.1.0";
+
+/* open reply fifo */
+$myfilename="webfifo_".rand();
+$mypath="/tmp/".$myfilename;
+$outbound_proxy=".";
+
+
+$caller = $_POST['caller'];
+$callee = $_POST['callee'];
+
+echo "Initiating your request...<p>";
+/* open fifo now */
+$fifo_handle=fopen( $fifo, "w" );
+if (!$fifo_handle) {
+    exit ("Sorry -- cannot open fifo: ".$fifo);
+}
+
+/* construct FIFO command */
+
+$fifo_cmd=":t_uac_dlg:".$myfilename."\n".
+    "REFER\n".
+     $caller."\n".
+	 $outbound_proxy."\n".
+	 ".\n".
+     "\"From: ".$web_contact."\r\n".
+     "To: ".$callee."\r\n".
+     "p-version: ".$signature."\r\n".
+    "Contact: ".$web_contact."\r\n".
+    "Referred-By: ".$web_contact."\r\n".
+	"Refer-To: ".$callee."\r\n".
+	"\"\n\n";
+	
+    
+/* create fifo for replies */
+system("mkfifo -m 666 ".$mypath );
+
+/* write fifo command */
+if (fwrite( $fifo_handle, $fifo_cmd)==-1) {
+    unlink($mypath);
+    fclose($fifo_handle);
+    exit("Sorry -- fifo writing error");
+}
+fclose($fifo_handle);
+
+/* read output now */
+if (readfile( $mypath )==-1) {
+    unlink($mypath);
+	exit("Sorry -- fifo reading error");
+}
+unlink($mypath);
+echo "<p>Thank you for using click-to-dial<p>";
+
+?>
+
+</body>
+</html>
+

+ 37 - 0
examples/kamailio/web_im/send_im.html

@@ -0,0 +1,37 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Send IM
+</title>
+</header>
+
+<body>
+<h1>
+Send IM
+</h1>
+
+<form method=POST action=send_im.php>
+<table>
+<tr>
+<td>
+SIP Address
+<br>
+Example: [email protected]
+<td>
+<input name=sip_address>
+<tr>
+<td>
+Message
+<td>
+<textarea name=instant_message rows=6 cols=40>
+</textarea>
+<tr>
+<td>Click to send
+<td>
+<input type=submit value=submit>
+</table>
+</form>
+
+
+</body>

+ 77 - 0
examples/kamailio/web_im/send_im.php

@@ -0,0 +1,77 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Send IM Status
+</title>
+</header>
+
+<body>
+<h1>
+Send IM Status
+</h1>
+
+<?php
+
+/* config values */
+$web_contact="sip:[email protected]";
+$fifo="/tmp/kamailio_fifo";
+$signature="web_im_0.1.0";
+
+/* open reply fifo */
+$myfilename="webfifo_".rand();
+$mypath="/tmp/".$myfilename;
+$outbound_proxy=".";
+
+
+$sip_address = $_POST['sip_address'];
+$instant_message = $_POST['instant_message'];
+
+
+echo "Initiating your request...<p>";
+
+/* open fifo now */
+$fifo_handle=fopen( $fifo, "w" );
+if (!$fifo_handle) {
+    exit ("Sorry -- cannot open fifo: ".$fifo);
+}
+
+/* construct FIFO command */
+$fifo_cmd=":t_uac_dlg:".$myfilename."\n".
+    "MESSAGE\n".
+    $sip_address."\n".
+	$outbound_proxy."\n".
+    ".\n".
+    "\"From: ".$web_contact."\r\n".
+	"To: ".$sip_address."\r\n".
+	"p-version: ".$signature."\r\n".
+    "Contact: ".$web_contact."\r\n".
+    "Content-Type: text/plain; charset=UTF-8\r\n".
+    "\"\n".
+    "\"".$instant_message."\"".
+  	"\n\n";  
+
+/* create fifo for replies */
+system("mkfifo -m 666 ".$mypath );
+
+/* write fifo command */
+if (fwrite( $fifo_handle, $fifo_cmd)==-1) {
+    unlink($mypath);
+    fclose($fifo_handle);
+    exit("Sorry -- fifo writing error");
+}
+fclose($fifo_handle);
+
+/* read output now */
+if (readfile( $mypath )==-1) {
+    unlink($mypath);
+	exit("Sorry -- fifo reading error");
+}
+unlink($mypath);
+echo "<p>Thank you for using IM<p>";
+
+?>
+
+</body>
+</html>
+

+ 2 - 2
io_wait.c

@@ -29,7 +29,7 @@
 
 
 
-#ifdef USE_TCP /* for now it make sense only with tcp */
+#ifndef NO_IO_WAIT
 
 #ifdef HAVE_EPOLL
 #include <unistd.h> /* close() */
@@ -631,4 +631,4 @@ void destroy_io_wait(io_wait_h* h)
 
 
 
-#endif
+#endif /*ifndef NO_IO_WAIT */

+ 2 - 0
lib/kmi/Makefile

@@ -4,6 +4,8 @@ NAME:=kmi
 MAJOR_VER=1
 MINOR_VER=0
 BUGFIX_VER=0
+## uncomment next line for using system malloc with MI
+#DEFS+= -DMI_SYSTEM_MALLOC
 LIBS=
 
 include ../../Makefile.libs

+ 3 - 3
lib/kmi/attr.c

@@ -36,8 +36,8 @@
 #include <string.h>
 #include <errno.h>
 
-#include "../../mem/mem.h"
 #include "../../dprint.h"
+#include "mi_mem.h"
 #include "attr.h"
 #include "fmt.h"
 
@@ -75,7 +75,7 @@ struct mi_attr *add_mi_attr(struct mi_node *node, int flags,
 		size_mem += value_len;
 	}
 
-	new = (struct mi_attr *)pkg_malloc(size_mem);
+	new = (struct mi_attr *)mi_malloc(size_mem);
 	if (!new) {
 		LM_ERR("no more pkg mem (%d)\n",size_mem);
 		return NULL;
@@ -167,7 +167,7 @@ void del_mi_attr_list(struct mi_node *node)
 
 	for(head = node->attributes; head ;){
 		p = head->next;
-		pkg_free(head);
+		mi_free(head);
 		head = p;
 	}
 

+ 2 - 2
lib/kmi/fmt.c

@@ -34,7 +34,7 @@
 
 #include <string.h>
 #include "../../dprint.h"
-#include "../../mem/mem.h"
+#include "mi_mem.h"
 
 char *mi_fmt_buf = 0;
 int  mi_fmt_buf_len = 0;
@@ -42,7 +42,7 @@ int  mi_fmt_buf_len = 0;
 
 int mi_fmt_init( unsigned int size )
 {
-	mi_fmt_buf = (char*)pkg_malloc(size);
+	mi_fmt_buf = (char*)mi_malloc(size);
 	if (mi_fmt_buf==NULL) {
 		LM_ERR("no more pkg mem\n");
 		return -1;

+ 2 - 2
lib/kmi/mi.c

@@ -46,7 +46,7 @@
 #include <string.h>
 
 #include "../../dprint.h"
-#include "../../mem/mem.h"
+#include "mi_mem.h"
 #include "mi.h"
 
 static struct mi_cmd*  mi_cmds = 0;
@@ -138,7 +138,7 @@ int register_mi_cmd( mi_cmd_f f, char *name, void *param,
 		return -1;
 	}
 
-	cmds = (struct mi_cmd*)pkg_realloc( mi_cmds,
+	cmds = (struct mi_cmd*)mi_realloc( mi_cmds,
 			(mi_cmds_no+1)*sizeof(struct mi_cmd) );
 	if (cmds==0) {
 		LM_ERR("no more pkg memory\n");

+ 49 - 0
lib/kmi/mi_mem.h

@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2009 Daniel-Constantin Mierla
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/*!
+ * \file 
+ * \brief MI_MEM :: MI Memory Management
+ * \ingroup mi
+ */
+
+
+#ifndef _MI_MEM_H_
+#define _MI_MEM_H_
+
+#include "../../mem/shm_mem.h"
+
+#ifdef MI_SYSTEM_MALLOC
+#include <stdlib.h>
+#define mi_malloc malloc
+#define mi_realloc realloc
+#define mi_free free
+#else
+#include "../../mem/mem.h"
+#define mi_malloc pkg_malloc
+#define mi_realloc pkg_realloc
+#define mi_free pkg_free
+#endif
+
+#endif
+

+ 5 - 6
lib/kmi/tree.c

@@ -34,9 +34,8 @@
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
-#include "../../mem/mem.h"
-#include "../../mem/shm_mem.h"
 #include "../../dprint.h"
+#include "mi_mem.h"
 #include "tree.h"
 #include "fmt.h"
 
@@ -50,7 +49,7 @@ struct mi_root *init_mi_tree(unsigned int code, char *reason, int reason_len)
 	if (use_shm)
 		root = (struct mi_root *)shm_malloc(sizeof(struct mi_root));
 	else
-		root = (struct mi_root *)pkg_malloc(sizeof(struct mi_root));
+		root = (struct mi_root *)mi_malloc(sizeof(struct mi_root));
 	if (!root) {
 		LM_ERR("no more pkg mem\n");
 		return NULL;
@@ -83,7 +82,7 @@ static void free_mi_node(struct mi_node *parent)
 		shm_free(parent);
 	} else {
 		del_mi_attr_list(parent);
-		pkg_free(parent);
+		mi_free(parent);
 	}
 }
 
@@ -100,7 +99,7 @@ void free_mi_tree(struct mi_root *parent)
 	if (use_shm)
 		shm_free(parent);
 	else
-		pkg_free(parent);
+		mi_free(parent);
 }
 
 
@@ -135,7 +134,7 @@ static inline struct mi_node *create_mi_node(char *name, int name_len,
 	if (use_shm)
 		new = (struct mi_node *)shm_malloc(size_mem);
 	else
-		new = (struct mi_node *)pkg_malloc(size_mem);
+		new = (struct mi_node *)mi_malloc(size_mem);
 	if(!new) {
 		LM_ERR("no more pkg mem\n");
 		return NULL;

+ 9 - 16
lib/srdb1/schema/gw.xml

@@ -10,7 +10,7 @@
 
 <table id="gw" xmlns:db="http://docbook.org/ns/docbook">
     <name>gw</name>
-    <version>9</version>
+    <version>10</version>
     <type db="mysql">&MYSQL_TABLE_TYPE;</type>
     <description>
         <db:para>This table contains Least Cost Routing Gateway definitions for the LCR module.
@@ -27,6 +27,12 @@
         <type db="dbtext">int,auto</type>
     </column>
 
+    <column id="lcr_id">
+        <name>lcr_id</name>
+        <type>unsigned short</type>
+        <description>LCR instance identifier</description>
+    </column>
+
     <column id="gw_name">
         <name>gw_name</name>
         <type>string</type>
@@ -100,13 +106,6 @@
         <description>Weight of gateway within gw_grp.  Valid values are 1-254.</description>
     </column>
 
-    <column>
-        <name>ping</name>
-        <type>unsigned char</type>
-        <default>0</default>
-        <description>Is gateway eligible for aliveness check (0 = no, 1 = yes)</description>
-    </column>
-
     <column>
         <name>flags</name>
         <type>unsigned int</type>
@@ -115,14 +114,8 @@
     </column>
 
     <index>
-        <name>gw_name_idx</name>
-        <colref linkend="gw_name"/>
-        <unique/>
-    </index>
-
-    <index>
-        <name>grp_id_idx</name>
-        <colref linkend="grp_id"/>
+        <name>lcr_id_idx</name>
+        <colref linkend="lcr_id"/>
     </index>
 
 </table>

+ 9 - 12
lib/srdb1/schema/lcr.xml

@@ -9,7 +9,7 @@
 
 <table id="lcr" xmlns:db="http://docbook.org/ns/docbook">
     <name>lcr</name>
-    <version>2</version>
+    <version>3</version>
     <type db="mysql">&MYSQL_TABLE_TYPE;</type>
     <description>
         <db:para>This table is used by the lcr (Least Cost Routing) rules.
@@ -26,6 +26,12 @@
         <type db="dbtext">int,auto</type>
     </column>
 
+    <column id="lcr_id">
+        <name>lcr_id</name>
+        <type>unsigned short</type>
+        <description>LCR instance identifier</description>
+    </column>
+
     <column id="prefix">
         <name>prefix</name>
         <type>string</type>
@@ -58,17 +64,8 @@
     </column>
 
     <index>
-        <name>prefix_idx</name>
-        <colref linkend="prefix"/>
+        <name>lcr_id_idx</name>
+        <colref linkend="lcr_id"/>
     </index>
 
-    <index>
-        <name>from_uri_idx</name>
-        <colref linkend="from_uri"/>
-    </index>
-
-    <index>
-        <name>grp_id_idx</name>
-        <colref linkend="grp_id"/>
-    </index>
 </table>

+ 8 - 1
main.c

@@ -176,6 +176,7 @@
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
 #endif
+#include "autover.h"
 #include "version.h"
 
 /* define SIG_DEBUG by default */
@@ -186,7 +187,7 @@
 #endif
 
 static char id[]="@(#) $Id$";
-static char* version=SER_FULL_VERSION;
+static char* version=SER_FULL_VERSION " " REPO_VER;
 static char* flags=SER_COMPILE_FLAGS;
 char compiled[]= __TIME__ " " __DATE__ ;
 
@@ -1959,6 +1960,12 @@ try_again:
 		goto error;
 	}
 #endif /* USE_TCP */
+#ifdef USE_SCTP
+	if (sctp_register_cfg()){
+		LOG(L_CRIT, "could not register the sctp configuration\n");
+		goto error;
+	}
+#endif /* USE_SCTP */
 	/*init timer, before parsing the cfg!*/
 	if (init_timer()<0){
 		LOG(L_CRIT, "could not initialize timer, exiting...\n");

+ 0 - 0
modules_k/avpops/Makefile → modules/avpops/Makefile


+ 0 - 0
modules_k/avpops/README → modules/avpops/README


+ 0 - 0
modules_k/avpops/avpops.c → modules/avpops/avpops.c


+ 0 - 0
modules_k/avpops/avpops_db.c → modules/avpops/avpops_db.c


+ 0 - 0
modules_k/avpops/avpops_db.h → modules/avpops/avpops_db.h


+ 0 - 0
modules_k/avpops/avpops_impl.c → modules/avpops/avpops_impl.c


+ 0 - 0
modules_k/avpops/avpops_impl.h → modules/avpops/avpops_impl.h


+ 0 - 0
modules_k/avpops/avpops_parse.c → modules/avpops/avpops_parse.c


+ 0 - 0
modules_k/avpops/avpops_parse.h → modules/avpops/avpops_parse.h


+ 0 - 0
modules_k/avpops/doc/Makefile → modules/avpops/doc/Makefile


+ 0 - 0
modules_k/avpops/doc/avpops.xml → modules/avpops/doc/avpops.xml


+ 0 - 0
modules_k/avpops/doc/avpops_admin.xml → modules/avpops/doc/avpops_admin.xml


+ 16 - 16
modules/carrierroute/README

@@ -854,17 +854,17 @@ domain register {
 +----+---------+--------+-------------+-------+------+---------------+
 | id | carrier | domain | scan_prefix | flags | prob | rewrite_host  |
 +----+---------+--------+-------------+-------+------+---------------+
-| 1  |       1 |      0 | 49          |     0 |  0.5 | de-1.carrier1 |
-| 2  |       1 |      0 | 49          |     0 |  0.5 | de-2.carrier1 |
-| 3  |       1 |      0 | 49          |    16 |    1 | de-3.carrier1 |
-| 4  |       1 |      0 |             |     0 |    1 | gw.carrier1-1 |
-| 5  |       1 |      1 | 49          |     0 |    1 | gw.carrier1-1 |
-| 6  |       1 |      2 |             |     0 |    1 | gw.carrier1-2 |
-| 7  |       1 |      3 |             |     0 |    1 | gw.carrier1-3 |
-| 8  |       2 |      0 | 49          |     0 |  0.5 | de-1.carrier2 |
-| 9  |       2 |      0 | 49          |     0 |  0.5 | de-2.carrier2 |
-| 10 |       2 |      0 |             |     0 |    1 | gw.carrier2   |
-| 11 |       2 |      1 | 49          |     0 |    1 | gw.carrier2   |
+| 1  |       1 |      1 | 49          |     0 |  0.5 | de-1.carrier1 |
+| 2  |       1 |      1 | 49          |     0 |  0.5 | de-2.carrier1 |
+| 3  |       1 |      1 | 49          |    16 |    1 | de-3.carrier1 |
+| 4  |       1 |      1 |             |     0 |    1 | gw.carrier1-1 |
+| 5  |       1 |      2 | 49          |     0 |    1 | gw.carrier1-1 |
+| 6  |       1 |      3 |             |     0 |    1 | gw.carrier1-2 |
+| 7  |       1 |      4 |             |     0 |    1 | gw.carrier1-3 |
+| 8  |       2 |      1 | 49          |     0 |  0.5 | de-1.carrier2 |
+| 9  |       2 |      1 | 49          |     0 |  0.5 | de-2.carrier2 |
+| 10 |       2 |      1 |             |     0 |    1 | gw.carrier2   |
+| 11 |       2 |      2 | 49          |     0 |    1 | gw.carrier2   |
 | 12 |       3 |      8 | 49          |     0 |    1 | de-gw.default |
 | 13 |       3 |      8 |             |     0 |    1 | gw.default    |
 +----+---------+--------+-------------+-------+------+---------------+
@@ -875,9 +875,9 @@ domain register {
    and carrier 1. The gateways for the default carrier will be
    used for functions that don't support the user specific carrier
    lookup. The routing rules for carrier 1 and carrier 2 for the
-   "49" prefix contains a additional rule with the domain 1, that
-   can be used for example as fallback if the gateways in domain 0
-   are not reachable. Two more fallback rules (domain 2 and 3) for
+   "49" prefix contains a additional rule with the domain 2, that
+   can be used for example as fallback if the gateways in domain 1
+   are not reachable. Two more fallback rules (domain 3 and 4) for
    carrier 1 are also supplied to support the functionality of the
    carrierfailureroute table example that is provided in the next
    section.
@@ -894,8 +894,8 @@ domain register {
 +----+---------+--------+---------------+------------+-------------+
 | id | carrier | domain | host_name     | reply_code | next_domain |
 +----+---------+--------+---------------+------------+-------------+
-|  1 |       1 | 0      | gw.carrier1-2 | ...        | 3           |
-|  2 |       1 | 0      | gw.carrier1-3 | ...        | 2           |
+|  1 |       1 | 1      | gw.carrier1-2 | ...        | 3           |
+|  2 |       1 | 1      | gw.carrier1-3 | ...        | 2           |
 +----+---------+--------+---------------+------------+-------------+
 ...
 

+ 14 - 8
modules/carrierroute/cr_fifo.c

@@ -155,14 +155,14 @@ struct mi_root* dump_fifo (struct mi_root* cmd_tree, void *param) {
 					node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for domain '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i]->domains[j]->id);
 					if(node == NULL)
 						goto error;
- 					dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->domains[j]->tree, "");
-				}
+					if (dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->domains[j]->tree, "") < 0) 
+						goto error;
+ 				}
  			}
 		}
 	}
 	release_data (rd);
 	return rpl_tree;
-	return 0;
 
 error:
 	release_data (rd);
@@ -394,7 +394,7 @@ struct mi_root* delete_host (struct mi_root* cmd_tree, void * param) {
  * @param node pointer to the routing tree node
  * @param prefix carries the current scan prefix
  *
- * @return mi node containing the route rules
+ * @return 0 for success, negative result for error 
  */
 static int dump_tree_recursor (struct mi_node* msg, struct dtrie_node_t *node, char *prefix) {
 	char s[256];
@@ -404,6 +404,7 @@ static int dump_tree_recursor (struct mi_node* msg, struct dtrie_node_t *node, c
 	struct route_rule *rr;
 	struct route_rule_p_list * rl;
 	double prob;
+	struct mi_node* tmp_node = NULL;
 
 	strcpy (s, prefix);
 	p = s + strlen (s);
@@ -411,7 +412,9 @@ static int dump_tree_recursor (struct mi_node* msg, struct dtrie_node_t *node, c
 	for (i = 0; i < cr_match_mode; ++i) {
 		if (node->child[i] != NULL) {
 			*p = i + '0';
-			dump_tree_recursor (msg->next, node->child[i], s);
+			/* if there is a problem in processing the child nodes .. return an error */
+			if(dump_tree_recursor (msg->next, node->child[i], s) < 0)
+				return -1;
 		}
 	}
 	*p = '\0';
@@ -422,21 +425,24 @@ static int dump_tree_recursor (struct mi_node* msg, struct dtrie_node_t *node, c
 			} else {
 				prob = rr->prob;
 			}
-			addf_mi_node_child(msg->next, 0, 0, 0, "%10s: %0.3f %%, '%.*s': %s, '%i', '%.*s', '%.*s', '%.*s'\n",
+			tmp_node = addf_mi_node_child(msg->next, 0, 0, 0, "%10s: %0.3f %%, '%.*s': %s, '%i', '%.*s', '%.*s', '%.*s'\n",
 												 strlen(prefix) > 0 ? prefix : "NULL", prob * 100, rr->host.len, rr->host.s,
 												 (rr->status ? "ON" : "OFF"), rr->strip,
 												 rr->local_prefix.len, rr->local_prefix.s,
 												 rr->local_suffix.len, rr->local_suffix.s,
 												 rr->comment.len, rr->comment.s);
+			if(!tmp_node) return -1;
 			if(!rr->status && rr->backup && rr->backup->rr){
-				addf_mi_node_child(msg->next, 0, 0, 0, "            Rule is backed up by: %.*s\n", rr->backup->rr->host.len, rr->backup->rr->host.s);
+				tmp_node = addf_mi_node_child(msg->next, 0, 0, 0, "            Rule is backed up by: %.*s\n", rr->backup->rr->host.len, rr->backup->rr->host.s);
+				if(!tmp_node) return -1;
 			}
 			if(rr->backed_up){
 				rl = rr->backed_up;
 				i=0;
 				while(rl){
 					if(rl->rr){
-						addf_mi_node_child(msg->next, 0, 0, 0, "            Rule is backup for: %.*s", rl->rr->host.len, rl->rr->host.s);
+						tmp_node = addf_mi_node_child(msg->next, 0, 0, 0, "            Rule is backup for: %.*s", rl->rr->host.len, rl->rr->host.s);
+						if(!tmp_node) return -1;
 					}
 					rl = rl->next;
 					i++;

+ 15 - 15
modules/carrierroute/doc/carrierroute_admin.xml

@@ -1000,17 +1000,17 @@ domain register {
 +----+---------+--------+-------------+-------+------+---------------+
 | id | carrier | domain | scan_prefix | flags | prob | rewrite_host  |
 +----+---------+--------+-------------+-------+------+---------------+
-| 1  |       1 |      0 | 49          |     0 |  0.5 | de-1.carrier1 |
-| 2  |       1 |      0 | 49          |     0 |  0.5 | de-2.carrier1 |
-| 3  |       1 |      0 | 49          |    16 |    1 | de-3.carrier1 |
-| 4  |       1 |      0 |             |     0 |    1 | gw.carrier1-1 |
-| 5  |       1 |      1 | 49          |     0 |    1 | gw.carrier1-1 |
-| 6  |       1 |      2 |             |     0 |    1 | gw.carrier1-2 |
-| 7  |       1 |      3 |             |     0 |    1 | gw.carrier1-3 |
-| 8  |       2 |      0 | 49          |     0 |  0.5 | de-1.carrier2 |
-| 9  |       2 |      0 | 49          |     0 |  0.5 | de-2.carrier2 |
-| 10 |       2 |      0 |             |     0 |    1 | gw.carrier2   |
-| 11 |       2 |      1 | 49          |     0 |    1 | gw.carrier2   |
+| 1  |       1 |      1 | 49          |     0 |  0.5 | de-1.carrier1 |
+| 2  |       1 |      1 | 49          |     0 |  0.5 | de-2.carrier1 |
+| 3  |       1 |      1 | 49          |    16 |    1 | de-3.carrier1 |
+| 4  |       1 |      1 |             |     0 |    1 | gw.carrier1-1 |
+| 5  |       1 |      2 | 49          |     0 |    1 | gw.carrier1-1 |
+| 6  |       1 |      3 |             |     0 |    1 | gw.carrier1-2 |
+| 7  |       1 |      4 |             |     0 |    1 | gw.carrier1-3 |
+| 8  |       2 |      1 | 49          |     0 |  0.5 | de-1.carrier2 |
+| 9  |       2 |      1 | 49          |     0 |  0.5 | de-2.carrier2 |
+| 10 |       2 |      1 |             |     0 |    1 | gw.carrier2   |
+| 11 |       2 |      2 | 49          |     0 |    1 | gw.carrier2   |
 | 12 |       3 |      8 | 49          |     0 |    1 | de-gw.default |
 | 13 |       3 |      8 |             |     0 |    1 | gw.default    |
 +----+---------+--------+-------------+-------+------+---------------+
@@ -1023,8 +1023,8 @@ domain register {
 			gateways for the default carrier will be used for functions that don't
 			support the user specific carrier lookup. The routing rules for carrier 1
 			and carrier 2 for the <quote>49</quote> prefix contains a additional rule
-			with the domain 1, that can be used for example as fallback if the gateways
-			in domain 0 are not reachable. Two more fallback rules (domain 2 and 3) for 
+			with the domain 2, that can be used for example as fallback if the gateways
+			in domain 1 are not reachable. Two more fallback rules (domain 3 and 4) for 
 			carrier 1 are also supplied to support the functionality of the carrierfailureroute
 			table example that is provided in the next section.
 		</para>
@@ -1041,8 +1041,8 @@ domain register {
 +----+---------+--------+---------------+------------+-------------+
 | id | carrier | domain | host_name     | reply_code | next_domain |
 +----+---------+--------+---------------+------------+-------------+
-|  1 |       1 | 0      | gw.carrier1-2 | ...        | 3           |
-|  2 |       1 | 0      | gw.carrier1-3 | ...        | 2           |
+|  1 |       1 | 1      | gw.carrier1-2 | ...        | 3           |
+|  2 |       1 | 1      | gw.carrier1-3 | ...        | 2           |
 +----+---------+--------+---------------+------------+-------------+
 ...
 </programlisting>

+ 345 - 261
modules/lcr/README

@@ -10,7 +10,7 @@ Juha Heinanen
 
    <[email protected]>
 
-   Copyright © 2005-2008 Juha Heinanen
+   Copyright © 2005-2009 Juha Heinanen
    Revision History
    Revision $Revision$ $Date$
      __________________________________________________________________
@@ -22,43 +22,48 @@ Juha Heinanen
         1. Overview
         2. Dependencies
 
-              2.1. Kamailio modules
+              2.1. SIP Router modules
               2.2. External libraries or applications
 
         3. Exported Parameters
 
               3.1. db_url (string)
               3.2. gw_table (string)
-              3.3. gw_name_column (string)
-              3.4. grp_id_column (string)
-              3.5. ip_addr_column (string)
-              3.6. hostname_column (string)
-              3.7. port_column (string)
-              3.8. uri_scheme_column (string)
-              3.9. transport_column (string)
-              3.10. strip_column (string)
-              3.11. tag_column (string)
-              3.12. weight_column (string)
-              3.13. flags_column (string)
-              3.14. lcr_table (string)
-              3.15. prefix_column (string)
-              3.16. from_uri_column (string)
-              3.17. priority_column (string)
-              3.18. gw_uri_avp (AVP string)
-              3.19. rpid_avp (AVP string)
-              3.20. ruri_user_avp (AVP string)
-              3.21. flags_avp (AVP string)
-              3.22. lcr_hash_size (integer)
-              3.23. fetch_rows (integer)
+              3.3. lcr_id_column (string)
+              3.4. gw_name_column (string)
+              3.5. grp_id_column (string)
+              3.6. ip_addr_column (string)
+              3.7. hostname_column (string)
+              3.8. port_column (string)
+              3.9. uri_scheme_column (string)
+              3.10. transport_column (string)
+              3.11. strip_column (string)
+              3.12. tag_column (string)
+              3.13. weight_column (string)
+              3.14. flags_column (string)
+              3.15. lcr_table (string)
+              3.16. prefix_column (string)
+              3.17. from_uri_column (string)
+              3.18. priority_column (string)
+              3.19. lcr_count (integer)
+              3.20. gw_uri_avp (AVP string)
+              3.21. ruri_user_avp (AVP string)
+              3.22. flags_avp (AVP string)
+              3.23. defunct_capability (integer)
+              3.24. lcr_id_avp (AVP string)
+              3.25. defunct_gw_avp (AVP string)
+              3.26. lcr_hash_size (integer)
+              3.27. fetch_rows (integer)
 
         4. Exported Functions
 
-              4.1. load_gws([pvar])
-              4.2. load_gws_from_grp(group-id)
-              4.3. next_gw()
-              4.4. from_gw([pvar])
-              4.5. from_gw_grp(group-id)
-              4.6. to_gw([group-id])
+              4.1. load_gws(lcr_id, caller_uri)
+              4.2. next_gw()
+              4.3. defunct_gw(period)
+              4.4. from_gw(lcr_id [, ip_addr])
+              4.5. from_any_gw([ip_addr])
+              4.6. to_gw(lcr_id [, ip_addr])
+              4.7. to_any_gw([ip_addr])
 
         5. Exported MI Commands
 
@@ -70,7 +75,7 @@ Juha Heinanen
 
               6.1. lcr.reload
               6.2. lcr.dump_gws
-              6.3. lcr.dump_lcr
+              6.3. lcr.dump_lcrs
 
         7. Known Limitations
 
@@ -78,39 +83,42 @@ Juha Heinanen
 
    1.1. Setting db_url module parameter
    1.2. Setting gw_table module parameter
-   1.3. Setting gw_name_column module parameter
-   1.4. Setting grp_id_column module parameter
-   1.5. Setting ip_addr_column module parameter
-   1.6. Setting hostname_column module parameter
-   1.7. Setting port_column module parameter
-   1.8. Setting uri_scheme_column module parameter
-   1.9. Setting transport_column module parameter
-   1.10. Setting strip_column module parameter
-   1.11. Setting tag_column module parameter
-   1.12. Setting weight_column module parameter
-   1.13. Setting flags_column module parameter
-   1.14. Setting lcr_table module parameter
-   1.15. Setting prefix_column module parameter
-   1.16. Setting from_uri_column module parameter
-   1.17. Setting priority_column module parameter
-   1.18. Setting gw_uri_avp module parameter
-   1.19. Setting rpid_avp module parameter
-   1.20. Setting ruri_user_avp module parameter
-   1.21. Setting flags_avp module parameter
-   1.22. Setting lcr_hash_size module parameter
-   1.23. Set fetch_rows parameter
-   1.24. load_gws usage
-   1.25. load_gws_from_grp usage
-   1.26. next_gw usage from a route block
-   1.27. next_gw usage from a failure route block
-   1.28. from_gw usage
-   1.29. from_gw usage with pseudo variable argument
-   1.30. from_gw_grp usage
-   1.31. to_gw usage
-   1.32. to_gw usage with group-id
-   1.33. lcr.reload RPC example
-   1.34. lcr.dump_gws RPC example
-   1.35. lcr.dump_lcr RPC example
+   1.3. Setting lcr_id_column module parameter
+   1.4. Setting gw_name_column module parameter
+   1.5. Setting grp_id_column module parameter
+   1.6. Setting ip_addr_column module parameter
+   1.7. Setting hostname_column module parameter
+   1.8. Setting port_column module parameter
+   1.9. Setting uri_scheme_column module parameter
+   1.10. Setting transport_column module parameter
+   1.11. Setting strip_column module parameter
+   1.12. Setting tag_column module parameter
+   1.13. Setting weight_column module parameter
+   1.14. Setting flags_column module parameter
+   1.15. Setting lcr_table module parameter
+   1.16. Setting prefix_column module parameter
+   1.17. Setting from_uri_column module parameter
+   1.18. Setting priority_column module parameter
+   1.19. Setting lcr_count module parameter
+   1.20. Setting gw_uri_avp module parameter
+   1.21. Setting ruri_user_avp module parameter
+   1.22. Setting flags_avp module parameter
+   1.23. Setting defunct_capability module parameter
+   1.24. Setting lcr_id_avp module parameter
+   1.25. Setting defunct_gw_avp module parameter
+   1.26. Setting lcr_hash_size module parameter
+   1.27. Set fetch_rows parameter
+   1.28. load_gws usage
+   1.29. next_gw usage from a route block
+   1.30. next_gw usage from a failure route block
+   1.31. defunct_gw usage
+   1.32. from_gw usage
+   1.33. from_gw usage
+   1.34. to_gw usage
+   1.35. to_gw usage
+   1.36. lcr.reload RPC example
+   1.37. lcr.dump_gws RPC example
+   1.38. lcr.dump_lcr RPC example
 
 Chapter 1. Admin Guide
 
@@ -119,43 +127,48 @@ Chapter 1. Admin Guide
    1. Overview
    2. Dependencies
 
-        2.1. Kamailio modules
+        2.1. SIP Router modules
         2.2. External libraries or applications
 
    3. Exported Parameters
 
         3.1. db_url (string)
         3.2. gw_table (string)
-        3.3. gw_name_column (string)
-        3.4. grp_id_column (string)
-        3.5. ip_addr_column (string)
-        3.6. hostname_column (string)
-        3.7. port_column (string)
-        3.8. uri_scheme_column (string)
-        3.9. transport_column (string)
-        3.10. strip_column (string)
-        3.11. tag_column (string)
-        3.12. weight_column (string)
-        3.13. flags_column (string)
-        3.14. lcr_table (string)
-        3.15. prefix_column (string)
-        3.16. from_uri_column (string)
-        3.17. priority_column (string)
-        3.18. gw_uri_avp (AVP string)
-        3.19. rpid_avp (AVP string)
-        3.20. ruri_user_avp (AVP string)
-        3.21. flags_avp (AVP string)
-        3.22. lcr_hash_size (integer)
-        3.23. fetch_rows (integer)
+        3.3. lcr_id_column (string)
+        3.4. gw_name_column (string)
+        3.5. grp_id_column (string)
+        3.6. ip_addr_column (string)
+        3.7. hostname_column (string)
+        3.8. port_column (string)
+        3.9. uri_scheme_column (string)
+        3.10. transport_column (string)
+        3.11. strip_column (string)
+        3.12. tag_column (string)
+        3.13. weight_column (string)
+        3.14. flags_column (string)
+        3.15. lcr_table (string)
+        3.16. prefix_column (string)
+        3.17. from_uri_column (string)
+        3.18. priority_column (string)
+        3.19. lcr_count (integer)
+        3.20. gw_uri_avp (AVP string)
+        3.21. ruri_user_avp (AVP string)
+        3.22. flags_avp (AVP string)
+        3.23. defunct_capability (integer)
+        3.24. lcr_id_avp (AVP string)
+        3.25. defunct_gw_avp (AVP string)
+        3.26. lcr_hash_size (integer)
+        3.27. fetch_rows (integer)
 
    4. Exported Functions
 
-        4.1. load_gws([pvar])
-        4.2. load_gws_from_grp(group-id)
-        4.3. next_gw()
-        4.4. from_gw([pvar])
-        4.5. from_gw_grp(group-id)
-        4.6. to_gw([group-id])
+        4.1. load_gws(lcr_id, caller_uri)
+        4.2. next_gw()
+        4.3. defunct_gw(period)
+        4.4. from_gw(lcr_id [, ip_addr])
+        4.5. from_any_gw([ip_addr])
+        4.6. to_gw(lcr_id [, ip_addr])
+        4.7. to_any_gw([ip_addr])
 
    5. Exported MI Commands
 
@@ -167,7 +180,7 @@ Chapter 1. Admin Guide
 
         6.1. lcr.reload
         6.2. lcr.dump_gws
-        6.3. lcr.dump_lcr
+        6.3. lcr.dump_lcrs
 
    7. Known Limitations
 
@@ -175,14 +188,17 @@ Chapter 1. Admin Guide
 
    Least cost routing (LCR) module implements capability to serially
    forward a request to one or more gateways so that the order in which
-   the gateways is tried is based on admin defined "least cost".
+   the gateways is tried is based on admin defined "least cost" rules.
+
+   LCR module supports many independent LCR instances (gateways and least
+   cost rules). Each such instance has its own LCR identifier.
 
    For the purpose of facilitating least cost routing of requests, each
-   gateway belongs to a gateway group and each gateway group is associated
-   with one or more <prefix, from pattern, priority> tuples. A gateway
-   matches a request if user part of Request URI matches a prefix and
-   caller's URI matches a from pattern in a tuple that belongs to the
-   group of the gateway.
+   gateway of an LCR instance belongs to a gateway group and each gateway
+   group is associated with one or more <prefix, from pattern, priority>
+   tuples. A gateway matches a request if user part of Request URI matches
+   a prefix and caller's URI matches a from pattern in a tuple that
+   belongs to the group of the gateway.
 
    When function load_gws() is called, matching gateways are ordered for
    forwarding purpose (1) according to longest user part match, (2)
@@ -214,10 +230,10 @@ Chapter 1. Admin Guide
 
 2. Dependencies
 
-   2.1. Kamailio modules
+   2.1. SIP Router modules
    2.2. External libraries or applications
 
-2.1. Kamailio modules
+2.1. SIP Router modules
 
    The following modules must be loaded before this module:
      * TM module
@@ -226,34 +242,38 @@ Chapter 1. Admin Guide
 2.2. External libraries or applications
 
    The following libraries or applications must be installed before
-   running Kamailio with this module:
+   running SIP Router with this module:
      * none.
 
 3. Exported Parameters
 
    3.1. db_url (string)
    3.2. gw_table (string)
-   3.3. gw_name_column (string)
-   3.4. grp_id_column (string)
-   3.5. ip_addr_column (string)
-   3.6. hostname_column (string)
-   3.7. port_column (string)
-   3.8. uri_scheme_column (string)
-   3.9. transport_column (string)
-   3.10. strip_column (string)
-   3.11. tag_column (string)
-   3.12. weight_column (string)
-   3.13. flags_column (string)
-   3.14. lcr_table (string)
-   3.15. prefix_column (string)
-   3.16. from_uri_column (string)
-   3.17. priority_column (string)
-   3.18. gw_uri_avp (AVP string)
-   3.19. rpid_avp (AVP string)
-   3.20. ruri_user_avp (AVP string)
-   3.21. flags_avp (AVP string)
-   3.22. lcr_hash_size (integer)
-   3.23. fetch_rows (integer)
+   3.3. lcr_id_column (string)
+   3.4. gw_name_column (string)
+   3.5. grp_id_column (string)
+   3.6. ip_addr_column (string)
+   3.7. hostname_column (string)
+   3.8. port_column (string)
+   3.9. uri_scheme_column (string)
+   3.10. transport_column (string)
+   3.11. strip_column (string)
+   3.12. tag_column (string)
+   3.13. weight_column (string)
+   3.14. flags_column (string)
+   3.15. lcr_table (string)
+   3.16. prefix_column (string)
+   3.17. from_uri_column (string)
+   3.18. priority_column (string)
+   3.19. lcr_count (integer)
+   3.20. gw_uri_avp (AVP string)
+   3.21. ruri_user_avp (AVP string)
+   3.22. flags_avp (AVP string)
+   3.23. defunct_capability (integer)
+   3.24. lcr_id_avp (AVP string)
+   3.25. defunct_gw_avp (AVP string)
+   3.26. lcr_hash_size (integer)
+   3.27. fetch_rows (integer)
 
 3.1. db_url (string)
 
@@ -268,7 +288,7 @@ modparam("lcr","db_url","dbdriver://username:password@dbhost/dbname")
 
 3.2. gw_table (string)
 
-   Name of the table holding the gateways definitions.
+   Name of the table holding gateways definitions.
 
    Default value is "gw".
 
@@ -277,41 +297,53 @@ modparam("lcr","db_url","dbdriver://username:password@dbhost/dbname")
 modparam("lcr","gw_table","gw")
 ...
 
-3.3. gw_name_column (string)
+3.3. lcr_id_column (string)
+
+   Name of the column holding the identifier of LCR instance. Common to
+   both gw and lcr tables.
+
+   Default value is "lcr_id".
+
+   Example 1.3. Setting lcr_id_column module parameter
+...
+modparam("lcr", "lcr_id_column", "lcr_identifier")
+...
+
+3.4. gw_name_column (string)
 
    Name of the column holding the gateway name.
 
    Default value is "gw_name".
 
-   Example 1.3. Setting gw_name_column module parameter
+   Example 1.4. Setting gw_name_column module parameter
 ...
 modparam("lcr","gw_name_column","gw_name")
 ...
 
-3.4. grp_id_column (string)
+3.5. grp_id_column (string)
 
    Name of the column holding the group ID of gateway both in gw and lcr
    tables.
 
    Default value is "grp_id".
 
-   Example 1.4. Setting grp_id_column module parameter
+   Example 1.5. Setting grp_id_column module parameter
 ...
 modparam("lcr","grp_id_column","grp_id")
 ...
 
-3.5. ip_addr_column (string)
+3.6. ip_addr_column (string)
 
    Name of the column holding the IP address of the gateway.
 
    Default value is "ip_addr".
 
-   Example 1.5. Setting ip_addr_column module parameter
+   Example 1.6. Setting ip_addr_column module parameter
 ...
 modparam("lcr","ip_addr_column","ip_addr")
 ...
 
-3.6. hostname_column (string)
+3.7. hostname_column (string)
 
    Name of the column holding gateway's hostname that is used in
    Request-URI, when request is sent to the gateway. Note that request is
@@ -320,186 +352,223 @@ modparam("lcr","ip_addr_column","ip_addr")
 
    Default value is "hostname".
 
-   Example 1.6. Setting hostname_column module parameter
+   Example 1.7. Setting hostname_column module parameter
 ...
 modparam("lcr", "hostname_column","host")
 ...
 
-3.7. port_column (string)
+3.8. port_column (string)
 
    Name of the column holding the port number of the gateway.
 
    Default value is "port".
 
-   Example 1.7. Setting port_column module parameter
+   Example 1.8. Setting port_column module parameter
 ...
 modparam("lcr","port_column","port")
 ...
 
-3.8. uri_scheme_column (string)
+3.9. uri_scheme_column (string)
 
    Name of the column holding the uri scheme of the gateway.
 
    Default value is "uri_scheme".
 
-   Example 1.8. Setting uri_scheme_column module parameter
+   Example 1.9. Setting uri_scheme_column module parameter
 ...
 modparam("lcr","uri_scheme_column","scheme")
 ...
 
-3.9. transport_column (string)
+3.10. transport_column (string)
 
    Name of the column holding the transport type to be used for the
    gateway.
 
    Default value is "transport".
 
-   Example 1.9. Setting transport_column module parameter
+   Example 1.10. Setting transport_column module parameter
 ...
 modparam("lcr","transport_column","transport")
 ...
 
-3.10. strip_column (string)
+3.11. strip_column (string)
 
    Name of the column holding the number of characters to be stripped from
    the front of Request URI user part before inserting tag.
 
    Default value is "strip".
 
-   Example 1.10. Setting strip_column module parameter
+   Example 1.11. Setting strip_column module parameter
 ...
 modparam("lcr","strip_column","strip_count")
 ...
 
-3.11. tag_column (string)
+3.12. tag_column (string)
 
    Name of the column holding gateway specific tag string.
 
    Default value is "tag".
 
-   Example 1.11. Setting tag_column module parameter
+   Example 1.12. Setting tag_column module parameter
 ...
 modparam("lcr","tag_column","gw_tag")
 ...
 
-3.12. weight_column (string)
+3.13. weight_column (string)
 
    Name of the column holding gateway's weight within its group.
 
    Default value is "weight".
 
-   Example 1.12. Setting weight_column module parameter
+   Example 1.13. Setting weight_column module parameter
 ...
 modparam("lcr","weight_column","gw_weight")
 ...
 
-3.13. flags_column (string)
+3.14. flags_column (string)
 
    Name of the column holding gateway specific flag values.
 
    Default value is "flags".
 
-   Example 1.13. Setting flags_column module parameter
+   Example 1.14. Setting flags_column module parameter
 ...
 modparam("lcr","flags_column","gw_flags")
 ...
 
-3.14. lcr_table (string)
+3.15. lcr_table (string)
 
    Name of the table holding the LCR rules.
 
    Default value is "lcr".
 
-   Example 1.14. Setting lcr_table module parameter
+   Example 1.15. Setting lcr_table module parameter
 ...
 modparam("lcr","lcr_table","lcr")
 ...
 
-3.15. prefix_column (string)
+3.16. prefix_column (string)
 
    Name of the column holding prefix of Request URI user part.
 
    Default value is "prefix".
 
-   Example 1.15. Setting prefix_column module parameter
+   Example 1.16. Setting prefix_column module parameter
 ...
 modparam("lcr","prefix_column","prefix")
 ...
 
-3.16. from_uri_column (string)
+3.17. from_uri_column (string)
 
    Name of the column holding the FROM (source) URI.
 
    Default value is "from_uri".
 
-   Example 1.16. Setting from_uri_column module parameter
+   Example 1.17. Setting from_uri_column module parameter
 ...
 modparam("lcr","from_uri_column","from_uri")
 ...
 
-3.17. priority_column (string)
+3.18. priority_column (string)
 
    Name of the column holding the priority of the rule.
 
    Default value is "priority".
 
-   Example 1.17. Setting priority_column module parameter
+   Example 1.18. Setting priority_column module parameter
 ...
 modparam("lcr","priority_column","priority")
 ...
 
-3.18. gw_uri_avp (AVP string)
+3.19. lcr_count (integer)
 
-   Internal AVP that load_gws function uses to store information of
-   matching gateways.
+   Number of LCR instances.
 
-   There is NO default value, thus this variable must be defined in
-   kamailio.cfg.
+   Default value is 1.
 
-   Example 1.18. Setting gw_uri_avp module parameter
+   Example 1.19.  Setting lcr_count module parameter
 ...
-modparam("lcr", "gw_uri_avp", "$avp(i:709)")
+modparam("lcr", "lcr_count", 10)
 ...
 
-3.19. rpid_avp (AVP string)
+3.20. gw_uri_avp (AVP string)
 
-   An AVP that contains caller's RPID (if any).
+   Internal AVP that load_gws() function uses to store information of
+   matching gateways.
 
    There is NO default value, thus this variable must be defined in
-   kamailio.cfg.
+   sip-router.cfg.
 
-   Example 1.19. Setting rpid_avp module parameter
+   Example 1.20. Setting gw_uri_avp module parameter
 ...
-modparam("^auth$|lcr", "rpid_avp", "$avp(i:302)")
+modparam("lcr", "gw_uri_avp", "$avp(i:709)")
 ...
 
-3.20. ruri_user_avp (AVP string)
+3.21. ruri_user_avp (AVP string)
 
    Internal AVP that next_gw function uses to store Request-URI user for
    subsequent next_gw calls.
 
    There is NO default value, thus this variable must be defined in
-   kamailio.cfg.
+   sip-router.cfg.
 
-   Example 1.20. Setting ruri_user_avp module parameter
+   Example 1.21. Setting ruri_user_avp module parameter
 ...
 modparam("lcr", "ruri_user_avp", "$avp(i:500)")
 ...
 
-3.21. flags_avp (AVP string)
+3.22. flags_avp (AVP string)
 
    An AVP where successful next_gw and from_gw functions store gateway's
    flags.
 
    There is NO default value, thus this variable must be defined in
-   kamailio.cfg.
+   sip-router.cfg.
 
-   Example 1.21. Setting flags_avp module parameter
+   Example 1.22. Setting flags_avp module parameter
 ...
 modparam("lcr", "flags_avp", "$avp(i:712)")
 ...
 
-3.22. lcr_hash_size (integer)
+3.23. defunct_capability (integer)
+
+   Tells if defunct capability of (non-responsive) gateways is supported.
+   Non-zero value turns on defunct capability.
+
+   Default value is 0.
+
+   Example 1.23.  Setting defunct_capability module parameter
+...
+modparam("lcr", "defunct_capability", 1)
+...
+
+3.24. lcr_id_avp (AVP string)
+
+   Internal AVP that load_gws() function uses to store LCR instance
+   identifier of loaded gateways. Only needed if gateway defunct
+   capability has been activated.
+
+   There is NO default value.
+
+   Example 1.24. Setting lcr_id_avp module parameter
+...
+modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
+...
+
+3.25. defunct_gw_avp (AVP string)
+
+   Internal AVP that next_gw() function uses to store IP address of the
+   selected gateway for later use by defunct_gw() function. Only needed if
+   gateway defunct capability has been activated.
+
+   There is NO default value.
+
+   Example 1.25. Setting defunct_gw_avp module parameter
+...
+modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
+...
+
+3.26. lcr_hash_size (integer)
 
    Defines the size of hash table used to store <prefix, from_pattern,
    priority> tuples. Hashing is done based on prefix. Larger value means
@@ -508,12 +577,12 @@ modparam("lcr", "flags_avp", "$avp(i:712)")
 
    Default value is 128.
 
-   Example 1.22.  Setting lcr_hash_size module parameter
+   Example 1.26.  Setting lcr_hash_size module parameter
 ...
 modparam("lcr", "lcr_hash_size", 1024)
 ...
 
-3.23. fetch_rows (integer)
+3.27. fetch_rows (integer)
 
    The number of the rows to be fetched at once from database when loading
    data from lcr table. This value can be used to tune the load time at
@@ -523,72 +592,46 @@ modparam("lcr", "lcr_hash_size", 1024)
 
    Default value is "2000".
 
-   Example 1.23. Set fetch_rows parameter
+   Example 1.27. Set fetch_rows parameter
 ...
 modparam("lcr", "fetch_rows", 3000)
 ...
 
 4. Exported Functions
 
-   4.1. load_gws([pvar])
-   4.2. load_gws_from_grp(group-id)
-   4.3. next_gw()
-   4.4. from_gw([pvar])
-   4.5. from_gw_grp(group-id)
-   4.6. to_gw([group-id])
+   4.1. load_gws(lcr_id, caller_uri)
+   4.2. next_gw()
+   4.3. defunct_gw(period)
+   4.4. from_gw(lcr_id [, ip_addr])
+   4.5. from_any_gw([ip_addr])
+   4.6. to_gw(lcr_id [, ip_addr])
+   4.7. to_any_gw([ip_addr])
 
-4.1.  load_gws([pvar])
+4.1.  load_gws(lcr_id, caller_uri)
 
    Loads URI schemes, IP addresses, hostnames, ports, and transports of
-   matching gateways to gw_uri_avp (see Overview section). If optional
-   pseudo variable argument is included, caller's URI is taken from it. If
-   pseudo variable argument is not included, caller's URI is taken from
-   rpid_avp or, if rpid_avp value is empty, from From URI. Returns 1 or -1
-   depending on success.
+   matching gateways to gw_uri_avp (see Overview section). Argument lcr_id
+   specifies the used LCR instance. It can be an integer or a pseudo
+   variable containing an integer value. Caller's URI is given by
+   caller_uri argument, which must be a pseudo variable.
+
+   Returns 1 on success and -1 on error.
 
    Execution time of load_gws() function is O(N) * O(M), where N is number
    of different prefix lengths and M is number of collisions for matching
-   prefix(es) in lcr hash table.
-
-   This function can be used from REQUEST_ROUTE.
-
-   Example 1.24. load_gws usage
-...
-if (!load_gws("$var(caller_uri)")) {
-        sl_send_reply("500", "Server Internal Error - Cannot load gateways");
-        exit;
-};
-...
-
-4.2.  load_gws_from_grp(group-id)
-
-   Loads URI schemes, IP addresses, hostnames, ports, and transports of
-   gateways that belong to a given group to gw_uri_avp. group-id argument
-   is a string that may contain pseudo-variables. Its value must be a a
-   string of digits that are converted to an integer group id. Returns 1
-   or -1 depending on success.
-
-   Execution time of load_gws_from_grp() function is O(N), where N is
-   number of gateways.
+   prefix(es) in lcr hash table of the LCR instance.
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.25. load_gws_from_grp usage
+   Example 1.28. load_gws usage
 ...
-if (!load_gws_from_grp("1")) {
-        sl_send_reply("500", "Server Internal Error - Cannot load gateways from
-group 1");
-        exit;
-};
-...
-
-if (!load_gws_from_grp("$avp(s:gateway_group)")) {
+if (!load_gws("1", "$var(caller_uri)")) {
         sl_send_reply("500", "Server Internal Error - Cannot load gateways");
         exit;
 };
 ...
 
-4.3.  next_gw()
+4.2.  next_gw()
 
    Upon first call, replaces URI scheme, host, port, and transport of
    Request-URI by the values stored in first gw_uri_avp and destroys that
@@ -609,7 +652,7 @@ if (!load_gws_from_grp("$avp(s:gateway_group)")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.26. next_gw usage from a route block
+   Example 1.29. next_gw usage from a route block
 ...
 if (!next_gw()) {
         sl_send_reply("503", "Service not available - No gateways");
@@ -617,7 +660,7 @@ if (!next_gw()) {
 };
 ...
 
-   Example 1.27. next_gw usage from a failure route block
+   Example 1.30. next_gw usage from a failure route block
 ...
 if (!next_gw()) {
         t_reply("503", "Service not available - No more gateways");
@@ -625,72 +668,111 @@ if (!next_gw()) {
 };
 ...
 
-4.4.  from_gw([pvar])
+4.3.  defunct_gw(period)
+
+   Defuncts gateway selected by preceding next_gw() call for a period of
+   seconds given as argument. Argument must be a positive integer constant
+   or a pseudo variable with positive integer value.
+
+   Returns 1 on success and -1 in case of error (see syslog).
+
+   Must be preceded by successful next_gw() call.
+
+   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
+
+   Example 1.31. defunct_gw usage
+...
+defunct_gw("60");
+...
+
+4.4.  from_gw(lcr_id [, ip_addr])
 
-   Checks if request came from IP address of a gateway. IP address to be
-   checked is either taken from source IP address of the request or (if
-   present) from pseudo variable argument. As a side effect, stores
-   gateway's flags to flags_avp.
+   Checks if request comes from IP address of a gateway in LCR instance
+   specified by lcr_id argument, which can be an integer constant or a
+   pseudo variable with integer value. IP address to be checked is either
+   taken from source IP address of the request or (if present) from
+   ip_addr pseudo variable argument.
+
+   If request comes from a gateway, gateway's flags are stored into
+   flags_avp as side effect.
+
+   Returns 1 on success and -1 on failure or on error.
 
    Execution time of from_gw() function is O(log N), where N is number of
-   gateways.
+   gateways in the LCR instance.
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.28. from_gw usage
+   Example 1.32. from_gw usage
 ...
-if (from_gw()) {
+if (from_gw("1", "$avp(s:real_source_addr)") {
         ...
 };
 ...
 
-   Example 1.29. from_gw usage with pseudo variable argument
-...
-if (from_gw("$si")) {
-        ...
-};
-...
+4.5.  from_any_gw([ip_addr])
+
+   Checks if request comes from IP address of any gateway. IP address to
+   be checked is either taken from source IP address of the request or (if
+   present) from ip_addr pseudo variable argument.
 
-4.5.  from_gw_grp(group-id)
+   If any gateway has the IP address, function returns LCR identifier of
+   the gateway. Returns -1 on error or if request does not come from a
+   gateway.
 
-   Checks if request came from IP address of a gateway that belongs to the
-   given group (integer string). Sets or resets a message flag depending
-   on whether the gateway supports directed media.
+   If request comes from a gateway, gateway's flags are stored into
+   flags_avp as side effect.
 
-   Execution time of from_gw_grp() function is O(log N), where N is number
-   of gateways.
+   Execution time of from_gw() function is M * O(log N), where M is number
+   of LCR instances and N is average number of gateways in LCR instances.
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.30. from_gw_grp usage
+   Example 1.33. from_gw usage
 ...
-if (from_gw_grp("1")) {
-        ...
-};
+$var(lcr_id) = from_any_gw();
 ...
 
-4.6.  to_gw([group-id])
+4.6.  to_gw(lcr_id [, ip_addr])
+
+   Checks if in-dialog request goes to a gateway in LCR instance specified
+   by lcr_id argument. IP address to be checked is either taken from
+   Request-URI hostpart or (if present) from ip_addr pseudo variable
+   argument.
 
-   Checks if in-dialog request goes to a gateway. If an optional group-id
-   (integer string) is given, only gateways belonging to this group are
-   checked.
+   Returns 1 on success and -1 on failure and error.
 
    Execution time of to_gw() function is O(log N), where N is number of
-   gateways.
+   gateways in the LCR instance.
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.31. to_gw usage
+   Example 1.34. to_gw usage
 ...
-if (to_gw()) {
+if (to_gw("1")) {
         ...
         exit;
 };
 ...
 
-   Example 1.32. to_gw usage with group-id
+4.7.  to_any_gw([ip_addr])
+
+   Checks if in-dialog request goes to any gateway. IP address to be
+   checked is either taken from Request-URI hostpart or (if present) from
+   ip_addr pseudo variable argument.
+
+   Execution time of to_any_gw() function is M * O(log N), where M is
+   number of LCR instances and N is average number of gateways in LCR
+   instances.
+
+   If any gateway has the IP address, returns LCR identifier of the
+   gateway. Returns -1 if request does not go to a gateway and on error.
+
+   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
+
+   Example 1.35. to_gw usage
 ...
 if (to_gw("1")) {
         ...
@@ -706,7 +788,8 @@ if (to_gw("1")) {
 
 5.1. lcr_reload
 
-   Causes lcr module to re-read the contents of gateway table into memory.
+   Causes lcr module to re-read the contents of gw and lcr tables into
+   memory.
 
    Name: lcr_reload
 
@@ -744,17 +827,18 @@ if (to_gw("1")) {
 
    6.1. lcr.reload
    6.2. lcr.dump_gws
-   6.3. lcr.dump_lcr
+   6.3. lcr.dump_lcrs
 
 6.1. lcr.reload
 
-   Causes lcr module to re-read the contents of gateway table into memory.
+   Causes lcr module to re-read the contents of gw and lcr tables into
+   memory.
 
    Name: lcr.reload
 
    Parameters: none
 
-   Example 1.33. lcr.reload RPC example
+   Example 1.36. lcr.reload RPC example
                 $ sercmd lcr.reload
 
 6.2. lcr.dump_gws
@@ -763,17 +847,17 @@ if (to_gw("1")) {
 
    Parameters: none
 
-   Example 1.34. lcr.dump_gws RPC example
+   Example 1.37. lcr.dump_gws RPC example
                 $ sercmd lcr.dump_gws
 
-6.3. lcr.dump_lcr
+6.3. lcr.dump_lcrs
 
    Causes lcr module to dump the contents of its in-memory lcr table.
 
    Parameters: none
 
-   Example 1.35. lcr.dump_lcr RPC example
-                $ sercmd lcr.dump_lcr
+   Example 1.38. lcr.dump_lcr RPC example
+                $ sercmd lcr.dump_lcrs
 
 7. Known Limitations
 

+ 1 - 1
modules/lcr/doc/lcr.xml

@@ -24,7 +24,7 @@
 		</editor>
 	</authorgroup>
 	<copyright>
-		<year>2005-2008</year>
+		<year>2005-2009</year>
 	 	<holder>Juha Heinanen</holder>
 	</copyright>
 	<revhistory>

+ 240 - 112
modules/lcr/doc/lcr_admin.xml

@@ -19,11 +19,17 @@
 	Least cost routing (LCR) module implements capability to
 	serially forward a request to one or more gateways so that the
 	order in which the gateways is tried is based on admin defined
-	"least cost".
+	"least cost" rules.
+	</para>
+	<para>
+	LCR module supports many independent LCR instances (gateways and
+	least cost rules).  Each such instance has its own LCR
+	identifier.
 	</para>
 	<para>
 	For the purpose of facilitating least cost routing of requests,
-	each gateway belongs to a gateway group and each gateway group
+	each gateway of an LCR instance belongs to a gateway group and
+	each gateway group
 	is associated with one or more &lt;prefix, from pattern, priority&gt;
 	tuples.  A gateway matches a request if	user part of Request URI
 	matches a prefix and caller's URI matches a from pattern in a
@@ -70,7 +76,7 @@
 	<section>
 	<title>Dependencies</title>
 	<section>
-	<title>&kamailio; modules</title>
+	<title>&siprouter; modules</title>
 	<para>
 		The following modules must be loaded before this module:
 		<itemizedlist>
@@ -92,7 +98,7 @@
 	<title>External libraries or applications</title>
 	<para>
 		The following libraries or applications must be installed before
-		running &kamailio; with this module:
+		running &siprouter; with this module:
 			<itemizedlist>
 			<listitem>
 			<para>
@@ -130,7 +136,7 @@ modparam("lcr","db_url","&exampledb;")
 	<section>
 		<title><varname>gw_table</varname> (string)</title>
 		<para>
-		Name of the table holding the gateways definitions.
+		Name of the table holding gateways definitions.
 		</para>
 		<para>
 		<emphasis>
@@ -147,6 +153,27 @@ modparam("lcr","gw_table","gw")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>lcr_id_column</varname> (string)</title>
+		<para>
+		Name of the column holding the identifier of LCR
+		instance.  Common to both gw and lcr tables.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>lcr_id</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>lcr_id_column</varname> module parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "lcr_id_column", "lcr_identifier")
+...
+</programlisting>
+		</example>
+	</section>
+
 	<section>
 		<title><varname>gw_name_column</varname> (string)</title>
 		<para>
@@ -461,43 +488,45 @@ modparam("lcr","priority_column","priority")
 	</section>
 
 	<section>
-		<title><varname>gw_uri_avp</varname> (AVP string)</title>
+		<title><varname>lcr_count</varname> (integer)</title>
 		<para>
-   Internal AVP that load_gws function uses to store information of
-   matching gateways.
+		Number of LCR instances.
 		</para>
 		<para>
 		<emphasis>
-			There is NO default value, thus this variable must
-			be defined in kamailio.cfg.
+			Default value is 1.
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>gw_uri_avp</varname> module parameter</title>
+		<title>
+		Setting <varname>lcr_count</varname> module
+		parameter
+		</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr", "gw_uri_avp", "$avp(i:709)")
+modparam("lcr", "lcr_count", 10)
 ...
 </programlisting>
-		</example>
+                </example>
 	</section>
 
 	<section>
-		<title><varname>rpid_avp</varname> (AVP string)</title>
+		<title><varname>gw_uri_avp</varname> (AVP string)</title>
 		<para>
-		An AVP that contains caller's RPID (if any).
+		Internal AVP that load_gws() function uses to store
+		information of matching gateways.
 		</para>
 		<para>
 		<emphasis>
 			There is NO default value, thus this variable must
-			be defined in kamailio.cfg.
+			be defined in &siprouterconfig;.
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>rpid_avp</varname> module parameter</title>
+		<title>Setting <varname>gw_uri_avp</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("^auth$|lcr", "rpid_avp", "$avp(i:302)")
+modparam("lcr", "gw_uri_avp", "$avp(i:709)")
 ...
 </programlisting>
 		</example>
@@ -512,7 +541,7 @@ modparam("^auth$|lcr", "rpid_avp", "$avp(i:302)")
 		<para>
 		<emphasis>
 			There is NO default value, thus this variable must
-			be defined in kamailio.cfg.
+			be defined in &siprouterconfig;.
 		</emphasis>
 		</para>
 		<example>
@@ -534,7 +563,7 @@ modparam("lcr", "ruri_user_avp", "$avp(i:500)")
 		<para>
 		<emphasis>
 			There is NO default value, thus this variable must
-			be defined in kamailio.cfg.
+			be defined in &siprouterconfig;.
 		</emphasis>
 		</para>
 		<example>
@@ -547,6 +576,75 @@ modparam("lcr", "flags_avp", "$avp(i:712)")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>defunct_capability</varname> (integer)</title>
+		<para>
+		Tells if defunct capability of (non-responsive) gateways is
+		supported.  Non-zero value turns on defunct capability.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 0.
+		</emphasis>
+		</para>
+		<example>
+		<title>
+		Setting <varname>defunct_capability</varname> module
+		parameter
+		</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "defunct_capability", 1)
+...
+</programlisting>
+                </example>
+	</section>
+
+	<section>
+		<title><varname>lcr_id_avp</varname> (AVP string)</title>
+		<para>
+		Internal AVP that load_gws() function uses to store
+		LCR instance identifier of loaded gateways.  Only needed if
+		gateway defunct capability has been activated.
+		</para>
+		<para>
+		<emphasis>
+			There is NO default value.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>lcr_id_avp</varname> module parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>defunct_gw_avp</varname> (AVP string)</title>
+		<para>
+		Internal AVP that next_gw() function uses to store
+		IP address of the selected gateway for later use by
+		defunct_gw() function.  Only needed if
+		gateway defunct capability has been activated.
+		</para>
+		<para>
+		<emphasis>
+			There is NO default value.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>defunct_gw_avp</varname> module parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
+...
+</programlisting>
+		</example>
+	</section>
+
 	<section>
 		<title><varname>lcr_hash_size</varname> (integer)</title>
 		<para>
@@ -605,23 +703,25 @@ modparam("lcr", "fetch_rows", 3000)
 	<title>Exported Functions</title>
 	<section>
 		<title>
-		<function moreinfo="none">load_gws([pvar])</function>
+		<function moreinfo="none">load_gws(lcr_id, caller_uri)</function>
 		</title>
 		<para>
 		Loads URI schemes, IP addresses, hostnames, ports, and
 		transports of matching gateways to gw_uri_avp
-		(see Overview section). If optional pseudo variable
-		argument is included, caller's URI is taken from it.
-		If pseudo variable argument is not included, caller's
-		URI is taken from rpid_avp or, if rpid_avp value is
-		empty, from From URI. Returns 1 or -1 depending on
-		success.
+		(see Overview section).  Argument lcr_id specifies the used
+	        LCR instance.  It can be an integer or a pseudo
+		variable containing an integer value. 
+		Caller's URI is given by caller_uri argument, which
+		must be a pseudo variable.
+		</para>
+		<para>
+		Returns 1 on success and -1 on error.
 		</para>
 		<para>
 		Execution time of load_gws() function is O(N) * O(M),
 		where N is number of different prefix lengths and M
 		is number of collisions for matching prefix(es) in lcr
-		hash table.
+		hash table of the LCR instance.
 		</para>
 		<para>
 		This function can be used from REQUEST_ROUTE.
@@ -630,7 +730,7 @@ modparam("lcr", "fetch_rows", 3000)
 		<title><function>load_gws</function> usage</title>
 		<programlisting format="linespecific">
 ...
-if (!load_gws("$var(caller_uri)")) {
+if (!load_gws("1", "$var(caller_uri)")) {
 	sl_send_reply("500", "Server Internal Error - Cannot load gateways");
 	exit;
 };
@@ -638,44 +738,7 @@ if (!load_gws("$var(caller_uri)")) {
 </programlisting>
 		</example>
 	</section>
-	<section>
-		<title>
-		<function moreinfo="none">load_gws_from_grp(group-id)</function>
-		</title>
-		<para>
-		Loads URI schemes, IP addresses, hostnames, ports, and
-		transports of 
-		gateways that belong to a given group to gw_uri_avp.
-		group-id argument is a string that may contain 
-		pseudo-variables.  Its value must be a a string of
-		digits that are converted to an integer group id.
-		Returns 1 or -1 depending on success. 
-		</para>
-		<para>
-		Execution time of load_gws_from_grp() function is O(N),
-		where N is number of gateways.
-		</para>
-		<para>
-		This function can be used from REQUEST_ROUTE.
-		</para>
-		<example>
-		<title><function>load_gws_from_grp</function> usage</title>
-		<programlisting format="linespecific">
-...
-if (!load_gws_from_grp("1")) {
-	sl_send_reply("500", "Server Internal Error - Cannot load gateways from group 1");
-	exit;
-};
-...
 
-if (!load_gws_from_grp("$avp(s:gateway_group)")) {
-	sl_send_reply("500", "Server Internal Error - Cannot load gateways");
-	exit;
-};
-...
-</programlisting>
-		</example>
-	</section>
 	<section>
 		<title>
 		<function moreinfo="none">next_gw()</function>
@@ -731,92 +794,132 @@ if (!next_gw()) {
 </programlisting>
 		</example>
 	</section>
+
 	<section>
 		<title>
-		<function moreinfo="none">from_gw([pvar])</function>
-		</title>
+		<function moreinfo="none">defunct_gw(period)</function>
+		</title>	
 		<para>
-			Checks if request came from IP address of a
-			gateway.  IP address to be checked is either
-			taken from source IP address of the request or
-			(if present) from pseudo variable argument.
-			As a side effect, stores gateway's flags to
-			flags_avp.
+		Defuncts gateway selected by preceding next_gw() call
+		for a period of seconds given as argument.  Argument
+		must be a positive integer constant or a pseudo variable
+		with positive integer value.
 		</para>
 		<para>
-		Execution time of from_gw() function is O(log N),
-		where N is number of gateways.
+		Returns 1 on success and -1 in case of error (see syslog).
 		</para>
 		<para>
-		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
-		ONREPLY_ROUTE.
+		Must be preceded by successful next_gw() call.
+		</para>
+		<para>
+		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 		</para>
 		<example>
-		<title><function>from_gw</function> usage</title>
+		<title><function>defunct_gw</function> usage</title>
 		<programlisting format="linespecific">
 ...
-if (from_gw()) {
-	...
-};
+defunct_gw("60");
 ...
 </programlisting>
 		</example>
+	</section>
+
+	<section>
+		<title>
+		<function moreinfo="none">from_gw(lcr_id [, ip_addr])</function>
+		</title>
+		<para>
+		Checks if request comes from IP address of a
+		gateway in LCR instance specified by lcr_id argument,
+		which can be an integer constant or a pseudo variable
+		with integer value.
+		IP address to be checked is either 
+		taken from source IP address of the request or
+		(if present) from ip_addr pseudo variable argument.
+		</para>
+		<para>
+		If request comes from a gateway, gateway's flags are
+		stored into flags_avp as side effect.
+		</para>
+		<para>
+		Returns 1 on success and -1 on failure or on error.
+		</para>
+		<para>
+		Execution time of from_gw() function is O(log N),
+		where N is number of gateways in the LCR instance.
+		</para>
+		<para>
+		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
+		ONREPLY_ROUTE.
+		</para>
 		<example>
-		<title><function>from_gw</function> usage with pseudo
-		variable argument</title>
+		<title><function>from_gw</function> usage</title>
 		<programlisting format="linespecific">
 ...
-if (from_gw("$si")) {
+if (from_gw("1", "$avp(s:real_source_addr)") {
 	...
 };
 ...
 </programlisting>
 		</example>
 		</section>
+
 	<section>
 		<title>
-		<function moreinfo="none">from_gw_grp(group-id)</function>
+		<function moreinfo="none">from_any_gw([ip_addr])</function>
 		</title>
 		<para>
-			Checks if request came from IP address of a
-			gateway that belongs to the given group
-			(integer string).  Sets
-			or resets a message flag depending on whether
-			the gateway supports directed media. 
+		Checks if request comes from IP address of
+		any gateway.  IP address to be checked is either
+		taken from source IP address of the request or
+		(if present) from ip_addr pseudo variable argument.
+		</para>
+		<para>
+		If any gateway has the IP address, function returns LCR
+		identifier 
+		of the gateway.  Returns -1 on error or if request does
+		not come from a gateway. 
+		</para>
+		<para>
+		If request comes
+		from a gateway, gateway's flags are stored into flags_avp
+		as side effect.
 		</para>
 		<para>
-		Execution time of from_gw_grp() function is O(log N),
-		where N is number of gateways.
+		Execution time of from_gw() function is M * O(log N),
+		where M is number of LCR instances and N is average number of
+		gateways in LCR instances.
 		</para>
 		<para>
 		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
 		ONREPLY_ROUTE.
 		</para>
 		<example>
-		<title><function>from_gw_grp</function> usage</title>
+		<title><function>from_gw</function> usage</title>
 		<programlisting format="linespecific">
 ...
-if (from_gw_grp("1")) {
-	...
-};
+$var(lcr_id) = from_any_gw();
 ...
 </programlisting>
 		</example>
 		</section>
+
 		<section>
 		<title>
-		<function moreinfo="none">to_gw([group-id])</function>
+		<function moreinfo="none">to_gw(lcr_id [, ip_addr])</function>
 		</title>
 		<para>
-		Checks if in-dialog request goes to a
-			gateway. If an optional 
-			group-id (integer string) is given,
-			only gateways belonging to
-			this group are checked.
+		Checks if in-dialog request goes to a gateway in LCR
+		instance specified by lcr_id argument. IP address to be
+		checked is either taken from Request-URI hostpart or (if
+		present) from ip_addr pseudo variable argument. 
+		</para>
+		<para>
+		Returns 1 on success and -1 on failure and error.
 		</para>
 		<para>
 		Execution time of to_gw() function is O(log N),
-		where N is number of gateways.
+		where N is number of gateways in the LCR instance.
 		</para>
 		<para>
 		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
@@ -825,15 +928,40 @@ if (from_gw_grp("1")) {
 		<title><function>to_gw</function> usage</title>
 		<programlisting format = "linespecific">
 ...
-if (to_gw()) {
+if (to_gw("1")) {
 	...
 	exit;
 };
 ...
 </programlisting>
 		</example>
+	</section>
+
+	<section>
+		<title>
+		<function moreinfo="none">to_any_gw([ip_addr])</function>
+		</title>
+		<para>
+		Checks if in-dialog request goes to any gateway.  IP
+		address to be checked is either taken from Request-URI
+		hostpart or (if present) from ip_addr pseudo variable
+		argument.
+		</para>
+		<para>
+		Execution time of to_any_gw() function is M * O(log N),
+		where M is number of LCR instances and N is average
+		number of gateways in LCR instances.
+		</para>
+		<para>
+		If any gateway has the IP address, returns LCR identifier
+		of the gateway.  Returns -1 if request does
+		not go to a gateway and on error.
+		</para>
+		<para>
+		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
+		</para>
 		<example>
-		<title><function>to_gw</function> usage with group-id</title>
+		<title><function>to_gw</function> usage</title>
 		<programlisting format = "linespecific">
 ...
 if (to_gw("1")) {
@@ -852,8 +980,8 @@ if (to_gw("1")) {
 		<section>
 		<title><function>lcr_reload</function></title>
 		<para>
-			Causes lcr module to re-read the contents of gateway table
-			into memory.
+			Causes lcr module to re-read the contents of
+			gw and lcr tables into memory.
 		</para>
 		<para>
 		Name: <emphasis>lcr_reload</emphasis>
@@ -914,8 +1042,8 @@ if (to_gw("1")) {
 		<section>
 		<title><function>lcr.reload</function></title>
 		<para>
-			Causes lcr module to re-read the contents of gateway table
-			into memory.
+			Causes lcr module to re-read the contents of
+			gw and lcr tables into memory.
 		</para>
 		<para>
 		Name: <emphasis>lcr.reload</emphasis>
@@ -945,7 +1073,7 @@ if (to_gw("1")) {
 		</section>
 		
 		<section>
-		<title><function>lcr.dump_lcr</function></title>
+		<title><function>lcr.dump_lcrs</function></title>
 		<para>
 			Causes lcr module to dump the contents of its
 			in-memory lcr table.
@@ -954,7 +1082,7 @@ if (to_gw("1")) {
  		<example>
 		<title><function>lcr.dump_lcr</function> RPC example</title>
         <programlisting  format="linespecific">
-		$ sercmd lcr.dump_lcr
+		$ sercmd lcr.dump_lcrs
 		</programlisting>
 		</example>
 		</section>

+ 0 - 2
modules/lcr/hash.c

@@ -83,8 +83,6 @@ struct lcr_info *lcr_hash_table_lookup(struct lcr_info **hash_table,
 {
     str prefix_str;
 
-    LM_DBG("looking for <%.*s>\n", prefix_len, prefix);
-
     prefix_str.len = prefix_len;
     prefix_str.s = prefix;
 

File diff suppressed because it is too large
+ 280 - 375
modules/lcr/lcr_mod.c


+ 6 - 4
modules/lcr/lcr_mod.h

@@ -70,19 +70,21 @@ struct gw_info {
     unsigned short tag_len;
     unsigned short weight;
     unsigned int flags;
-    unsigned short ping;
+    unsigned int defunct_until;
     unsigned int next;  /* index of next gw in the same group */
 };
 
 extern unsigned int lcr_hash_size_param;
 
+extern unsigned int lcr_count;
+
 extern gen_lock_t *reload_lock;
 
-extern struct gw_info **gws;
-extern struct lcr_info ***lcrs;
+extern struct gw_info **gwtp;
+extern struct lcr_info ***lcrtp;
 
 int  mi_print_gws(struct mi_node* rpl);
 int  mi_print_lcrs(struct mi_node* rpl);
-int  reload_gws_and_lcrs(void);
+int  reload_gws_and_lcrs(int id);
 
 #endif /* LCR_MOD_H */

+ 62 - 43
modules/lcr/lcr_rpc.c

@@ -34,22 +34,25 @@
 
 
 static const char* reload_doc[2] = {
-	"Reload gateway table from database.",
+	"Reload gw and lcr tables from database.",
 	0
 };
 
 
 static void reload(rpc_t* rpc, void* c)
 {
+        int i;
 	lock_get(reload_lock);
-	if (reload_gws_and_lcrs() !=1)
-		rpc->fault(c, 500, "LCR Gateway Reload Failed");
+	for (i = 1; i <= lcr_count; i++) {
+	        if (reload_gws_and_lcrs(i) != 1)
+		        rpc->fault(c, 500, "LCR Module Reload Failed");
+	}
 	lock_release(reload_lock);
 }
 
 
 static const char* dump_gws_doc[2] = {
-	"Dump the contents of the gateway table.",
+	"Dump the contents of the gw table.",
 	0
 };
 
@@ -57,30 +60,36 @@ static const char* dump_gws_doc[2] = {
 static void dump_gws(rpc_t* rpc, void* c)
 {
 	void* st;
-	unsigned int i;
+	unsigned int i, j;
 	enum sip_protos transport;
 	str hostname;
 	str tag;
+	struct gw_info *gws;
+
+	for (j = 1; j <= lcr_count; j++) {
 	
-	for (i = 0; i <= (*gws)[0].ip_addr; i++) {
+	    gws = gwtp[j];
+
+	    for (i = 1; i <= gws[0].ip_addr; i++) {
 		if (rpc->add(c, "{", &st) < 0) return;
-		rpc->struct_add(st, "d", "grp_id", (*gws)[i].grp_id);
+		rpc->struct_add(st, "d", "lcr_id", j);
+		rpc->struct_add(st, "d", "grp_id", gws[i].grp_id);
 		rpc->struct_printf(st,   "ip_addr", "%d.%d.%d.%d",
-								((*gws)[i].ip_addr << 24) >> 24,
-								(((*gws)[i].ip_addr >> 8) << 24) >> 24,
-								(((*gws)[i].ip_addr >> 16) << 24) >> 24,
-								(*gws)[i].ip_addr >> 24);
-		hostname.s=(*gws)[i].hostname;
-		hostname.len=(*gws)[i].hostname_len;
+				   (gws[i].ip_addr << 24) >> 24,
+				   ((gws[i].ip_addr >> 8) << 24) >> 24,
+				   ((gws[i].ip_addr >> 16) << 24) >> 24,
+				   gws[i].ip_addr >> 24);
+		hostname.s=gws[i].hostname;
+		hostname.len=gws[i].hostname_len;
 		rpc->struct_add(st, "S", "hostname", &hostname);
-		if  ((*gws)[i].port > 0)
-			rpc->struct_add(st, "d", "port", (*gws)[i].port);
-		if ((*gws)[i].scheme == SIP_URI_T) {
+		if  (gws[i].port > 0)
+			rpc->struct_add(st, "d", "port", gws[i].port);
+		if (gws[i].scheme == SIP_URI_T) {
 		    rpc->struct_add(st, "s", "scheme", "sip");
 		} else {
 		    rpc->struct_add(st, "s", "scheme", "sips");
 		}
-		transport = (*gws)[i].transport;
+		transport = gws[i].transport;
 		switch(transport){
 			case PROTO_UDP:
 				rpc->struct_add(st, "s", "transport", "UDP");
@@ -95,54 +104,64 @@ static void dump_gws(rpc_t* rpc, void* c)
 				rpc->struct_add(st, "s", "transport", "SCTP");
 				break;
 			case PROTO_NONE:
-				break;
+			    break;
 		}
-		tag.s=(*gws)[i].tag;
-		tag.len=(*gws)[i].tag_len;
-		rpc->struct_add(st, "dSddd", "strip",  (*gws)[i].strip,
-									 "tag",    (*gws)[i].tag, /* FIXME */
-									 "weight", (*gws)[i].weight,
-									 "flags",  &tag,
-									 "ping",   (*gws)[i].ping
-									 );
+		tag.s=gws[i].tag;
+		tag.len=gws[i].tag_len;
+		rpc->struct_add(st, "dSddd",
+				"strip",  gws[i].strip,
+				"tag",    gws[i].tag, /* FIXME */
+				"weight", gws[i].weight,
+				"flags",  &tag,
+				"defunct_until",  &gws[i].defunct_until
+				);
+	    }
 	}
 }
 
 
 
-static const char* dump_lcr_doc[2] = {
+static const char* dump_lcrs_doc[2] = {
 	"Dump the contents of the lcr table.",
 	0
 };
 
 
-static void dump_lcr(rpc_t* rpc, void* c)
+static void dump_lcrs(rpc_t* rpc, void* c)
 {
-	int i;
-	struct lcr_info* lcr_rec;
+        int i, j;
+	struct lcr_info **lcrs, *lcr_rec;
 	void* st;
-	str prefix, from_uri;
-	
-	for (i=0; i < lcr_hash_size_param; i++){
-		lcr_rec=(*lcrs)[i];
+	str prefix, from_uri, lcr_id;
+
+	for (j = 1; j <= lcr_count; j++) {
+	    
+	    lcrs = lcrtp[j];
+
+	    for (i = 0; i < lcr_hash_size_param; i++) {
+		lcr_rec = lcrs[i];
 		while(lcr_rec){
 			if (rpc->add(c, "{", &st) < 0) return;
+			lcr_id.s = int2str(j, &(lcr_id.len));
 			prefix.s=lcr_rec->prefix;
 			prefix.len=lcr_rec->prefix_len;
 			from_uri.s=lcr_rec->from_uri;
 			from_uri.len=lcr_rec->from_uri_len;
-			rpc->struct_add(st, "SSdd",	"prefix",	&prefix,
-										"from_uri",	&from_uri,
-										"grp_id",	lcr_rec->grp_id,
-										"priority",	lcr_rec->priority
-							);
+			rpc->struct_add(st, "dSSdd",
+					"lcr_id", j,
+					"prefix", &prefix,
+					"from_uri", &from_uri,
+					"grp_id", lcr_rec->grp_id,
+					"priority", lcr_rec->priority
+					);
 			lcr_rec=lcr_rec->next;
 		}
-	}
-	lcr_rec=(*lcrs)[lcr_hash_size_param];
-	while(lcr_rec){
+	    }
+	    lcr_rec=lcrs[lcr_hash_size_param];
+	    while(lcr_rec){
 		rpc->add(c, "d", lcr_rec->prefix_len);
 		lcr_rec=lcr_rec->next;
+	    }
 	}
 }
 
@@ -151,7 +170,7 @@ static void dump_lcr(rpc_t* rpc, void* c)
 rpc_export_t lcr_rpc[] = {
 	{"lcr.reload", reload, reload_doc, 0},
 	{"lcr.dump_gws",   dump_gws,   dump_gws_doc,   0},
-	{"lcr.dump_lcr",   dump_lcr,   dump_lcr_doc,   0},
+	{"lcr.dump_lcrs",   dump_lcrs,   dump_lcrs_doc,   0},
 	{0, 0, 0, 0}
 };
 

+ 10 - 7
modules/lcr/mi.c

@@ -30,22 +30,25 @@
 #include "lcr_mod.h"
 #include "../../dprint.h"
 #include "../../lib/srdb1/db.h"
+#include "../../locking.h"
 #include "mi.h"
 
 
 /*
  * MI function to reload lcr table(s)
  */
-struct mi_root*  mi_lcr_reload(struct mi_root* cmd_tree, void* param)
+struct mi_root* mi_lcr_reload(struct mi_root* cmd_tree, void* param)
 {
+    int i;
     lock_get(reload_lock);
-    if (reload_gws_and_lcrs() == 1) {
-	lock_release(reload_lock);
-	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
-    } else {
-	lock_release(reload_lock);
-	return init_mi_tree( 400, "Reload of gateways failed", 25);
+    for (i = 1; i <= lcr_count; i++) {
+	if (reload_gws_and_lcrs(i) < 0) {
+	    lock_release(reload_lock);
+	    return init_mi_tree( 400, "Reload of lcr gateways failed", 29);
+	}
     }
+    lock_release(reload_lock);
+    return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
 }
 
 

+ 5 - 4
modules_s/avpops/Makefile → modules/mi_rpc/Makefile

@@ -1,17 +1,18 @@
 # $Id$
 #
-# example module makefile
+# mi_rpc module makefile
 #
 # 
 # WARNING: do not run this directly, it should be run by the master Makefile
 
 include ../../Makefile.defs
 auto_gen=
-NAME=avpops.so
-LIBS= 
+NAME=mi_rpc.so
+LIBS=
 
 DEFS+=-DSER_MOD_INTERFACE
 
 SERLIBPATH=../../lib
-SER_LIBS+=$(SERLIBPATH)/srdb2/srdb2
+SER_LIBS+=$(SERLIBPATH)/kmi/kmi
+
 include ../../Makefile.modules

+ 84 - 0
modules/mi_rpc/README

@@ -0,0 +1,84 @@
+MI_RPC Module
+
+Daniel-Constantin Mierla
+
+   asipto.com
+   <[email protected]>
+
+Edited by
+
+Daniel-Constantin Mierla
+
+   <[email protected]>
+
+   Copyright © 2009 http://www.asipto.com
+     __________________________________________________________________
+
+   Table of Contents
+
+   1. Admin Guide
+
+        1.1. Overview
+        1.2. Dependencies
+
+              1.2.1. Kamailio Modules
+              1.2.2. External Libraries or Applications
+
+        1.3. Exported Parameters
+        1.4. Exported Functions
+        1.5. Exported RPC commands
+
+              1.5.1. mi
+
+Chapter 1. Admin Guide
+
+1.1. Overview
+
+   The module exports a RPC command to execute MI commands.
+
+   The other way around not implemented (MI command to execute RPC) -- to
+   be investigated if worth the effort. Also, execution of asynchronous MI
+   command is not yet supported.
+
+1.2. Dependencies
+
+1.2.1. Kamailio Modules
+
+   The following modules must be loaded before this module:
+     * No dependencies on other Kamailio modules.
+
+1.2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running Kamailio with this module loaded:
+     * None.
+
+1.3. Exported Parameters
+
+   none
+
+1.4. Exported Functions
+
+   none
+
+1.5. Exported RPC commands
+
+1.5.1.  mi
+
+   Execute a MI command.
+
+   Name: mi
+
+   Parameters:
+
+   _mi_command_ - the MI command to execute (mandatory).
+
+   _parameters_ - the MI command parameters (optional).
+
+   Example using 'sercmd':
+sercmd> mi uptime
+200 OK
+
++ Now:: Sun Jun 28 12:45:37 2009
++ Up since:: Sun Jun 28 12:24:27 2009
++ Up time:: 1270 [sec]

+ 4 - 0
modules/mi_rpc/doc/Makefile

@@ -0,0 +1,4 @@
+docs = mi_rpc.xml
+
+docbook_dir = ../../../docbook
+include $(docbook_dir)/Makefile.module

Some files were not shown because too many files changed in this diff