Merge pull request #1345 from kamailio/lazedo-patch-2
authorDaniel-Constantin Mierla <miconda@gmail.com>
Sat, 9 Dec 2017 08:20:00 +0000 (09:20 +0100)
committerGitHub <noreply@github.com>
Sat, 9 Dec 2017 08:20:00 +0000 (09:20 +0100)
schema: allow null in active_watchers reason

145 files changed:
pkg/kamailio/deb/buster/control
pkg/kamailio/deb/buster/rules
pkg/kamailio/deb/debian/backports/jessie
pkg/kamailio/deb/debian/backports/precise
pkg/kamailio/deb/debian/backports/trusty
pkg/kamailio/deb/debian/backports/wheezy
pkg/kamailio/deb/debian/control
pkg/kamailio/deb/debian/rules
pkg/kamailio/deb/jessie/rules
pkg/kamailio/deb/precise/rules
pkg/kamailio/deb/sid/control
pkg/kamailio/deb/sid/rules
pkg/kamailio/deb/stretch/control
pkg/kamailio/deb/stretch/rules
pkg/kamailio/deb/trusty/rules
pkg/kamailio/deb/wheezy/rules
pkg/kamailio/deb/xenial/control
pkg/kamailio/deb/xenial/rules
src/Makefile.groups
src/core/cfg.y
src/core/kemi.c
src/core/pvapi.c
src/core/receive.c
src/core/select_core.c
src/core/udp_server.c
src/lib/srdb1/schema/topos_d.xml
src/lib/srdb1/schema/topos_t.xml
src/modules/acc_radius/acc_radius_mod.c
src/modules/app_mono/app_mono_api.c
src/modules/app_python/app_python_mod.c
src/modules/app_python/apy_kemi.c
src/modules/app_python/apy_kemi.h
src/modules/async/async_mod.c
src/modules/async/async_sleep.c
src/modules/async/async_sleep.h
src/modules/auth_ephemeral/auth_ephemeral_mod.c
src/modules/auth_ephemeral/authorize.c
src/modules/auth_ephemeral/authorize.h
src/modules/auth_radius/auth_radius.c
src/modules/auth_radius/authorize.c
src/modules/auth_radius/authorize.h
src/modules/auth_radius/extra.c
src/modules/auth_radius/extra.h
src/modules/auth_radius/sterman.c
src/modules/auth_radius/sterman.h
src/modules/benchmark/README
src/modules/benchmark/benchmark.c
src/modules/benchmark/doc/benchmark_admin.xml
src/modules/counters/counters.c
src/modules/cplc/cpl_log.c
src/modules/cplc/cpl_time.c
src/modules/crypto/crypto_mod.c
src/modules/db2_ops/db2_ops.c
src/modules/db_postgres/pg_uri.c
src/modules/dmq/bind_dmq.c
src/modules/dmq/bind_dmq.h
src/modules/dmq/dmq.c
src/modules/dmq/dmq.h
src/modules/dmq/dmq_funcs.c
src/modules/dmq/dmq_funcs.h
src/modules/dmq/dmqnode.c
src/modules/dmq/dmqnode.h
src/modules/dmq/message.c
src/modules/dmq/message.h
src/modules/dmq/notification_peer.c
src/modules/dmq/notification_peer.h
src/modules/dmq/peer.c
src/modules/dmq/peer.h
src/modules/dmq/worker.c
src/modules/dmq/worker.h
src/modules/group/group.c
src/modules/group/group.h
src/modules/group/group_mod.c
src/modules/http_async_client/async_http.c
src/modules/http_async_client/async_http.h
src/modules/http_async_client/http_async_client_mod.c
src/modules/http_client/curl_api.c
src/modules/http_client/curl_api.h
src/modules/http_client/curlcon.c
src/modules/http_client/curlcon.h
src/modules/http_client/curlrpc.c
src/modules/http_client/functions.c
src/modules/http_client/functions.h
src/modules/http_client/http_client.c
src/modules/http_client/http_client.h
src/modules/ipops/ipops_mod.c
src/modules/jansson/jansson_path.h
src/modules/jsonrpcc/jsonrpc_io.c
src/modules/lcr/lcr_mod.c
src/modules/log_systemd/log_systemd_mod.c
src/modules/mediaproxy/mediaproxy.c
src/modules/misc_radius/extra.c
src/modules/misc_radius/extra.h
src/modules/misc_radius/functions.c
src/modules/misc_radius/functions.h
src/modules/misc_radius/misc_radius.c
src/modules/misc_radius/misc_radius.h
src/modules/misc_radius/radius.h
src/modules/msilo/msilo.c
src/modules/mtree/mtree.c
src/modules/nat_traversal/nat_traversal.c
src/modules/ndb_mongodb/ndb_mongodb_mod.c
src/modules/peering/verify.c
src/modules/presence/hash.c
src/modules/presence/subscribe.c
src/modules/pua/send_subscribe.c
src/modules/rabbitmq/rabbitmq.c
src/modules/rabbitmq/rabbitmq.h
src/modules/rabbitmq/utils.c
src/modules/rls/notify.c
src/modules/rls/resource_notify.c
src/modules/rls/resource_notify.h
src/modules/rls/rls.c
src/modules/rls/subscribe.c
src/modules/rls/subscribe.h
src/modules/sca/sca.c
src/modules/sca/sca_call_info.c
src/modules/sca/sca_call_info.h
src/modules/sca/sca_subscribe.c
src/modules/sca/sca_subscribe.h
src/modules/sipdump/sipdump_mod.c
src/modules/textopsx/textopsx.c
src/modules/tls/tls_select.c
src/modules/tm/t_suspend.c
src/modules/tm/t_suspend.h
src/modules/tm/tm.c
src/modules/tm/tm_load.c
src/modules/tm/tm_load.h
src/modules/tm/uac.c
src/modules/tmrec/tmrec_mod.c
src/modules/tmx/tmx_mod.c
src/modules/topos/tps_msg.c
src/modules/uac_redirect/uac_redirect.c
src/modules/uri_db/checks.c
src/modules/uri_db/checks.h
src/modules/uri_db/uri_db.c
src/modules/userblacklist/userblacklist.c
test/unit/24.sh
test/unit/3.sh
utils/kamctl/db_sqlite/topos-create.sql
utils/kamctl/kamctlrc
utils/kamctl/kamdbctl.mysql
utils/kamctl/mysql/topos-create.sql
utils/kamctl/oracle/topos-create.sql
utils/kamctl/postgres/topos-create.sql

index eb5c417..aadf72d 100644 (file)
@@ -27,11 +27,13 @@ Build-Depends:
  libjson-c-dev,
  libldap2-dev,
  liblua5.1-0-dev,
+ libmaxminddb-dev,
  libmemcached-dev,
  libmono-2.0-dev,
  libncurses5-dev,
  libpcre3-dev,
  libperl-dev,
+ libphonenumber-dev (>= 7),
  libpq-dev,
  librabbitmq-dev,
  libradcli-dev,
@@ -146,6 +148,24 @@ Description: The geoip module for the Kamailio SIP Server
  This package provides the geoip module, an extension enabling
  usage of the GeoIP API within the Kamailio configuration file.
 
+Package: kamailio-geoip2-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: The geoip2 module for the Kamailio SIP Server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides the geoip2 module, an extension enabling
+ real-time queries against the Max Mind GeoIP2 database within the Kamailio
+ configuration file.
+
 Package: kamailio-sqlite-modules
 Architecture: linux-any
 Multi-Arch: same
@@ -741,6 +761,23 @@ Description: systemd logging modules for the Kamailio SIP server
  This package provides logging to systemd journal directly from the
  Kamailio configuration and routing scripts.
 
+Package: kamailio-phonenum-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: phonenum modules for the Kamailio SIP server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides real-time queries against the libphonenumber to be
+ performed directly from the Kamailio configuration and routing scripts.
+
 Package: kamailio-extra-modules
 Architecture: linux-any
 Multi-Arch: same
index 53e7361..83aaaad 100755 (executable)
@@ -35,10 +35,10 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip geoip2 \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph kazoo cnxcc \
-                          erlang systemd rabbitmq
+                          erlang systemd phonenum rabbitmq
 
 # module groups to be packaged onto kamailio-extra-modules
 EXTRA_GROUPS=gzcompress uuid ev jansson http_async
index 8b6faf4..44d4d9a 100755 (executable)
@@ -27,6 +27,18 @@ echo "kamailio-mysql-modules: depends-on-obsolete-package depends: mysql-client
 # no libssl-dev
 sed -i -e '/libssl-dev/d' ${DIST}/control
 
+# No geoip2 module
+sed -i -e '/libmaxminddb-dev/d' -e '/^Package: kamailio-geoip2-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ geoip2[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ geoip2/' ${DIST}/rules
+
+# No phonenum module
+sed -i -e '/libphonenumber-dev/d' -e '/^Package: kamailio-phonenum-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ phonenum[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ phonenum/' ${DIST}/rules
+
 # clean backports scripts
 rm -rf ${DIST}/backports
 exit 0
index 457426f..844fac8 100755 (executable)
@@ -64,6 +64,18 @@ sed -i -e '/librabbitmq-dev/d' \
 sed -i -e 's/ rabbitmq[ ,$]*/ /' ${DIST}/rules
 sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ rabbitmq/' ${DIST}/rules
 
+# No geoip2 module
+sed -i -e '/libmaxminddb-dev/d' -e '/^Package: kamailio-geoip2-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ geoip2[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ geoip2/' ${DIST}/rules
+
+# No phonenum module
+sed -i -e '/libphonenumber-dev/d' -e '/^Package: kamailio-phonenum-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ phonenum[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ phonenum/' ${DIST}/rules
+
 # clean backports scripts
 rm -rf ${DIST}/backports
 exit 0
index 5924af0..2cb4188 100755 (executable)
@@ -38,6 +38,18 @@ echo "kamailio-mysql-modules: depends-on-obsolete-package depends: mysql-client
 # no libssl-dev
 sed -i -e '/libssl-dev/d' ${DIST}/control
 
+# No geoip2 module
+sed -i -e '/libmaxminddb-dev/d' -e '/^Package: kamailio-geoip2-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ geoip2[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ geoip2/' ${DIST}/rules
+
+# No phonenum module
+sed -i -e '/libphonenumber-dev/d' -e '/^Package: kamailio-phonenum-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ phonenum[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ phonenum/' ${DIST}/rules
+
 # clean backports scripts
 rm -rf ${DIST}/backports
 exit 0
index 411e0ae..d7e1d06 100755 (executable)
@@ -64,6 +64,18 @@ sed -i -e '/librabbitmq-dev/d' \
 sed -i -e 's/ rabbitmq[ ,$]*/ /' ${DIST}/rules
 sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ rabbitmq/' ${DIST}/rules
 
+# No geoip2 module
+sed -i -e '/libmaxminddb-dev/d' -e '/^Package: kamailio-geoip2-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ geoip2[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ geoip2/' ${DIST}/rules
+
+# No phonenum module
+sed -i -e '/libphonenumber-dev/d' -e '/^Package: kamailio-phonenum-modules/,/^$/d' \
+       ${DIST}/control
+sed -i -e 's/ phonenum[ ,$]*/ /' ${DIST}/rules
+sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ phonenum/' ${DIST}/rules
+
 # clean backports scripts
 rm -rf ${DIST}/backports
 exit 0
index a494a7f..f5c38c1 100644 (file)
@@ -27,11 +27,13 @@ Build-Depends:
  libjson-c-dev,
  libldap2-dev,
  liblua5.1-0-dev,
+ libmaxminddb-dev,
  libmemcached-dev,
  libmono-2.0-dev,
  libncurses5-dev,
  libpcre3-dev,
  libperl-dev,
+ libphonenumber-dev (>= 7),
  libpq-dev,
  librabbitmq-dev,
  libradcli-dev,
@@ -148,6 +150,24 @@ Description: The geoip module for the Kamailio SIP Server
  This package provides the geoip module, an extension enabling
  usage of the GeoIP API within the Kamailio configuration file.
 
+Package: kamailio-geoip2-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: The geoip2 module for the Kamailio SIP Server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides the geoip2 module, an extension enabling
+ real-time queries against the Max Mind GeoIP2 database within the Kamailio
+ configuration file.
+
 Package: kamailio-sqlite-modules
 Architecture: linux-any
 Multi-Arch: same
@@ -759,6 +779,23 @@ Description: systemd logging modules for the Kamailio SIP server
  This package provides logging to systemd journal directly from the
  Kamailio configuration and routing scripts.
 
+Package: kamailio-phonenum-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: phonenum modules for the Kamailio SIP server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides real-time queries against the libphonenumber to be
+ performed directly from the Kamailio configuration and routing scripts.
+
 Package: kamailio-extra-modules
 Architecture: linux-any
 Multi-Arch: same
index 7319a6c..71f9338 100755 (executable)
@@ -35,10 +35,10 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip geoip2 \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph dnssec kazoo cnxcc \
-                          erlang systemd rabbitmq
+                          erlang systemd phonenum rabbitmq
 
 # module groups to be packaged onto kamailio-extra-modules
 EXTRA_GROUPS=gzcompress uuid ev jansson http_async
index 51fbf60..c9280e2 100755 (executable)
@@ -27,7 +27,7 @@ EXCLUDED_MODULES=
 # extra modules to skip, because they are not compilable now
 # - regardless if they go to the main kamailio package or to some module package,
 # they will be excluded from compile and install of all
-EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc
+EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc geoip2 phonenum
 
 # module groups that are packaged in seperate packages
 # (with the name kamailio-$(group_name)-modules)
@@ -35,7 +35,7 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph dnssec kazoo cnxcc \
                           erlang systemd rabbitmq
index 2a1920b..d2ae4f0 100755 (executable)
@@ -26,7 +26,7 @@ EXCLUDED_MODULES=
 # extra modules to skip, because they are not compilable now
 # - regardless if they go to the main kamailio package or to some module package,
 # they will be excluded from compile and install of all
-EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec kazoo cnxcc systemd rabbitmq
+EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec kazoo cnxcc systemd rabbitmq geoip2 phonenum
 
 # module groups that are packaged in seperate packages
 # (with the name kamailio-$(group_name)-modules)
@@ -34,7 +34,7 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec kazoo c
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph \
                           erlang 
index eb5c417..aadf72d 100644 (file)
@@ -27,11 +27,13 @@ Build-Depends:
  libjson-c-dev,
  libldap2-dev,
  liblua5.1-0-dev,
+ libmaxminddb-dev,
  libmemcached-dev,
  libmono-2.0-dev,
  libncurses5-dev,
  libpcre3-dev,
  libperl-dev,
+ libphonenumber-dev (>= 7),
  libpq-dev,
  librabbitmq-dev,
  libradcli-dev,
@@ -146,6 +148,24 @@ Description: The geoip module for the Kamailio SIP Server
  This package provides the geoip module, an extension enabling
  usage of the GeoIP API within the Kamailio configuration file.
 
+Package: kamailio-geoip2-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: The geoip2 module for the Kamailio SIP Server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides the geoip2 module, an extension enabling
+ real-time queries against the Max Mind GeoIP2 database within the Kamailio
+ configuration file.
+
 Package: kamailio-sqlite-modules
 Architecture: linux-any
 Multi-Arch: same
@@ -741,6 +761,23 @@ Description: systemd logging modules for the Kamailio SIP server
  This package provides logging to systemd journal directly from the
  Kamailio configuration and routing scripts.
 
+Package: kamailio-phonenum-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: phonenum modules for the Kamailio SIP server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides real-time queries against the libphonenumber to be
+ performed directly from the Kamailio configuration and routing scripts.
+
 Package: kamailio-extra-modules
 Architecture: linux-any
 Multi-Arch: same
index 53e7361..83aaaad 100755 (executable)
@@ -35,10 +35,10 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip geoip2 \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph kazoo cnxcc \
-                          erlang systemd rabbitmq
+                          erlang systemd phonenum rabbitmq
 
 # module groups to be packaged onto kamailio-extra-modules
 EXTRA_GROUPS=gzcompress uuid ev jansson http_async
index eb5c417..aadf72d 100644 (file)
@@ -27,11 +27,13 @@ Build-Depends:
  libjson-c-dev,
  libldap2-dev,
  liblua5.1-0-dev,
+ libmaxminddb-dev,
  libmemcached-dev,
  libmono-2.0-dev,
  libncurses5-dev,
  libpcre3-dev,
  libperl-dev,
+ libphonenumber-dev (>= 7),
  libpq-dev,
  librabbitmq-dev,
  libradcli-dev,
@@ -146,6 +148,24 @@ Description: The geoip module for the Kamailio SIP Server
  This package provides the geoip module, an extension enabling
  usage of the GeoIP API within the Kamailio configuration file.
 
+Package: kamailio-geoip2-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: The geoip2 module for the Kamailio SIP Server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides the geoip2 module, an extension enabling
+ real-time queries against the Max Mind GeoIP2 database within the Kamailio
+ configuration file.
+
 Package: kamailio-sqlite-modules
 Architecture: linux-any
 Multi-Arch: same
@@ -741,6 +761,23 @@ Description: systemd logging modules for the Kamailio SIP server
  This package provides logging to systemd journal directly from the
  Kamailio configuration and routing scripts.
 
+Package: kamailio-phonenum-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: phonenum modules for the Kamailio SIP server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides real-time queries against the libphonenumber to be
+ performed directly from the Kamailio configuration and routing scripts.
+
 Package: kamailio-extra-modules
 Architecture: linux-any
 Multi-Arch: same
index 53e7361..83aaaad 100755 (executable)
@@ -35,10 +35,10 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip geoip2 \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph kazoo cnxcc \
-                          erlang systemd rabbitmq
+                          erlang systemd phonenum rabbitmq
 
 # module groups to be packaged onto kamailio-extra-modules
 EXTRA_GROUPS=gzcompress uuid ev jansson http_async
index f547e34..6501a34 100755 (executable)
@@ -27,7 +27,7 @@ EXCLUDED_MODULES=
 # extra modules to skip, because they are not compilable now
 # - regardless if they go to the main kamailio package or to some module package,
 # they will be excluded from compile and install of all
-EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc systemd
+EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc systemd geoip2 phonenum
 
 # module groups that are packaged in seperate packages
 # (with the name kamailio-$(group_name)-modules)
@@ -35,7 +35,7 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc systemd
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph dnssec kazoo cnxcc \
                           erlang rabbitmq
index 2a1920b..d2ae4f0 100755 (executable)
@@ -26,7 +26,7 @@ EXCLUDED_MODULES=
 # extra modules to skip, because they are not compilable now
 # - regardless if they go to the main kamailio package or to some module package,
 # they will be excluded from compile and install of all
-EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec kazoo cnxcc systemd rabbitmq
+EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec kazoo cnxcc systemd rabbitmq geoip2 phonenum
 
 # module groups that are packaged in seperate packages
 # (with the name kamailio-$(group_name)-modules)
@@ -34,7 +34,7 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy mi_xmlrpc dnssec kazoo c
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph \
                           erlang 
index 18997bc..7c6c39f 100644 (file)
@@ -27,11 +27,13 @@ Build-Depends:
  libjson-c-dev,
  libldap2-dev,
  liblua5.1-0-dev,
+ libmaxminddb-dev,
  libmemcached-dev,
  libmono-2.0-dev,
  libncurses5-dev,
  libpcre3-dev,
  libperl-dev,
+ libphonenumber-dev (>= 7),
  libpq-dev,
  librabbitmq-dev,
  libradcli-dev,
@@ -147,6 +149,24 @@ Description: The geoip module for the Kamailio SIP Server
  This package provides the geoip module, an extension enabling
  usage of the GeoIP API within the Kamailio configuration file.
 
+Package: kamailio-geoip2-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: The geoip2 module for the Kamailio SIP Server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides the geoip2 module, an extension enabling
+ real-time queries against the Max Mind GeoIP2 database within the Kamailio
+ configuration file.
+
 Package: kamailio-sqlite-modules
 Architecture: linux-any
 Multi-Arch: same
@@ -758,6 +778,23 @@ Description: systemd logging modules for the Kamailio SIP server
  This package provides logging to systemd journal directly from the
  Kamailio configuration and routing scripts.
 
+Package: kamailio-phonenum-modules
+Architecture: linux-any
+Multi-Arch: same
+Pre-Depends:
+ ${misc:Pre-Depends},
+Depends:
+ kamailio (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: phonenum modules for the Kamailio SIP server
+ Kamailio is a very fast and flexible SIP (RFC3261)
+ server. Written entirely in C, Kamailio can handle thousands calls
+ per second even on low-budget hardware.
+ .
+ This package provides real-time queries against the libphonenumber to be
+ performed directly from the Kamailio configuration and routing scripts.
+
 Package: kamailio-extra-modules
 Architecture: linux-any
 Multi-Arch: same
index 7319a6c..71f9338 100755 (executable)
@@ -35,10 +35,10 @@ EXTRA_EXCLUDED_MODULES=bdb dbtext oracle pa iptrtpproxy
 # on which other depend first)
 PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
                           ldap xml perl utils lua memcached \
-                          snmpstats carrierroute xmpp cpl redis python geoip\
+                          snmpstats carrierroute xmpp cpl redis python geoip geoip2 \
                           sqlite json mono ims sctp java \
                           tls outbound websocket autheph dnssec kazoo cnxcc \
-                          erlang systemd rabbitmq
+                          erlang systemd phonenum rabbitmq
 
 # module groups to be packaged onto kamailio-extra-modules
 EXTRA_GROUPS=gzcompress uuid ev jansson http_async
index e9b6705..52bad0b 100644 (file)
@@ -21,7 +21,7 @@ mod_list_basic=async auth benchmark blst cfg_rpc cfgutils corex counters \
 mod_list_extra=avp auth_diameter call_control call_obj dmq domainpolicy msrp \
                             pdb qos sca seas sms sst timer tmrec uac_redirect xhttp \
                                 xhttp_rpc xprint jsonrpcs nosip dmq_usrloc statsd rtjson \
-                                log_custom keepalive ss7ops app_sqlang acc_diameter
+                                log_custom keepalive ss7ops app_sqlang acc_diameter evrexec
 
 # - common modules depending on database
 mod_list_db=acc alias_db auth_db avpops cfg_db db_text db_flatstore \
index 4548d32..8510512 100644 (file)
@@ -1556,11 +1556,11 @@ assign_stm:
        | MAX_WLOOPS EQUAL error { yyerror("number expected"); }
        | PVBUFSIZE EQUAL NUMBER { pv_set_buffer_size($3); }
        | PVBUFSIZE EQUAL error { yyerror("number expected"); }
-       | PVBUFSLOTS EQUAL NUMBER { default_core_cfg.pv_cache_limit=$3; }
+       | PVBUFSLOTS EQUAL NUMBER { pv_set_buffer_slots($3); }
        | PVBUFSLOTS EQUAL error { yyerror("number expected"); }
-       | PVCACHELIMIT EQUAL NUMBER { default_core_cfg.pv_cache_action=$3; }
+       | PVCACHELIMIT EQUAL NUMBER { default_core_cfg.pv_cache_limit=$3; }
        | PVCACHELIMIT EQUAL error { yyerror("number expected"); }
-       | PVCACHEACTION EQUAL NUMBER { pv_set_buffer_slots($3); }
+       | PVCACHEACTION EQUAL NUMBER { default_core_cfg.pv_cache_action=$3; }
        | PVCACHEACTION EQUAL error { yyerror("number expected"); }
        | HTTP_REPLY_PARSE EQUAL NUMBER { http_reply_parse=$3; }
        | HTTP_REPLY_PARSE EQUAL error { yyerror("boolean value expected"); }
index de07f05..55630c2 100644 (file)
@@ -938,6 +938,7 @@ static int sr_kemi_hdr_append_after(sip_msg_t *msg, str *txt, str *hname)
                        if (cmp_hdrname_str(&hf->name, &hfm.name)!=0)
                                continue;
                }
+               break;
        }
 
        hdr = (char*)pkg_malloc(txt->len);
@@ -1129,16 +1130,15 @@ static int sr_kemi_hdr_insert_before(sip_msg_t *msg, str *txt, str *hname)
                        if (cmp_hdrname_str(&hf->name, &hfm.name)!=0)
                                continue;
                }
+               break;
        }
 
-       hf = msg->headers;
        hdr = (char*)pkg_malloc(txt->len);
        if(hdr==NULL) {
                LM_ERR("no pkg memory left\n");
                return -1;
        }
        memcpy(hdr, txt->s, txt->len);
-       anchor = anchor_lump(msg, hf->name.s + hf->len - msg->buf, 0, 0);
        if(hf==0) { /* before first header */
                anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0);
        } else { /* before hf */
index 0e4d4d3..dac770a 100644 (file)
@@ -289,6 +289,7 @@ int pv_cache_drop(void)
                                pkg_free(pvi);
                                return 1;
                        }
+                       pvp = pvi;
                        pvi = pvi->next;
                }
        }
@@ -310,6 +311,7 @@ int pv_cache_drop(void)
                                pkg_free(pvi);
                                return 1;
                        }
+                       pvp = pvi;
                        pvi = pvi->next;
                }
        }
@@ -2105,7 +2107,8 @@ char* pv_get_buffer(void)
        char *p;
 
        p = _pv_print_buffer[_pv_print_buffer_index];
-       _pv_print_buffer_index = (_pv_print_buffer_index+1)%_pv_print_buffer_slots;
+       _pv_print_buffer_index = (_pv_print_buffer_index+1)
+                       % _pv_print_buffer_slots_active;
 
        return p;
 }
