Module: sip-router Branch: master Commit: c40883a7aa96a1a7fab1060bf9dfab2987971c89 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c40883a7...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Mon Dec 3 17:14:14 2012 -0500
sca: add working example kamailio.cfg
---
modules/sca/examples/kamailio.cfg | 414 +++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/modules/sca/examples/kamailio.cfg b/modules/sca/examples/kamailio.cfg new file mode 100644 index 0000000..8cbae87 --- /dev/null +++ b/modules/sca/examples/kamailio.cfg @@ -0,0 +1,414 @@ +#!KAMAILIO +# +# example kamailio.cfg with Shared Call Appearances (SCA) + +#!define WITH_AUTH +#!define WITH_MYSQL +#!define WITH_SCA + +####### Defined Values ######### + +#!ifdef WITH_MYSQL +# - database URL - used to connect to database server by modules such +# as: auth_db, acc, usrloc, a.s.o. +#!ifndef DBURL +#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" +#!endif +#!endif + +####### Global Parameters ######### + +#!ifdef WITH_DEBUG +debug=4 +log_stderror=yes +#!else +debug=2 +log_stderror=no +#!endif + +memdbg=5 +memlog=5 + +log_facility=LOG_LOCAL0 + +fork=yes +children=4 + +alias="vs7-dev.net.isc.upenn.edu" + +listen=udp:130.91.185.155:5060 +port=5060 + +####### Modules Section ######## + +# set paths to location of modules (to sources or installation folders) +#!ifdef WITH_SRCPATH +mpath="modules_k:modules" +#!else +mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/kamailio/modules/" +#!endif + +#!ifdef WITH_MYSQL +loadmodule "db_mysql.so" +#!endif + +loadmodule "tm.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "pv.so" +loadmodule "maxfwd.so" +loadmodule "usrloc.so" +loadmodule "registrar.so" +loadmodule "textops.so" +loadmodule "siputils.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "ctl.so" +loadmodule "cfg_rpc.so" + +#!ifdef WITH_AUTH +loadmodule "auth.so" +loadmodule "auth_db.so" +#!ifdef WITH_IPAUTH +loadmodule "permissions.so" +#!endif +#!endif + +#!ifdef WITH_SCA +loadmodule "sca.so" +#!endif + + +# ----------------- setting module-specific parameters --------------- + + +# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 30sec +modparam("tm", "fr_timer", 30000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000) + + +# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# do not append from tag to the RR (no need for this script) +modparam("rr", "append_fromtag", 0) + + +# ----- registrar params ----- +modparam("registrar", "method_filtering", 1) +/* uncomment the next line to disable parallel forking via location */ +# modparam("registrar", "append_branches", 0) +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) +# max value for expires of registrations +modparam("registrar", "max_expires", 3600) +# set it to 1 to enable GRUU +modparam("registrar", "gruu_enabled", 0) + + +# ----- usrloc params ----- +/* enable DB persistency for location entries */ +#!ifdef WITH_USRLOCDB +modparam("usrloc", "db_url", DBURL) +modparam("usrloc", "db_mode", 2) +modparam("usrloc", "use_domain", 0) +#!endif + + +# ----- auth_db params ----- +#!ifdef WITH_AUTH +modparam("auth_db", "db_url", DBURL) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "") + +# ----- permissions params ----- +#!ifdef WITH_IPAUTH +modparam("permissions", "db_url", DBURL) +modparam("permissions", "db_mode", 1) +#!endif + +#!endif + +# ----- sca params ----- +#!ifdef WITH_SCA +modparam("sca", "call_info_max_expires", 120) +modparam("sca", "db_url", DBURL) +#!endif + + +####### Routing Logic ######## + +# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route +# - note: this is the same as route { ... } +request_route { + + # per request initial checks + route(REQINIT); + + # CANCEL processing + if (is_method("CANCEL")) + { + if (t_check_trans()) + route(SCA); + t_relay(); + exit; + } + + # handle requests within SIP dialogs + route(WITHINDLG); + + ### only initial requests (no To tag) + + t_check_trans(); + + # authentication + route(AUTH); + + # record routing for dialog forming requests (in case they are routed) + # - remove preloaded route headers + remove_hf("Route"); + if (is_method("INVITE|SUBSCRIBE")) + record_route(); + + # handle registrations + route(REGISTRAR); + + if ($rU==$null) + { + # request with no Username in RURI + sl_send_reply("484","Address Incomplete"); + exit; + } + + # user location service + route(LOCATION); + + route(RELAY); +} + + +route[RELAY] { + + # enable additional event routes for forwarded requests + if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) { + if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY"); + } + if (is_method("INVITE")) { + if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); + } + +#!ifdef WITH_SCA + route(SCA); +#!endif + + if (!t_relay()) { + sl_reply_error(); + } + exit; +} + +# Per SIP request initial checks +route[REQINIT] { + if (!mf_process_maxfwd_header("10")) { + sl_send_reply("483","Too Many Hops"); + exit; + } + + if(!sanity_check("1511", "7")) + { + xlog("Malformed SIP message from $si:$sp\n"); + exit; + } +} + +# Handle requests within SIP dialogs +route[WITHINDLG] { + if (has_totag()) { + # sequential request withing a dialog should + # take the path determined by record-routing + if (loose_route()) { + if ( is_method("NOTIFY") ) { + # Add Record-Route for in-dialog NOTIFY as per RFC 6665. + record_route(); + } + route(RELAY); + } else { + if (is_method("SUBSCRIBE") && uri == myself) { + # in-dialog subscribe requests + route(SCA); + exit; + } + if ( is_method("ACK") ) { + if ( t_check_trans() ) { + # no loose-route, but stateful ACK; + # must be an ACK after a 487 + # or e.g. 404 from upstream server + t_relay(); + exit; + } else { + # ACK without matching transaction ... ignore and discard + exit; + } + } + sl_send_reply("404","Not here"); + } + exit; + } +} + +# Handle SIP registrations +route[REGISTRAR] { + if (is_method("REGISTER")) + { + if (!save("location")) + sl_reply_error(); + + exit; + } +} + +# USER location service +route[LOCATION] { + $avp(oexten) = $rU; + if (!lookup("location")) { + $var(rc) = $rc; + t_newtran(); + switch ($var(rc)) { + case -1: + case -3: + send_reply("404", "Not Found"); + exit; + case -2: + send_reply("405", "Method Not Allowed"); + exit; + } + } +} + +# Authentication route +route[AUTH] { +#!ifdef WITH_AUTH + +#!ifdef WITH_IPAUTH + if((!is_method("REGISTER")) && allow_source_address()) + { + # source IP allowed + return; + } +#!endif + + if (is_method("REGISTER") || from_uri==myself) + { + # authenticate requests + if (!auth_check("$fd", "subscriber", "1")) { + auth_challenge("$fd", "0"); + exit; + } + # user authenticated - remove auth header + if(!is_method("REGISTER|PUBLISH")) + consume_credentials(); + } + # if caller is not local subscriber, then check if it calls + # a local destination, otherwise deny, not an open relay here + if (from_uri!=myself && uri!=myself) + { + sl_send_reply("403","Not relaying"); + exit; + } + +#!endif + return; +} + +# Shared Call Appearances handling +route[SCA] { +#!ifdef WITH_SCA + if(is_method("SUBSCRIBE")) { + if ($hdr(Event) == "call-info" || $hdr(Event) == "line-seize") { + xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from $si:$sp"); + sca_handle_subscribe(); + exit; + } + + return; + } + + if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) { + return; + } + + sca_call_info_update(); +#!endif + + return; +} + +# Routing to foreign domains +route[SIPOUT] { + if (!uri==myself) + { + append_hf("P-hint: outbound\r\n"); + route(RELAY); + } +} + +# XMLRPC routing +#!ifdef WITH_XMLRPC +route[XMLRPC] { + # allow XMLRPC from localhost + if ((method=="POST" || method=="GET") + && (src_ip==127.0.0.1)) { + # close connection only for xmlrpclib user agents (there is a bug in + # xmlrpclib: it waits for EOF before interpreting the response). + if ($hdr(User-Agent) =~ "xmlrpclib") + set_reply_close(); + set_reply_no_connect(); + dispatch_rpc(); + exit; + } + send_reply("403", "Forbidden"); + exit; +} +#!endif + +# manage incoming replies +onreply_route[MANAGE_REPLY] { + xdbg("incoming reply\n"); + +#!ifdef WITH_SCA + sca_call_info_update(); +#!endif +} + +# manage failure routing cases +failure_route[MANAGE_FAILURE] { + if (t_is_canceled()) { + exit; + } + +#!ifdef WITH_SCA + route(SCA); +#!endif +} + +#!ifdef WITH_XHTTP +event_route[xhttp:request] { +#!ifdef WITH_XHTTP_RPC + $var(xhttp_rpc_root) = $(hu{s.substr,0,9}); + if ($var(xhttp_rpc_root) == "/http_rpc") { + dispatch_xhttp_rpc(); + } +#!endif + +#!ifdef WITH_SCA +event_route[tm:local-request] { + if (is_method("NOTIFY") { + record_route(); + } +}
Hello Andrew,
Maybe it would be good to move the example config into the examples directory and keep the config as simple as possible (no extra functionality, just SCA without any WITH_* directives). And if you can integrate the WITH_SCA directive into the master etc/kamailio.cfg, that would be great.
Just my 2c. -ovidiu
On Mon, Dec 3, 2012 at 5:14 PM, Andrew Mortensen admorten@isc.upenn.edu wrote:
Module: sip-router Branch: master Commit: c40883a7aa96a1a7fab1060bf9dfab2987971c89 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c40883a7...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Mon Dec 3 17:14:14 2012 -0500
sca: add working example kamailio.cfg
modules/sca/examples/kamailio.cfg | 414 +++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/modules/sca/examples/kamailio.cfg b/modules/sca/examples/kamailio.cfg new file mode 100644 index 0000000..8cbae87 --- /dev/null +++ b/modules/sca/examples/kamailio.cfg @@ -0,0 +1,414 @@ +#!KAMAILIO +# +# example kamailio.cfg with Shared Call Appearances (SCA)
+#!define WITH_AUTH +#!define WITH_MYSQL +#!define WITH_SCA
+####### Defined Values #########
+#!ifdef WITH_MYSQL +# - database URL - used to connect to database server by modules such +# as: auth_db, acc, usrloc, a.s.o. +#!ifndef DBURL +#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" +#!endif +#!endif
+####### Global Parameters #########
+#!ifdef WITH_DEBUG +debug=4 +log_stderror=yes +#!else +debug=2 +log_stderror=no +#!endif
+memdbg=5 +memlog=5
+log_facility=LOG_LOCAL0
+fork=yes +children=4
+alias="vs7-dev.net.isc.upenn.edu"
+listen=udp:130.91.185.155:5060 +port=5060
+####### Modules Section ########
+# set paths to location of modules (to sources or installation folders) +#!ifdef WITH_SRCPATH +mpath="modules_k:modules" +#!else +mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/kamailio/modules/" +#!endif
+#!ifdef WITH_MYSQL +loadmodule "db_mysql.so" +#!endif
+loadmodule "tm.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "pv.so" +loadmodule "maxfwd.so" +loadmodule "usrloc.so" +loadmodule "registrar.so" +loadmodule "textops.so" +loadmodule "siputils.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "ctl.so" +loadmodule "cfg_rpc.so"
+#!ifdef WITH_AUTH +loadmodule "auth.so" +loadmodule "auth_db.so" +#!ifdef WITH_IPAUTH +loadmodule "permissions.so" +#!endif +#!endif
+#!ifdef WITH_SCA +loadmodule "sca.so" +#!endif
+# ----------------- setting module-specific parameters ---------------
+# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 30sec +modparam("tm", "fr_timer", 30000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000)
+# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# do not append from tag to the RR (no need for this script) +modparam("rr", "append_fromtag", 0)
+# ----- registrar params ----- +modparam("registrar", "method_filtering", 1) +/* uncomment the next line to disable parallel forking via location */ +# modparam("registrar", "append_branches", 0) +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) +# max value for expires of registrations +modparam("registrar", "max_expires", 3600) +# set it to 1 to enable GRUU +modparam("registrar", "gruu_enabled", 0)
+# ----- usrloc params ----- +/* enable DB persistency for location entries */ +#!ifdef WITH_USRLOCDB +modparam("usrloc", "db_url", DBURL) +modparam("usrloc", "db_mode", 2) +modparam("usrloc", "use_domain", 0) +#!endif
+# ----- auth_db params ----- +#!ifdef WITH_AUTH +modparam("auth_db", "db_url", DBURL) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "")
+# ----- permissions params ----- +#!ifdef WITH_IPAUTH +modparam("permissions", "db_url", DBURL) +modparam("permissions", "db_mode", 1) +#!endif
+#!endif
+# ----- sca params ----- +#!ifdef WITH_SCA +modparam("sca", "call_info_max_expires", 120) +modparam("sca", "db_url", DBURL) +#!endif
+####### Routing Logic ########
+# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route +# - note: this is the same as route { ... } +request_route {
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
route(SCA);
t_relay();
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# handle registrations
route(REGISTRAR);
if ($rU==$null)
{
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# user location service
route(LOCATION);
route(RELAY);
+}
+route[RELAY] {
# enable additional event routes for forwarded requests
if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif
if (!t_relay()) {
sl_reply_error();
}
exit;
+}
+# Per SIP request initial checks +route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7"))
{
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
+}
+# Handle requests within SIP dialogs +route[WITHINDLG] {
if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(SCA);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
+}
+# Handle SIP registrations +route[REGISTRAR] {
if (is_method("REGISTER"))
{
if (!save("location"))
sl_reply_error();
exit;
}
+}
+# USER location service +route[LOCATION] {
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
+}
+# Authentication route +route[AUTH] { +#!ifdef WITH_AUTH
+#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address())
{
# source IP allowed
return;
}
+#!endif
if (is_method("REGISTER") || from_uri==myself)
{
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself)
{
sl_send_reply("403","Not relaying");
exit;
}
+#!endif
return;
+}
+# Shared Call Appearances handling +route[SCA] { +#!ifdef WITH_SCA
if(is_method("SUBSCRIBE")) {
if ($hdr(Event) == "call-info" || $hdr(Event) == "line-seize") {
xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from $si:$sp");
sca_handle_subscribe();
exit;
}
return;
}
if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) {
return;
}
sca_call_info_update();
+#!endif
return;
+}
+# Routing to foreign domains +route[SIPOUT] {
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
+}
+# XMLRPC routing +#!ifdef WITH_XMLRPC +route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET")
&& (src_ip==127.0.0.1)) {
# close connection only for xmlrpclib user agents (there is a bug in
# xmlrpclib: it waits for EOF before interpreting the response).
if ($hdr(User-Agent) =~ "xmlrpclib")
set_reply_close();
set_reply_no_connect();
dispatch_rpc();
exit;
}
send_reply("403", "Forbidden");
exit;
+} +#!endif
+# manage incoming replies +onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
+#!ifdef WITH_SCA
sca_call_info_update();
+#!endif +}
+# manage failure routing cases +failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {
exit;
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif +}
+#!ifdef WITH_XHTTP +event_route[xhttp:request] { +#!ifdef WITH_XHTTP_RPC
$var(xhttp_rpc_root) = $(hu{s.substr,0,9});
if ($var(xhttp_rpc_root) == "/http_rpc") {
dispatch_xhttp_rpc();
}
+#!endif
+#!ifdef WITH_SCA +event_route[tm:local-request] {
- if (is_method("NOTIFY") {
record_route();
- }
+}
Hello,
I think it is better to have the config example specific for a module in the module directory, eventually in the doc sub-folder and imported in the readme file in a dedicate section -- see the modules_k/dispatcher.
Definitely is not a good idea to add everything in the default configuration file of kamailio -- etc/kamailio.cfg -- this file should address common usage scenarios and be simple enough to understand and get people started.
Cheers, Daniel
On 12/3/12 11:25 PM, Ovidiu Sas wrote:
Hello Andrew,
Maybe it would be good to move the example config into the examples directory and keep the config as simple as possible (no extra functionality, just SCA without any WITH_* directives). And if you can integrate the WITH_SCA directive into the master etc/kamailio.cfg, that would be great.
Just my 2c. -ovidiu
On Mon, Dec 3, 2012 at 5:14 PM, Andrew Mortensen admorten@isc.upenn.edu wrote:
Module: sip-router Branch: master Commit: c40883a7aa96a1a7fab1060bf9dfab2987971c89 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c40883a7...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Mon Dec 3 17:14:14 2012 -0500
sca: add working example kamailio.cfg
modules/sca/examples/kamailio.cfg | 414 +++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/modules/sca/examples/kamailio.cfg b/modules/sca/examples/kamailio.cfg new file mode 100644 index 0000000..8cbae87 --- /dev/null +++ b/modules/sca/examples/kamailio.cfg @@ -0,0 +1,414 @@ +#!KAMAILIO +# +# example kamailio.cfg with Shared Call Appearances (SCA)
+#!define WITH_AUTH +#!define WITH_MYSQL +#!define WITH_SCA
+####### Defined Values #########
+#!ifdef WITH_MYSQL +# - database URL - used to connect to database server by modules such +# as: auth_db, acc, usrloc, a.s.o. +#!ifndef DBURL +#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" +#!endif +#!endif
+####### Global Parameters #########
+#!ifdef WITH_DEBUG +debug=4 +log_stderror=yes +#!else +debug=2 +log_stderror=no +#!endif
+memdbg=5 +memlog=5
+log_facility=LOG_LOCAL0
+fork=yes +children=4
+alias="vs7-dev.net.isc.upenn.edu"
+listen=udp:130.91.185.155:5060 +port=5060
+####### Modules Section ########
+# set paths to location of modules (to sources or installation folders) +#!ifdef WITH_SRCPATH +mpath="modules_k:modules" +#!else +mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/kamailio/modules/" +#!endif
+#!ifdef WITH_MYSQL +loadmodule "db_mysql.so" +#!endif
+loadmodule "tm.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "pv.so" +loadmodule "maxfwd.so" +loadmodule "usrloc.so" +loadmodule "registrar.so" +loadmodule "textops.so" +loadmodule "siputils.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "ctl.so" +loadmodule "cfg_rpc.so"
+#!ifdef WITH_AUTH +loadmodule "auth.so" +loadmodule "auth_db.so" +#!ifdef WITH_IPAUTH +loadmodule "permissions.so" +#!endif +#!endif
+#!ifdef WITH_SCA +loadmodule "sca.so" +#!endif
+# ----------------- setting module-specific parameters ---------------
+# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 30sec +modparam("tm", "fr_timer", 30000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000)
+# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# do not append from tag to the RR (no need for this script) +modparam("rr", "append_fromtag", 0)
+# ----- registrar params ----- +modparam("registrar", "method_filtering", 1) +/* uncomment the next line to disable parallel forking via location */ +# modparam("registrar", "append_branches", 0) +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) +# max value for expires of registrations +modparam("registrar", "max_expires", 3600) +# set it to 1 to enable GRUU +modparam("registrar", "gruu_enabled", 0)
+# ----- usrloc params ----- +/* enable DB persistency for location entries */ +#!ifdef WITH_USRLOCDB +modparam("usrloc", "db_url", DBURL) +modparam("usrloc", "db_mode", 2) +modparam("usrloc", "use_domain", 0) +#!endif
+# ----- auth_db params ----- +#!ifdef WITH_AUTH +modparam("auth_db", "db_url", DBURL) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "")
+# ----- permissions params ----- +#!ifdef WITH_IPAUTH +modparam("permissions", "db_url", DBURL) +modparam("permissions", "db_mode", 1) +#!endif
+#!endif
+# ----- sca params ----- +#!ifdef WITH_SCA +modparam("sca", "call_info_max_expires", 120) +modparam("sca", "db_url", DBURL) +#!endif
+####### Routing Logic ########
+# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route +# - note: this is the same as route { ... } +request_route {
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
route(SCA);
t_relay();
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# handle registrations
route(REGISTRAR);
if ($rU==$null)
{
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# user location service
route(LOCATION);
route(RELAY);
+}
+route[RELAY] {
# enable additional event routes for forwarded requests
if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif
if (!t_relay()) {
sl_reply_error();
}
exit;
+}
+# Per SIP request initial checks +route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7"))
{
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
+}
+# Handle requests within SIP dialogs +route[WITHINDLG] {
if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(SCA);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
+}
+# Handle SIP registrations +route[REGISTRAR] {
if (is_method("REGISTER"))
{
if (!save("location"))
sl_reply_error();
exit;
}
+}
+# USER location service +route[LOCATION] {
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
+}
+# Authentication route +route[AUTH] { +#!ifdef WITH_AUTH
+#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address())
{
# source IP allowed
return;
}
+#!endif
if (is_method("REGISTER") || from_uri==myself)
{
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself)
{
sl_send_reply("403","Not relaying");
exit;
}
+#!endif
return;
+}
+# Shared Call Appearances handling +route[SCA] { +#!ifdef WITH_SCA
if(is_method("SUBSCRIBE")) {
if ($hdr(Event) == "call-info" || $hdr(Event) == "line-seize") {
xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from $si:$sp");
sca_handle_subscribe();
exit;
}
return;
}
if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) {
return;
}
sca_call_info_update();
+#!endif
return;
+}
+# Routing to foreign domains +route[SIPOUT] {
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
+}
+# XMLRPC routing +#!ifdef WITH_XMLRPC +route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET")
&& (src_ip==127.0.0.1)) {
# close connection only for xmlrpclib user agents (there is a bug in
# xmlrpclib: it waits for EOF before interpreting the response).
if ($hdr(User-Agent) =~ "xmlrpclib")
set_reply_close();
set_reply_no_connect();
dispatch_rpc();
exit;
}
send_reply("403", "Forbidden");
exit;
+} +#!endif
+# manage incoming replies +onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
+#!ifdef WITH_SCA
sca_call_info_update();
+#!endif +}
+# manage failure routing cases +failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {
exit;
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif +}
+#!ifdef WITH_XHTTP +event_route[xhttp:request] { +#!ifdef WITH_XHTTP_RPC
$var(xhttp_rpc_root) = $(hu{s.substr,0,9});
if ($var(xhttp_rpc_root) == "/http_rpc") {
dispatch_xhttp_rpc();
}
+#!endif
+#!ifdef WITH_SCA +event_route[tm:local-request] {
- if (is_method("NOTIFY") {
record_route();
- }
+}
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Then we should move all config files from examples into the relevant module directory?
On Mon, Dec 3, 2012 at 5:31 PM, Daniel-Constantin Mierla miconda@gmail.com wrote:
Hello,
I think it is better to have the config example specific for a module in the module directory, eventually in the doc sub-folder and imported in the readme file in a dedicate section -- see the modules_k/dispatcher.
Definitely is not a good idea to add everything in the default configuration file of kamailio -- etc/kamailio.cfg -- this file should address common usage scenarios and be simple enough to understand and get people started.
Cheers, Daniel
On 12/3/12 11:25 PM, Ovidiu Sas wrote:
Hello Andrew,
Maybe it would be good to move the example config into the examples directory and keep the config as simple as possible (no extra functionality, just SCA without any WITH_* directives). And if you can integrate the WITH_SCA directive into the master etc/kamailio.cfg, that would be great.
Just my 2c. -ovidiu
On Mon, Dec 3, 2012 at 5:14 PM, Andrew Mortensen admorten@isc.upenn.edu wrote:
Module: sip-router Branch: master Commit: c40883a7aa96a1a7fab1060bf9dfab2987971c89 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c40883a7...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Mon Dec 3 17:14:14 2012 -0500
sca: add working example kamailio.cfg
modules/sca/examples/kamailio.cfg | 414 +++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/modules/sca/examples/kamailio.cfg b/modules/sca/examples/kamailio.cfg new file mode 100644 index 0000000..8cbae87 --- /dev/null +++ b/modules/sca/examples/kamailio.cfg @@ -0,0 +1,414 @@ +#!KAMAILIO +# +# example kamailio.cfg with Shared Call Appearances (SCA)
+#!define WITH_AUTH +#!define WITH_MYSQL +#!define WITH_SCA
+####### Defined Values #########
+#!ifdef WITH_MYSQL +# - database URL - used to connect to database server by modules such +# as: auth_db, acc, usrloc, a.s.o. +#!ifndef DBURL +#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" +#!endif +#!endif
+####### Global Parameters #########
+#!ifdef WITH_DEBUG +debug=4 +log_stderror=yes +#!else +debug=2 +log_stderror=no +#!endif
+memdbg=5 +memlog=5
+log_facility=LOG_LOCAL0
+fork=yes +children=4
+alias="vs7-dev.net.isc.upenn.edu"
+listen=udp:130.91.185.155:5060 +port=5060
+####### Modules Section ########
+# set paths to location of modules (to sources or installation folders) +#!ifdef WITH_SRCPATH +mpath="modules_k:modules" +#!else
+mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/kamailio/modules/" +#!endif
+#!ifdef WITH_MYSQL +loadmodule "db_mysql.so" +#!endif
+loadmodule "tm.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "pv.so" +loadmodule "maxfwd.so" +loadmodule "usrloc.so" +loadmodule "registrar.so" +loadmodule "textops.so" +loadmodule "siputils.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "ctl.so" +loadmodule "cfg_rpc.so"
+#!ifdef WITH_AUTH +loadmodule "auth.so" +loadmodule "auth_db.so" +#!ifdef WITH_IPAUTH +loadmodule "permissions.so" +#!endif +#!endif
+#!ifdef WITH_SCA +loadmodule "sca.so" +#!endif
+# ----------------- setting module-specific parameters ---------------
+# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 30sec +modparam("tm", "fr_timer", 30000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000)
+# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# do not append from tag to the RR (no need for this script) +modparam("rr", "append_fromtag", 0)
+# ----- registrar params ----- +modparam("registrar", "method_filtering", 1) +/* uncomment the next line to disable parallel forking via location */ +# modparam("registrar", "append_branches", 0) +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) +# max value for expires of registrations +modparam("registrar", "max_expires", 3600) +# set it to 1 to enable GRUU +modparam("registrar", "gruu_enabled", 0)
+# ----- usrloc params ----- +/* enable DB persistency for location entries */ +#!ifdef WITH_USRLOCDB +modparam("usrloc", "db_url", DBURL) +modparam("usrloc", "db_mode", 2) +modparam("usrloc", "use_domain", 0) +#!endif
+# ----- auth_db params ----- +#!ifdef WITH_AUTH +modparam("auth_db", "db_url", DBURL) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "")
+# ----- permissions params ----- +#!ifdef WITH_IPAUTH +modparam("permissions", "db_url", DBURL) +modparam("permissions", "db_mode", 1) +#!endif
+#!endif
+# ----- sca params ----- +#!ifdef WITH_SCA +modparam("sca", "call_info_max_expires", 120) +modparam("sca", "db_url", DBURL) +#!endif
+####### Routing Logic ########
+# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route +# - note: this is the same as route { ... } +request_route {
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
route(SCA);
t_relay();
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are
routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# handle registrations
route(REGISTRAR);
if ($rU==$null)
{
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# user location service
route(LOCATION);
route(RELAY);
+}
+route[RELAY] {
# enable additional event routes for forwarded requests
if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) {
if(!t_is_set("onreply_route"))
t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route"))
t_on_failure("MANAGE_FAILURE");
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif
if (!t_relay()) {
sl_reply_error();
}
exit;
+}
+# Per SIP request initial checks +route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7"))
{
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
+}
+# Handle requests within SIP dialogs +route[WITHINDLG] {
if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY
as per RFC 6665.
record_route();
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(SCA);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful
ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream
server
t_relay();
exit;
} else {
# ACK without matching
transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
+}
+# Handle SIP registrations +route[REGISTRAR] {
if (is_method("REGISTER"))
{
if (!save("location"))
sl_reply_error();
exit;
}
+}
+# USER location service +route[LOCATION] {
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
+}
+# Authentication route +route[AUTH] { +#!ifdef WITH_AUTH
+#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address())
{
# source IP allowed
return;
}
+#!endif
if (is_method("REGISTER") || from_uri==myself)
{
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself)
{
sl_send_reply("403","Not relaying");
exit;
}
+#!endif
return;
+}
+# Shared Call Appearances handling +route[SCA] { +#!ifdef WITH_SCA
if(is_method("SUBSCRIBE")) {
if ($hdr(Event) == "call-info" || $hdr(Event) ==
"line-seize") {
xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from
$si:$sp");
sca_handle_subscribe();
exit;
}
return;
}
if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) {
return;
}
sca_call_info_update();
+#!endif
return;
+}
+# Routing to foreign domains +route[SIPOUT] {
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
+}
+# XMLRPC routing +#!ifdef WITH_XMLRPC +route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET")
&& (src_ip==127.0.0.1)) {
# close connection only for xmlrpclib user agents (there
is a bug in
# xmlrpclib: it waits for EOF before interpreting the
response).
if ($hdr(User-Agent) =~ "xmlrpclib")
set_reply_close();
set_reply_no_connect();
dispatch_rpc();
exit;
}
send_reply("403", "Forbidden");
exit;
+} +#!endif
+# manage incoming replies +onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
+#!ifdef WITH_SCA
sca_call_info_update();
+#!endif +}
+# manage failure routing cases +failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {
exit;
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif +}
+#!ifdef WITH_XHTTP +event_route[xhttp:request] { +#!ifdef WITH_XHTTP_RPC
$var(xhttp_rpc_root) = $(hu{s.substr,0,9});
if ($var(xhttp_rpc_root) == "/http_rpc") {
dispatch_xhttp_rpc();
}
+#!endif
+#!ifdef WITH_SCA +event_route[tm:local-request] {
- if (is_method("NOTIFY") {
record_route();
- }
+}
On 12/3/12 11:36 PM, Ovidiu Sas wrote:
Then we should move all config files from examples into the relevant module directory?
At least a cleanup should be done. The fact is that the examples directory it was not really kept up to date. I noticed that you did an addition quite recently and wanted to discuss, just that the task didn't reach the top of my stack yet, due to traveling.
From my point of view, examples folder is not the right place because is not really visible from documentation, many peoples don't have a clue about it and one has to go to sources tree. So I think it would be better if the example config for some module would be reflected directly in the readme docs - people will use it then, either from README or from the web html docs.
Cheers, Daniel
On Mon, Dec 3, 2012 at 5:31 PM, Daniel-Constantin Mierla miconda@gmail.com wrote:
Hello,
I think it is better to have the config example specific for a module in the module directory, eventually in the doc sub-folder and imported in the readme file in a dedicate section -- see the modules_k/dispatcher.
Definitely is not a good idea to add everything in the default configuration file of kamailio -- etc/kamailio.cfg -- this file should address common usage scenarios and be simple enough to understand and get people started.
Cheers, Daniel
On 12/3/12 11:25 PM, Ovidiu Sas wrote:
Hello Andrew,
Maybe it would be good to move the example config into the examples directory and keep the config as simple as possible (no extra functionality, just SCA without any WITH_* directives). And if you can integrate the WITH_SCA directive into the master etc/kamailio.cfg, that would be great.
Just my 2c. -ovidiu
On Mon, Dec 3, 2012 at 5:14 PM, Andrew Mortensen admorten@isc.upenn.edu wrote:
Module: sip-router Branch: master Commit: c40883a7aa96a1a7fab1060bf9dfab2987971c89 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c40883a7...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Mon Dec 3 17:14:14 2012 -0500
sca: add working example kamailio.cfg
modules/sca/examples/kamailio.cfg | 414 +++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/modules/sca/examples/kamailio.cfg b/modules/sca/examples/kamailio.cfg new file mode 100644 index 0000000..8cbae87 --- /dev/null +++ b/modules/sca/examples/kamailio.cfg @@ -0,0 +1,414 @@ +#!KAMAILIO +# +# example kamailio.cfg with Shared Call Appearances (SCA)
+#!define WITH_AUTH +#!define WITH_MYSQL +#!define WITH_SCA
+####### Defined Values #########
+#!ifdef WITH_MYSQL +# - database URL - used to connect to database server by modules such +# as: auth_db, acc, usrloc, a.s.o. +#!ifndef DBURL +#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" +#!endif +#!endif
+####### Global Parameters #########
+#!ifdef WITH_DEBUG +debug=4 +log_stderror=yes +#!else +debug=2 +log_stderror=no +#!endif
+memdbg=5 +memlog=5
+log_facility=LOG_LOCAL0
+fork=yes +children=4
+alias="vs7-dev.net.isc.upenn.edu"
+listen=udp:130.91.185.155:5060 +port=5060
+####### Modules Section ########
+# set paths to location of modules (to sources or installation folders) +#!ifdef WITH_SRCPATH +mpath="modules_k:modules" +#!else
+mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/kamailio/modules/" +#!endif
+#!ifdef WITH_MYSQL +loadmodule "db_mysql.so" +#!endif
+loadmodule "tm.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "pv.so" +loadmodule "maxfwd.so" +loadmodule "usrloc.so" +loadmodule "registrar.so" +loadmodule "textops.so" +loadmodule "siputils.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "ctl.so" +loadmodule "cfg_rpc.so"
+#!ifdef WITH_AUTH +loadmodule "auth.so" +loadmodule "auth_db.so" +#!ifdef WITH_IPAUTH +loadmodule "permissions.so" +#!endif +#!endif
+#!ifdef WITH_SCA +loadmodule "sca.so" +#!endif
+# ----------------- setting module-specific parameters ---------------
+# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 30sec +modparam("tm", "fr_timer", 30000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000)
+# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# do not append from tag to the RR (no need for this script) +modparam("rr", "append_fromtag", 0)
+# ----- registrar params ----- +modparam("registrar", "method_filtering", 1) +/* uncomment the next line to disable parallel forking via location */ +# modparam("registrar", "append_branches", 0) +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) +# max value for expires of registrations +modparam("registrar", "max_expires", 3600) +# set it to 1 to enable GRUU +modparam("registrar", "gruu_enabled", 0)
+# ----- usrloc params ----- +/* enable DB persistency for location entries */ +#!ifdef WITH_USRLOCDB +modparam("usrloc", "db_url", DBURL) +modparam("usrloc", "db_mode", 2) +modparam("usrloc", "use_domain", 0) +#!endif
+# ----- auth_db params ----- +#!ifdef WITH_AUTH +modparam("auth_db", "db_url", DBURL) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "")
+# ----- permissions params ----- +#!ifdef WITH_IPAUTH +modparam("permissions", "db_url", DBURL) +modparam("permissions", "db_mode", 1) +#!endif
+#!endif
+# ----- sca params ----- +#!ifdef WITH_SCA +modparam("sca", "call_info_max_expires", 120) +modparam("sca", "db_url", DBURL) +#!endif
+####### Routing Logic ########
+# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route +# - note: this is the same as route { ... } +request_route {
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
route(SCA);
t_relay();
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are
routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# handle registrations
route(REGISTRAR);
if ($rU==$null)
{
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# user location service
route(LOCATION);
route(RELAY);
+}
+route[RELAY] {
# enable additional event routes for forwarded requests
if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) {
if(!t_is_set("onreply_route"))
t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route"))
t_on_failure("MANAGE_FAILURE");
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif
if (!t_relay()) {
sl_reply_error();
}
exit;
+}
+# Per SIP request initial checks +route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7"))
{
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
+}
+# Handle requests within SIP dialogs +route[WITHINDLG] {
if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY
as per RFC 6665.
record_route();
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(SCA);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful
ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream
server
t_relay();
exit;
} else {
# ACK without matching
transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
+}
+# Handle SIP registrations +route[REGISTRAR] {
if (is_method("REGISTER"))
{
if (!save("location"))
sl_reply_error();
exit;
}
+}
+# USER location service +route[LOCATION] {
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
+}
+# Authentication route +route[AUTH] { +#!ifdef WITH_AUTH
+#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address())
{
# source IP allowed
return;
}
+#!endif
if (is_method("REGISTER") || from_uri==myself)
{
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself)
{
sl_send_reply("403","Not relaying");
exit;
}
+#!endif
return;
+}
+# Shared Call Appearances handling +route[SCA] { +#!ifdef WITH_SCA
if(is_method("SUBSCRIBE")) {
if ($hdr(Event) == "call-info" || $hdr(Event) ==
"line-seize") {
xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from
$si:$sp");
sca_handle_subscribe();
exit;
}
return;
}
if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) {
return;
}
sca_call_info_update();
+#!endif
return;
+}
+# Routing to foreign domains +route[SIPOUT] {
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
+}
+# XMLRPC routing +#!ifdef WITH_XMLRPC +route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET")
&& (src_ip==127.0.0.1)) {
# close connection only for xmlrpclib user agents (there
is a bug in
# xmlrpclib: it waits for EOF before interpreting the
response).
if ($hdr(User-Agent) =~ "xmlrpclib")
set_reply_close();
set_reply_no_connect();
dispatch_rpc();
exit;
}
send_reply("403", "Forbidden");
exit;
+} +#!endif
+# manage incoming replies +onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
+#!ifdef WITH_SCA
sca_call_info_update();
+#!endif +}
+# manage failure routing cases +failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {
exit;
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif +}
+#!ifdef WITH_XHTTP +event_route[xhttp:request] { +#!ifdef WITH_XHTTP_RPC
$var(xhttp_rpc_root) = $(hu{s.substr,0,9});
if ($var(xhttp_rpc_root) == "/http_rpc") {
dispatch_xhttp_rpc();
}
+#!endif
+#!ifdef WITH_SCA +event_route[tm:local-request] {
- if (is_method("NOTIFY") {
record_route();
- }
+}
On Mon, Dec 3, 2012 at 5:44 PM, Daniel-Constantin Mierla miconda@gmail.com wrote:
On 12/3/12 11:36 PM, Ovidiu Sas wrote:
Then we should move all config files from examples into the relevant module directory?
At least a cleanup should be done. The fact is that the examples directory it was not really kept up to date. I noticed that you did an addition quite recently and wanted to discuss, just that the task didn't reach the top of my stack yet, due to traveling.
From my point of view, examples folder is not the right place because is not really visible from documentation, many peoples don't have a clue about it and one has to go to sources tree. So I think it would be better if the example config for some module would be reflected directly in the readme docs - people will use it then, either from README or from the web html docs.
I like the idea of having all the examples into one directory (no need to change directory to see examples from other modules). And it also keeps the module source directory cleaner. But maybe that's just me :)
Cheers, Ovidiu
4 dec 2012 kl. 00:02 skrev Ovidiu Sas osas@voipembedded.com:
On Mon, Dec 3, 2012 at 5:44 PM, Daniel-Constantin Mierla miconda@gmail.com wrote:
On 12/3/12 11:36 PM, Ovidiu Sas wrote:
Then we should move all config files from examples into the relevant module directory?
At least a cleanup should be done. The fact is that the examples directory it was not really kept up to date. I noticed that you did an addition quite recently and wanted to discuss, just that the task didn't reach the top of my stack yet, due to traveling.
From my point of view, examples folder is not the right place because is not really visible from documentation, many peoples don't have a clue about it and one has to go to sources tree. So I think it would be better if the example config for some module would be reflected directly in the readme docs - people will use it then, either from README or from the web html docs.
I like the idea of having all the examples into one directory (no need to change directory to see examples from other modules). And it also keeps the module source directory cleaner. But maybe that's just me :)
We need a new "core examples" directory. The problem with the old directory is that it is old and filled with stuff that may or may not be relevant for current users.
Module-related examples should go into the module docs first. There might be cases where there are many modules involved in an example, like with the presence solutions, that we decide to create a shared example.
Daniel - can we create an /etc/examples directory and add current stuff to it for these cases, and then start moving working configurations from /examples to it?
/etc is a directory that usually is included in distributions.
/O
3 dec 2012 kl. 23:25 skrev Ovidiu Sas osas@voipembedded.com:
Hello Andrew,
Maybe it would be good to move the example config into the examples directory and keep the config as simple as possible (no extra functionality, just SCA without any WITH_* directives). And if you can integrate the WITH_SCA directive into the master etc/kamailio.cfg, that would be great.
+1 for making it more simple -1 for integrating everything in the sample configuration.
If we keep making the sample configuration more complicated and add everything to it, it will not help people who begin using kamailio to learn anything. Like Asterisk's "sample" configuration it will just be a big mess. The sample configuration is not a reference documentation.
I am still for adding it to the README. The /examples directory need a big cleanup, there is a lot of old stuff in there, so adding anything new in there right now would mean that it disappears in the old attic of sip-router, never to be found again :-)
/O
Just my 2c. -ovidiu
On Mon, Dec 3, 2012 at 5:14 PM, Andrew Mortensen admorten@isc.upenn.edu wrote:
Module: sip-router Branch: master Commit: c40883a7aa96a1a7fab1060bf9dfab2987971c89 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c40883a7...
Author: Andrew Mortensen admorten@isc.upenn.edu Committer: Andrew Mortensen admorten@isc.upenn.edu Date: Mon Dec 3 17:14:14 2012 -0500
sca: add working example kamailio.cfg
modules/sca/examples/kamailio.cfg | 414 +++++++++++++++++++++++++++++++++++++ 1 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/modules/sca/examples/kamailio.cfg b/modules/sca/examples/kamailio.cfg new file mode 100644 index 0000000..8cbae87 --- /dev/null +++ b/modules/sca/examples/kamailio.cfg @@ -0,0 +1,414 @@ +#!KAMAILIO +# +# example kamailio.cfg with Shared Call Appearances (SCA)
+#!define WITH_AUTH +#!define WITH_MYSQL +#!define WITH_SCA
+####### Defined Values #########
+#!ifdef WITH_MYSQL +# - database URL - used to connect to database server by modules such +# as: auth_db, acc, usrloc, a.s.o. +#!ifndef DBURL +#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" +#!endif +#!endif
+####### Global Parameters #########
+#!ifdef WITH_DEBUG +debug=4 +log_stderror=yes +#!else +debug=2 +log_stderror=no +#!endif
+memdbg=5 +memlog=5
+log_facility=LOG_LOCAL0
+fork=yes +children=4
+alias="vs7-dev.net.isc.upenn.edu"
+listen=udp:130.91.185.155:5060 +port=5060
+####### Modules Section ########
+# set paths to location of modules (to sources or installation folders) +#!ifdef WITH_SRCPATH +mpath="modules_k:modules" +#!else +mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/kamailio/modules/" +#!endif
+#!ifdef WITH_MYSQL +loadmodule "db_mysql.so" +#!endif
+loadmodule "tm.so" +loadmodule "sl.so" +loadmodule "rr.so" +loadmodule "pv.so" +loadmodule "maxfwd.so" +loadmodule "usrloc.so" +loadmodule "registrar.so" +loadmodule "textops.so" +loadmodule "siputils.so" +loadmodule "xlog.so" +loadmodule "sanity.so" +loadmodule "ctl.so" +loadmodule "cfg_rpc.so"
+#!ifdef WITH_AUTH +loadmodule "auth.so" +loadmodule "auth_db.so" +#!ifdef WITH_IPAUTH +loadmodule "permissions.so" +#!endif +#!endif
+#!ifdef WITH_SCA +loadmodule "sca.so" +#!endif
+# ----------------- setting module-specific parameters ---------------
+# ----- tm params ----- +# auto-discard branches from previous serial forking leg +modparam("tm", "failure_reply_mode", 3) +# default retransmission timeout: 30sec +modparam("tm", "fr_timer", 30000) +# default invite retransmission timeout after 1xx: 120sec +modparam("tm", "fr_inv_timer", 120000)
+# ----- rr params ----- +# add value to ;lr param to cope with most of the UAs +modparam("rr", "enable_full_lr", 1) +# do not append from tag to the RR (no need for this script) +modparam("rr", "append_fromtag", 0)
+# ----- registrar params ----- +modparam("registrar", "method_filtering", 1) +/* uncomment the next line to disable parallel forking via location */ +# modparam("registrar", "append_branches", 0) +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) +# max value for expires of registrations +modparam("registrar", "max_expires", 3600) +# set it to 1 to enable GRUU +modparam("registrar", "gruu_enabled", 0)
+# ----- usrloc params ----- +/* enable DB persistency for location entries */ +#!ifdef WITH_USRLOCDB +modparam("usrloc", "db_url", DBURL) +modparam("usrloc", "db_mode", 2) +modparam("usrloc", "use_domain", 0) +#!endif
+# ----- auth_db params ----- +#!ifdef WITH_AUTH +modparam("auth_db", "db_url", DBURL) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "")
+# ----- permissions params ----- +#!ifdef WITH_IPAUTH +modparam("permissions", "db_url", DBURL) +modparam("permissions", "db_mode", 1) +#!endif
+#!endif
+# ----- sca params ----- +#!ifdef WITH_SCA +modparam("sca", "call_info_max_expires", 120) +modparam("sca", "db_url", DBURL) +#!endif
+####### Routing Logic ########
+# Main SIP request routing logic +# - processing of any incoming SIP request starts with this route +# - note: this is the same as route { ... } +request_route {
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL"))
{
if (t_check_trans())
route(SCA);
t_relay();
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# handle registrations
route(REGISTRAR);
if ($rU==$null)
{
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# user location service
route(LOCATION);
route(RELAY);
+}
+route[RELAY] {
# enable additional event routes for forwarded requests
if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif
if (!t_relay()) {
sl_reply_error();
}
exit;
+}
+# Per SIP request initial checks +route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7"))
{
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
+}
+# Handle requests within SIP dialogs +route[WITHINDLG] {
if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(SCA);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
+}
+# Handle SIP registrations +route[REGISTRAR] {
if (is_method("REGISTER"))
{
if (!save("location"))
sl_reply_error();
exit;
}
+}
+# USER location service +route[LOCATION] {
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
+}
+# Authentication route +route[AUTH] { +#!ifdef WITH_AUTH
+#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address())
{
# source IP allowed
return;
}
+#!endif
if (is_method("REGISTER") || from_uri==myself)
{
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself)
{
sl_send_reply("403","Not relaying");
exit;
}
+#!endif
return;
+}
+# Shared Call Appearances handling +route[SCA] { +#!ifdef WITH_SCA
if(is_method("SUBSCRIBE")) {
if ($hdr(Event) == "call-info" || $hdr(Event) == "line-seize") {
xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from $si:$sp");
sca_handle_subscribe();
exit;
}
return;
}
if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) {
return;
}
sca_call_info_update();
+#!endif
return;
+}
+# Routing to foreign domains +route[SIPOUT] {
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
+}
+# XMLRPC routing +#!ifdef WITH_XMLRPC +route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET")
&& (src_ip==127.0.0.1)) {
# close connection only for xmlrpclib user agents (there is a bug in
# xmlrpclib: it waits for EOF before interpreting the response).
if ($hdr(User-Agent) =~ "xmlrpclib")
set_reply_close();
set_reply_no_connect();
dispatch_rpc();
exit;
}
send_reply("403", "Forbidden");
exit;
+} +#!endif
+# manage incoming replies +onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
+#!ifdef WITH_SCA
sca_call_info_update();
+#!endif +}
+# manage failure routing cases +failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {
exit;
}
+#!ifdef WITH_SCA
route(SCA);
+#!endif +}
+#!ifdef WITH_XHTTP +event_route[xhttp:request] { +#!ifdef WITH_XHTTP_RPC
$var(xhttp_rpc_root) = $(hu{s.substr,0,9});
if ($var(xhttp_rpc_root) == "/http_rpc") {
dispatch_xhttp_rpc();
}
+#!endif
+#!ifdef WITH_SCA +event_route[tm:local-request] {
- if (is_method("NOTIFY") {
record_route();
- }
+}
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
3 dec 2012 kl. 23:14 skrev Andrew Mortensen admorten@isc.upenn.edu:
sca: add working example kamailio.cfg
I suggest kindly that you move that into the doc directory and possibly include it all or parts in the documentation. You can include the file into the XML, but still have it as a separate text file. There are many modules that do similar things.
There's no such thing as too much information, and information that we put there ends up in the README that will be part of packages in distros like Debian. Stuff that is stored somewhere in the source code usually do not end up in such distributions, unless the package manager is really awake and performs a very, very detailed review of all files.
We have a few more modules that have interesting examples outside of the doc that propably should be integrated too.
/O
On Dec 4, 2012, at 1:10 AM, "Olle E. Johansson" oej@edvina.net wrote:
3 dec 2012 kl. 23:14 skrev Andrew Mortensen admorten@isc.upenn.edu:
sca: add working example kamailio.cfg
I suggest kindly that you move that into the doc directory and possibly include it all or parts in the documentation. You can include the file into the XML, but still have it as a separate text file. There are many modules that do similar things.
I looked into the future, saw your suggestion, and did this last night before you sent this message. :)
andrew
4 dec 2012 kl. 14:15 skrev Andrew Mortensen admorten@isc.upenn.edu:
On Dec 4, 2012, at 1:10 AM, "Olle E. Johansson" oej@edvina.net wrote:
3 dec 2012 kl. 23:14 skrev Andrew Mortensen admorten@isc.upenn.edu:
sca: add working example kamailio.cfg
I suggest kindly that you move that into the doc directory and possibly include it all or parts in the documentation. You can include the file into the XML, but still have it as a separate text file. There are many modules that do similar things.
I looked into the future, saw your suggestion, and did this last night before you sent this message. :)
I looked into the past and noticed a reminder: "Read all the mail in the morning, before you start responding to anything". I forgot all about it. Will forget tomorrow to :-)
The result is a better documentation, regardless! Thanks!
/O