@@ -2115,7 +2118,7 @@ char* pv_get_buffer(void)
  */
 int pv_get_buffer_size(void)
 {
-       return _pv_print_buffer_size;
+       return _pv_print_buffer_size_active;
 }
 
 /**
@@ -2123,7 +2126,7 @@ int pv_get_buffer_size(void)
  */
 int pv_get_buffer_slots(void)
 {
-       return _pv_print_buffer_slots;
+       return _pv_print_buffer_slots_active;
 }
 
 /**
index bb9342a..7729467 100644 (file)
@@ -50,7 +50,7 @@
 #endif
 #include "select_buf.h"
 
-#include "tcp_server.h" /* for tcpconn_add_alias */
+#include "tcp_server.h"  /* for tcpconn_add_alias */
 #include "tcp_options.h" /* for access to tcp_accept_aliases*/
 #include "cfg/cfg.h"
 #include "core_stats.h"
 
 int _sr_ip_free_bind = 0;
 
-unsigned int msg_no=0;
+unsigned int msg_no = 0;
 /* address preset vars */
-str default_global_address={0,0};
-str default_global_port={0,0};
-str default_via_address={0,0};
-str default_via_port={0,0};
+str default_global_address = {0, 0};
+str default_global_port = {0, 0};
+str default_via_address = {0, 0};
+str default_via_port = {0, 0};
 
 /**
  * increment msg_no and return the new value
@@ -80,27 +80,30 @@ unsigned int inc_msg_no(void)
 /**
  *
  */
-int sip_check_fline(charbuf, unsigned int len)
+int sip_check_fline(char *buf, unsigned int len)
 {
        char *p;
        int m;
 
        m = 0;
-       for(p=buf; p<buf+len; p++) {
+       for(p = buf; p < buf + len; p++) {
                /* first check if is a reply - starts with SIP/2.0 */
-               if(m==0) {
-                       if(*p==' ' || *p=='\t' || *p=='\r' || *p=='\n') continue;
-                       if(buf+len-p<10) return -1;
-                       if(strncmp(p, "SIP/2.0 ", 8)==0) {
+               if(m == 0) {
+                       if(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
+                               continue;
+                       if(buf + len - p < 10)
+                               return -1;
+                       if(strncmp(p, "SIP/2.0 ", 8) == 0) {
                                LM_DBG("first line indicates a SIP reply\n");
                                return 0;
                        }
-                       m=1;
+                       m = 1;
                } else {
                        /* check if a request - before end of first line is SIP/2.0 */
-                       if(*p!='\r' && *p!='\n') continue;
-                       if(p-10>=buf) {
-                               if(strncmp(p-8, " SIP/2.0", 8)==0) {
+                       if(*p != '\r' && *p != '\n')
+                               continue;
+                       if(p - 10 >= buf) {
+                               if(strncmp(p - 8, " SIP/2.0", 8) == 0) {
                                        LM_DBG("first line indicates a SIP request\n");
                                        return 0;
                                }
@@ -115,9 +118,9 @@ int sip_check_fline(char* buf, unsigned int len)
  *  WARNING: buf must be 0 terminated (buf[len]=0) or some things might
  * break (e.g.: modules/textops)
  */
-int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
+int receive_msg(char *buf, unsigned int len, struct receive_info *rcv_info)
 {
-       struct sip_msgmsg;
+       struct sip_msg *msg;
        struct run_act_ctx ctx;
        struct run_act_ctx *bctx;
        int ret;
@@ -136,68 +139,70 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
        sr_event_param_t evp = {0};
 
        if(sr_event_enabled(SREV_NET_DATA_RECV)) {
-               if(sip_check_fline(buf, len)==0) {
+               if(sip_check_fline(buf, len) == 0) {
                        memset(&netinfo, 0, sizeof(sr_net_info_t));
                        netinfo.data.s = buf;
                        netinfo.data.len = len;
                        netinfo.rcv = rcv_info;
-                       evp.data = (void*)&netinfo;
+                       evp.data = (void *)&netinfo;
                        sr_event_exec(SREV_NET_DATA_RECV, &evp);
                }
        }
 
        inb.s = buf;
        inb.len = len;
-       evp.data = (void*)&inb;
+       evp.data = (void *)&inb;
        evp.rcv = rcv_info;
        sr_event_exec(SREV_NET_DATA_IN, &evp);
        len = inb.len;
 
-       msg=pkg_malloc(sizeof(struct sip_msg));
-       if (msg==0) {
+       msg = pkg_malloc(sizeof(struct sip_msg));
+       if(msg == 0) {
                LM_ERR("no mem for sip_msg\n");
                goto error00;
        }
        msg_no++;
        /* number of vias parsed -- good for diagnostic info in replies */
-       via_cnt=0;
+       via_cnt = 0;
 
-       memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
+       memset(msg, 0, sizeof(struct sip_msg)); /* init everything to 0 */
        /* fill in msg */
-       msg->buf=buf;
-       msg->len=len;
+       msg->buf = buf;
+       msg->len = len;
        /* zero termination (termination of orig message bellow not that
         * useful as most of the work is done with scratch-pad; -jiri  */
        /* buf[len]=0; */ /* WARNING: zero term removed! */
-       msg->rcv=*rcv_info;
-       msg->id=msg_no;
-       msg->pid=my_pid();
-       msg->set_global_address=default_global_address;
-       msg->set_global_port=default_global_port;
-
-       if(likely(sr_msg_time==1)) msg_set_time(msg);
-
-       if (parse_msg(buf,len, msg)!=0){
-               evp.data = (void*)msg;
-               if((ret=sr_event_exec(SREV_RCV_NOSIP, &evp))<NONSIP_MSG_DROP) {
+       msg->rcv = *rcv_info;
+       msg->id = msg_no;
+       msg->pid = my_pid();
+       msg->set_global_address = default_global_address;
+       msg->set_global_port = default_global_port;
+
+       if(likely(sr_msg_time == 1))
+               msg_set_time(msg);
+
+       if(parse_msg(buf, len, msg) != 0) {
+               evp.data = (void *)msg;
+               if((ret = sr_event_exec(SREV_RCV_NOSIP, &evp)) < NONSIP_MSG_DROP) {
                        LOG(cfg_get(core, core_cfg, corelog),
-                               "core parsing of SIP message failed (%s:%d/%d)\n",
-                               ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
-                               (int)msg->rcv.proto);
+                                       "core parsing of SIP message failed (%s:%d/%d)\n",
+                                       ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
+                                       (int)msg->rcv.proto);
                        sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
-               }
-               else if(ret == NONSIP_MSG_DROP) goto error02;
+               } else if(ret == NONSIP_MSG_DROP)
+                       goto error02;
        }
 
-       if(parse_headers(msg, HDR_FROM_F|HDR_TO_F|HDR_CALLID_F|HDR_CSEQ_F, 0)<0) {
+       if(parse_headers(msg, HDR_FROM_F | HDR_TO_F | HDR_CALLID_F | HDR_CSEQ_F, 0)
+                       < 0) {
                LM_WARN("parsing relevant headers failed\n");
        }
        LM_DBG("--- received sip message - %s - call-id: [%.*s] - cseq: [%.*s]\n",
-                       (msg->first_line.type==SIP_REQUEST)?"request":"reply",
-                       (msg->callid && msg->callid->body.s)?msg->callid->body.len:0,
-                       (msg->callid && msg->callid->body.s)?msg->callid->body.s:"",
-                       (msg->cseq && msg->cseq->body.s)?msg->cseq->body.len:0,
-                       (msg->cseq && msg->cseq->body.s)?msg->cseq->body.s:"");
+                       (msg->first_line.type == SIP_REQUEST) ? "request" : "reply",
+                       (msg->callid && msg->callid->body.s) ? msg->callid->body.len : 0,
+                       (msg->callid && msg->callid->body.s) ? msg->callid->body.s : "",
+                       (msg->cseq && msg->cseq->body.s) ? msg->cseq->body.len : 0,
+                       (msg->cseq && msg->cseq->body.s) ? msg->cseq->body.s : "");
 
        /* set log prefix */
        log_prefix_set(msg);
@@ -205,45 +210,45 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
        /* ... clear branches from previous message */
        clear_branches();
 
-       if (msg->first_line.type==SIP_REQUEST){
+       if(msg->first_line.type == SIP_REQUEST) {
                ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
-               if (!IS_SIP(msg)){
-                       if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
-                               if (unlikely(ret==NONSIP_MSG_ERROR))
+               if(!IS_SIP(msg)) {
+                       if((ret = nonsip_msg_run_hooks(msg)) != NONSIP_MSG_ACCEPT) {
+                               if(unlikely(ret == NONSIP_MSG_ERROR))
                                        goto error03;
                                goto end; /* drop the message */
                        }
                }
                /* sanity checks */
-               if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
+               if((msg->via1 == 0) || (msg->via1->error != PARSE_OK)) {
                        /* no via, send back error ? */
                        LM_ERR("no via found in request\n");
                        STATS_BAD_MSG();
                        goto error02;
                }
-               /* check if necessary to add receive?->moved to forward_req */
-               /* check for the alias stuff */
+/* check if necessary to add receive?->moved to forward_req */
+/* check for the alias stuff */
 #ifdef USE_TCP
-               if (msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases) &&
-                               (((rcv_info->proto==PROTO_TCP) && !tcp_disable)
+               if(msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases)
+                               && (((rcv_info->proto == PROTO_TCP) && !tcp_disable)
 #ifdef USE_TLS
-                                       || ((rcv_info->proto==PROTO_TLS) && !tls_disable)
+                                                  || ((rcv_info->proto == PROTO_TLS) && !tls_disable)
 #endif
-                               )
-                       ){
-                       if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
-                                                                       rcv_info->proto)!=0){
+                                                                  )) {
+                       if(tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
+                                          rcv_info->proto)
+                                       != 0) {
                                LM_ERR("tcp alias failed\n");
                                /* continue */
                        }
                }
 #endif
 
-       /*      skip: */
+               /*      skip: */
                LM_DBG("preparing to run routing scripts...\n");
                if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
-                               || stats_on==1) {
-                       gettimeofday( & tvb, &tz );
+                               || stats_on == 1) {
+                       gettimeofday(&tvb, &tz);
                }
                /* execute pre-script callbacks, if any; -jiri */
                /* if some of the callbacks said not to continue with
@@ -252,48 +257,48 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                 * (like presence of at least one via), so you can count
                 * on via1 being parsed in a pre-script callback --andrei
                */
-               if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
-               {
+               if(exec_pre_script_cb(msg, REQUEST_CB_TYPE) == 0) {
                        STATS_REQ_FWD_DROP();
                        goto end; /* drop the request */
                }
 
                set_route_type(REQUEST_ROUTE);
                /* exec the routing script */
-               if(unlikely(main_rt.rlist[DEFAULT_RT]==NULL)) {
+               if(unlikely(main_rt.rlist[DEFAULT_RT] == NULL)) {
                        keng = sr_kemi_eng_get();
-                       if(keng==NULL) {
+                       if(keng == NULL) {
                                LM_ERR("no config routing engine registered\n");
                                goto error_req;
                        }
-                       if(keng->froute(msg, REQUEST_ROUTE, NULL, NULL)<0) {
+                       if(keng->froute(msg, REQUEST_ROUTE, NULL, NULL) < 0) {
                                LM_NOTICE("negative return code from engine function\n");
                        }
                } else {
-                       if (run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0)<0){
+                       if(run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0) < 0) {
                                LM_WARN("error while trying script\n");
                                goto error_req;
                        }
                }
 
                if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
-                               || stats_on==1) {
-                       gettimeofday( & tve, &tz );
-                       diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
+                               || stats_on == 1) {
+                       gettimeofday(&tve, &tz);
+                       diff = (tve.tv_sec - tvb.tv_sec) * 1000000
+                                  + (tve.tv_usec - tvb.tv_usec);
                        LOG(cfg_get(core, core_cfg, latency_cfg_log),
                                        "request-route executed in: %d usec\n", diff);
 #ifdef STATS
                        stats->processed_requests++;
                        stats->acc_req_time += diff;
-                       STATS_RX_REQUEST( msg->first_line.u.request.method_value );
+                       STATS_RX_REQUEST(msg->first_line.u.request.method_value);
 #endif
                }
 
                /* execute post request-script callbacks */
                exec_post_script_cb(msg, REQUEST_CB_TYPE);
-       }else if (msg->first_line.type==SIP_REPLY){
+       } else if(msg->first_line.type == SIP_REPLY) {
                /* sanity checks */
-               if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
+               if((msg->via1 == 0) || (msg->via1->error != PARSE_OK)) {
                        /* no via, send back error ? */
                        LM_ERR("no via found in reply\n");
                        STATS_BAD_RPL();
@@ -301,11 +306,11 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                }
 
                if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
-                               || stats_on==1) {
-                       gettimeofday( & tvb, &tz );
+                               || stats_on == 1) {
+                       gettimeofday(&tvb, &tz);
                }
 #ifdef STATS
-               STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
+               STATS_RX_RESPONSE(msg->first_line.u.reply.statuscode / 100);
 #endif
 
                /* execute pre-script callbacks, if any; -jiri */
@@ -315,33 +320,32 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                 * (like presence of at least one via), so you can count
                 * on via1 being parsed in a pre-script callback --andrei
                */
-               if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
-               {
+               if(exec_pre_script_cb(msg, ONREPLY_CB_TYPE) == 0) {
                        STATS_RPL_FWD_DROP();
                        goto end; /* drop the reply */
                }
 
                /* exec the onreply routing script */
                keng = sr_kemi_eng_get();
-               if (onreply_rt.rlist[DEFAULT_RT]!=NULL || keng!=NULL){
+               if(onreply_rt.rlist[DEFAULT_RT] != NULL || keng != NULL) {
                        set_route_type(CORE_ONREPLY_ROUTE);
                        ret = 1;
-                       if(unlikely(keng!=NULL)) {
+                       if(unlikely(keng != NULL)) {
                                bctx = sr_kemi_act_ctx_get();
                                init_run_actions_ctx(&ctx);
                                sr_kemi_act_ctx_set(&ctx);
                                ret = keng->froute(msg, CORE_ONREPLY_ROUTE, NULL, NULL);
                                sr_kemi_act_ctx_set(bctx);
                        } else {
-                               ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
+                               ret = run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
                        }
 #ifndef NO_ONREPLY_ROUTE_ERROR
-                       if (unlikely(ret<0)){
+                       if(unlikely(ret < 0)) {
                                LM_WARN("error while trying onreply script\n");
                                goto error_rpl;
-                       }else
+                       } else
 #endif /* NO_ONREPLY_ROUTE_ERROR */
-                       if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
+                                       if(unlikely(ret == 0 || (ctx.run_flags & DROP_R_F))) {
                                STATS_RPL_FWD_DROP();
                                goto skip_send_reply; /* drop the message, no error */
                        }
@@ -350,14 +354,15 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                forward_reply(msg);
        skip_send_reply:
                if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
-                               || stats_on==1) {
-                       gettimeofday( & tve, &tz );
-                       diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
+                               || stats_on == 1) {
+                       gettimeofday(&tve, &tz);
+                       diff = (tve.tv_sec - tvb.tv_sec) * 1000000
+                                  + (tve.tv_usec - tvb.tv_usec);
                        LOG(cfg_get(core, core_cfg, latency_cfg_log),
                                        "reply-route executed in: %d usec\n", diff);
 #ifdef STATS
                        stats->processed_responses++;
-                       stats->acc_res_time+=diff;
+                       stats->acc_res_time += diff;
 #endif
                }
 
@@ -374,7 +379,8 @@ end:
        free_sip_msg(msg);
        pkg_free(msg);
 #ifdef STATS
-       if (skipped) STATS_RX_DROPS;
+       if(skipped)
+               STATS_RX_DROPS;
 #endif
        /* reset log prefix */
        log_prefix_set(NULL);
@@ -411,5 +417,4 @@ void ksr_msg_env_reset(void)
 #ifdef WITH_XAVP
        xavp_reset_list();
 #endif
-
 }
index d1f2ae7..112dee4 100644 (file)
@@ -1286,7 +1286,7 @@ ABSTRACT_F(select_dst)
 ABSTRACT_F(select_rcv)
 int select_ip_port(str* res, select_t* s, struct sip_msg* msg)
 {
-       str ip_str=STR_NULL, port_str=STR_NULL, proto_str=STR_NULL;
+       str ip_str=STR_NULL, port_str=STR_NULL, proto_str=str_init("udp");
        int param, pos;
        
 
index 0392136..b88d3d8 100644 (file)
@@ -425,7 +425,9 @@ int udp_rcv_loop()
        unsigned int fromlen;
        struct receive_info ri;
        sr_event_param_t evp = {0};
-       char printbuf[512];
+#define UDP_RCV_PRINTBUF_SIZE 512
+#define UDP_RCV_PRINT_LEN 100
+       char printbuf[UDP_RCV_PRINTBUF_SIZE];
        int i;
        int j;
        int l;
@@ -472,20 +474,22 @@ int udp_rcv_loop()
 
                if(is_printable(L_DBG) && len>10) {
                        j = 0;
-                       for(i=0; i<len && i<100; i++) {
+                       for(i=0; i<len && i<UDP_RCV_PRINT_LEN
+                                               && j+8<UDP_RCV_PRINTBUF_SIZE; i++) {
                                if(isprint(buf[i])) {
                                        printbuf[j++] = buf[i];
                                } else {
                                        l = snprintf(printbuf+j, 6, " %02X ", buf[i]);
                                        if(l<0 || l>=6) {
-                                               LM_ERR("print buffer building failed\n");
+                                               LM_ERR("print buffer building failed (%d/%d/%d)\n",
+                                                               l, j, i);
                                                goto error;
                                        }
                                        j += l;
                                }
                        }
-                       LM_DBG("received on udp socket: (%d/%d) [[%.*s]]\n",
-                                       j, len, len, printbuf);
+                       LM_DBG("received on udp socket: (%d/%d/%d) [[%.*s]]\n",
+                                       j, i, len, j, printbuf);
                }
                ri.src_su=*from;
                su2ip_addr(&ri.src_ip, from);
index 85984fa..5b13333 100644 (file)
         <colref linkend="a_callid"/>
     </index>
 
+    <index>
+        <name>a_uuid_idx</name>
+        <colref linkend="a_uuid"/>
+    </index>
+
+    <index>
+        <name>b_uuid_idx</name>
+        <colref linkend="b_uuid"/>
+    </index>
+
 </table>
index 793fed4..c6bc095 100644 (file)
         <colref linkend="a_callid"/>
     </index>
 
+    <index>
+        <name>x_vbranch_idx</name>
+        <colref linkend="x_vbranch"/>
+    </index>
+
+    <index>
+        <name>a_uuid_idx</name>
+        <colref linkend="a_uuid"/>
+    </index>
+
 </table>
index 94e521f..ce68aa7 100644 (file)
@@ -41,6 +41,7 @@
 #include "../../core/dprint.h"
 #include "../../core/mem/mem.h"
 #include "../../core/parser/parse_to.h"
+#include "../../core/kemi.h"
 #include "../misc_radius/radius.h"
 #include "../../modules/acc/acc_api.h"
 #include "acc_radius_mod.h"
@@ -56,8 +57,8 @@ int acc_radius_init(acc_init_info_t *inf);
 int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf);
 
 static int w_acc_radius_request(struct sip_msg *rq, char *comment, char *foo);
-static int acc_api_fixup(void** param, int param_no);
-static int free_acc_api_fixup(void** param, int param_no);
+static int acc_api_fixup(void **param, int param_no);
+static int free_acc_api_fixup(void **param, int param_no);
 
 int init_acc_rad(acc_extra_t *leg_info, char *rad_cfg, int srv_type);
 int extra2attrs(struct acc_extra *extra, struct attr *attrs, int offset);
@@ -74,7 +75,7 @@ static char *radius_config = 0;
 int radius_flag = -1;
 int radius_missed_flag = -1;
 static int service_type = -1;
-int rad_time_mode=0;
+int rad_time_mode = 0;
 void *rh;
 /* rad extra variables */
 static char *rad_extra_str = 0;
@@ -82,10 +83,10 @@ acc_extra_t *rad_extra = 0;
 /*@}*/
 
 
+/* clang-format off */
 static cmd_export_t cmds[] = {
        {"acc_rad_request", (cmd_function)w_acc_radius_request, 1,
-               acc_api_fixup, free_acc_api_fixup,
-               ANY_ROUTE},
+               acc_api_fixup, free_acc_api_fixup, ANY_ROUTE},
        {0, 0, 0, 0, 0, 0}
 };
 
@@ -116,26 +117,26 @@ struct module_exports exports= {
        destroy,    /* destroy function */
        child_init  /* per-child init function */
 };
-
+/* clang-format on */
 
 
 /************************** INTERFACE functions ****************************/
 
-static int mod_init( void )
+static int mod_init(void)
 {
-       if (radius_config==NULL || radius_config[0]=='\0') {
+       if(radius_config == NULL || radius_config[0] == '\0') {
                LM_ERR("radius config file not set\n");
                return -1;
        }
 
        /* bind the ACC API */
-       if (acc_load_api(&accb)<0) {
+       if(acc_load_api(&accb) < 0) {
                LM_ERR("cannot bind to ACC API\n");
                return -1;
        }
 
        /* parse the extra string, if any */
-       if (rad_extra_str && (rad_extra=accb.parse_extra(rad_extra_str))==0 ) {
+       if(rad_extra_str && (rad_extra = accb.parse_extra(rad_extra_str)) == 0) {
                LM_ERR("failed to parse rad_extra param\n");
                return -1;
        }
@@ -143,14 +144,13 @@ static int mod_init( void )
        memset(&_acc_radius_engine, 0, sizeof(acc_engine_t));
 
        if(radius_flag != -1)
-               _acc_radius_engine.acc_flag        = 1<<radius_flag;
+               _acc_radius_engine.acc_flag = 1 << radius_flag;
        if(radius_missed_flag != -1)
-               _acc_radius_engine.missed_flag = 1<<radius_missed_flag;
-       _acc_radius_engine.acc_req     = acc_radius_send_request;
-       _acc_radius_engine.acc_init    = acc_radius_init;
+               _acc_radius_engine.missed_flag = 1 << radius_missed_flag;
+       _acc_radius_engine.acc_req = acc_radius_send_request;
+       _acc_radius_engine.acc_init = acc_radius_init;
        memcpy(_acc_radius_engine.name, "radius", 6);
-       if(accb.register_engine(&_acc_radius_engine)<0)
-       {
+       if(accb.register_engine(&_acc_radius_engine) < 0) {
                LM_ERR("cannot register ACC RADIUS engine\n");
                return -1;
        }
@@ -161,7 +161,7 @@ static int mod_init( void )
 
 static int child_init(int rank)
 {
-       if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
+       if(rank == PROC_INIT || rank == PROC_MAIN || rank == PROC_TCP_MAIN)
                return 0; /* do nothing for the main process */
 
        return 0;
@@ -172,45 +172,45 @@ static void destroy(void)
 {
 }
 
-static int acc_api_fixup(void** param, int param_no)
+static int acc_api_fixup(void **param, int param_no)
 {
        struct acc_param *accp;
        char *p;
 
-       p = (char*)*param;
-       if (p==0 || p[0]==0) {
+       p = (char *)*param;
+       if(p == 0 || p[0] == 0) {
                LM_ERR("first parameter is empty\n");
                return E_SCRIPT;
        }
 
-       if (param_no == 1) {
-               accp = (struct acc_param*)pkg_malloc(sizeof(struct acc_param));
-               if (!accp) {
+       if(param_no == 1) {
+               accp = (struct acc_param *)pkg_malloc(sizeof(struct acc_param));
+               if(!accp) {
                        LM_ERR("no more pkg mem\n");
                        return E_OUT_OF_MEM;
                }
-               memset( accp, 0, sizeof(struct acc_param));
+               memset(accp, 0, sizeof(struct acc_param));
                accp->reason.s = p;
                accp->reason.len = strlen(p);
                /* any code? */
-               if (accp->reason.len>=3 && isdigit((int)p[0])
-                               && isdigit((int)p[1]) && isdigit((int)p[2]) ) {
-                       accp->code = (p[0]-'0')*100 + (p[1]-'0')*10 + (p[2]-'0');
+               if(accp->reason.len >= 3 && isdigit((int)p[0]) && isdigit((int)p[1])
+                               && isdigit((int)p[2])) {
+                       accp->code = (p[0] - '0') * 100 + (p[1] - '0') * 10 + (p[2] - '0');
                        accp->code_s.s = p;
                        accp->code_s.len = 3;
                        accp->reason.s += 3;
-                       for( ; isspace((int)accp->reason.s[0]) ; accp->reason.s++ );
+                       for(; isspace((int)accp->reason.s[0]); accp->reason.s++)
+                               ;
                        accp->reason.len = strlen(accp->reason.s);
                }
-               *param = (void*)accp;
+               *param = (void *)accp;
        }
        return 0;
 }
 
-static int free_acc_api_fixup(void** param, int param_no)
+static int free_acc_api_fixup(void **param, int param_no)
 {
-       if(*param)
-       {
+       if(*param) {
                pkg_free(*param);
                *param = 0;
        }
@@ -218,12 +218,26 @@ static int free_acc_api_fixup(void** param, int param_no)
 }
 
 
-enum { RA_ACCT_STATUS_TYPE=0, RA_SERVICE_TYPE, RA_SIP_RESPONSE_CODE,
-       RA_SIP_METHOD, RA_TIME_STAMP, RA_STATIC_MAX};
-enum {RV_STATUS_START=0, RV_STATUS_STOP, RV_STATUS_ALIVE, RV_STATUS_FAILED,
-       RV_SIP_SESSION, RV_STATIC_MAX};
-static struct attr
-               rd_attrs[RA_STATIC_MAX+ACC_CORE_LEN-2+MAX_ACC_EXTRA+MAX_ACC_LEG];
+enum
+{
+       RA_ACCT_STATUS_TYPE = 0,
+       RA_SERVICE_TYPE,
+       RA_SIP_RESPONSE_CODE,
+       RA_SIP_METHOD,
+       RA_TIME_STAMP,
+       RA_STATIC_MAX
+};
+enum
+{
+       RV_STATUS_START = 0,
+       RV_STATUS_STOP,
+       RV_STATUS_ALIVE,
+       RV_STATUS_FAILED,
+       RV_SIP_SESSION,
+       RV_STATIC_MAX
+};
+static struct attr rd_attrs[RA_STATIC_MAX + ACC_CORE_LEN - 2 + MAX_ACC_EXTRA
+                                                       + MAX_ACC_LEG];
 static struct val rd_vals[RV_STATIC_MAX];
 
 int init_acc_rad(acc_extra_t *leg_info, char *rad_cfg, int srv_type)
@@ -232,42 +246,42 @@ int init_acc_rad(acc_extra_t *leg_info, char *rad_cfg, int srv_type)
 
        memset(rd_attrs, 0, sizeof(rd_attrs));
        memset(rd_vals, 0, sizeof(rd_vals));
-       rd_attrs[RA_ACCT_STATUS_TYPE].n  = "Acct-Status-Type";
-       rd_attrs[RA_SERVICE_TYPE].n      = "Service-Type";
+       rd_attrs[RA_ACCT_STATUS_TYPE].n = "Acct-Status-Type";
+       rd_attrs[RA_SERVICE_TYPE].n = "Service-Type";
        rd_attrs[RA_SIP_RESPONSE_CODE].n = "Sip-Response-Code";
-       rd_attrs[RA_SIP_METHOD].n        = "Sip-Method";
-       rd_attrs[RA_TIME_STAMP].n        = "Event-Timestamp";
+       rd_attrs[RA_SIP_METHOD].n = "Sip-Method";
+       rd_attrs[RA_TIME_STAMP].n = "Event-Timestamp";
        n = RA_STATIC_MAX;
        /* caution: keep these aligned to core acc output */
-       rd_attrs[n++].n                  = "Sip-From-Tag";
-       rd_attrs[n++].n                  = "Sip-To-Tag";
-       rd_attrs[n++].n                  = "Acct-Session-Id";
+       rd_attrs[n++].n = "Sip-From-Tag";
+       rd_attrs[n++].n = "Sip-To-Tag";
+       rd_attrs[n++].n = "Acct-Session-Id";
 
-       rd_vals[RV_STATUS_START].n        = "Start";
-       rd_vals[RV_STATUS_STOP].n         = "Stop";
-       rd_vals[RV_STATUS_ALIVE].n        = "Alive";
-       rd_vals[RV_STATUS_FAILED].n       = "Failed";
-       rd_vals[RV_SIP_SESSION].n         = "Sip-Session";
+       rd_vals[RV_STATUS_START].n = "Start";
+       rd_vals[RV_STATUS_STOP].n = "Stop";
+       rd_vals[RV_STATUS_ALIVE].n = "Alive";
+       rd_vals[RV_STATUS_FAILED].n = "Failed";
+       rd_vals[RV_SIP_SESSION].n = "Sip-Session";
 
        /* add and count the extras as attributes */
-       n += extra2attrs( rad_extra, rd_attrs, n);
+       n += extra2attrs(rad_extra, rd_attrs, n);
        /* add and count the legs as attributes */
-       n += extra2attrs( leg_info, rd_attrs, n);
+       n += extra2attrs(leg_info, rd_attrs, n);
 
        /* read config */
-       if ((rh = rc_read_config(rad_cfg)) == NULL) {
-               LM_ERR("failed to open radius config file: %s\n", rad_cfg );
+       if((rh = rc_read_config(rad_cfg)) == NULL) {
+               LM_ERR("failed to open radius config file: %s\n", rad_cfg);
                return -1;
        }
        /* read dictionary */
-       if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))!=0) {
+       if(rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
                LM_ERR("failed to read radius dictionary\n");
                return -1;
        }
 
        INIT_AV(rh, rd_attrs, n, rd_vals, RV_STATIC_MAX, "acc", -1, -1);
 
-       if (srv_type != -1)
+       if(srv_type != -1)
                rd_vals[RV_SIP_SESSION].v = srv_type;
 
        return 0;
@@ -276,8 +290,8 @@ int init_acc_rad(acc_extra_t *leg_info, char *rad_cfg, int srv_type)
 
 int acc_radius_init(acc_init_info_t *inf)
 {
-       if (radius_config && radius_config[0]) {
-               if (init_acc_rad(inf->leg_info, radius_config, service_type)!=0 ) {
+       if(radius_config && radius_config[0]) {
+               if(init_acc_rad(inf->leg_info, radius_config, service_type) != 0) {
                        LM_ERR("failed to init radius\n");
                        return -1;
                }
@@ -285,32 +299,32 @@ int acc_radius_init(acc_init_info_t *inf)
        return 0;
 }
 
-static inline uint32_t rad_status( struct sip_msg *req, int code )
+static inline uint32_t rad_status(struct sip_msg *req, int code)
 {
        str tag;
        unsigned int in_dialog_req = 0;
 
        tag = get_to(req)->tag_value;
-       if(tag.s!=0 && tag.len!=0)
+       if(tag.s != 0 && tag.len != 0)
                in_dialog_req = 1;
 
-       if (req->REQ_METHOD==METHOD_INVITE && in_dialog_req == 0
-                       && code>=200 && code<300)
+       if(req->REQ_METHOD == METHOD_INVITE && in_dialog_req == 0 && code >= 200
+                       && code < 300)
                return rd_vals[RV_STATUS_START].v;
-       if ((req->REQ_METHOD==METHOD_BYE || req->REQ_METHOD==METHOD_CANCEL))
+       if((req->REQ_METHOD == METHOD_BYE || req->REQ_METHOD == METHOD_CANCEL))
                return rd_vals[RV_STATUS_STOP].v;
-       if (in_dialog_req != 0)
+       if(in_dialog_req != 0)
                return rd_vals[RV_STATUS_ALIVE].v;
        return rd_vals[RV_STATUS_FAILED].v;
 }
 
-#define ADD_RAD_AVPAIR(_attr,_val,_len)                \
-       do {                                                            \
-               if (!rc_avpair_add(rh, &send, rd_attrs[_attr].v, _val, _len, 0)) { \
-                       LM_ERR("failed to add %s, %d\n", rd_attrs[_attr].n, _attr);     \
-                       goto error;                                                     \
-               } \
-       }while(0)
+#define ADD_RAD_AVPAIR(_attr, _val, _len)                                 \
+       do {                                                                  \
+               if(!rc_avpair_add(rh, &send, rd_attrs[_attr].v, _val, _len, 0)) { \
+                       LM_ERR("failed to add %s, %d\n", rd_attrs[_attr].n, _attr);   \
+                       goto error;                                                   \
+               }                                                                 \
+       } while(0)
 
 int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
 {
@@ -319,60 +333,61 @@ int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
        uint32_t av_type;
        int offset;
        int i;
-       int m=0;
-       int o=0;
-       int rc_result=-1;
+       int m = 0;
+       int o = 0;
+       int rc_result = -1;
        double tsecmicro;
        char smicrosec[18];
 
-       send=NULL;
+       send = NULL;
 
-       attr_cnt = accb.get_core_attrs( req, inf->varr, inf->iarr, inf->tarr );
+       attr_cnt = accb.get_core_attrs(req, inf->varr, inf->iarr, inf->tarr);
        /* not interested in the last 2 values */
        attr_cnt -= 2;
 
-       av_type = rad_status( req, inf->env->code); /* RADIUS status */
-       ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1);
+       av_type = rad_status(req, inf->env->code); /* RADIUS status */
+       ADD_RAD_AVPAIR(RA_ACCT_STATUS_TYPE, &av_type, -1);
 
        av_type = rd_vals[RV_SIP_SESSION].v; /* session*/
-       ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1);
+       ADD_RAD_AVPAIR(RA_SERVICE_TYPE, &av_type, -1);
 
        av_type = (uint32_t)inf->env->code; /* status=integer */
-       ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1);
+       ADD_RAD_AVPAIR(RA_SIP_RESPONSE_CODE, &av_type, -1);
 
        av_type = req->REQ_METHOD; /* method */
-       ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1);
+       ADD_RAD_AVPAIR(RA_SIP_METHOD, &av_type, -1);
 
        // Event Time Stamp with Microseconds
-       if(rad_time_mode==1){
+       if(rad_time_mode == 1) {
                gettimeofday(&inf->env->tv, NULL);
-               tsecmicro=inf->env->tv.tv_sec+((double)inf->env->tv.tv_usec/1000000.0);
+               tsecmicro = inf->env->tv.tv_sec
+                                       + ((double)inf->env->tv.tv_usec / 1000000.0);
                //radius client doesn t support double so convert it
-               sprintf(smicrosec,"%17.6f",tsecmicro);
+               sprintf(smicrosec, "%17.6f", tsecmicro);
                ADD_RAD_AVPAIR(RA_TIME_STAMP, &smicrosec, -1);
-       }else{
+       } else {
                av_type = (uint32_t)inf->env->ts;
                ADD_RAD_AVPAIR(RA_TIME_STAMP, &av_type, -1);
        }
 
 
        /* add extra also */
-       o = accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt,
-                       inf->iarr+attr_cnt, inf->tarr+attr_cnt);
+       o = accb.get_extra_attrs(rad_extra, req, inf->varr + attr_cnt,
+                       inf->iarr + attr_cnt, inf->tarr + attr_cnt);
        attr_cnt += o;
        m = attr_cnt;
 
 
        /* add the values for the vector - start from 1 instead of
         * 0 to skip the first value which is the METHOD as string */
-       offset = RA_STATIC_MAX-1;
-       for( i=1; i<attr_cnt; i++) {
-               switch (inf->tarr[i]) {
+       offset = RA_STATIC_MAX - 1;
+       for(i = 1; i < attr_cnt; i++) {
+               switch(inf->tarr[i]) {
                        case TYPE_STR:
-                               ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len);
+                               ADD_RAD_AVPAIR(offset + i, inf->varr[i].s, inf->varr[i].len);
                                break;
                        case TYPE_INT:
-                               ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1);
+                               ADD_RAD_AVPAIR(offset + i, &(inf->iarr[i]), -1);
                                break;
                        default:
                                break;
@@ -380,46 +395,48 @@ int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
        }
 
        /* call-legs attributes also get inserted */
-       if ( inf->leg_info ) {
+       if(inf->leg_info) {
                offset += attr_cnt;
-               attr_cnt = accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,inf->tarr,1);
+               attr_cnt = accb.get_leg_attrs(
+                               inf->leg_info, req, inf->varr, inf->iarr, inf->tarr, 1);
                do {
-                       for (i=0; i<attr_cnt; i++)
-                               ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len );
-               }while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,
-                                               inf->tarr, 0))!=0 );
+                       for(i = 0; i < attr_cnt; i++)
+                               ADD_RAD_AVPAIR(offset + i, inf->varr[i].s, inf->varr[i].len);
+               } while((attr_cnt = accb.get_leg_attrs(inf->leg_info, req, inf->varr,
+                                                inf->iarr, inf->tarr, 0))
+                               != 0);
        }
 
-       rc_result=rc_acct(rh, SIP_PORT, send);
+       rc_result = rc_acct(rh, SIP_PORT, send);
 
-       if (rc_result==ERROR_RC) {
+       if(rc_result == ERROR_RC) {
                LM_ERR("Radius accounting - ERROR - \n");
                goto error;
-       }else if(rc_result==BADRESP_RC){
+       } else if(rc_result == BADRESP_RC) {
                LM_ERR("Radius accounting - BAD RESPONSE \n");
                goto error;
-       }else if(rc_result==TIMEOUT_RC){
+       } else if(rc_result == TIMEOUT_RC) {
                LM_ERR("Radius accounting - TIMEOUT \n");
                goto error;
-       }else if(rc_result==REJECT_RC){
+       } else if(rc_result == REJECT_RC) {
                LM_ERR("Radius accounting - REJECTED \n");
                goto error;
-       }else if(rc_result==OK_RC){
+       } else if(rc_result == OK_RC) {
                LM_DBG("Radius accounting - OK \n");
-       }else{
+       } else {
                LM_ERR("Radius accounting - Unknown response \n");
                goto error;
        }
 
        rc_avpair_free(send);
        /* free memory allocated by extra2strar */
-       free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
+       free_strar_mem(&(inf->tarr[m - o]), &(inf->varr[m - o]), o, m);
        return 1;
 
 error:
        rc_avpair_free(send);
        /* free memory allocated by extra2strar */
-       free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
+       free_strar_mem(&(inf->tarr[m - o]), &(inf->varr[m - o]), o, m);
        return -1;
 }
 
@@ -430,8 +447,8 @@ int extra2attrs(struct acc_extra *extra, struct attr *attrs, int offset)
 {
        int i;
 
-       for(i=0 ; extra ; i++, extra=extra->next) {
-               attrs[offset+i].n = extra->name.s;
+       for(i = 0; extra; i++, extra = extra->next) {
+               attrs[offset + i].n = extra->name.s;
        }
        return i;
 }
@@ -441,6 +458,88 @@ int extra2attrs(struct acc_extra *extra, struct attr *attrs, int offset)
  */
 static int w_acc_radius_request(struct sip_msg *rq, char *comment, char *foo)
 {
-       return accb.exec(rq, &_acc_radius_engine, (acc_param_t*)comment);
+       return accb.exec(rq, &_acc_radius_engine, (acc_param_t *)comment);
+}
+
+static int acc_radius_parse_code(char *p, acc_param_t *param)
+{
+       if(p == NULL || param == NULL)
+               return -1;
+
+       /* any code? */
+       if(param->reason.len >= 3 && isdigit((int)p[0]) && isdigit((int)p[1])
+                       && isdigit((int)p[2])) {
+               param->code = (p[0] - '0') * 100 + (p[1] - '0') * 10 + (p[2] - '0');
+               param->code_s.s = p;
+               param->code_s.len = 3;
+               param->reason.s += 3;
+               for(; isspace((int)param->reason.s[0]); param->reason.s++)
+                       ;
+               param->reason.len = strlen(param->reason.s);
+       }
+       return 0;
 }
 
+/**
+ *
+ */
+static int acc_radius_param_parse(str *s, acc_param_t *accp)
+{
+       if(s == NULL || s->s == NULL || s->len <= 0 || accp == NULL) {
+               LM_ERR("invalid parameters\n");
+               return -1;
+       }
+       memset(accp, 0, sizeof(acc_param_t));
+       accp->reason.s = s->s;
+       accp->reason.len = s->len;
+       if(strchr(s->s, PV_MARKER) != NULL) {
+               /* there is a cfg variable - not through kemi */
+               LM_ERR("cfg variable detected - not supported\n");
+               return -1;
+       } else {
+               if(acc_radius_parse_code(s->s, accp) < 0) {
+                       LM_ERR("failed to parse: [%.*s] (expected [code text])\n", s->len,
+                                       s->s);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/**
+ *
+ */
+static int ki_acc_radius_request(sip_msg_t *rq, str *comment)
+{
+       acc_param_t accp;
+
+       if(acc_radius_param_parse(comment, &accp) < 0) {
+               LM_ERR("failed to parse parameter\n");
+               return -1;
+       }
+       return accb.exec(rq, &_acc_radius_engine, &accp);
+}
+
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_acc_radius_exports[] = {
+       { str_init("acc_radius"), str_init("request"),
+               SR_KEMIP_INT, ki_acc_radius_request,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
+
+/**
+ *
+ */
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+       sr_kemi_modules_add(sr_kemi_acc_radius_exports);
+       return 0;
+}
index 7bdfcb9..37ece20 100644 (file)
@@ -136,7 +136,7 @@ int mono_sr_init_load(void)
        }
        mono_config_parse (NULL);
        mi = _sr_mono_load_list;
-       if(mi->domain != NULL)
+       if(mi && mi->domain != NULL)
        {
                LM_ERR("worker mono environment already initialized\n");
                return 0;
@@ -769,13 +769,14 @@ static int sr_mono_hdr_append (MonoString *hv)
        }
 
        hf = env_M->msg->last_header;
-       hdr = (char*)pkg_malloc(txt.len);
+       hdr = (char*)pkg_malloc(txt.len+1);
        if(hdr==NULL)
        {
                LM_ERR("no pkg memory left\n");
                goto error;
        }
        memcpy(hdr, txt.s, txt.len);
+       hdr[txt.len] = '\0';
        anchor = anchor_lump(env_M->msg,
                                hf->name.s + hf->len - env_M->msg->buf, 0, 0);
        if(insert_new_lump_before(anchor, hdr, txt.len, 0) == 0)
@@ -863,13 +864,14 @@ static int sr_mono_hdr_insert (MonoString *hv)
 
        LM_DBG("insert hf: %s\n", txt.s);
        hf = env_M->msg->headers;
-       hdr = (char*)pkg_malloc(txt.len);
+       hdr = (char*)pkg_malloc(txt.len+1);
        if(hdr==NULL)
        {
                LM_ERR("no pkg memory left\n");
                goto error;
        }
        memcpy(hdr, txt.s, txt.len);
+       hdr[txt.len] = '\0';
        anchor = anchor_lump(env_M->msg,
                                hf->name.s + hf->len - env_M->msg->buf, 0, 0);
        if(insert_new_lump_before(anchor, hdr, txt.len, 0) == 0)
index fc1ea83..fc349dc 100644 (file)
@@ -55,6 +55,8 @@ PyObject *_sr_apy_handler_obj;
 
 char *dname = NULL, *bname = NULL;
 
+int _apy_process_rank = 0;
+
 PyThreadState *myThreadState;
 
 /** module parameters */
@@ -93,16 +95,14 @@ struct module_exports exports = {
        child_init                      /* per-child init function */
 };
 
+
 /**
  *
  */
 static int mod_init(void)
 {
        char *dname_src, *bname_src;
-
        int i;
-       PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
-       PyThreadState *mainThreadState;
 
        if(apy_sr_init_mod()<0) {
                LM_ERR("failed to init the sr mod\n");
@@ -157,6 +157,48 @@ static int mod_init(void)
                return -1;
        }
 
+       if(apy_load_script()<0) {
+               pkg_free(dname_src);
+               pkg_free(bname_src);
+               LM_ERR("failed to load python script\n");
+               return -1;
+       }
+
+       pkg_free(dname_src);
+       pkg_free(bname_src);
+       return 0;
+}
+
+/**
+ *
+ */
+static int child_init(int rank)
+{
+       _apy_process_rank = rank;
+       return apy_init_script(rank);
+}
+
+/**
+ *
+ */
+static void mod_destroy(void)
+{
+       if (dname)
+               free(dname);    // dname was strdup'ed
+       if (bname)
+               free(bname);    // bname was strdup'ed
+
+       destroy_mod_Core();
+       destroy_mod_Ranks();
+       destroy_mod_Logger();
+       destroy_mod_Router();
+}
+
+int apy_load_script(void)
+{
+       PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
+       PyThreadState *mainThreadState;
+
        Py_Initialize();
        PyEval_InitThreads();
        mainThreadState = PyThreadState_Get();
@@ -167,8 +209,6 @@ static int mod_init(void)
        {
                Py_XDECREF(format_exc_obj);
                PyEval_ReleaseLock();
-               pkg_free(dname_src);
-               pkg_free(bname_src);
                return -1;
        }
 
@@ -181,8 +221,6 @@ static int mod_init(void)
                python_handle_exception("mod_init");
                Py_DECREF(format_exc_obj);
                PyEval_ReleaseLock();
-               pkg_free(dname_src);
-               pkg_free(bname_src);
                return -1;
        }
 
@@ -194,8 +232,6 @@ static int mod_init(void)
                python_handle_exception("mod_init");
                Py_DECREF(format_exc_obj);
                PyEval_ReleaseLock();
-               pkg_free(dname_src);
-               pkg_free(bname_src);
                return -1;
        }
 
@@ -208,8 +244,6 @@ static int mod_init(void)
                python_handle_exception("mod_init");
                Py_DECREF(format_exc_obj);
                PyEval_ReleaseLock();
-               pkg_free(dname_src);
-               pkg_free(bname_src);
                return -1;
        }
 
@@ -220,8 +254,6 @@ static int mod_init(void)
                python_handle_exception("mod_init");
                Py_DECREF(format_exc_obj);
                PyEval_ReleaseLock();
-               pkg_free(dname_src);
-               pkg_free(bname_src);
                return -1;
        }
 
@@ -232,14 +264,10 @@ static int mod_init(void)
                python_handle_exception("mod_init");
                Py_DECREF(format_exc_obj);
                PyEval_ReleaseLock();
-               pkg_free(dname_src);
-               pkg_free(bname_src);
+
                return -1;
        }
 
-       pkg_free(dname_src);
-       pkg_free(bname_src);
-
        pFunc = PyObject_GetAttrString(pModule, mod_init_fname.s);
        Py_DECREF(pModule);
 
@@ -322,10 +350,7 @@ static int mod_init(void)
        return 0;
 }
 
-/**
- *
- */
-static int child_init(int rank)
+int apy_init_script(int rank)
 {
        PyObject *pFunc, *pArgs, *pValue, *pResult;
        int rval;
@@ -436,23 +461,6 @@ static int child_init(int rank)
 
        return rval;
 }
-
-/**
- *
- */
-static void mod_destroy(void)
-{
-       if (dname)
-               free(dname);    // dname was strdup'ed
-       if (bname)
-               free(bname);    // bname was strdup'ed
-
-       destroy_mod_Core();
-       destroy_mod_Ranks();
-       destroy_mod_Logger();
-       destroy_mod_Router();
-}
-
 /**
  *
  */
index 5689136..e221c1d 100644 (file)
 static int *_sr_python_reload_version = NULL;
 static int _sr_python_local_version = 0;
 extern str _sr_python_load_file;
+extern int _apy_process_rank;
 
+/**
+ * 
+ */
+
+int apy_reload_script(void)
+{
+       if(_sr_python_reload_version == NULL) {
+               return 0;
+       }
+       if(*_sr_python_reload_version == _sr_python_local_version) {
+               return 0;
+       }
+       if(apy_load_script()<0) {
+               LM_ERR("failed to load script file\n");
+               return -1;
+       }
+       if(apy_init_script(_apy_process_rank)<0) {
+               LM_ERR("failed to init script\n");
+               return -1;
+       }
+       _sr_python_local_version = *_sr_python_reload_version;
+       return 0;
+}
 /**
  *
  */
@@ -1119,7 +1143,6 @@ static const char* app_python_rpc_reload_doc[2] = {
 
 static void app_python_rpc_reload(rpc_t* rpc, void* ctx)
 {
-#if 0
        int v;
        void *vh;
 
@@ -1140,6 +1163,11 @@ static void app_python_rpc_reload(rpc_t* rpc, void* ctx)
                                _sr_python_local_version, v);
        *_sr_python_reload_version += 1;
 
+       if(apy_reload_script()<0) {
+               rpc->fault(ctx, 500, "Reload failed");
+               return; 
+       }
+
        if (rpc->add(ctx, "{", &vh) < 0) {
                rpc->fault(ctx, 500, "Server error");
                return;
@@ -1147,9 +1175,7 @@ static void app_python_rpc_reload(rpc_t* rpc, void* ctx)
        rpc->struct_add(vh, "dd",
                        "old", v,
                        "new", *_sr_python_reload_version);
-#endif
 
-       rpc->fault(ctx, 500, "Not implemented");
        return;
 }
 
index ad42c0c..6cb19cd 100644 (file)
@@ -34,5 +34,7 @@ PyObject *sr_apy_kemi_exec_func(PyObject *self, PyObject *args, int idx);
 
 int apy_sr_init_mod(void);
 int app_python_init_rpc(void);
+int apy_load_script(void);
+int apy_init_script(int rank);
 
 #endif
index 90588f1..c338bcf 100644 (file)
@@ -170,7 +170,7 @@ static int w_async_sleep(sip_msg_t *msg, char *sec, char *str2)
                        LM_ERR("cannot be executed as last action in a route block\n");
                        return -1;
                }
-               if(async_sleep(msg, s, ap->u.paction->next) < 0)
+               if(async_sleep(msg, s, ap->u.paction->next, NULL) < 0)
                        return -1;
                /* force exit in config */
                return 0;
@@ -208,21 +208,27 @@ static int fixup_async_sleep(void **param, int param_no)
  */
 int ki_async_route(sip_msg_t *msg, str *rn, int s)
 {
-       cfg_action_t *act;
+       cfg_action_t *act = NULL;
        int ri;
-
-       ri = route_get(&main_rt, rn->s);
-       if(ri < 0) {
-               LM_ERR("unable to find route block [%.*s]\n", rn->len, rn->s);
-               return -1;
-       }
-       act = main_rt.rlist[ri];
-       if(act == NULL) {
-               LM_ERR("empty action lists in route block [%.*s]\n", rn->len, rn->s);
-               return -1;
+       sr_kemi_eng_t *keng = NULL;
+
+       keng = sr_kemi_eng_get();
+       if(keng == NULL) {
+               ri = route_lookup(&main_rt, rn->s);
+               if(ri >= 0) {
+                       act = main_rt.rlist[ri];
+                       if(act == NULL) {
+                               LM_ERR("empty action lists in route block [%.*s]\n", rn->len,
+                                               rn->s);
+                               return -1;
+                       }
+               } else {
+                       LM_ERR("route block not found: %.*s\n", rn->len, rn->s);
+                       return -1;
+               }
        }
 
-       if(async_sleep(msg, s, act) < 0)
+       if(async_sleep(msg, s, act, rn) < 0)
                return -1;
        /* force exit in config */
        return 0;
@@ -277,21 +283,27 @@ static int fixup_async_route(void **param, int param_no)
  */
 int ki_async_task_route(sip_msg_t *msg, str *rn)
 {
-       cfg_action_t *act;
+       cfg_action_t *act = NULL;
        int ri;
-
-       ri = route_get(&main_rt, rn->s);
-       if(ri < 0) {
-               LM_ERR("unable to find route block [%.*s]\n", rn->len, rn->s);
-               return -1;
-       }
-       act = main_rt.rlist[ri];
-       if(act == NULL) {
-               LM_ERR("empty action lists in route block [%.*s]\n", rn->len, rn->s);
-               return -1;
+       sr_kemi_eng_t *keng = NULL;
+
+       keng = sr_kemi_eng_get();
+       if(keng == NULL) {
+               ri = route_lookup(&main_rt, rn->s);
+               if(ri >= 0) {
+                       act = main_rt.rlist[ri];
+                       if(act == NULL) {
+                               LM_ERR("empty action lists in route block [%.*s]\n", rn->len,
+                                               rn->s);
+                               return -1;
+                       }
+               } else {
+                       LM_ERR("route block not found: %.*s\n", rn->len, rn->s);
+                       return -1;
+               }
        }
 
-       if(async_send_task(msg, act) < 0)
+       if(async_send_task(msg, act, rn) < 0)
                return -1;
        /* force exit in config */
        return 0;
index 20a5a86..66de747 100644 (file)
 #include "../../core/timer.h"
 #include "../../core/async_task.h"
 #include "../../modules/tm/tm_load.h"
+#include "../../core/kemi.h"
 
 #include "async_sleep.h"
 
+#define ASYNC_CBNAME_SIZE 64
 /* tm */
 extern struct tm_binds tmb;
 
@@ -43,7 +45,9 @@ typedef struct async_item {
        unsigned int tindex;
        unsigned int tlabel;
        unsigned int ticks;
-       cfg_action_t *act;
+       cfg_action_t *ract;
+       char cbname[ASYNC_CBNAME_SIZE];
+       int cbname_len;
        struct async_item *next;
 } async_item_t;
 
@@ -105,7 +109,7 @@ int async_destroy_timer_list(void)
        return 0;
 }
 
-int async_sleep(struct sip_msg *msg, int seconds, cfg_action_t *act)
+int async_sleep(sip_msg_t *msg, int seconds, cfg_action_t *act, str *cbname)
 {
        int slot;
        unsigned int ticks;
@@ -120,6 +124,10 @@ int async_sleep(struct sip_msg *msg, int seconds, cfg_action_t *act)
                LM_ERR("max sleep time is %d sec (%d)\n", ASYNC_RING_SIZE, seconds);
                return -1;
        }
+       if(cbname && cbname->len>=ASYNC_CBNAME_SIZE-1) {
+               LM_ERR("callback name is too long: %.*s\n", cbname->len, cbname->s);
+               return -1;
+       }
        t = tmb.t_gett();
        if(t == NULL || t == T_UNDEFINED) {
                if(tmb.t_newtran(msg) < 0) {
@@ -142,7 +150,12 @@ int async_sleep(struct sip_msg *msg, int seconds, cfg_action_t *act)
        }
        memset(ai, 0, sizeof(async_item_t));
        ai->ticks = ticks;
-       ai->act = act;
+       ai->ract = act;
+       if(cbname && cbname->len>0) {
+               memcpy(ai->cbname, cbname->s, cbname->len);
+               ai->cbname[cbname->len] = '\0';
+               ai->cbname_len = cbname->len;
+       }
        if(tmb.t_suspend(msg, &ai->tindex, &ai->tlabel) < 0) {
                LM_ERR("failed to suspend the processing\n");
                shm_free(ai);
@@ -160,6 +173,9 @@ void async_timer_exec(unsigned int ticks, void *param)
 {
        int slot;
        async_item_t *ai;
+       sr_kemi_eng_t *keng = NULL;
+       str cbname = STR_NULL;
+       str evname = str_init("async:timer-exec");
 
        if(_async_list_head == NULL)
                return;
@@ -175,33 +191,57 @@ void async_timer_exec(unsigned int ticks, void *param)
 
                if(ai == NULL)
                        break;
-               if(ai->act != NULL) {
-                       tmb.t_continue(ai->tindex, ai->tlabel, ai->act);
+               if(ai->ract != NULL) {
+                       tmb.t_continue(ai->tindex, ai->tlabel, ai->ract);
                        ksr_msg_env_reset();
+               } else {
+                       keng = sr_kemi_eng_get();
+                       if(keng != NULL && ai->cbname_len>0) {
+                               cbname.s = ai->cbname;
+                               cbname.len = ai->cbname_len;
+                               tmb.t_continue_cb(ai->tindex, ai->tlabel, &cbname, &evname);
+                               ksr_msg_env_reset();
+                       } else {
+                               LM_WARN("no callback to be executed\n");
+                       }
                }
                shm_free(ai);
        }
 }
 
+typedef struct async_task_param {
+       unsigned int tindex;
+       unsigned int tlabel;
+       cfg_action_t *ract;
+       char cbname[ASYNC_CBNAME_SIZE];
+       int cbname_len;
+} async_task_param_t;
 
 /**
  *
  */
 void async_exec_task(void *param)
 {
-       cfg_action_t *act;
-       unsigned int *p;
-       unsigned int tindex;
-       unsigned int tlabel;
+       async_task_param_t *atp;
+       sr_kemi_eng_t *keng = NULL;
+       str cbname = STR_NULL;
+       str evname = str_init("async:task-exec");
 
-       act = *((cfg_action_t **)param);
-       p = (unsigned int *)((char *)param + sizeof(cfg_action_t *));
-       tindex = p[0];
-       tlabel = p[1];
+       atp = (async_task_param_t *)param;
 
-       if(act != NULL) {
-               tmb.t_continue(tindex, tlabel, act);
+       if(atp->ract != NULL) {
+               tmb.t_continue(atp->tindex, atp->tlabel, atp->ract);
                ksr_msg_env_reset();
+       } else {
+               keng = sr_kemi_eng_get();
+               if(keng != NULL && atp->cbname_len > 0) {
+                       cbname.s = atp->cbname;
+                       cbname.len = atp->cbname_len;
+                       tmb.t_continue_cb(atp->tindex, atp->tlabel, &cbname, &evname);
+                       ksr_msg_env_reset();
+               } else {
+                       LM_WARN("no callback to be executed\n");
+               }
        }
        /* param is freed along with the async task strucutre in core */
 }
@@ -209,14 +249,19 @@ void async_exec_task(void *param)
 /**
  *
  */
-int async_send_task(sip_msg_t *msg, cfg_action_t *act)
+int async_send_task(sip_msg_t *msg, cfg_action_t *act, str *cbname)
 {
        async_task_t *at;
        tm_cell_t *t = 0;
        unsigned int tindex;
        unsigned int tlabel;
        int dsize;
-       unsigned int *p;
+       async_task_param_t *atp;
+
+       if(cbname && cbname->len>=ASYNC_CBNAME_SIZE-1) {
+               LM_ERR("callback name is too long: %.*s\n", cbname->len, cbname->s);
+               return -1;
+       }
 
        t = tmb.t_gett();
        if(t == NULL || t == T_UNDEFINED) {
@@ -230,8 +275,7 @@ int async_send_task(sip_msg_t *msg, cfg_action_t *act)
                        return -1;
                }
        }
-       dsize = sizeof(async_task_t) + sizeof(cfg_action_t *)
-                       + 2 * sizeof(unsigned int);
+       dsize = sizeof(async_task_t) + sizeof(async_task_param_t);
        at = (async_task_t *)shm_malloc(dsize);
        if(at == NULL) {
                LM_ERR("no more shm memory\n");
@@ -245,10 +289,15 @@ int async_send_task(sip_msg_t *msg, cfg_action_t *act)
        }
        at->exec = async_exec_task;
        at->param = (char *)at + sizeof(async_task_t);
-       *((cfg_action_t **)at->param) = act;
-       p = (unsigned int *)((char *)at->param + sizeof(cfg_action_t *));
-       p[0] = tindex;
-       p[1] = tlabel;
+       atp = (async_task_param_t *)at->param;
+       atp->ract = act;
+       atp->tindex = tindex;
+       atp->tlabel = tlabel;
+       if(cbname && cbname->len>0) {
+               memcpy(atp->cbname, cbname->s, cbname->len);
+               atp->cbname[cbname->len] = '\0';
+               atp->cbname_len = cbname->len;
+       }
        async_task_push(at);
        return 0;
 }
index dbde646..9fac192 100644 (file)
@@ -42,10 +42,10 @@ int async_init_timer_list(void);
 
 int async_destroy_timer_list(void);
 
-int async_sleep(sip_msg_t *msg, int seconds, cfg_action_t *act);
+int async_sleep(sip_msg_t *msg, int seconds, cfg_action_t *act, str *cbname);
 
 void async_timer_exec(unsigned int ticks, void *param);
 
-int async_send_task(sip_msg_t *msg, cfg_action_t *act);
+int async_send_task(sip_msg_t *msg, cfg_action_t *act, str *cbname);
 
 #endif
index e4fe5e9..69efc60 100644 (file)
@@ -31,6 +31,7 @@
 #include "../../core/str.h"
 #include "../../core/rpc.h"
 #include "../../core/rpc_lookup.h"
+#include "../../core/kemi.h"
 #include "../../modules/auth/api.h"
 
 #include "auth_ephemeral_mod.h"
@@ -409,3 +410,43 @@ static int autheph_init_rpc(void)
        return 0;
 }
 
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_auth_ephemeral_exports[] = {
+       { str_init("auth_ephemeral"), str_init("autheph_check"),
+               SR_KEMIP_INT, ki_autheph_check,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_ephemeral"), str_init("autheph_www"),
+               SR_KEMIP_INT, ki_autheph_www,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_ephemeral"), str_init("autheph_www_method"),
+               SR_KEMIP_INT, ki_autheph_www_method,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_ephemeral"), str_init("autheph_proxy"),
+               SR_KEMIP_INT, ki_autheph_proxy,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_ephemeral"), str_init("autheph_authenticate"),
+               SR_KEMIP_INT, ki_autheph_authenticate,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
+
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+       sr_kemi_modules_add(sr_kemi_auth_ephemeral_exports);
+       return 0;
+}
\ No newline at end of file
index a8815a3..745f12d 100644 (file)
@@ -213,7 +213,7 @@ static inline int digest_authenticate(struct sip_msg *_m, str *_realm,
                                hdr_types_t _hftype, str *_method)
 {
        struct hdr_field* h;
-       auth_cfg_result_t ret;
+       auth_cfg_result_t ret = AUTH_ERROR;
        auth_result_t rauth;
        struct secret *secret_struct;
        str username;
@@ -278,9 +278,8 @@ static inline int digest_authenticate(struct sip_msg *_m, str *_realm,
        return ret;
 }
 
-int autheph_check(struct sip_msg *_m, char *_realm)
+int ki_autheph_check(sip_msg_t *_m, str *srealm)
 {
-       str srealm;
 
        if (eph_auth_api.pre_auth == NULL)
        {
@@ -289,24 +288,12 @@ int autheph_check(struct sip_msg *_m, char *_realm)
                return AUTH_ERROR;
        }
 
-       if(_m == NULL || _realm == NULL)
-       {
-               LM_ERR("invalid parameters\n");
-               return AUTH_ERROR;
-       }
-
        if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
        {
                return AUTH_OK;
        }
 
-       if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
-       {
-               LM_ERR("failed to get realm value\n");
-               return AUTH_ERROR;
-       }
-
-       if (srealm.len == 0)
+       if (srealm->len == 0)
        {
                LM_ERR("invalid realm parameter - empty value\n");
                return AUTH_ERROR;
@@ -314,65 +301,62 @@ int autheph_check(struct sip_msg *_m, char *_realm)
 
        if (_m->REQ_METHOD == METHOD_REGISTER)
        {
-               return digest_authenticate(_m, &srealm, HDR_AUTHORIZATION_T,
+               return digest_authenticate(_m, srealm, HDR_AUTHORIZATION_T,
                                        &_m->first_line.u.request.method);
        }
        else
        {
-               return digest_authenticate(_m, &srealm, HDR_PROXYAUTH_T,
+               return digest_authenticate(_m, srealm, HDR_PROXYAUTH_T,
                                        &_m->first_line.u.request.method);
        }
 }
 
-int autheph_www(struct sip_msg *_m, char *_realm)
+int autheph_check(struct sip_msg *_m, char *_realm, char *_p2)
 {
        str srealm;
 
-       if (eph_auth_api.pre_auth == NULL)
+       if(_m == NULL || _realm == NULL)
        {
-               LM_ERR("autheph_www() cannot be used without the auth "
-                       "module\n");
+               LM_ERR("invalid parameters\n");
                return AUTH_ERROR;
        }
 
-       if(_m == NULL || _realm == NULL)
+       if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
        {
-               LM_ERR("invalid parameters\n");
+               LM_ERR("failed to get realm value\n");
                return AUTH_ERROR;
        }
 
-       if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
+       return ki_autheph_check(_m, &srealm);
+}
+
+int ki_autheph_www(sip_msg_t *_m, str *srealm)
+{
+       if (eph_auth_api.pre_auth == NULL)
        {
-               return AUTH_OK;
+               LM_ERR("autheph_www() cannot be used without the auth "
+                       "module\n");
+               return AUTH_ERROR;
        }
 
-       if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
+       if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
        {
-               LM_ERR("failed to get realm value\n");
-               return AUTH_ERROR;
+               return AUTH_OK;
        }
 
-       if (srealm.len == 0)
+       if (srealm->len == 0)
        {
                LM_ERR("invalid realm parameter - empty value\n");
                return AUTH_ERROR;
        }
 
-       return digest_authenticate(_m, &srealm, HDR_AUTHORIZATION_T,
+       return digest_authenticate(_m, srealm, HDR_AUTHORIZATION_T,
                                        &_m->first_line.u.request.method);
 }
 
-int autheph_www2(struct sip_msg *_m, char *_realm, char *_method)
+int autheph_www(struct sip_msg *_m, char *_realm, char *_p2)
 {
        str srealm;
-       str smethod;
-
-       if (eph_auth_api.pre_auth == NULL)
-       {
-               LM_ERR("autheph_www() cannot be used without the auth "
-                       "module\n");
-               return AUTH_ERROR;
-       }
 
        if(_m == NULL || _realm == NULL)
        {
@@ -380,121 +364,139 @@ int autheph_www2(struct sip_msg *_m, char *_realm, char *_method)
                return AUTH_ERROR;
        }
 
-       if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
-       {
-               return AUTH_OK;
-       }
-
        if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
        {
                LM_ERR("failed to get realm value\n");
                return AUTH_ERROR;
        }
 
-       if (srealm.len == 0)
+       return ki_autheph_www(_m, &srealm);
+}
+
+int ki_autheph_www_method(sip_msg_t *_m, str *srealm, str *smethod)
+{
+       if (eph_auth_api.pre_auth == NULL)
        {
-               LM_ERR("invalid realm parameter - empty value\n");
+               LM_ERR("autheph_www() cannot be used without the auth "
+                       "module\n");
                return AUTH_ERROR;
        }
 
-       if (get_str_fparam(&smethod, _m, (fparam_t*)_method) < 0)
+       if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
        {
-               LM_ERR("failed to get method value\n");
+               return AUTH_OK;
+       }
+
+       if (srealm->len == 0)
+       {
+               LM_ERR("invalid realm parameter - empty value\n");
                return AUTH_ERROR;
        }
 
-       if (smethod.len == 0)
+       if (smethod->len == 0)
        {
                LM_ERR("invalid method value - empty value\n");
                return AUTH_ERROR;
        }
 
-       return digest_authenticate(_m, &srealm, HDR_AUTHORIZATION_T, &smethod);
+       return digest_authenticate(_m, srealm, HDR_AUTHORIZATION_T, smethod);
 }
 
-int autheph_proxy(struct sip_msg *_m, char *_realm)
+int autheph_www2(struct sip_msg *_m, char *_realm, char *_method)
 {
        str srealm;
+       str smethod;
 
-       if (eph_auth_api.pre_auth == NULL)
+       if(_m == NULL || _realm == NULL || _method == NULL)
        {
-               LM_ERR("autheph_proxy() cannot be used without the auth "
-                       "module\n");
+               LM_ERR("invalid parameters\n");
                return AUTH_ERROR;
        }
 
-       if(_m == NULL || _realm == NULL)
+       if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
        {
-               LM_ERR("invalid parameters\n");
+               LM_ERR("failed to get realm value\n");
                return AUTH_ERROR;
        }
 
-       if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
+       if (get_str_fparam(&smethod, _m, (fparam_t*)_method) < 0)
        {
-               return AUTH_OK;
+               LM_ERR("failed to get method value\n");
+               return AUTH_ERROR;
        }
 
-       if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
+       return ki_autheph_www_method(_m, &srealm, &smethod);
+}
+
+int ki_autheph_proxy(sip_msg_t *_m, str *srealm)
+{
+       if (eph_auth_api.pre_auth == NULL)
        {
-               LM_ERR("failed to get realm value\n");
+               LM_ERR("autheph_proxy() cannot be used without the auth "
+                       "module\n");
                return AUTH_ERROR;
        }
 
-       if (srealm.len == 0)
+       if (_m->REQ_METHOD == METHOD_ACK || _m->REQ_METHOD == METHOD_CANCEL)
+       {
+               return AUTH_OK;
+       }
+
+       if (srealm->len == 0)
        {
                LM_ERR("invalid realm parameter - empty value\n");
                return AUTH_ERROR;
        }
 
-       return digest_authenticate(_m, &srealm, HDR_PROXYAUTH_T,
+       return digest_authenticate(_m, srealm, HDR_PROXYAUTH_T,
                                        &_m->first_line.u.request.method);
 }
 
-int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password)
+int autheph_proxy(struct sip_msg *_m, char *_realm, char *_p2)
 {
-       str susername, spassword;
-       char generated_password[base64_enc_len(SHA_DIGEST_LENGTH)];
-       str sgenerated_password;
-       struct secret *secret_struct;
+       str srealm;
 
-       if (_m == NULL || _username == NULL || _password == NULL)
+       if(_m == NULL || _realm == NULL)
        {
                LM_ERR("invalid parameters\n");
                return AUTH_ERROR;
        }
 
-       if (get_str_fparam(&susername, _m, (fparam_t*)_username) < 0)
+       if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0)
        {
-               LM_ERR("failed to get username value\n");
+               LM_ERR("failed to get realm value\n");
                return AUTH_ERROR;
        }
 
-       if (susername.len == 0)
-       {
-               LM_ERR("invalid username parameter - empty value\n");
-               return AUTH_ERROR;
-       }
+       return ki_autheph_proxy(_m, &srealm);
+}
 
-       if (get_str_fparam(&spassword, _m, (fparam_t*)_password) < 0)
+int ki_autheph_authenticate(sip_msg_t *_m, str *susername, str *spassword)
+{
+       char generated_password[base64_enc_len(SHA_DIGEST_LENGTH)];
+       str sgenerated_password;
+       struct secret *secret_struct;
+
+       if (susername->len == 0)
        {
-               LM_ERR("failed to get password value\n");
+               LM_ERR("invalid username parameter - empty value\n");
                return AUTH_ERROR;
        }
 
-       if (spassword.len == 0)
+       if (spassword->len == 0)
        {
                LM_ERR("invalid password parameter - empty value\n");
                return AUTH_ERROR;
        }
 
-       if (autheph_verify_timestamp(&susername) < 0)
+       if (autheph_verify_timestamp(susername) < 0)
        {
                LM_ERR("invalid timestamp in username\n");
                return AUTH_ERROR;
        }
 
-       LM_DBG("username: %.*s\n", susername.len, susername.s);
-       LM_DBG("password: %.*s\n", spassword.len, spassword.s);
+       LM_DBG("username: %.*s\n", susername->len, susername->s);
+       LM_DBG("password: %.*s\n", spassword->len, spassword->s);
 
        sgenerated_password.s = generated_password;
        SECRET_LOCK;
@@ -504,13 +506,13 @@ int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password)
                LM_DBG("trying secret: %.*s\n",
                        secret_struct->secret_key.len,
                        secret_struct->secret_key.s);
-               if (get_pass(&susername, &secret_struct->secret_key,
+               if (get_pass(susername, &secret_struct->secret_key,
                                &sgenerated_password) == 0)
                {
                        LM_DBG("generated password: %.*s\n",
                                sgenerated_password.len, sgenerated_password.s);
-                       if (strncmp(spassword.s, sgenerated_password.s,
-                                       spassword.len) == 0)
+                       if (strncmp(spassword->s, sgenerated_password.s,
+                                       spassword->len) == 0)
                        {
                                SECRET_UNLOCK;
                                return AUTH_OK;
@@ -522,3 +524,28 @@ int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password)
 
        return AUTH_ERROR;
 }
+
+int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password)
+{
+       str susername, spassword;
+
+       if (_m == NULL || _username == NULL || _password == NULL)
+       {
+               LM_ERR("invalid parameters\n");
+               return AUTH_ERROR;
+       }
+
+       if (get_str_fparam(&susername, _m, (fparam_t*)_username) < 0)
+       {
+               LM_ERR("failed to get username value\n");
+               return AUTH_ERROR;
+       }
+
+       if (get_str_fparam(&spassword, _m, (fparam_t*)_password) < 0)
+       {
+               LM_ERR("failed to get password value\n");
+               return AUTH_ERROR;
+       }
+
+       return ki_autheph_authenticate(_m, &susername, &spassword);
+}
index d455fc8..e4d45af 100644 (file)
 
 int autheph_verify_timestamp(str *_username);
 
-int autheph_check(struct sip_msg *_m, char *_realm);
-int autheph_www(struct sip_msg *_m, char *_realm);
+int autheph_check(struct sip_msg *_m, char *_realm, char *_p2);
+int autheph_www(struct sip_msg *_m, char *_realm, char *_p2);
 int autheph_www2(struct sip_msg *_m, char *_realm, char *_method);
-int autheph_proxy(struct sip_msg *_m, char *_realm);
+int autheph_proxy(struct sip_msg *_m, char *_realm, char *_p2);
 int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password);
 
+int ki_autheph_check(sip_msg_t *_m, str *srealm);
+int ki_autheph_www(sip_msg_t *_m, str *srealm);
+int ki_autheph_www_method(sip_msg_t *_m, str *srealm, str *smethod);
+int ki_autheph_proxy(sip_msg_t *_m, str *srealm);
+int ki_autheph_authenticate(sip_msg_t *_m, str *susername, str *spassword);
+
 #endif /* AUTHORIZE_H */
index eaba09f..a521905 100644 (file)
@@ -30,7 +30,8 @@
 #include "../../core/error.h"
 #include "../../core/dprint.h"
 #include "../../core/config.h"
-#include "../../core/pvar.h"
+#include "../../core/mod_fix.h"
+#include "../../core/kemi.h"
 #include "../misc_radius/radius.h"
 #include "../../core/mem/mem.h"
 #include "auth_radius.h"
 
 MODULE_VERSION
 
-struct attr attrs[A_MAX+MAX_EXTRA];
-struct val vals[V_MAX+MAX_EXTRA];
+struct attr attrs[A_MAX + MAX_EXTRA];
+struct val vals[V_MAX + MAX_EXTRA];
 void *rh;
 
 auth_api_s_t auth_api;
 
-static int mod_init(void);         /* Module initialization function */
-static int auth_fixup(void** param, int param_no); /* char* -> str* */
-
+static int mod_init(void); /* Module initialization function */
 
 /*
  * Module parameter variables
  */
-static charradius_config = DEFAULT_RADIUSCLIENT_CONF;
+static char *radius_config = DEFAULT_RADIUSCLIENT_CONF;
 static int service_type = -1;
 
 int use_ruri_flag = -1;
@@ -65,15 +64,16 @@ struct extra_attr *auth_extra = 0;
 /*
  * Exported functions
  */
+/* clang-format off */
 static cmd_export_t cmds[] = {
-       {"radius_www_authorize", (cmd_function)radius_www_authorize_1,   1, auth_fixup,
-                       0, REQUEST_ROUTE},
-       {"radius_www_authorize", (cmd_function)radius_www_authorize_2,   2, auth_fixup,
-                       0, REQUEST_ROUTE},
-       {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_1, 1, auth_fixup,
-                       0, REQUEST_ROUTE},
-       {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_2, 2, auth_fixup,
-                       0, REQUEST_ROUTE},
+       {"radius_www_authorize", (cmd_function)radius_www_authorize_1,   1,
+                       fixup_spve_null, fixup_free_spve_null, REQUEST_ROUTE},
+       {"radius_www_authorize", (cmd_function)radius_www_authorize_2,   2,
+                       fixup_spve_spve, fixup_free_spve_spve, REQUEST_ROUTE},
+       {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_1, 1,
+                       fixup_spve_null, fixup_free_spve_null, REQUEST_ROUTE},
+       {"radius_proxy_authorize", (cmd_function)radius_proxy_authorize_2, 2,
+                       fixup_spve_spve, fixup_free_spve_spve, REQUEST_ROUTE},
        {0, 0, 0, 0, 0, 0}
 };
 
@@ -87,7 +87,7 @@ static param_export_t params[] = {
        {"use_ruri_flag",    INT_PARAM, &use_ruri_flag  },
        {"auth_extra",       PARAM_STRING, &auth_extra_str      },
        {"radius_avps_mode",     INT_PARAM, &ar_radius_avps_mode        },
-       {"append_realm_to_username", INT_PARAM, &append_realm_to_username       },
+       {"append_realm_to_username", INT_PARAM, &append_realm_to_username  },
        {0, 0, 0}
 };
 
@@ -96,7 +96,7 @@ static param_export_t params[] = {
  * Module interface
  */
 struct module_exports exports = {
-       "auth_radius", 
+       "auth_radius",
        DEFAULT_DLFLAGS, /* dlopen flags */
        cmds,       /* Exported functions */
        params,     /* Exported parameters */
@@ -109,6 +109,7 @@ struct module_exports exports = {
        0,          /* destroy function */
        0           /* child initialization function */
 };
+/* clang-format off */
 
 
 /*
@@ -186,50 +187,41 @@ static int mod_init(void)
        return 0;
 }
 
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_auth_radius_exports[] = {
+       { str_init("auth_radius"), str_init("proxy_authorize"),
+               SR_KEMIP_INT, ki_radius_proxy_authorize,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_radius"), str_init("proxy_authorize_user"),
+               SR_KEMIP_INT, ki_radius_proxy_authorize_user,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_radius"), str_init("www_authorize"),
+               SR_KEMIP_INT, ki_radius_www_authorize,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("auth_radius"), str_init("www_authorize_user"),
+               SR_KEMIP_INT, ki_radius_www_authorize_user,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
 
-/*
- * Convert char* parameter to pv_elem_t* parameter
+/**
+ *
  */
-static int auth_fixup(void** param, int param_no)
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
 {
-       pv_elem_t *model;
-       str s;
-       pv_spec_t *sp;
-
-       if (param_no == 1) { /* realm (string that may contain pvars) */
-               s.s = (char*)*param;
-               if (s.s==0 || s.s[0]==0) {
-                       model = 0;
-               } else {
-                       s.len = strlen(s.s);
-                       if (pv_parse_format(&s,&model)<0) {
-                               LM_ERR("pv_parse_format failed\n");
-                               return E_OUT_OF_MEM;
-                       }
-               }
-               *param = (void*)model;
-       }
-
-       if (param_no == 2) { /* URI user (a pvar) */
-               sp = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
-               if (sp == 0) {
-                       LM_ERR("no pkg memory left\n");
-                       return -1;
-               }
-               s.s = (char*)*param;
-               s.len = strlen(s.s);
-               if (pv_parse_spec(&s, sp) == 0) {
-                       LM_ERR("parsing of pseudo variable %s failed!\n", (char*)*param);
-                       pkg_free(sp);
-                       return -1;
-               }
-               if (sp->type == PVT_NULL) {
-                       LM_ERR("bad pseudo variable\n");
-                       pkg_free(sp);
-                       return -1;
-               }
-               *param = (void*)sp;
-       }       
-
+       sr_kemi_modules_add(sr_kemi_auth_radius_exports);
        return 0;
 }
index 6866c57..20d8f30 100644 (file)
@@ -16,8 +16,8 @@
  * 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 
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
@@ -34,7 +34,7 @@
 #include "../../core/parser/parse_to.h"
 #include "../../core/dprint.h"
 #include "../../core/ut.h"
-#include "../../core/pvar.h"
+#include "../../core/mod_fix.h"
 #include "../../modules/auth/api.h"
 #include "authorize.h"
 #include "sterman.h"
 /* 
  * Extract URI depending on the request from To or From header 
  */
-static inline int get_uri_user(struct sip_msg* _m, str** _uri_user)
+static inline int get_uri_user(struct sip_msg *_m, str **_uri_user)
 {
-    struct sip_uri *puri;
+       struct sip_uri *puri;
 
-    if ((REQ_LINE(_m).method.len == 8) && 
-       (memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) == 0)) {
-       if ((puri=parse_to_uri(_m))==NULL) {
-           LM_ERR("failed to parse To header\n");
-           return -1;
-       }
-    } else {
-       if ((puri=parse_from_uri(_m))==NULL) {
-           LM_ERR("parsing From header\n");
-           return -1;
+       if((REQ_LINE(_m).method.len == 8)
+                       && (memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) == 0)) {
+               if((puri = parse_to_uri(_m)) == NULL) {
+                       LM_ERR("failed to parse To header\n");
+                       return -1;
+               }
+       } else {
+               if((puri = parse_from_uri(_m)) == NULL) {
+                       LM_ERR("parsing From header\n");
+                       return -1;
+               }
        }
-    }
 
-    *_uri_user = &(puri->user);
+       *_uri_user = &(puri->user);
 
-    return 0;
+       return 0;
 }
 
 
 /*
  * Authorize digest credentials
  */
-static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
-                           pv_spec_t * _uri_user, hdr_types_t _hftype)
+static int ki_authorize(sip_msg_t *_msg, str *srealm,
+               str *suser, hdr_types_t _hftype)
 {
-    int res;
-    auth_cfg_result_t ret;
-    struct hdr_field* h;
-    auth_body_t* cred;
-    str *uri_user;
-    str user, domain;
-    pv_value_t pv_val;
-
-    cred = 0;
-    ret = -1;
-    user.s = 0;
-
-    /* get pre_auth domain from _realm pvar (if exists) */
-    if (_realm) {
-       if (pv_printf_s(_msg, _realm, &domain) != 0) {
-           LM_ERR("pv_printf_s failed\n");
-           return -5;
+       int res;
+       auth_cfg_result_t ret;
+       struct hdr_field *h;
+       auth_body_t *cred;
+       str *uri_user;
+       str user = STR_NULL, domain;
+
+       cred = 0;
+       ret = -1;
+       user.s = 0;
+
+       /* get pre_auth domain from _realm pvar (if exists) */
+       if(srealm) {
+               domain = *srealm;
+       } else {
+               domain.len = 0;
+               domain.s = 0;
        }
-    } else {
-       domain.len = 0;
-       domain.s = 0;
-    }
-
-    switch(auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)) {
-    default:
-       BUG("unexpected reply '%d'.\n",
-           auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
+
+       switch(auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)) {
+               default:
+                       BUG("unexpected reply '%d'.\n",
+                                       auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
 #ifdef EXTRA_DEBUG
-       abort();
+                       abort();
 #endif
-       ret = -7;
-       goto end;
-
-    case NONCE_REUSED:
-       ret = AUTH_NONCE_REUSED;
-       goto end;
-
-    case STALE_NONCE:
-       ret = AUTH_STALE_NONCE;
-       goto end;
-       
-    case ERROR:
-    case BAD_CREDENTIALS:
-    case NOT_AUTHENTICATED:
-       ret = AUTH_ERROR;
-       goto end;
-
-    case NO_CREDENTIALS:
-       ret = AUTH_NO_CREDENTIALS;
-       goto end;
-       
-    case DO_AUTHENTICATION:
-       break;
-       
-    case AUTHENTICATED:
-       ret = AUTH_OK;
-       goto end;
-    }
-
-    cred = (auth_body_t*)h->parsed;
-
-    /* get uri_user from _uri_user pvap (if exists) or
+                       ret = -7;
+                       goto end;
+
+               case NONCE_REUSED:
+                       ret = AUTH_NONCE_REUSED;
+                       goto end;
+
+               case STALE_NONCE:
+                       ret = AUTH_STALE_NONCE;
+                       goto end;
+
+               case ERROR:
+               case BAD_CREDENTIALS:
+               case NOT_AUTHENTICATED:
+                       ret = AUTH_ERROR;
+                       goto end;
+
+               case NO_CREDENTIALS:
+                       ret = AUTH_NO_CREDENTIALS;
+                       goto end;
+
+               case DO_AUTHENTICATION:
+                       break;
+
+               case AUTHENTICATED:
+                       ret = AUTH_OK;
+                       goto end;
+       }
+
+       cred = (auth_body_t *)h->parsed;
+
+       /* get uri_user from _uri_user pvap (if exists) or
        from To/From URI */
-    if (_uri_user) {
-       if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) {
-           if (pv_val.flags & PV_VAL_STR) {
-               res = radius_authorize_sterman(_msg, &cred->digest, 
-                                              &_msg->
-                                              first_line.u.request.method,
-                                              &pv_val.rs);
-           } else {
-               LM_ERR("uri_user pvar value is not string\n");
-               ret = AUTH_ERROR;
-               goto end;
-           }
+       if(suser != NULL && suser->len > 0) {
+               res = radius_authorize_sterman(_msg, &cred->digest,
+                                       &_msg->first_line.u.request.method, suser);
        } else {
-           LM_ERR("cannot get uri_user pvar value\n");
-           ret = AUTH_ERROR;
-           goto end;
-       }
-    } else {
-       if (get_uri_user(_msg, &uri_user) < 0) {
-           LM_ERR("To/From URI not found\n");
-           ret = AUTH_ERROR;;
-           goto end;
+               if(get_uri_user(_msg, &uri_user) < 0) {
+                       LM_ERR("To/From URI not found\n");
+                       ret = AUTH_ERROR;
+                       ;
+                       goto end;
+               }
+               user.s = (char *)pkg_malloc(uri_user->len);
+               if(user.s == NULL) {
+                       LM_ERR("no pkg memory left for user\n");
+                       ret = -7;
+                       goto end;
+               }
+               un_escape(uri_user, &user);
+               res = radius_authorize_sterman(
+                               _msg, &cred->digest, &_msg->first_line.u.request.method, &user);
        }
-       user.s = (char *)pkg_malloc(uri_user->len);
-       if (user.s == NULL) {
-           LM_ERR("no pkg memory left for user\n");
-           ret = -7;
-           goto end;
-       }
-       un_escape(uri_user, &user);
-       res = radius_authorize_sterman(_msg, &cred->digest, 
-                                      &_msg->first_line.u.request.method,
-                                      &user);
-    }
-
-    if (res == 1) {
-       switch(auth_api.post_auth(_msg, h, NULL)) {
-       default:
-           BUG("unexpected reply '%d'.\n",
-               auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
+
+       if(res == 1) {
+               switch(auth_api.post_auth(_msg, h, NULL)) {
+                       default:
+                               BUG("unexpected reply '%d'.\n",
+                                               auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL));
 #ifdef EXTRA_DEBUG
-           abort();
+                               abort();
 #endif
-           ret = -7;
-           break;
-       case ERROR:             
-       case NOT_AUTHENTICATED:
-           ret = AUTH_ERROR;
-           break;
-       case AUTHENTICATED:
-           ret = AUTH_OK;
-           break;
+                               ret = -7;
+                               break;
+                       case ERROR:
+                       case NOT_AUTHENTICATED:
+                               ret = AUTH_ERROR;
+                               break;
+                       case AUTHENTICATED:
+                               ret = AUTH_OK;
+                               break;
+               }
+       } else {
+               ret = AUTH_INVALID_PASSWORD;
        }
-    } else {
-       ret = AUTH_INVALID_PASSWORD;
-    }
-
- end:
-    if (user.s) pkg_free(user.s);
-    if (ret < 0) {
-       if (auth_api.build_challenge(_msg, (cred ? cred->stale : 0), &domain,
-                                    NULL, NULL, _hftype) < 0) {
-           LM_ERR("while creating challenge\n");
-           ret = -7;
+
+end:
+       if(user.s)
+               pkg_free(user.s);
+       if(ret < 0) {
+               if(auth_api.build_challenge(
+                                  _msg, (cred ? cred->stale : 0), &domain, NULL, NULL, _hftype)
+                               < 0) {
+                       LM_ERR("while creating challenge\n");
+                       ret = -7;
+               }
        }
-    }
-    return ret;
+       return ret;
 }
 
 
+/*
+ * Authorize digest credentials
+ */
+static inline int authorize(struct sip_msg *_msg, gparam_t *_realm,
+               gparam_t *_uri_user, hdr_types_t _hftype)
+{
+       str srealm = STR_NULL;
+       str suser = STR_NULL;
+
+       /* get pre_auth domain from _realm param (if exists) */
+       if(_realm) {
+               if(fixup_get_svalue(_msg, _realm, &srealm)<0) {
+                       LM_ERR("failed to get realm value\n");
+                       return -5;
+               }
+       }
+       if(_uri_user) {
+               if(fixup_get_svalue(_msg, _uri_user, &suser)<0) {
+                       LM_ERR("cannot get uri user value\n");
+                       return AUTH_ERROR;
+               }
+       }
+       return ki_authorize(_msg, &srealm, &suser, _hftype);
+}
+
+/**
+ *
+ */
+int ki_radius_proxy_authorize(sip_msg_t *msg, str *srealm)
+{
+       return ki_authorize(msg, srealm, NULL, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+int ki_radius_proxy_authorize_user(sip_msg_t *msg, str *srealm, str *suser)
+{
+       return ki_authorize(msg, srealm, suser, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+int ki_radius_www_authorize(sip_msg_t *msg, str *srealm)
+{
+       return ki_authorize(msg, srealm, NULL, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+int ki_radius_www_authorize_user(sip_msg_t *msg, str *srealm, str *suser)
+{
+       return ki_authorize(msg, srealm, suser, HDR_AUTHORIZATION_T);
+}
+
 /*
  * Authorize using Proxy-Authorize header field (no URI user parameter given)
  */
-int radius_proxy_authorize_1(struct sip_msg* _msg, char* _realm, char* _s2)
+int radius_proxy_authorize_1(struct sip_msg *_msg, char *_realm, char *_s2)
 {
        /* realm parameter is converted in fixup */
-       return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)0,
-               HDR_PROXYAUTH_T);
+       return authorize(
+                       _msg, (gparam_t *)_realm, (gparam_t *)0, HDR_PROXYAUTH_T);
 }
 
 
 /*
  * Authorize using Proxy-Authorize header field (URI user parameter given)
  */
-int radius_proxy_authorize_2(struct sip_msg* _msg, char* _realm,
-                                                                                                               char* _uri_user)
+int radius_proxy_authorize_2(
+               struct sip_msg *_msg, char *_realm, char *_uri_user)
 {
-       return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)_uri_user,
-               HDR_PROXYAUTH_T);
+       return authorize(
+                       _msg, (gparam_t *)_realm, (gparam_t *)_uri_user, HDR_PROXYAUTH_T);
 }
 
 
 /*
  * Authorize using WWW-Authorize header field (no URI user parameter given)
  */
-int radius_www_authorize_1(struct sip_msg* _msg, char* _realm, char* _s2)
+int radius_www_authorize_1(struct sip_msg *_msg, char *_realm, char *_s2)
 {
-       return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)0,
-                        HDR_AUTHORIZATION_T);
+       return authorize(
+                       _msg, (gparam_t *)_realm, (gparam_t *)0, HDR_AUTHORIZATION_T);
 }
 
 
 /*
  * Authorize using WWW-Authorize header field (URI user parameter given)
  */
-int radius_www_authorize_2(struct sip_msg* _msg, char* _realm, char* _uri_user)
+int radius_www_authorize_2(struct sip_msg *_msg, char *_realm, char *_uri_user)
 {
-       return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)_uri_user,
-                        HDR_AUTHORIZATION_T);
+       return authorize(_msg, (gparam_t *)_realm, (gparam_t *)_uri_user,
+                       HDR_AUTHORIZATION_T);
 }
index e9f034d..3944e0e 100644 (file)
 /*
  * Authorize using Proxy-Authorize header field (no URI user parameter given)
  */
-int radius_proxy_authorize_1(struct sip_msg* _msg, char* _realm, char* _s2);
+int radius_proxy_authorize_1(struct sip_msg *_msg, char *_realm, char *_s2);
 
 
 /*
  * Authorize using Proxy-Authorize header field (URI user parameter given)
  */
-int radius_proxy_authorize_2(struct sip_msg* _msg, char* _realm, char* _uri_user);
+int radius_proxy_authorize_2(
+               struct sip_msg *_msg, char *_realm, char *_uri_user);
 
 
 /*
  * Authorize using WWW-Authorization header field (no URI user parameter given)
  */
-int radius_www_authorize_1(struct sip_msg* _msg, char* _realm, char* _s2);
+int radius_www_authorize_1(struct sip_msg *_msg, char *_realm, char *_s2);
 
 /*
  * Authorize using WWW-Authorization header field (URI user parameter given)
  */
-int radius_www_authorize_2(struct sip_msg* _msg, char* _realm, char* _uri_user);
+int radius_www_authorize_2(struct sip_msg *_msg, char *_realm, char *_uri_user);
 
 
+int ki_radius_proxy_authorize(sip_msg_t *msg, str *srealm);
+int ki_radius_proxy_authorize_user(sip_msg_t *msg, str *srealm, str *suser);
+int ki_radius_www_authorize(sip_msg_t *msg, str *srealm);
+int ki_radius_www_authorize_user(sip_msg_t *msg, str *srealm, str *suser);
+
 #endif /* AUTHORIZE_H */
index 8fe9476..8605c3d 100644 (file)
@@ -34,7 +34,7 @@
 
 
 /* here we copy the strings returned by int2str (which uses a static buffer) */
-static char int_buf[INT2STR_MAX_LEN*MAX_EXTRA];
+static char int_buf[INT2STR_MAX_LEN * MAX_EXTRA];
 static char *static_detector = 0;
 
 
@@ -43,7 +43,7 @@ void init_extra_engine(void)
 {
        int i;
        /* ugly trick to get the address of the static buffer */
-       static_detector = int2str( (unsigned long)3, &i) + i;
+       static_detector = int2str((unsigned long)3, &i) + i;
 }
 
 
@@ -53,93 +53,102 @@ void init_extra_engine(void)
  */
 struct extra_attr *parse_extra_str(char *extra_str)
 {
-    struct extra_attr *head;
-    struct extra_attr *tail;
-    struct extra_attr *extra;
-    char *foo;
-    char *s;
-    int  n;
-    str stmp;
-
-    n = 0;
-    head = 0;
-    extra = 0;
-    tail = 0;
-    s = extra_str;
-
-    if (s==0) {
-       LM_ERR("null string received\n");
-       goto error;
-    }
-
-    while (*s) {
-       /* skip white spaces */
-       while (*s && isspace((int)*s))  s++;
-       if (*s == 0) goto parse_error;
-       if (n == MAX_EXTRA) {
-           LM_ERR("too many extras -> please increase the internal buffer\n");
-           goto error;
+       struct extra_attr *head;
+       struct extra_attr *tail;
+       struct extra_attr *extra;
+       char *foo;
+       char *s;
+       int n;
+       str stmp;
+
+       n = 0;
+       head = 0;
+       extra = 0;
+       tail = 0;
+       s = extra_str;
+
+       if(s == 0) {
+               LM_ERR("null string received\n");
+               goto error;
        }
-       extra = (struct extra_attr*)pkg_malloc(sizeof(struct extra_attr));
-       if (extra == 0) {
-           LM_ERR("no more pkg memory\n");
-           goto error;
-       }
-       memset( extra, 0, sizeof(struct extra_attr));
 
-       /* link the new extra at the end */
-       if (tail == 0) {
-           head = extra;
-       } else {
-           tail->next = extra;
-       }
-       tail = extra;
-       n++;
-
-       /* get name */
-       foo = s;
-       while (*s && !isspace((int)*s) && EQUAL != *s)  s++;
-       if (*s == 0) goto parse_error;
-       if (*s==EQUAL) {
-           extra->name.len = (s++) - foo;
-       } else {
-           extra->name.len = (s++) - foo;
-           /* skip spaces */
-           while (*s && isspace((int)*s))  s++;
-           if (*s != EQUAL) goto parse_error;
-           s++;
+       while(*s) {
+               /* skip white spaces */
+               while(*s && isspace((int)*s))
+                       s++;
+               if(*s == 0)
+                       goto parse_error;
+               if(n == MAX_EXTRA) {
+                       LM_ERR("too many extras -> please increase the internal buffer\n");
+                       goto error;
+               }
+               extra = (struct extra_attr *)pkg_malloc(sizeof(struct extra_attr));
+               if(extra == 0) {
+                       LM_ERR("no more pkg memory\n");
+                       goto error;
+               }
+               memset(extra, 0, sizeof(struct extra_attr));
+
+               /* link the new extra at the end */
+               if(tail == 0) {
+                       head = extra;
+               } else {
+                       tail->next = extra;
+               }
+               tail = extra;
+               n++;
+
+               /* get name */
+               foo = s;
+               while(*s && !isspace((int)*s) && EQUAL != *s)
+                       s++;
+               if(*s == 0)
+                       goto parse_error;
+               if(*s == EQUAL) {
+                       extra->name.len = (s++) - foo;
+               } else {
+                       extra->name.len = (s++) - foo;
+                       /* skip spaces */
+                       while(*s && isspace((int)*s))
+                               s++;
+                       if(*s != EQUAL)
+                               goto parse_error;
+                       s++;
+               }
+               extra->name.s = foo;
+
+               /* skip spaces */
+               while(*s && isspace((int)*s))
+                       s++;
+
+               /* get value type */
+               stmp.s = s;
+               stmp.len = strlen(s);
+               if((foo = pv_parse_spec(&stmp, &extra->spec)) == 0)
+                       goto parse_error;
+               s = foo;
+
+               /* skip spaces */
+               while(*s && isspace((int)*s))
+                       s++;
+               if(*s && ((*(s++) != SEPARATOR) || (*s == 0)))
+                       goto parse_error;
        }
-       extra->name.s = foo;
-
-       /* skip spaces */
-       while (*s && isspace((int)*s))  s++;
 
-       /* get value type */
-       stmp.s = s; stmp.len = strlen(s);
-       if ((foo = pv_parse_spec(&stmp, &extra->spec)) == 0 )
-           goto parse_error;
-       s = foo;
+       /* go throught all extras and make the names null terminated */
+       for(extra = head; extra; extra = extra->next)
+               extra->name.s[extra->name.len] = 0;
 
-       /* skip spaces */
-       while (*s && isspace((int)*s))  s++;
-       if (*s && ((*(s++) != SEPARATOR) || (*s == 0)))
-           goto parse_error;
-    }
-
-    /* go throught all extras and make the names null terminated */
-    for( extra = head; extra; extra = extra->next)
-       extra->name.s[extra->name.len] = 0;
-
-    return head;
+       return head;
 
 parse_error:
-    LM_ERR("parse failed in <%s> around position %d\n",
-          extra_str, (int)(long)(s-extra_str));
+       LM_ERR("parse failed in <%s> around position %d\n", extra_str,
+                       (int)(long)(s - extra_str));
 
 error:
-    LM_ERR("error\n");
-    destroy_extras(head);
-    return 0;
+       LM_ERR("error\n");
+       destroy_extras(head);
+       return 0;
 }
 
 
@@ -149,12 +158,12 @@ error:
  */
 int extra2attrs(struct extra_attr *extra, struct attr *attrs, int offset)
 {
-    int i;
+       int i;
 
-    for (i = 0; extra; i++, extra = extra->next) {
-       attrs[offset+i].n = extra->name.s;
-    }
-    return i;
+       for(i = 0; extra; i++, extra = extra->next) {
+               attrs[offset + i].n = extra->name.s;
+       }
+       return i;
 }
 
 
@@ -162,63 +171,63 @@ int extra2attrs(struct extra_attr *extra, struct attr *attrs, int offset)
  * Get pseudo variable values of extra attributes to val_arr.
  * Return number of values or -1 in case of error.
  */
-int extra2strar( struct extra_attr *extra, struct sip_msg *rq, str *val_arr)
+int extra2strar(struct extra_attr *extra, struct sip_msg *rq, str *val_arr)
 {
-    pv_value_t value;
-    int n;
-    int r;
-
-    n = 0;
-    r = 0;
-
-    while (extra) {
-       /* get the value */
-       if (pv_get_spec_value(rq, &extra->spec, &value) != 0) {
-           LM_ERR("failed to get value of extra attribute'%.*s'\n",
-                  extra->name.len,extra->name.s);
-       }
-
-       /* check for overflow */
-       if (n == MAX_EXTRA) {
-           LM_WARN("array too short -> omitting extras for accounting\n");
-           return -1;
+       pv_value_t value;
+       int n;
+       int r;
+
+       n = 0;
+       r = 0;
+
+       while(extra) {
+               /* get the value */
+               if(pv_get_spec_value(rq, &extra->spec, &value) != 0) {
+                       LM_ERR("failed to get value of extra attribute'%.*s'\n",
+                                       extra->name.len, extra->name.s);
+               }
+
+               /* check for overflow */
+               if(n == MAX_EXTRA) {
+                       LM_WARN("array too short -> omitting extras for accounting\n");
+                       return -1;
+               }
+
+               if(value.flags & PV_VAL_NULL) {
+                       /* convert <null> to empty to have consistency */
+                       val_arr[n].s = 0;
+                       val_arr[n].len = 0;
+               } else if(value.flags & PV_VAL_INT) {
+                       /* len = -1 denotes int type */
+                       val_arr[n].s = (char *)(long)value.ri;
+                       val_arr[n].len = -1;
+               } else {
+                       /* set the value into the acc buffer */
+                       if(value.rs.s + value.rs.len == static_detector) {
+                               val_arr[n].s = int_buf + r * INT2STR_MAX_LEN;
+                               val_arr[n].len = value.rs.len;
+                               memcpy(val_arr[n].s, value.rs.s, value.rs.len);
+                               r++;
+                       } else {
+                               val_arr[n] = value.rs;
+                       }
+               }
+               n++;
+               extra = extra->next;
        }
 
-       if(value.flags&PV_VAL_NULL) {
-           /* convert <null> to empty to have consistency */
-           val_arr[n].s = 0;
-           val_arr[n].len = 0;
-       } else if (value.flags&PV_VAL_INT) {
-           /* len = -1 denotes int type */
-           val_arr[n].s = (char *)(long)value.ri;
-           val_arr[n].len = -1;
-       } else {
-           /* set the value into the acc buffer */
-           if (value.rs.s+value.rs.len == static_detector) {
-               val_arr[n].s = int_buf + r*INT2STR_MAX_LEN;
-               val_arr[n].len = value.rs.len;
-               memcpy(val_arr[n].s, value.rs.s, value.rs.len);
-               r++;
-           } else {
-               val_arr[n] = value.rs;
-           }
-       }
-       n++;
-       extra = extra->next;
-    }
-
-    return n;
+       return n;
 }
 
 
 /* Free memory allocated for extra attributes */
 void destroy_extras(struct extra_attr *extra)
 {
-    struct extra_attr *foo;
+       struct extra_attr *foo;
 
-    while (extra) {
-       foo = extra;
-       extra = extra->next;
-       pkg_free(foo);
-    }
+       while(extra) {
+               foo = extra;
+               extra = extra->next;
+               pkg_free(foo);
+       }
 }
index e9aa70b..0ec7fbe 100644 (file)
 #include "../../core/parser/msg_parser.h"
 #include "../misc_radius/radius.h"
 
-struct extra_attr {
-    str name;
-    pv_spec_t spec;
-    struct extra_attr *next;
+struct extra_attr
+{
+       str name;
+       pv_spec_t spec;
+       struct extra_attr *next;
 };
 
 #define MAX_EXTRA 4
index 6d77cd6..db50b39 100644 (file)
@@ -41,102 +41,104 @@ static str val_arr[MAX_EXTRA];
 
 
 /* Macro to add extra attribute */
-#define ADD_EXTRA_AVPAIR(_attrs, _attr, _val, _len)                    \
-    do {                                                               \
-       if ((_len) != 0) {                                              \
-           if ((_len) == -1) {                                         \
-               if (_attrs[_attr].t != PW_TYPE_INTEGER) {               \
-                   LM_ERR("attribute %d is not of type integer\n",     \
-                          _attrs[_attr].v);                            \
-                   goto err;                                           \
-               }                                                       \
-           }                                                           \
-           if (!rc_avpair_add( rh, &send, _attrs[_attr].v, _val, _len, 0)) { \
-               LM_ERR("failed to add %s, %d\n", _attrs[_attr].n, _attr); \
-               goto err;                                               \
-           }                                                           \
-       }                                                               \
-    }while(0)
-
-
-static inline int extract_avp(VALUE_PAIR* vp, unsigned short *flags,
-                             int_str *name, int_str *value)
+#define ADD_EXTRA_AVPAIR(_attrs, _attr, _val, _len)                         \
+       do {                                                                    \
+               if((_len) != 0) {                                                   \
+                       if((_len) == -1) {                                              \
+                               if(_attrs[_attr].t != PW_TYPE_INTEGER) {                    \
+                                       LM_ERR("attribute %d is not of type integer\n",         \
+                                                       _attrs[_attr].v);                               \
+                                       goto err;                                               \
+                               }                                                           \
+                       }                                                               \
+                       if(!rc_avpair_add(rh, &send, _attrs[_attr].v, _val, _len, 0)) { \
+                               LM_ERR("failed to add %s, %d\n", _attrs[_attr].n, _attr);   \
+                               goto err;                                                   \
+                       }                                                               \
+               }                                                                   \
+       } while(0)
+
+
+static inline int extract_avp(
+               VALUE_PAIR *vp, unsigned short *flags, int_str *name, int_str *value)
 {
        char *p, *q, *r;
 
-       LM_DBG("vp->name '%.*s'\n",(int)strlen(vp->name),vp->name);
-       LM_DBG("vp->attribute '%d'\n",vp->attribute);
-       LM_DBG("vp->type '%d'\n",vp->type);
-       LM_DBG("vp->lvalue '%d'\n",vp->lvalue);
-       if (vp->type == PW_TYPE_STRING) 
-               LM_DBG("vp->strvalue '%.*s'\n",(int)strlen(vp->strvalue),vp->strvalue);
-
-       if ( vp->attribute == attrs[A_SIP_AVP].v && vp->type == PW_TYPE_STRING ) {
-               p = strchr(vp->strvalue,'#');
-               q = strchr(vp->strvalue,':');
-               if (!q && p == vp->strvalue && vp->strvalue+sizeof(char) != '\0' ) {
-                               r = p;
-                               r = strchr(r++,'#');
-               } else 
+       LM_DBG("vp->name '%.*s'\n", (int)strlen(vp->name), vp->name);
+       LM_DBG("vp->attribute '%d'\n", vp->attribute);
+       LM_DBG("vp->type '%d'\n", vp->type);
+       LM_DBG("vp->lvalue '%d'\n", vp->lvalue);
+       if(vp->type == PW_TYPE_STRING)
+               LM_DBG("vp->strvalue '%.*s'\n", (int)strlen(vp->strvalue),
+                               vp->strvalue);
+
+       if(vp->attribute == attrs[A_SIP_AVP].v && vp->type == PW_TYPE_STRING) {
+               p = strchr(vp->strvalue, '#');
+               q = strchr(vp->strvalue, ':');
+               if(!q && p == vp->strvalue && vp->strvalue + sizeof(char) != '\0') {
+                       r = p;
+                       r = strchr(r++, '#');
+               } else
                        r = NULL;
                errno = 0;
-               if ( p == vp->strvalue && q ) {
+               if(p == vp->strvalue && q) {
                        /* int name and str value */
                        *flags |= AVP_VAL_STR;
-                       name->n = strtol(++p,&q,10);
+                       name->n = strtol(++p, &q, 10);
                        value->s.s = ++q;
                        value->s.len = strlen(q);
-               } else if ( p && !r && p > vp->strvalue && !q ) {
+               } else if(p && !r && p > vp->strvalue && !q) {
                        /* str name and int value */
                        *flags |= AVP_NAME_STR;
                        name->s.len = p - vp->strvalue;
                        name->s.s = vp->strvalue;
-                       value->n = strtol(++p,&r,10);
-               } else if ( p && p != r && !q ) {
+                       value->n = strtol(++p, &r, 10);
+               } else if(p && r && p != r && !q) {
                        /* int name and int vale */
-                       name->n = strtol(++p,&q,10);
-                       value->n = strtol(++r,&q,10);
-               } else if ( (!p || p > q) && q ) {
+                       name->n = strtol(++p, &q, 10);
+                       value->n = strtol(++r, &q, 10);
+               } else if((!p || p > q) && q) {
                        /* str name and str value */
-                       *flags |= AVP_VAL_STR|AVP_NAME_STR;
+                       *flags |= AVP_VAL_STR | AVP_NAME_STR;
                        name->s.len = q - vp->strvalue;
                        name->s.s = vp->strvalue;
                        value->s.len = strlen(++q);
                        value->s.s = q;
                } else /* error - unknown */
                        return 0;
-           if ( errno != 0 )
+               if(errno != 0)
                        return 0;
-       } else if (vp->type == PW_TYPE_STRING) {
-                       *flags |= AVP_VAL_STR|AVP_NAME_STR;
-                       /* if start of value is the name of value */
-                       if (vp->strvalue == strstr(vp->strvalue,vp->name))
-                               /* then get value after name + one char delimiter */
-                               p = vp->strvalue + strlen(vp->name) + sizeof(char);
-                       else
-                               p = vp->strvalue;
-                       value->s.len = vp->lvalue - (p - vp->strvalue);
-                       value->s.s = p;
-                       name->s.len = strlen(vp->name); 
-                       name->s.s = vp->name;
-       } else if ((vp->type == PW_TYPE_INTEGER) || (vp->type == PW_TYPE_IPADDR) || (vp->type == PW_TYPE_DATE)) {
-                       *flags |= AVP_NAME_STR;
-                       value->n = vp->lvalue;
-                       name->s.len = strlen(vp->name); 
-                       name->s.s = vp->name;
+       } else if(vp->type == PW_TYPE_STRING) {
+               *flags |= AVP_VAL_STR | AVP_NAME_STR;
+               /* if start of value is the name of value */
+               if(vp->strvalue == strstr(vp->strvalue, vp->name))
+                       /* then get value after name + one char delimiter */
+                       p = vp->strvalue + strlen(vp->name) + sizeof(char);
+               else
+                       p = vp->strvalue;
+               value->s.len = vp->lvalue - (p - vp->strvalue);
+               value->s.s = p;
+               name->s.len = strlen(vp->name);
+               name->s.s = vp->name;
+       } else if((vp->type == PW_TYPE_INTEGER) || (vp->type == PW_TYPE_IPADDR)
+                         || (vp->type == PW_TYPE_DATE)) {
+               *flags |= AVP_NAME_STR;
+               value->n = vp->lvalue;
+               name->s.len = strlen(vp->name);
+               name->s.s = vp->name;
        } else {
-                       LM_ERR("Unknown AVP type '%d'!\n",vp->type);
-                       return 0;
+               LM_ERR("Unknown AVP type '%d'!\n", vp->type);
+               return 0;
        }
-       if ( ! name->s.len )
-          return 0;
+       if(!name->s.len)
+               return 0;
        return 1;
 }
 
 /*
  * Generate AVPs from the database result
  */
-static int generate_avps(VALUE_PAIRreceived)
+static int generate_avps(VALUE_PAIR *received)
 {
        int_str name, val;
        unsigned short flags;
@@ -144,24 +146,27 @@ static int generate_avps(VALUE_PAIR* received)
 
        LM_DBG("getting AVPs from RADIUS Reply\n");
        vp = received;
-       if ( ! ar_radius_avps_mode )
-               vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0);
-       for( ; vp; vp=((ar_radius_avps_mode)?vp->next:rc_avpair_get(vp->next,attrs[A_SIP_AVP].v,0)) ) {
+       if(!ar_radius_avps_mode)
+               vp = rc_avpair_get(vp, attrs[A_SIP_AVP].v, 0);
+       for(; vp; vp = ((ar_radius_avps_mode) ? vp->next
+                                                                                 : rc_avpair_get(vp->next,
+                                                                                                       attrs[A_SIP_AVP].v, 0))) {
                flags = 0;
-               if (!extract_avp( vp, &flags, &name, &val)){
-                       LM_ERR("error while extracting AVP '%.*s'\n",(int)strlen(vp->name),vp->name);
+               if(!extract_avp(vp, &flags, &name, &val)) {
+                       LM_ERR("error while extracting AVP '%.*s'\n", (int)strlen(vp->name),
+                                       vp->name);
                        continue;
                }
-               if (add_avp( flags, name, val) < 0) {
+               if(add_avp(flags, name, val) < 0) {
                        LM_ERR("unable to create a new AVP\n");
                } else {
                        LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
-                               (flags&AVP_NAME_STR)?name.s.len:4,
-                               (flags&AVP_NAME_STR)?name.s.s:"null",
-                               (flags&AVP_NAME_STR)?0:name.n,
-                               (flags&AVP_VAL_STR)?val.s.len:4,
-                               (flags&AVP_VAL_STR)?val.s.s:"null",
-                               (flags&AVP_VAL_STR)?0:val.n );
+                                       (flags & AVP_NAME_STR) ? name.s.len : 4,
+                                       (flags & AVP_NAME_STR) ? name.s.s : "null",
+                                       (flags & AVP_NAME_STR) ? 0 : name.n,
+                                       (flags & AVP_VAL_STR) ? val.s.len : 4,
+                                       (flags & AVP_VAL_STR) ? val.s.s : "null",
+                                       (flags & AVP_VAL_STR) ? 0 : val.n);
                }
        }
 
@@ -169,23 +174,23 @@ static int generate_avps(VALUE_PAIR* received)
 }
 
 
-static int add_cisco_vsa(VALUE_PAIR** send, struct sip_msg* msg)
+static int add_cisco_vsa(VALUE_PAIR **send, struct sip_msg *msg)
 {
        str callid;
 
-       if (!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) == -1) {
+       if(!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) == -1) {
                LM_ERR("cannot parse Call-ID header field\n");
                return -1;
        }
 
-       if (!msg->callid) {
+       if(!msg->callid) {
                LM_ERR("call-ID header field not found\n");
                return -1;
        }
 
        callid.len = msg->callid->body.len + 8;
        callid.s = pkg_malloc(callid.len);
-       if (callid.s == NULL) {
+       if(callid.s == NULL) {
                LM_ERR("no pkg memory left\n");
                return -1;
        }
@@ -193,8 +198,9 @@ static int add_cisco_vsa(VALUE_PAIR** send, struct sip_msg* msg)
        memcpy(callid.s, "call-id=", 8);
        memcpy(callid.s + 8, msg->callid->body.s, msg->callid->body.len);
 
-       if (rc_avpair_add(rh, send, attrs[A_CISCO_AVPAIR].v, callid.s,
-                       callid.len, VENDOR(attrs[A_CISCO_AVPAIR].v)) == 0) {
+       if(rc_avpair_add(rh, send, attrs[A_CISCO_AVPAIR].v, callid.s, callid.len,
+                          VENDOR(attrs[A_CISCO_AVPAIR].v))
+                       == 0) {
                LM_ERR("unable to add Cisco-AVPair attribute\n");
                pkg_free(callid.s);
                return -1;
@@ -212,7 +218,8 @@ static int add_cisco_vsa(VALUE_PAIR** send, struct sip_msg* msg)
  * which can be be used as a check item in the request.  Service type of
  * the request is Authenticate-Only.
  */
-int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user) 
+int radius_authorize_sterman(
+               struct sip_msg *_msg, dig_cred_t *_cred, str *_method, str *_user)
 {
        static char msg[4096];
        VALUE_PAIR *send, *received;
@@ -220,39 +227,40 @@ int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _meth
        str method, user, user_name;
        str *ruri;
        int extra_cnt, offset, i;
-               
+
        send = received = 0;
 
-       if (!(_cred && _method && _user)) {
+       if(!(_cred && _method && _user)) {
                LM_ERR("invalid parameter value\n");
                return -1;
        }
 
        method = *_method;
        user = *_user;
-       
+
        /*
         * Add all the user digest parameters according to the qop defined.
         * Most devices tested only offer support for the simplest digest.
         */
-       if (_cred->username.domain.len || !append_realm_to_username) {
-               if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
+       if(_cred->username.domain.len || !append_realm_to_username) {
+               if(!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
+                                  _cred->username.whole.s, _cred->username.whole.len, 0)) {
                        LM_ERR("unable to add User-Name attribute\n");
                        goto err;
                }
        } else {
                user_name.len = _cred->username.user.len + _cred->realm.len + 1;
                user_name.s = pkg_malloc(user_name.len);
-               if (!user_name.s) {
+               if(!user_name.s) {
                        LM_ERR("no pkg memory left\n");
                        return -3;
                }
                memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
                user_name.s[_cred->username.whole.len] = '@';
                memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s,
-                       _cred->realm.len);
-               if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s,
-               user_name.len, 0)) {
+                               _cred->realm.len);
+               if(!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s,
+                                  user_name.len, 0)) {
                        LM_ERR("unable to add User-Name attribute\n");
                        pkg_free(user_name.s);
                        goto err;
@@ -260,131 +268,130 @@ int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _meth
                pkg_free(user_name.s);
        }
 
-       if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v, 
-       _cred->username.whole.s, _cred->username.whole.len, 0)) {
+       if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v,
+                          _cred->username.whole.s, _cred->username.whole.len, 0)) {
                LM_ERR("unable to add Digest-User-Name attribute\n");
                goto err;
        }
 
-       if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s,
-       _cred->realm.len, 0)) {
+       if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s,
+                          _cred->realm.len, 0)) {
                LM_ERR("unable to add Digest-Realm attribute\n");
                goto err;
        }
-       if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s,
-       _cred->nonce.len, 0)) {
+       if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s,
+                          _cred->nonce.len, 0)) {
                LM_ERR("unable to add Digest-Nonce attribute\n");
                goto err;
        }
 
-       if (use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) {
+       if(use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) {
                ruri = &_cred->uri;
        } else {
                ruri = GET_RURI(_msg);
        }
-       if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, ruri->s,
-       ruri->len, 0)) {
+       if(!rc_avpair_add(
+                          rh, &send, attrs[A_DIGEST_URI].v, ruri->s, ruri->len, 0)) {
                LM_ERR("unable to add Digest-URI attribute\n");
                goto err;
        }
 
-       if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s,
-       method.len, 0)) {
+       if(!rc_avpair_add(
+                          rh, &send, attrs[A_DIGEST_METHOD].v, method.s, method.len, 0)) {
                LM_ERR("unable to add Digest-Method attribute\n");
                goto err;
        }
-       
+
        /* 
         * Add the additional authentication fields according to the QOP.
         */
-       if (_cred->qop.qop_parsed == QOP_AUTH) {
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) {
+       if(_cred->qop.qop_parsed == QOP_AUTH) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) {
                        LM_ERR("unable to add Digest-QOP attribute\n");
                        goto err;
                }
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, 
-               _cred->nc.s, _cred->nc.len, 0)) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s,
+                                  _cred->nc.len, 0)) {
                        LM_ERR("unable to add Digest-CNonce-Count attribute\n");
                        goto err;
                }
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, 
-               _cred->cnonce.s, _cred->cnonce.len, 0)) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s,
+                                  _cred->cnonce.len, 0)) {
                        LM_ERR("unable to add Digest-CNonce attribute\n");
                        goto err;
                }
-       } else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v,
-               "auth-int", 8, 0)) {
+       } else if(_cred->qop.qop_parsed == QOP_AUTHINT) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth-int", 8, 0)) {
                        LM_ERR("unable to add Digest-QOP attribute\n");
                        goto err;
                }
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v,
-               _cred->nc.s, _cred->nc.len, 0)) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s,
+                                  _cred->nc.len, 0)) {
                        LM_ERR("unable to add Digest-Nonce-Count attribute\n");
                        goto err;
                }
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v,
-               _cred->cnonce.s, _cred->cnonce.len, 0)) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s,
+                                  _cred->cnonce.len, 0)) {
                        LM_ERR("unable to add Digest-CNonce attribute\n");
                        goto err;
                }
-               if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v, 
-               _cred->opaque.s, _cred->opaque.len, 0)) {
+               if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v,
+                                  _cred->opaque.s, _cred->opaque.len, 0)) {
                        LM_ERR("unable to add Digest-Body-Digest attribute\n");
                        goto err;
                }
-               
-       } else  {
+
+       } else {
                /* send nothing for qop == "" */
        }
 
        /* Add the response... What to calculate against... */
-       if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v, 
-       _cred->response.s, _cred->response.len, 0)) {
+       if(!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v, _cred->response.s,
+                          _cred->response.len, 0)) {
                LM_ERR("unable to add Digest-Response attribute\n");
                goto err;
        }
 
        /* Indicate the service type, Authenticate only in our case */
        service = vals[V_SIP_SESSION].v;
-       if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
+       if(!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
                LM_ERR("unable to add Service-Type attribute\n");
                goto err;
        }
 
        /* Add SIP URI as a check item */
-       if (!rc_avpair_add(rh,&send,attrs[A_SIP_URI_USER].v,user.s,user.len,0)) {
+       if(!rc_avpair_add(
+                          rh, &send, attrs[A_SIP_URI_USER].v, user.s, user.len, 0)) {
                LM_ERR("unable to add Sip-URI-User attribute\n");
                goto err;
        }
 
-       if (attrs[A_CISCO_AVPAIR].n != NULL) {
-               if (add_cisco_vsa(&send, _msg)) {
+       if(attrs[A_CISCO_AVPAIR].n != NULL) {
+               if(add_cisco_vsa(&send, _msg)) {
                        goto err;
                }
        }
 
        /* Add extra attributes */
        extra_cnt = extra2strar(auth_extra, _msg, val_arr);
-       if (extra_cnt == -1) {
-           LM_ERR("in getting values of extra attributes\n");
-           goto err;
+       if(extra_cnt == -1) {
+               LM_ERR("in getting values of extra attributes\n");
+               goto err;
        }
        offset = A_MAX;
-       for (i = 0; i < extra_cnt; i++) {
-           if (val_arr[i].len == -1) {
-               /* Add integer attribute */
-               ADD_EXTRA_AVPAIR(attrs, offset+i,
-                                &(val_arr[i].s), val_arr[i].len );
-           } else {
-               /* Add string attribute */
-               ADD_EXTRA_AVPAIR(attrs, offset+i,
-                                val_arr[i].s, val_arr[i].len );
-           }
+       for(i = 0; i < extra_cnt; i++) {
+               if(val_arr[i].len == -1) {
+                       /* Add integer attribute */
+                       ADD_EXTRA_AVPAIR(
+                                       attrs, offset + i, &(val_arr[i].s), val_arr[i].len);
+               } else {
+                       /* Add string attribute */
+                       ADD_EXTRA_AVPAIR(attrs, offset + i, val_arr[i].s, val_arr[i].len);
+               }
        }
 
        /* Send request */
-       if ((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) {
+       if((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) {
                LM_DBG("Success\n");
                rc_avpair_free(send);
                send = 0;
@@ -395,16 +402,18 @@ int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _meth
                return 1;
        } else {
 #ifdef REJECT_RC
-                if (i == REJECT_RC) {
-                        LM_DBG("Failure\n");
-                        goto err;
-                }
-#endif 
+               if(i == REJECT_RC) {
+                       LM_DBG("Failure\n");
+                       goto err;
+               }
+#endif
                LM_ERR("authorization failed. RC auth returned %d\n", i);
        }
 
- err:
-       if (send) rc_avpair_free(send);
-       if (received) rc_avpair_free(received);
+err:
+       if(send)
+               rc_avpair_free(send);
+       if(received)
+               rc_avpair_free(received);
        return -1;
 }
index b518f92..8386f4e 100644 (file)
@@ -35,7 +35,7 @@
  * which can be be used as a check item in the request.  Service type of
  * the request is Authenticate-Only.
  */
-int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred,
-                            str* _method, str* _user); 
+int radius_authorize_sterman(
+               struct sip_msg *_msg, dig_cred_t *_cred, str *_method, str *_user);
 
 #endif /* STERMAN_H */
index 6f38bcd..30ac60e 100644 (file)
@@ -35,6 +35,7 @@ Bastian Friedrich
               3.1. enable (int)
               3.2. granularity (int)
               3.3. loglevel (int)
+              3.4. register (str)
 
         4. Functions
 
@@ -69,10 +70,11 @@ Bastian Friedrich
    1.1. Set enable parameter
    1.2. Set granularity parameter
    1.3. Set loglevel parameter
-   1.4. bm_start_timer usage
-   1.5. bm_log_timer usage
-   1.6. Enabling a timer
-   1.7. benchmark usage
+   1.4. Set register parameter
+   1.5. bm_start_timer usage
+   1.6. bm_log_timer usage
+   1.7. Enabling a timer
+   1.8. benchmark usage
    2.1. Using the benchmark module's API from another module
 
 Chapter 1. Admin Guide
@@ -90,6 +92,7 @@ Chapter 1. Admin Guide
         3.1. enable (int)
         3.2. granularity (int)
         3.3. loglevel (int)
+        3.4. register (str)
 
    4. Functions
 
@@ -140,6 +143,7 @@ Chapter 1. Admin Guide
    3.1. enable (int)
    3.2. granularity (int)
    3.3. loglevel (int)
+   3.4. register (str)
 
 3.1. enable (int)
 
@@ -193,6 +197,20 @@ modparam("benchmark", "loglevel", 4)
 
    This will set the logging level to L_DBG.
 
+3.4. register (str)
+
+   Register a timer id at startup. Required when using the start/log
+   functions via Kemi framework. This parameter can be set many times to
+   register several timer ids.
+
+   Default value is “NONE”.
+
+   Example 1.4. Set register parameter
+...
+modparam("benchmark", "register", "test")
+modparam("benchmark", "register", "auth")
+...
+
 4. Functions
 
    4.1. bm_start_timer(name)
@@ -202,7 +220,7 @@ modparam("benchmark", "loglevel", 4)
 
    Start timer “name”. A later call to “bm_log_timer()” logs this timer..
 
-   Example 1.4. bm_start_timer usage
+   Example 1.5. bm_start_timer usage
 ...
 bm_start_timer("test");
 ...
@@ -235,7 +253,7 @@ bm_start_timer("test");
 
      * Global avg possibly the most interesting value.
 
-   Example 1.5. bm_log_timer usage
+   Example 1.6. bm_log_timer usage
 ...
 bm_log_timer("test");
 ...
@@ -269,7 +287,7 @@ bm_log_timer("test");
    Enable or disable a single timer. The following example enables timer
    "test" (the second parameter must be 0 to disable):
 
-   Example 1.6. Enabling a timer
+   Example 1.7. Enabling a timer
 ...
 kamcmd benchmark.enable_timer test 1
 ...
@@ -286,7 +304,7 @@ kamcmd benchmark.enable_timer test 1
 
    Measure the duration of user location lookup.
 
-   Example 1.7. benchmark usage
+   Example 1.8. benchmark usage
 ...
 bm_start_timer("usrloc-lookup");
 lookup("location");
index 61e866b..cfa6469 100644 (file)
@@ -48,6 +48,7 @@
 #include "../../core/ut.h"
 #include "../../core/rpc.h"
 #include "../../core/rpc_lookup.h"
+#include "../../core/kemi.h"
 
 
 #include "benchmark.h"
@@ -58,6 +59,8 @@
 MODULE_VERSION
 
 static int bm_init_rpc(void);
+static int bm_init_mycfg(void);
+int bm_register_timer_param(modparam_t type, void* val);
 
 /* Exported functions */
 int bm_start_timer(struct sip_msg* _msg, char* timer, char *foobar);
@@ -128,6 +131,8 @@ static param_export_t params[] = {
        {"enable",      INT_PARAM, &bm_enable_global},
        {"granularity", INT_PARAM, &bm_granularity},
        {"loglevel",    INT_PARAM, &bm_loglevel},
+       {"register",    PARAM_STRING|USE_FUNC_PARAM, (void*)bm_register_timer_param},
+
        { 0, 0, 0 }
 };
 
@@ -162,23 +167,21 @@ struct module_exports exports = {
 
 /****************/
 
-
 /*
  * mod_init
  * Called by Kamailio at init time
  */
-static int mod_init(void) {
+static int mod_init(void)
+{
 
        if(bm_init_rpc()<0) {
                LM_ERR("failed to register RPC commands\n");
                return -1;
        }
 
-       bm_mycfg = (bm_cfg_t*)shm_malloc(sizeof(bm_cfg_t));
-       memset(bm_mycfg, 0, sizeof(bm_cfg_t));
-       bm_mycfg->enable_global = bm_enable_global;
-       bm_mycfg->granularity   = bm_granularity;
-       bm_mycfg->loglevel      = bm_loglevel;
+       if(bm_init_mycfg()<0) {
+               return -1;
+       }
 
        return 0;
 }
@@ -208,6 +211,28 @@ static void destroy(void)
        }
 }
 
+/**
+ * 
+ */
+static int bm_init_mycfg(void)
+{
+       if(bm_mycfg!=NULL) {
+               LM_DBG("config structure initialized\n");
+               return 0;
+       }
+       bm_mycfg = (bm_cfg_t*)shm_malloc(sizeof(bm_cfg_t));
+       if(bm_mycfg==NULL) {
+               LM_ERR("failed to allocated shared memory\n");
+               return -1;
+       }
+       memset(bm_mycfg, 0, sizeof(bm_cfg_t));
+       bm_mycfg->enable_global = bm_enable_global;
+       bm_mycfg->granularity   = bm_granularity;
+       bm_mycfg->loglevel      = bm_loglevel;
+
+       return 0;
+}
+
 void bm_reset_timer(int i)
 {
        if(bm_mycfg==NULL || bm_mycfg->tindex[i]==NULL)
@@ -349,6 +374,7 @@ int bm_log_timer(struct sip_msg* _msg, char* timer, char* mystr)
        return _bm_log_timer((unsigned int)(unsigned long)timer);
 }
 
+
 int _bm_register_timer(char *tname, int mode, unsigned int *id)
 {
        benchmark_timer_t *bmt = 0;
@@ -431,6 +457,44 @@ int _bm_register_timer(char *tname, int mode, unsigned int *id)
        return 0;
 }
 
+int bm_register_timer_param(modparam_t type, void* val)
+{
+       unsigned int tid;
+
+       if(bm_init_mycfg()<0) {
+               return -1;
+       }
+       if((_bm_register_timer((char*)val, 1, &tid))!=0) {
+               LM_ERR("cannot find timer [%s]\n", (char*)val);
+               return -1;
+       }
+       LM_ERR("timer [%s] registered: %u\n", (char*)val, tid);
+       return 0;
+}
+
+static int ki_bm_start_timer(struct sip_msg* _msg, str* tname)
+{
+       unsigned int tid;
+
+       if((_bm_register_timer(tname->s, 0, &tid))!=0) {
+                       LM_ERR("cannot find timer [%s]\n", tname->s);
+                       return -1;
+       }
+
+       return _bm_start_timer(tid);
+}
+
+static int ki_bm_log_timer(sip_msg_t* _msg, str* tname)
+{
+       unsigned int tid;
+
+       if((_bm_register_timer(tname->s, 0, &tid))!=0) {
+                       LM_ERR("cannot find timer [%s]\n", tname->s);
+                       return -1;
+       }
+       return _bm_log_timer(tid);
+}
+
 /*! \brief API Binding */
 int load_bm( struct bm_binds *bmb)
 {
@@ -591,7 +655,32 @@ static int bm_init_rpc(void)
        return 0;
 }
 
-/*@} */
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_benchmark_exports[] = {
+       { str_init("benchmark"), str_init("bm_start_timer"),
+               SR_KEMIP_INT, ki_bm_start_timer,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("benchmark"), str_init("bm_log_timer"),
+               SR_KEMIP_INT, ki_bm_log_timer,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
 
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+       sr_kemi_modules_add(sr_kemi_benchmark_exports);
+       return 0;
+}
+
+/*@} */
 
-/* End of file */
+/* End of file */
\ No newline at end of file
index e666d10..2216dc2 100644 (file)
@@ -156,6 +156,29 @@ modparam("benchmark", "loglevel", 4)
                </para>
        </section>
 
+       <section id="benchmark.p.register">
+               <title><varname>register</varname> (str)</title>
+               <para>
+                       Register a timer id at startup. Required when using the start/log
+                       functions via Kemi framework. This parameter can be set many
+                       times to register several timer ids.
+               </para>
+               <para>
+               <emphasis>
+                       Default value is <quote>NONE</quote>.
+               </emphasis>
+               </para>
+               <example>
+               <title>Set <varname>register</varname> parameter</title>
+               <programlisting format="linespecific">
+...
+modparam("benchmark", "register", "test")
+modparam("benchmark", "register", "auth")
+...
+</programlisting>
+               </example>
+       </section>
+
        </section>
        <section>
        <title>Functions</title>
index 2041009..29bce00 100644 (file)
@@ -31,6 +31,7 @@
 #include "../../core/dprint.h"
 #include "../../core/compiler_opt.h"
 #include "../../core/counters.h"
+#include "../../core/kemi.h"
 
 MODULE_VERSION
 
@@ -238,7 +239,9 @@ static int cnt_int_fixup(void** param, int param_no)
 }
 
 
-
+/**
+ * 
+ */
 static int cnt_inc_f(struct sip_msg* msg, char* handle, char* bar)
 {
        counter_handle_t h;
@@ -248,8 +251,39 @@ static int cnt_inc_f(struct sip_msg* msg, char* handle, char* bar)
        return 1;
 }
 
+#define cnt_op_handle_get() \
+       do { \
+               name = sname->s; \
+               grp = cnt_script_grp; /* default group */ \
+               if ((p = strchr(name, '.')) != 0) { \
+                       /* found group */ \
+                       grp = name; \
+                       name = p+1; \
+                       *p = 0; \
+               } \
+               if (counter_lookup(&h, grp, name) < 0) { \
+                       ERR("counter %s.%s does not exist (forgot to define it?)\n", \
+                                       grp, name); \
+                       return -1; \
+               } \
+       } while(0)
+
+static int ki_cnt_inc(sip_msg_t* msg, str *sname)
+{
+       char* name;
+       char* grp;
+       char* p;
+       counter_handle_t h;
+
+       cnt_op_handle_get();
 
+       counter_inc(h);
+       return 1;
+}
 
+/**
+ * 
+ */
 static int cnt_add_f(struct sip_msg* msg, char* handle, char* val)
 {
        counter_handle_t h;
@@ -264,8 +298,22 @@ static int cnt_add_f(struct sip_msg* msg, char* handle, char* val)
        return 1;
 }
 
+static int ki_cnt_add(sip_msg_t* msg, str *sname, int v)
+{
+       char* name;
+       char* grp;
+       char* p;
+       counter_handle_t h;
+
+       cnt_op_handle_get();
 
+       counter_add(h, v);
+       return 1;
+}
 
+/**
+ * 
+ */
 static int cnt_reset_f(struct sip_msg* msg, char* handle, char* bar)
 {
        counter_handle_t h;
@@ -276,6 +324,19 @@ static int cnt_reset_f(struct sip_msg* msg, char* handle, char* bar)
 }
 
 
+static int ki_cnt_reset(sip_msg_t* msg, str *sname)
+{
+       char* name;
+       char* grp;
+       char* p;
+       counter_handle_t h;
+
+       cnt_op_handle_get();
+
+       counter_reset(h);
+       return 1;
+}
+
 
 static void cnt_grp_get_all(rpc_t* rpc, void* c, char* group);
 
@@ -461,4 +522,35 @@ static void cnt_help_rpc(rpc_t* rpc, void* ctx)
        return;
 }
 
-/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_counters_exports[] = {
+       { str_init("counters"), str_init("inc"),
+               SR_KEMIP_INT, ki_cnt_inc,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("counters"), str_init("add"),
+               SR_KEMIP_INT, ki_cnt_add,
+               { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("counters"), str_init("reset"),
+               SR_KEMIP_INT, ki_cnt_reset,
+               { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
+
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+       sr_kemi_modules_add(sr_kemi_counters_exports);
+       return 0;
+}
+
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
\ No newline at end of file
index 195b11c..39ad19b 100644 (file)
@@ -84,7 +84,7 @@ void compile_logs( str *log)
                log->len += cpl_logs[i].len;
 
        /* get a buffer */
-       log->s = (char*)pkg_malloc(log->len);
+       log->s = (char*)pkg_malloc(log->len+1);
        if (log->s==0) {
                LM_ERR("no more pkg mem\n");
                log->len = 0;
@@ -97,6 +97,7 @@ void compile_logs( str *log)
                memcpy( p, cpl_logs[i].s, cpl_logs[i].len);
                p += cpl_logs[i].len;
        }
+       log->s[log->len] = '\0';
 
        return;
 }
index 36758f8..653c3a2 100644 (file)
@@ -328,6 +328,7 @@ int tr_byxxx_init(tr_byxxx_p _bxp, int _nr)
        if(!_bxp->req)
        {
                pkg_free(_bxp->xxx);
+               _bxp->xxx = NULL;
                return -1;
        }
        
index 6d09d19..d3541ad 100644 (file)
@@ -31,6 +31,7 @@
 #include "../../core/pvapi.h"
 #include "../../core/lvalue.h"
 #include "../../core/basex.h"
+#include "../../core/kemi.h"
 
 #include "crypto_uuid.h"
 
@@ -152,39 +153,28 @@ static void mod_destroy(void)
 /**
  *
  */
-static int w_crypto_aes_encrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
+static int ki_crypto_aes_encrypt_helper(sip_msg_t* msg, str *ins, str *keys,
+               pv_spec_t *dst)
 {
-       str ins;
-       str keys;
-       pv_spec_t *dst;
        pv_value_t val;
        EVP_CIPHER_CTX *en = NULL;
        str etext;
 
-       if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
-               LM_ERR("cannot get input value\n");
-               return -1;
-       }
-       if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
-               LM_ERR("cannot get key value\n");
-               return -1;
-       }
        en = EVP_CIPHER_CTX_new();
        if(en==NULL) {
                LM_ERR("cannot get new cipher context\n");
                return -1;
        }
-       dst = (pv_spec_t*)outb;
 
        /* gen key and iv. init the cipher ctx object */
-       if (crypto_aes_init((unsigned char *)keys.s, keys.len,
+       if (crypto_aes_init((unsigned char *)keys->s, keys->len,
                                (unsigned char*)((_crypto_salt_param)?_crypto_salt:0), en, NULL)) {
                EVP_CIPHER_CTX_free(en);
                LM_ERR("couldn't initialize AES cipher\n");
                return -1;
        }
-       etext.len = ins.len;
-       etext.s = (char *)crypto_aes_encrypt(en, (unsigned char *)ins.s, &etext.len);
+       etext.len = ins->len;
+       etext.s = (char *)crypto_aes_encrypt(en, (unsigned char *)ins->s, &etext.len);
        if(etext.s==NULL) {
                EVP_CIPHER_CTX_free(en);
                LM_ERR("AES encryption failed\n");
@@ -217,6 +207,45 @@ error:
        return -1;
 }
 
+/**
+ *
+ */
+static int ki_crypto_aes_encrypt(sip_msg_t* msg, str *ins, str *keys, str *dpv)
+{
+       pv_spec_t *dst;
+
+       dst = pv_cache_get(dpv);
+
+       if(dst==NULL) {
+               LM_ERR("failed getting pv: %.*s\n", dpv->len, dpv->s);
+               return -1;
+       }
+
+       return ki_crypto_aes_encrypt_helper(msg, ins, keys, dst);
+}
+
+/**
+ *
+ */
+static int w_crypto_aes_encrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
+{
+       str ins;
+       str keys;
+       pv_spec_t *dst;
+
+       if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
+               LM_ERR("cannot get input value\n");
+               return -1;
+       }
+       if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
+               LM_ERR("cannot get key value\n");
+               return -1;
+       }
+       dst = (pv_spec_t*)outb;
+
+       return ki_crypto_aes_encrypt_helper(msg, &ins, &keys, dst);
+}
+
 /**
  *
  */
@@ -242,32 +271,22 @@ static int fixup_crypto_aes_encrypt(void** param, int param_no)
 /**
  *
  */
-static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
+static int ki_crypto_aes_decrypt_helper(sip_msg_t* msg, str *ins, str *keys,
+               pv_spec_t *dst)
 {
-       str ins;
-       str keys;
-       pv_spec_t *dst;
+
        pv_value_t val;
        EVP_CIPHER_CTX *de=NULL;
        str etext;
 
-       if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
-               LM_ERR("cannot get input value\n");
-               return -1;
-       }
-       if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
-               LM_ERR("cannot get key value\n");
-               return -1;
-       }
        de = EVP_CIPHER_CTX_new();
        if(de==NULL) {
                LM_ERR("cannot get new cipher context\n");
                return -1;
        }
-       dst = (pv_spec_t*)outb;
 
        /* gen key and iv. init the cipher ctx object */
-       if (crypto_aes_init((unsigned char *)keys.s, keys.len,
+       if (crypto_aes_init((unsigned char *)keys->s, keys->len,
                                (unsigned char*)((_crypto_salt_param)?_crypto_salt:0), NULL, de)) {
                EVP_CIPHER_CTX_free(de);
                LM_ERR("couldn't initialize AES cipher\n");
@@ -276,7 +295,7 @@ static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* out
 
        memset(&val, 0, sizeof(pv_value_t));
        etext.s = pv_get_buffer();
-       etext.len = base64_dec((unsigned char *)ins.s, ins.len,
+       etext.len = base64_dec((unsigned char *)ins->s, ins->len,
                                        (unsigned char *)etext.s, pv_get_buffer_size()-1);
        if (etext.len < 0) {
                EVP_CIPHER_CTX_free(de);
@@ -302,6 +321,46 @@ static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* out
        return 1;
 }
 
+/**
+ *
+ */
+static int ki_crypto_aes_decrypt(sip_msg_t* msg, str *ins, str *keys, str *dpv)
+{
+       pv_spec_t *dst;
+
+       dst = pv_cache_get(dpv);
+
+       if(dst==NULL) {
+               LM_ERR("failed getting pv: %.*s\n", dpv->len, dpv->s);
+               return -1;
+       }
+
+       return ki_crypto_aes_decrypt_helper(msg, ins, keys, dst);
+}
+
+/**
+ *
+ */
+static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
+{
+       str ins;
+       str keys;
+       pv_spec_t *dst;
+
+       if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
+               LM_ERR("cannot get input value\n");
+               return -1;
+       }
+       if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
+               LM_ERR("cannot get key value\n");
+               return -1;
+       }
+
+       dst = (pv_spec_t*)outb;
+
+       return ki_crypto_aes_decrypt_helper(msg, &ins, &keys, dst);
+}
+
 /**
  *
  */
@@ -521,3 +580,29 @@ int crypto_aes_test(void)
 
        return 0;
 }
+
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_crypto_exports[] = {
+       { str_init("crypto"), str_init("aes_encrypt"),
+               SR_KEMIP_INT, ki_crypto_aes_encrypt,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("crypto"), str_init("aes_decrypt"),
+               SR_KEMIP_INT, ki_crypto_aes_decrypt,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
+
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+       sr_kemi_modules_add(sr_kemi_crypto_exports);
+       return 0;
+}
\ No newline at end of file
index 647face..dca2c81 100644 (file)
@@ -201,6 +201,9 @@ static int split_fields(char *part, int *n, struct xlstr **strs) {
        int i, res;
        char *c, *fld;
 
+       if(part==NULL || *part=='\0')
+               return -1;
+
        *n = 0;
        *strs = 0;
        c = part;
index 6170de3..3e4f9a3 100644 (file)
@@ -255,8 +255,10 @@ static int parse_postgres_uri(struct pg_uri *res, str *uri)
        return 0;
 
 err:
-       if(prev_token)
-               pkg_free(prev_token);
+       if(prev_token) {
+               if(res==NULL || (res->username!=prev_token && res->host!=prev_token))
+                       pkg_free(prev_token);
+       }
        if(res == NULL)
                return -1;
        if(res->username) {
index 04e7494..0535a00 100644 (file)
 /**
  * @brief bind dmq module api
  */
-int bind_dmq(dmq_api_t* api) {
+int bind_dmq(dmq_api_t *api)
+{
        api->register_dmq_peer = register_dmq_peer;
        api->send_message = dmq_send_message;
        api->bcast_message = bcast_dmq_message;
        api->find_dmq_node_uri = find_dmq_node_uri2;
        return 0;
 }
-
index 57f983f..8b4694e 100644 (file)
 #include "dmqnode.h"
 #include "dmq_funcs.h"
 
-typedef int (*bcast_message_t)(dmq_peer_t* peer, str* body, dmq_node_t* except,
-               dmq_resp_cback_t* resp_cback, int max_forwards, str* content_type);
-typedef int (*send_message_t)(dmq_peer_t* peer, str* body, dmq_node_t* node,
-               dmq_resp_cback_t* resp_cback, int max_forwards, str* content_type);
-typedef dmq_node_t* (*find_dmq_node_uri_t)(str* uri);
+typedef int (*bcast_message_t)(dmq_peer_t *peer, str *body, dmq_node_t *except,
+               dmq_resp_cback_t *resp_cback, int max_forwards, str *content_type);
+typedef int (*send_message_t)(dmq_peer_t *peer, str *body, dmq_node_t *node,
+               dmq_resp_cback_t *resp_cback, int max_forwards, str *content_type);
+typedef dmq_node_t *(*find_dmq_node_uri_t)(str *uri);
 
-typedef struct dmq_api {
+typedef struct dmq_api
+{
        register_dmq_peer_t register_dmq_peer;
        bcast_message_t bcast_message;
        send_message_t send_message;
        find_dmq_node_uri_t find_dmq_node_uri;
 } dmq_api_t;
 
-typedef int (*bind_dmq_f)(dmq_api_tapi);
+typedef int (*bind_dmq_f)(dmq_api_t *api);
 
-int bind_dmq(dmq_api_tapi);
+int bind_dmq(dmq_api_t *api);
 
-static inline int dmq_load_api(dmq_api_t* api) {
+static inline int dmq_load_api(dmq_api_t *api)
+{
        bind_dmq_f binddmq;
        binddmq = (bind_dmq_f)find_export("bind_dmq", 0, 0);
-       if ( binddmq == 0) {
+       if(binddmq == 0) {
                LM_ERR("cannot find bind_dmq\n");
                return -1;
        }
-       if (binddmq(api) < 0)
-       {
+       if(binddmq(api) < 0) {
                LM_ERR("cannot bind dmq api\n");
                return -1;
        }
@@ -62,4 +63,3 @@ static inline int dmq_load_api(dmq_api_t* api) {
 }
 
 #endif
-
index f06111f..6f34a23 100644 (file)
@@ -38,6 +38,7 @@
 #include "../../core/hashes.h"
 #include "../../core/mod_fix.h"
 #include "../../core/rpc_lookup.h"
+#include "../../core/kemi.h"
 
 #include "dmq.h"
 #include "dmq_funcs.h"
@@ -74,35 +75,34 @@ sl_api_t slb;
 
 /** module variables */
 str dmq_request_method = str_init("KDMQ");
-dmq_worker_tworkers = NULL;
-dmq_peer_list_tpeer_list = 0;
+dmq_worker_t *workers = NULL;
+dmq_peer_list_t *peer_list = 0;
 /* the list of dmq servers */
-dmq_node_list_tnode_list = NULL;
+dmq_node_list_t *node_list = NULL;
 // the dmq module is a peer itself for receiving notifications regarding nodes
-dmq_peer_tdmq_notification_peer = NULL;
+dmq_peer_t *dmq_notification_peer = NULL;
 
 /** module functions */
 static int mod_init(void);
 static int child_init(int);
 static void destroy(void);
-static int handle_dmq_fixup(void** param, int param_no);
-static int send_dmq_fixup(void** param, int param_no);
-static int bcast_dmq_fixup(void** param, int param_no);
 
+/* clang-format off */
 static cmd_export_t cmds[] = {
-       {"dmq_handle_message",  (cmd_function)dmq_handle_message, 0, handle_dmq_fixup, 0,
-               REQUEST_ROUTE},
-       {"dmq_send_message", (cmd_function)cfg_dmq_send_message, 4, send_dmq_fixup, 0,
-               ANY_ROUTE},
-        {"dmq_bcast_message", (cmd_function)cfg_dmq_bcast_message, 3, bcast_dmq_fixup, 0,
-                ANY_ROUTE},
-       {"dmq_t_replicate",  (cmd_function)cfg_dmq_t_replicate, 0, 0, 0,
-               REQUEST_ROUTE},
-        {"dmq_t_replicate",  (cmd_function)cfg_dmq_t_replicate, 1, fixup_spve_null, 0,
-                REQUEST_ROUTE},
-        {"dmq_is_from_node",  (cmd_function)cfg_dmq_is_from_node, 0, 0, 0,
-                REQUEST_ROUTE},
-        {"bind_dmq",        (cmd_function)bind_dmq,       0, 0,              0},
+       {"dmq_handle_message", (cmd_function)dmq_handle_message, 0,
+               0, 0, REQUEST_ROUTE},
+       {"dmq_send_message", (cmd_function)cfg_dmq_send_message, 4,
+               fixup_spve_all, 0, ANY_ROUTE},
+       {"dmq_bcast_message", (cmd_function)cfg_dmq_bcast_message, 3,
+               fixup_spve_all, 0, ANY_ROUTE},
+       {"dmq_t_replicate", (cmd_function)cfg_dmq_t_replicate, 0,
+               0, 0, REQUEST_ROUTE},
+       {"dmq_t_replicate", (cmd_function)cfg_dmq_t_replicate, 1,
+               fixup_spve_null, 0, REQUEST_ROUTE},
+       {"dmq_is_from_node", (cmd_function)cfg_dmq_is_from_node, 0,
+               0, 0, REQUEST_ROUTE},
+       {"bind_dmq", (cmd_function)bind_dmq, 0,
+               0, 0, 0},
        {0, 0, 0, 0, 0, 0}
 };
 
@@ -133,9 +133,11 @@ struct module_exports exports = {
        (destroy_function) destroy,     /* destroy function */
        child_init                      /* per-child init function */
 };
+/* clang-format on */
 
 
-static int make_socket_str_from_uri(struct sip_uri *uri, str *socket) {
+static int make_socket_str_from_uri(struct sip_uri *uri, str *socket)
+{
        if(!uri->host.s || !uri->host.len) {
                LM_ERR("no host in uri\n");
                return -1;
@@ -143,7 +145,7 @@ static int make_socket_str_from_uri(struct sip_uri *uri, str *socket) {
 
        socket->len = uri->host.len + uri->port.len + 6;
        socket->s = pkg_malloc(socket->len);
-       if(socket->s==NULL) {
+       if(socket->s == NULL) {
                LM_ERR("no more pkg\n");
                return -1;
        }
@@ -170,32 +172,32 @@ static int make_socket_str_from_uri(struct sip_uri *uri, str *socket) {
 static int mod_init(void)
 {
        /* bind the SL API */
-       if (sl_load_api(&slb)!=0) {
+       if(sl_load_api(&slb) != 0) {
                LM_ERR("cannot bind to SL API\n");
                return -1;
        }
 
        /* load all TM stuff */
-       if(load_tm_api(&tmb)==-1) {
+       if(load_tm_api(&tmb) == -1) {
                LM_ERR("can't load tm functions. TM module probably not loaded\n");
                return -1;
        }
 
        /* load peer list - the list containing the module callbacks for dmq */
        peer_list = init_peer_list();
-       if(peer_list==NULL) {
+       if(peer_list == NULL) {
                LM_ERR("cannot initialize peer list\n");
                return -1;
        }
 
        /* load the dmq node list - the list containing the dmq servers */
        node_list = init_dmq_node_list();
-       if(node_list==NULL) {
+       if(node_list == NULL) {
                LM_ERR("cannot initialize node list\n");
                return -1;
        }
 
-       if (rpc_register_array(rpc_methods)!=0) {
+       if(rpc_register_array(rpc_methods) != 0) {
                LM_ERR("failed to register RPC commands\n");
                return -1;
        }
@@ -204,12 +206,15 @@ static int mod_init(void)
        register_procs(num_workers);
 
        /* check server_address and notification_address are not empty and correct */
-       if(parse_uri(dmq_server_address.s, dmq_server_address.len, &dmq_server_uri) < 0) {
+       if(parse_uri(dmq_server_address.s, dmq_server_address.len, &dmq_server_uri)
+                       < 0) {
                LM_ERR("server address invalid\n");
                return -1;
        }
 
-       if(parse_uri(dmq_notification_address.s, dmq_notification_address.len, &dmq_notification_uri) < 0) {
+       if(parse_uri(dmq_notification_address.s, dmq_notification_address.len,
+                          &dmq_notification_uri)
+                       < 0) {
                LM_ERR("notification address invalid\n");
                return -1;
        }
@@ -219,7 +224,7 @@ static int mod_init(void)
                LM_ERR("failed to create socket out of server_uri\n");
                return -1;
        }
-       if (lookup_local_socket(&dmq_server_socket) == NULL) {
+       if(lookup_local_socket(&dmq_server_socket) == NULL) {
                LM_ERR("server_uri is not a socket the proxy is listening on\n");
                return -1;
        }
@@ -232,7 +237,7 @@ static int mod_init(void)
        }
 
        dmq_init_callback_done = shm_malloc(sizeof(int));
-       if (!dmq_init_callback_done) {
+       if(!dmq_init_callback_done) {
                LM_ERR("no more shm\n");
                return -1;
        }
@@ -242,12 +247,12 @@ static int mod_init(void)
         * add the dmq notification peer.
         * the dmq is a peer itself so that it can receive node notifications
         */
-       if(add_notification_peer()<0) {
+       if(add_notification_peer() < 0) {
                LM_ERR("cannot add notification peer\n");
                return -1;
        }
 
-       startup_time = (int) time(NULL);
+       startup_time = (int)time(NULL);
 
        /**
         * add the ping timer
@@ -256,7 +261,7 @@ static int mod_init(void)
        if(ping_interval < MIN_PING_INTERVAL) {
                ping_interval = MIN_PING_INTERVAL;
        }
-       if(register_timer(ping_servers, 0, ping_interval)<0) {
+       if(register_timer(ping_servers, 0, ping_interval) < 0) {
                LM_ERR("cannot register timer callback\n");
                return -1;
        }
@@ -269,8 +274,8 @@ static int mod_init(void)
  */
 static int child_init(int rank)
 {
-       int i, newpid;
-       if (rank == PROC_MAIN) {
+       int i, newpid;
+       if(rank == PROC_MAIN) {
                /* fork worker processes */
                for(i = 0; i < num_workers; i++) {
                        init_worker(&workers[i]);
@@ -293,10 +298,11 @@ static int child_init(int rank)
                 * a master in this architecture
                 */
                if(dmq_notification_address.s) {
-                       notification_node = add_server_and_notify(&dmq_notification_address);
+                       notification_node =
+                                       add_server_and_notify(&dmq_notification_address);
                        if(!notification_node) {
                                LM_ERR("cannot retrieve initial nodelist from %.*s\n",
-                                      STR_FMT(&dmq_notification_address));
+                                               STR_FMT(&dmq_notification_address));
                                return -1;
                        }
                }
@@ -314,53 +320,39 @@ static int child_init(int rank)
 /*
  * destroy function
  */
-static void destroy(void) {
+static void destroy(void)
+{
        /* TODO unregister dmq node, free resources */
        if(dmq_notification_address.s && notification_node && self_node) {
                LM_DBG("unregistering node %.*s\n", STR_FMT(&self_node->orig_uri));
                self_node->status = DMQ_NODE_DISABLED;
                request_nodelist(notification_node, 1);
        }
-       if (dmq_server_socket.s) {
+       if(dmq_server_socket.s) {
                pkg_free(dmq_server_socket.s);
        }
-       if (dmq_init_callback_done) {
+       if(dmq_init_callback_done) {
                shm_free(dmq_init_callback_done);
        }
 }
 
-static int handle_dmq_fixup(void** param, int param_no)
-{
-       return 0;
-}
-
-static int send_dmq_fixup(void** param, int param_no)
-{
-       return fixup_spve_null(param, 1);
-}
-
-static int bcast_dmq_fixup(void** param, int param_no)
-{
-        return fixup_spve_null(param, 1);
-}
-
 static void dmq_rpc_list_nodes(rpc_t *rpc, void *c)
 {
        void *h;
-       dmq_node_tcur = node_list->nodes;
+       dmq_node_t *cur = node_list->nodes;
        char ip[IP6_MAX_STR_SIZE + 1];
 
        while(cur) {
                memset(ip, 0, IP6_MAX_STR_SIZE + 1);
                ip_addr2sbuf(&cur->ip_address, ip, IP6_MAX_STR_SIZE);
-               if (rpc->add(c, "{", &h) < 0) goto error;
-               if (rpc->struct_add(h, "SSsSdd",
-                       "host", &cur->uri.host,
-                       "port", &cur->uri.port,
-                       "resolved_ip", ip,
-                       "status", get_status_str(cur->status),
-                       "last_notification", cur->last_notification,
-                       "local", cur->local) < 0) goto error;
+               if(rpc->add(c, "{", &h) < 0)
+                       goto error;
+               if(rpc->struct_add(h, "SSsSdd", "host", &cur->uri.host, "port",
+                                  &cur->uri.port, "resolved_ip", ip, "status",
+                                  get_status_str(cur->status), "last_notification",
+                                  cur->last_notification, "local", cur->local)
+                               < 0)
+                       goto error;
                cur = cur->next;
        }
        return;
@@ -368,14 +360,57 @@ error:
        LM_ERR("Failed to add item to RPC response\n");
        rpc->fault(c, 500, "Server failure");
        return;
-
 }
 
-static const char *dmq_rpc_list_nodes_doc[2] = {
-       "Print all nodes", 0
-};
+static const char *dmq_rpc_list_nodes_doc[2] = {"Print all nodes", 0};
 
 static rpc_export_t rpc_methods[] = {
        {"dmq.list_nodes", dmq_rpc_list_nodes, dmq_rpc_list_nodes_doc, RET_ARRAY},
        {0, 0, 0, 0}
 };
+
+/**
+ *
+ */
+/* clang-format off */
+static sr_kemi_t sr_kemi_dmq_exports[] = {
+       { str_init("dmq"), str_init("handle_message"),
+               SR_KEMIP_INT, ki_dmq_handle_message,
+               { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("dmq"), str_init("is_from_node"),
+               SR_KEMIP_INT, is_from_remote_node,
+               { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("dmq"), str_init("t_replicate"),
+               SR_KEMIP_INT, ki_dmq_t_replicate,
+               { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("dmq"), str_init("t_replicate_mode"),
+               SR_KEMIP_INT, ki_dmq_t_replicate_mode,
+               { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("dmq"), str_init("send_message"),
+               SR_KEMIP_INT, ki_dmq_send_message,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+                       SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+       { str_init("dmq"), str_init("bcast_message"),
+               SR_KEMIP_INT, ki_dmq_bcast_message,
+               { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+                       SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+       },
+
+       { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
+};
+/* clang-format on */
+
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+       sr_kemi_modules_add(sr_kemi_dmq_exports);
+       return 0;
+}
\ No newline at end of file
index 06792f3..411e41a 100644 (file)
 #include "peer.h"
 #include "worker.h"
 
-#define DEFAULT_NUM_WORKERS    2
-#define MIN_PING_INTERVAL      5
+#define DEFAULT_NUM_WORKERS 2
+#define MIN_PING_INTERVAL 5
 
 extern int num_workers;
 extern int worker_usleep;
-extern dmq_worker_tworkers;
-extern dmq_peer_tdmq_notification_peer;
+extern dmq_worker_t *workers;
+extern dmq_peer_t *dmq_notification_peer;
 extern str dmq_server_address;
-extern dmq_peer_list_tpeer_list;
+extern dmq_peer_list_t *peer_list;
 extern str dmq_request_method;
 extern str dmq_server_socket;
 extern struct sip_uri dmq_server_uri;
@@ -58,4 +58,3 @@ extern str dmq_500_rpl;
 extern str dmq_404_rpl;
 
 #endif
-
index 622ec42..a7fa31e 100644 (file)
 /**
  * @brief register a DMQ peer
  */
-dmq_peer_t* register_dmq_peer(dmq_peer_t* peer)
+dmq_peer_t *register_dmq_peer(dmq_peer_t *peer)
 {
-       dmq_peer_tnew_peer;
-       if (!peer_list) {
+       dmq_peer_t *new_peer;
+       if(!peer_list) {
                LM_ERR("peer list not initialized\n");
                return NULL;
        }
        lock_get(&peer_list->lock);
        if(search_peer_list(peer_list, peer)) {
-               LM_ERR("peer already exists: %.*s %.*s\n", peer->peer_id.len, peer->peer_id.s,
-                      peer->description.len, peer->description.s);
+               LM_ERR("peer already exists: %.*s %.*s\n", peer->peer_id.len,
+                               peer->peer_id.s, peer->description.len, peer->description.s);
                lock_release(&peer_list->lock);
                return NULL;
        }
@@ -51,16 +51,18 @@ dmq_peer_t* register_dmq_peer(dmq_peer_t* peer)
  */
 void dmq_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
 {
-       dmq_cback_param_t* cb_param;
-       
-       cb_param = (dmq_cback_param_t*)(*ps->param);
+       dmq_cback_param_t *cb_param;
 
-       if(cb_param==NULL)
+       cb_param = (dmq_cback_param_t *)(*ps->param);
+
+       if(cb_param == NULL)
                return;
 
        LM_DBG("dmq_tm_callback start\n");
        if(cb_param->resp_cback.f) {
-               if(cb_param->resp_cback.f(ps->rpl, ps->code, cb_param->node, cb_param->resp_cback.param) < 0) {
+               if(cb_param->resp_cback.f(ps->rpl, ps->code, cb_param->node,
+                                  cb_param->resp_cback.param)
+                               < 0) {
                        LM_ERR("error in response callback\n");
                }
        }
@@ -70,11 +72,11 @@ void dmq_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
        *ps->param = NULL;
 }
 
-int build_uri_str(str* username, struct sip_uri* uri, str* from)
+int build_uri_str(str *username, struct sip_uri *uri, str *from)
 {
        /* sip:user@host:port */
        int from_len;
-       
+
        if(!uri->host.s || !uri->host.len) {
                LM_ERR("no host in uri\n");
                return -1;
@@ -86,24 +88,24 @@ int build_uri_str(str* username, struct sip_uri* uri, str* from)
 
        from_len = username->len + uri->host.len + uri->port.len + 10;
        from->s = pkg_malloc(from_len);
-       if(from->s==NULL) {
+       if(from->s == NULL) {
                LM_ERR("no more pkg\n");
                return -1;
        }
        from->len = 0;
-       
+
        memcpy(from->s, "sip:", 4);
        from->len += 4;
-       
+
        memcpy(from->s + from->len, username->s, username->len);
        from->len += username->len;
-       
+
        memcpy(from->s + from->len, "@", 1);
        from->len += 1;
-       
+
        memcpy(from->s + from->len, uri->host.s, uri->host.len);
        from->len += uri->host.len;
-       
+
        if(uri->port.s && uri->port.len) {
                memcpy(from->s + from->len, ":", 1);
                from->len += 1;
@@ -114,11 +116,11 @@ int build_uri_str(str* username, struct sip_uri* uri, str* from)
 }
 
 /* Checks if the request (sip_msg_t* msg) comes from another DMQ node based on source IP. */
-int is_from_remote_node(sip_msg_tmsg)
+int is_from_remote_node(sip_msg_t *msg)
 {
-       ip_addr_tip;
-        dmq_node_t* node;
-        int result = -1;
+       ip_addr_t *ip;
+       dmq_node_t *node;
+       int result = -1;
 
        ip = &msg->rcv.src_ip;
 
@@ -126,14 +128,14 @@ int is_from_remote_node(sip_msg_t* msg)
        node = node_list->nodes;
 
        while(node) {
-               if (!node->local && ip_addr_cmp(ip, &node->ip_address)) {
+               if(!node->local && ip_addr_cmp(ip, &node->ip_address)) {
                        result = 1;
                        goto done;
                }
                node = node->next;
-        }
+       }
 done:
-        lock_release(&node_list->lock);
+       lock_release(&node_list->lock);
        return result;
 }
 
@@ -145,11 +147,11 @@ done:
  * except - we do not send the message to this node
  * resp_cback - a response callback that gets called when the transaction is complete
  */
-int bcast_dmq_message(dmq_peer_t* peer, str* body, dmq_node_t* except,
-               dmq_resp_cback_t* resp_cback, int max_forwards, str* content_type)
+int bcast_dmq_message(dmq_peer_t *peer, str *body, dmq_node_t *except,
+               dmq_resp_cback_t *resp_cback, int max_forwards, str *content_type)
 {
-       dmq_node_tnode;
-       
+       dmq_node_t *node;
+
        lock_get(&node_list->lock);
        node = node_list->nodes;
        while(node) {
@@ -164,7 +166,9 @@ int bcast_dmq_message(dmq_peer_t* peer, str* body, dmq_node_t* except,
                        node = node->next;
                        continue;
                }
-               if(dmq_send_message(peer, body, node, resp_cback, max_forwards, content_type) < 0) {
+               if(dmq_send_message(
+                                  peer, body, node, resp_cback, max_forwards, content_type)
+                               < 0) {
                        LM_ERR("error sending dmq message\n");
                        goto error;
                }
@@ -185,43 +189,44 @@ error:
  * node - we send the message to this node
  * resp_cback - a response callback that gets called when the transaction is complete
  */
-int dmq_send_message(dmq_peer_t* peer, str* body, dmq_node_t* node,
-               dmq_resp_cback_t* resp_cback, int max_forwards, str* content_type)
+int dmq_send_message(dmq_peer_t *peer, str *body, dmq_node_t *node,
+               dmq_resp_cback_t *resp_cback, int max_forwards, str *content_type)
 {
        uac_req_t uac_r;
        str str_hdr = {0, 0};
        str from = {0, 0}, to = {0, 0};
-       dmq_cback_param_tcb_param = NULL;
+       dmq_cback_param_t *cb_param = NULL;
        int result = 0;
        int len = 0;
-       
-       if (!content_type) {
+
+       if(!content_type) {
                LM_ERR("content-type is null\n");
                return -1;
        }
        /* add Max-Forwards and Content-Type headers */
-       str_hdr.len = 34 + content_type->len + (CRLF_LEN*2);
+       str_hdr.len = 34 + content_type->len + (CRLF_LEN * 2);
        str_hdr.s = pkg_malloc(str_hdr.len);
-       if(str_hdr.s==NULL) {
+       if(str_hdr.s == NULL) {
                LM_ERR("no more pkg\n");
                return -1;
        }
-       len += sprintf(str_hdr.s, "Max-Forwards: %d" CRLF "Content-Type: %.*s" CRLF, max_forwards, content_type->len, content_type->s);
+       len += sprintf(str_hdr.s, "Max-Forwards: %d" CRLF "Content-Type: %.*s" CRLF,
+                       max_forwards, content_type->len, content_type->s);
        str_hdr.len = len;
-       
+
        cb_param = shm_malloc(sizeof(*cb_param));
-       if (cb_param == NULL) {
+       if(cb_param == NULL) {
                LM_ERR("no more shm for building callback parameter\n");
                goto error;
        }
        memset(cb_param, 0, sizeof(*cb_param));
        cb_param->resp_cback = *resp_cback;
        cb_param->node = shm_dup_node(node);
-       if (cb_param->node == NULL) {
+       if(cb_param->node == NULL) {
                LM_ERR("error building callback parameter\n");
                goto error;
        }
-       
+
        if(build_uri_str(&peer->peer_id, &dmq_server_uri, &from) < 0) {
                LM_ERR("error building from string [username %.*s]\n",
                                STR_FMT(&peer->peer_id));
@@ -231,14 +236,12 @@ int dmq_send_message(dmq_peer_t* peer, str* body, dmq_node_t* node,
                LM_ERR("error building to string\n");
                goto error;
        }
-       
+
        set_uac_req(&uac_r, &dmq_request_method, &str_hdr, body, NULL,
-                       TMCB_LOCAL_COMPLETED, dmq_tm_callback, (void*)cb_param);
+                       TMCB_LOCAL_COMPLETED, dmq_tm_callback, (void *)cb_param);
        uac_r.ssock = &dmq_server_socket;
 
-       result = tmb.t_request(&uac_r, &to,
-                              &to, &from,
-                              NULL);
+       result = tmb.t_request(&uac_r, &to, &to, &from, NULL);
        if(result < 0) {
                LM_ERR("error in tmb.t_request_within\n");
                goto error;
@@ -249,12 +252,12 @@ int dmq_send_message(dmq_peer_t* peer, str* body, dmq_node_t* node,
        return 0;
 error:
        pkg_free(str_hdr.s);
-       if (from.s!=NULL) 
+       if(from.s != NULL)
                pkg_free(from.s);
-       if (to.s!=NULL) 
+       if(to.s != NULL)
                pkg_free(to.s);
-       if (cb_param) {
-               if (cb_param->node)
+       if(cb_param) {
+               if(cb_param->node)
                        destroy_dmq_node(cb_param->node, 1);
                shm_free(cb_param);
        }
@@ -262,60 +265,37 @@ error:
 }
 
 /**
- * @brief config file function for sending dmq message
+ * @brief kemi function for sending dmq message
  */
-int cfg_dmq_send_message(struct sip_msg* msg, char* peer, char* to, char* body, char* content_type)
+int ki_dmq_send_message(sip_msg_t *msg, str *peer_str, str *to_str,
+               str *body_str, str *ct_str)
 {
-       str peer_str;
-       str to_str;
-       str body_str;
-       str ct_str;
-       
-       if(get_str_fparam(&peer_str, msg, (fparam_t*)peer)<0) {
-               LM_ERR("cannot get peer value\n");
-               return -1;
-       }
-       if(get_str_fparam(&to_str, msg, (fparam_t*)to)<0) {
-               LM_ERR("cannot get dst value\n");
-               return -1;
-       }
-       if(get_str_fparam(&body_str, msg, (fparam_t*)body)<0) {
-               LM_ERR("cannot get body value\n");
-               return -1;
-       }
-       if(get_str_fparam(&ct_str, msg, (fparam_t*)content_type)<0) {
-               LM_ERR("cannot get content-type value\n");
-               return -1;
-       }
+       LM_DBG("cfg_dmq_send_message: %.*s - %.*s - %.*s - %.*s\n", peer_str->len,
+                       peer_str->s, to_str->len, to_str->s, body_str->len, body_str->s,
+                       ct_str->len, ct_str->s);
 
-       
-       LM_DBG("cfg_dmq_send_message: %.*s - %.*s - %.*s - %.*s\n",
-               peer_str.len, peer_str.s,
-               to_str.len, to_str.s,
-               body_str.len, body_str.s,
-               ct_str.len, ct_str.s);
-       
-       dmq_peer_t* destination_peer = find_peer(peer_str);
+       dmq_peer_t *destination_peer = find_peer(*peer_str);
        if(!destination_peer) {
-               LM_INFO("cannot find peer %.*s\n", peer_str.len, peer_str.s);
+               LM_INFO("cannot find peer %.*s\n", peer_str->len, peer_str->s);
                dmq_peer_t new_peer;
                new_peer.callback = empty_peer_callback;
                new_peer.description.s = "";
                new_peer.description.len = 0;
-               new_peer.peer_id = peer_str;
+               new_peer.peer_id = *peer_str;
                destination_peer = register_dmq_peer(&new_peer);
                if(!destination_peer) {
                        LM_ERR("error in register_dmq_peer\n");
                        goto error;
                }
        }
-       dmq_node_t* to_dmq_node = find_dmq_node_uri(node_list, &to_str);
+       dmq_node_t *to_dmq_node = find_dmq_node_uri(node_list, to_str);
        if(!to_dmq_node) {
-               LM_ERR("cannot find dmq_node: %.*s\n", to_str.len, to_str.s);
+               LM_ERR("cannot find dmq_node: %.*s\n", to_str->len, to_str->s);
                goto error;
        }
-       if(dmq_send_message(destination_peer, &body_str, to_dmq_node,
-                               &notification_callback, 1, &ct_str) < 0) {
+       if(dmq_send_message(destination_peer, body_str, to_dmq_node,
+                          &notification_callback, 1, ct_str)
+                       < 0) {
                LM_ERR("cannot send dmq message\n");
                goto error;
        }
@@ -324,50 +304,63 @@ error:
        return -1;
 }
 
-
 /**
- * @brief config file function for broadcasting dmq message
+ * @brief config file function for sending dmq message
  */
-int cfg_dmq_bcast_message(struct sip_msg* msg, char* peer, char* body, char* content_type)
+int cfg_dmq_send_message(struct sip_msg *msg, char *peer, char *to, char *body,
+               char *content_type)
 {
        str peer_str;
+       str to_str;
        str body_str;
        str ct_str;
 
-       if(get_str_fparam(&peer_str, msg, (fparam_t*)peer)<0) {
+       if(get_str_fparam(&peer_str, msg, (fparam_t *)peer) < 0) {
                LM_ERR("cannot get peer value\n");
                return -1;
        }
-       if(get_str_fparam(&body_str, msg, (fparam_t*)body)<0) {
+       if(get_str_fparam(&to_str, msg, (fparam_t *)to) < 0) {
+               LM_ERR("cannot get dst value\n");
+               return -1;
+       }
+       if(get_str_fparam(&body_str, msg, (fparam_t *)body) < 0) {
                LM_ERR("cannot get body value\n");
                return -1;
        }
-       if(get_str_fparam(&ct_str, msg, (fparam_t*)content_type)<0) {
+       if(get_str_fparam(&ct_str, msg, (fparam_t *)content_type) < 0) {
                LM_ERR("cannot get content-type value\n");
                return -1;
        }
 
-       LM_DBG("cfg_dmq_bcast_message: %.*s - %.*s - %.*s\n",
-               peer_str.len, peer_str.s,
-               body_str.len, body_str.s,
-               ct_str.len, ct_str.s);
+       return ki_dmq_send_message(msg, &peer_str, &to_str, &body_str, &ct_str);
+}
 
-       dmq_peer_t* destination_peer = find_peer(peer_str);
+/**
+ * @brief config file function for broadcasting dmq message
+ */
+int ki_dmq_bcast_message(sip_msg_t *msg, str *peer_str, str *body_str,
+               str *ct_str)
+{
+       LM_DBG("cfg_dmq_bcast_message: %.*s - %.*s - %.*s\n", peer_str->len,
+                       peer_str->s, body_str->len, body_str->s, ct_str->len, ct_str->s);
+
+       dmq_peer_t *destination_peer = find_peer(*peer_str);
        if(!destination_peer) {
-               LM_INFO("cannot find peer %.*s - adding it.\n", peer_str.len, peer_str.s);
+               LM_INFO("cannot find peer %.*s - adding it.\n", peer_str->len,
+                               peer_str->s);
                dmq_peer_t new_peer;
                new_peer.callback = empty_peer_callback;
                new_peer.description.s = "";
                new_peer.description.len = 0;
-               new_peer.peer_id = peer_str;
+               new_peer.peer_id = *peer_str;
                destination_peer = register_dmq_peer(&new_peer);
                if(!destination_peer) {
                        LM_ERR("error in register_dmq_peer\n");
                        goto error;
                }
        }
-       if(bcast_dmq_message(destination_peer, &body_str, 0,
-                       &notification_callback, 1, &ct_str) < 0) {
+       if(bcast_dmq_message(destination_peer, body_str, 0, &notification_callback,
+                          1, ct_str) < 0) {
                LM_ERR("cannot send dmq message\n");
                goto error;
        }
@@ -376,28 +369,52 @@ error:
        return -1;
 }
 
+/**
+ * @brief config file function for broadcasting dmq message
+ */
+int cfg_dmq_bcast_message(sip_msg_t *msg, char *peer, char *body,
+               char *content_type)
+{
+       str peer_str;
+       str body_str;
+       str ct_str;
+
+       if(get_str_fparam(&peer_str, msg, (fparam_t *)peer) < 0) {
+               LM_ERR("cannot get peer value\n");
+               return -1;
+       }
+       if(get_str_fparam(&body_str, msg, (fparam_t *)body) < 0) {
+               LM_ERR("cannot get body value\n");
+               return -1;
+       }
+       if(get_str_fparam(&ct_str, msg, (fparam_t *)content_type) < 0) {
+               LM_ERR("cannot get content-type value\n");
+               return -1;
+       }
+
+       return ki_dmq_bcast_message(msg, &peer_str, &body_str, &ct_str);
+}
+
 /**
  * @brief config file function for replicating SIP message to all nodes (wraps t_replicate)
  */
-int cfg_dmq_t_replicate(struct sip_msg* msg, char* s)
+int ki_dmq_t_replicate_mode(struct sip_msg *msg, int mode)
 {
-       dmq_node_t* node;
-       struct socket_info* sock;
-       int i = 0;
+       dmq_node_t *node;
+       struct socket_info *sock;
        int first = 1;
 
        /* avoid loops - do not replicate if message has come from another node
         * (override if optional parameter is set)
         */
-       if ((!s || (get_int_fparam(&i, msg, (fparam_t*)s)==0 && !i))
-                       && (is_from_remote_node(msg) > 0)) {
+       if(mode==0      && is_from_remote_node(msg) > 0) {
                LM_DBG("message is from another node - skipping replication\n");
                return -1;
        }
 
        /* TODO - backup/restore original send socket */
        sock = lookup_local_socket(&dmq_server_socket);
-       if (sock) {
+       if(sock) {
                set_force_socket(msg, sock);
        }
 
@@ -414,8 +431,9 @@ int cfg_dmq_t_replicate(struct sip_msg* msg, char* s)
                        continue;
                }
 
-               if (!first) {
-                       if (append_branch(msg, 0, 0, 0, Q_UNSPECIFIED, 0, sock, 0, 0, 0, 0) == -1) {
+               if(!first) {
+                       if(append_branch(msg, 0, 0, 0, Q_UNSPECIFIED, 0, sock, 0, 0, 0, 0)
+                                       == -1) {
                                LM_ERR("failed to append a branch\n");
                                node = node->next;
                                continue;
@@ -438,10 +456,28 @@ error:
        return -1;
 }
 
+int ki_dmq_t_replicate(sip_msg_t *msg)
+{
+       return ki_dmq_t_replicate_mode(msg, 0);
+}
+
+/**
+ * @brief config file function for replicating SIP message to all nodes (wraps t_replicate)
+ */
+int cfg_dmq_t_replicate(struct sip_msg *msg, char *s, char *p2)
+{
+       int i = 0;
+       if(s!=NULL && get_int_fparam(&i, msg, (fparam_t *)s) < 0) {
+               LM_ERR("failed to get parameter value\n");
+               return -1;
+       }
+       return ki_dmq_t_replicate_mode(msg, i);
+}
+
 /*
  * @brief config file function to check if received message is from another DMQ node based on source IP
  */
-int cfg_dmq_is_from_node(struct sip_msg* msg)
+int cfg_dmq_is_from_node(struct sip_msg *msg, char *p1, char *p2)
 {
        return is_from_remote_node(msg);
 }
@@ -455,19 +491,23 @@ int cfg_dmq_is_from_node(struct sip_msg* msg)
  *   - checks if the servers in the list are up and running
  *   - updates the list of servers from the other nodes
  */
-void ping_servers(unsigned int ticks, void *param) {
-       str* body;
+void ping_servers(unsigned int ticks, void *param)
+{
+       str *body;
        int ret;
        LM_DBG("ping_servers\n");
 
-       if (!node_list->nodes || (node_list->nodes->local && !node_list->nodes->next)) {
-               LM_DBG("node list is empty - attempt to rebuild from notification address\n");
+       if(!node_list->nodes
+                       || (node_list->nodes->local && !node_list->nodes->next)) {
+               LM_DBG("node list is empty - attempt to rebuild from notification "
+                          "address\n");
                *dmq_init_callback_done = 0;
                if(dmq_notification_address.s) {
-                       notification_node = add_server_and_notify(&dmq_notification_address);
+                       notification_node =
+                                       add_server_and_notify(&dmq_notification_address);
                        if(!notification_node) {
                                LM_ERR("cannot retrieve initial nodelist from %.*s\n",
-                                       STR_FMT(&dmq_notification_address));
+                                               STR_FMT(&dmq_notification_address));
                        }
                } else {
                        LM_ERR("no notification address");
@@ -476,7 +516,7 @@ void ping_servers(unsigned int ticks, void *param) {
        }
 
        body = build_notification_body();
-       if (!body) {
+       if(!body) {
                LM_ERR("could not build notification body\n");
                return;
        }
@@ -488,4 +528,3 @@ void ping_servers(unsigned int ticks, void *param) {
                LM_ERR("error broadcasting message\n");
        }
 }
-