Hey All,
I always struggle with loose_route() and I implemented workarounds in the
past. But, I want to get a better understanding.
I have a SIP Endpoint -> Kamailio -> FreeSWITCH
The domain and alias is set to the ip address of the Kamailio server
(137.184.130.206)
When I get the ACK back from the SIP Endpoint it looks like this
ACK sip:18889072085@137.184.72.42:5060;transport=udp SIP/2.0
Via: SIP/2.0/UDP 10.1.10.140:1052
;branch=z9hG4bK-524287-1---740db0025fa217ce;rport
Max-Forwards: 70
*Route: <sip:137.184.130.206;lr>*
Contact: <sip:1000@50.192.97.226:53790;transport=UDP>
To: <sip:18889072085@dsiptest.dsiprouter.net>;tag=5gv4etZ8tUUcH
From: <sip:1000@dsiptest.dsiprouter.net;transport=UDP>;tag=0af5b751
Call-ID: fWido7VIUKIEI6f6kf4vkQ..
CSeq: 1 ACK
User-Agent: Z 5.5.8 v2.10.17.2
Content-Length: 0
Kamailio will then remove the ACK and change the RURI to itself, which
causes an ACK loop. This is what is look like
*ACK sip:137.184.130.206;lr* SIP/2.0
Via: SIP/2.0/UDP
137.184.130.206;branch=z9hG4bK3fd.0cf34b683f0627ee2455594ea6cb2517.0
Via: SIP/2.0/UDP 10.1.10.140:1052
;received=50.192.97.226;branch=z9hG4bK-524287-1---740db0025fa217ce;rport=1052
Max-Forwards: 69
Contact: <sip:1000@50.192.97.226:1052;transport=UDP>
To: <sip:18889072085@dsiptest.dsiprouter.net>;tag=5gv4etZ8tUUcH
From: <sip:1000@dsiptest.dsiprouter.net;transport=UDP>;tag=0af5b751
Call-ID: fWido7VIUKIEI6f6kf4vkQ..
CSeq: 1 ACK
User-Agent: Z 5.5.8 v2.10.17.2
Content-Length: 0
*Question:*
What am I missing here? We have the alias set and we even set it in the
domain module (with the register_myself flag). We have workarounds for
this, but I would prefer to figure out how to have Kamailio handle this
natively via the loose_route or tm module.
Thanks in advance,
Hello!
In order to keep the SIP/TCP connection alive for some specific clients
(more precisely, specific firewalls) in long calls, I use periodic SIP
OPTIONS probes through the dialog module.
I noticed that when subscribers are using the SIP/TLS protocol, such
keepalives are not sent (with SIP/UDP and SIP/TCP working well).
I did not detect any obvious errors in the debug mode.
Are there any ideas why the messages are not being sent for SIP/TLS leg?
----
loadmodule "dialog.so"
modparam("dialog", "db_url", "DBURL")
modparam("dialog", "db_mode", 1)
modparam("dialog", "ka_timer", 5)
modparam("dialog", "ka_interval", 30)
modparam("dialog", "ka_failed_limit", 2)
modparam("dialog", "send_bye", 1)
modparam("dialog", "track_cseq_updates", 1)
modparam("dialog", "default_timeout", 7205)
-----
dlg_manage();
dlg_set_property("ka-src");
dlg_set_property("ka-dst");
--
BR,
Denys Pozniak
Hi,
With Kamailio 5.5.3 (with KEMI/Lua) I noticed it apparently had stopped
responding to OPTIONS in my test system. It can cause problems if a similar
issue appears in production.
Only thing i could observe it was apparently responding to INVITE and
CANCEL etc randomly , its pretty strange as it was not dead completely.
There was no core dump, I restarted and it started functioning again.
Any clues please?
--
Muhammad Danish Moosa
" The core of mans' spirit comes from new experiences. "___ Christopher
McCandless
Running into an issue where I can't access certain functions inside the response route or "route_name" for handling the asynchronous reply from an http_async_query() that's being run. Does anyone know what type of route that is considered to be? I know it's not a request route or a failure route based on the errors I'm getting, but I can't find anything that outlines what that route actually is.
Thanks!
Brooks Bridges
1200 S. Rogers Circle, Unit 6
Boca Raton, FL 33487
Office: 916-235-2097 Main: 888-444-1111
email: bbridges(a)call48.com | web: www.call48.com
Confidentiality Notice: This e-mail, and any attachment to it, contains privileged and confidential information intended only for the use of the individual(s) or entity named on the e-mail. If the reader of this e-mail is not the intended recipient, or the employee or agent responsible for delivering it to the intended recipient, you are hereby notified that reading this e-mail is strictly prohibited. If you have received this e-mail in error, please immediately return it to the sender and delete it from your system.
Hi,
Are there any known contraindications for replicating contacts using dmq/dmq_usrloc, and injecting those contacts into a database on one of the nodes using usrloc with `db_mode` 1 or 2?
Predictably, this is being done to support the use-case of getting registration status from database. If you think this should be done with JSONRPC, I am in complete agreement with you, but it’s not up to me. :-)
I am doing this with `db_mode` 2 now, and finding that, for a small number of AORs, one can find instances where they are consistently stored in memory but not present in the `location` table. The overall proportion of these AORs, out of thousands, seems to be quite small. It was initially somewhat higher, and it went down once I increased usrloc `timer_processes` and increased the sync interval from 30 to 60 seconds.
Nevertheless, it is still non-zero, and I am getting intermittent reports. I wonder if there are some prior experiences with this and anything to watch out, or if `db_mode` 1 might be a superior choice. I personally cannot see how that would be; it seems to have all the performance downsides of mode 3. But perhaps if something about it is more “problem-free” vis-a-vis DMQ, it’s worth a shot?
— Alex
--
Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free)
Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Hello,
following the recent new feature of #!ifexp based on snexpr
(https://www.kamailio.org/w/2022/09/ifexp-conditional-preprocessor-blocks/),
another preprocessor directive was added which allows defining IDs with
a value computed from the evaluation of an expression, respectively:
#!defexp ID EXP
The EXP can be any expression supported by snexpr, including the
previously defined IDs. For example:
#!define IPADDR 1.2.3.4
#!define PORT 5060
#!defexp SIPURI "sip:" + IPADDR + ":" + PORT
The result is that SIPURI is defined to sip:1.2.3.4:5060.
Another variant is available as #!defexps, which encloses the result of
the expression in double quotes, making it suitable to be used further
as string value:
#!defexps SIPURI "sip:" + IPADDR + ":" + PORT
The result is that SIPURI is defined to “sip:1.2.3.4:5060”.
More details at:
- https://www.kamailio.org/wikidocs/cookbooks/devel/core/#defexp
- https://www.kamailio.org/wikidocs/cookbooks/devel/core/#defexps
Testing would be appreciated, feedback can be addressed to sr-users
mailing list!
Cheers,
Daniel
--
Daniel-Constantin Mierla -- www.asipto.comwww.twitter.com/miconda -- www.linkedin.com/in/miconda
Kamailio Advanced Training - Online
Nov 7-10, 2022 (Europe Timezone)
* https://www.asipto.com/sw/kamailio-advanced-training-online/
Hello everyone!
I'm testing calls with STIR/SHAKEN with a Secsipid module on a Kamailio
version 5.6.1 and ran into a problem. Outbound calls work fine when the
function *secsipid_add_identity* with appropriate parameters is called. But
as soon as I add function *secsipid_check_identity* to my configuration,
Kamilio would not start. Here is an error message I get:
*kamailio: CRITICAL: <core> [core/cfg.y:3791]: yyerror_at(): parse error in
config file /etc/kamailio/include/registrar.cfg, line 47, column 39:
unknown command, missing loadmodule?*
*loadmodule "secsipid.so"* is present and is above the function
*secsipid_check_identity* call. Both secsipid.so and secsipid_proc.so
module files are the correct version and present on the system.
Another question is related to the rpm package build. How do you build
additional modules? I made adjustment to the pkg/kamailio/Makefile file. In
the *cfg* section changed *$(MAKE) -C ../../src cfg* with *$(MAKE)
FLAVOUR=kamailio include_modules="secsipid secsipid_proc" -C ../../src cfg*.
Required modules appeared in the modules.lst file but their rpm packages
were not built.
Thank you very much!
Hi Community,
I'm experimenting with dmq to do dialog sync between two instances of
Kamailio. This works great so far. When I did my first experiments I
even could create a CDR when there was a failover. Since some Versions
(we are now on Version 5.6.1) I just get a acc-request in log but no
acc-cdr. In former versions this worked. Both server have the same
configuration and both server writes cdrs when theres no failover.
In case of a failover everything is fine, the dialogs are clean and
thanks to dmq all needed variables are replicated between the server.
There's just no cdr.
I found nothing on the issue-page on github but maybe somebody knows
something about it.
BR
Björn
--
Björn Klasen, Senior Specialist (VoIP)
TNG Stadtnetz GmbH, TNG-Technik
Projensdorfer Str. 324
24106 Kiel・Deutschland
T +49 431 7097-10
F +49 431 7097-555
bklasen(a)tng.de
www.tng.de <http://www.tng.de>
Executive board (Geschäftsführer):
Dr. Sven Willert (CEO/Vorsitz), Helmut Gertz,
Moritz Meis, Gunnar Peter, Sven Schade,
Carsten Tolkmit
Amtsgericht Kiel HRB 6002 KI
USt-ID: DE225201428
Die Information über die Verarbeitung Ihrer Daten
gemäß Artikel 12 DSGVO können Siehier <https://tng.de/privatkunden/datenschutz/>abrufen.
Hi Jerry,
I just joined so am unsure if you are good to go now but thought I would post my config as I also have a Freeswitch environment which I have placed Kamailio in front of to act as a load-balancing proxy. I also managed to get RTPEngine proxying through it too.
Here is the config, which I have created from Daniel’s default kamailio config. I have omitted the top portions of loading the modules and their settings. My dispatcher list is just a text file. I have two groups. One for registrations and outbound calls, and one for calls inbound coming from the FreeSwitch server.
In the NATMANAGE route, I currently have RTP proxying disabled as my free switch servers have external IPs and I let them handle the rtp stream.
On Freeswitch, I made the following changes to accomodate user/pass and IPAuth reg:
Changes to the Freeswitch servers listed in the dispatcher file
Edit /usr/local/freeswitch/conf/autoload_configs/acl.conf
<list name="proxy" default="deny">
<node type="allow" cidr=“IP address of Kamailio/32"/>
</list>
Edit /usr/local/freeswitch/conf/sip-profiles/internal-private.xml (or the sip-profile you need to edit in your instance)
<param name="apply-proxy-acl" value="proxy"/> #Add this line above the one below. This tells Freeswitch to look at the X-Auth-IP header which was inserted by Kamailio.
<param name="apply-inbound-acl" value="domains"/>
Then, restart freeswitch (with no active calls),
service freeswitch restart # or rescan the profile / reloadxml
I am not proxying RTP, however, I can un-comment out the stanza in the NATMANAGE route to get it to work.
The biggest gotcha for me was I was trying to use fix_nated_register when handling NAT for registrations instead of:
Fix_nated_contact() or the better set_contact_alias().
Using add_path_received(); in the Dispatcher just before sending to Freeswitch ensured all traffic returned to Kamailio too.
I am unsure of the SUBSCRIBE/PRESENCE stuff for you but the route should go out via the Kamailio proxy with this.
----------------------------
# main request routing logic
request_route {
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si\n");
# per request initial checks
route(REQINIT);
# NAT detection
route(NATDETECT);
if(ds_is_from_list("33")) {
setflag(FLT_FS);
#xlog("L_WARN", "This source $si is from the dispatcher list.\n");
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
}
exit;
}
# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}
# handle requests within SIP dialogs
route(WITHINDLG);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE")) {
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si\n");
xlog("L_ALERT", "Marker 1\n");
record_route();
}
# account only INVITEs
if (is_method("INVITE")) {
setflag(FLT_ACC); # do accounting
}
if (isflagset(FLT_FS)) {
##t_on_reply("EXTERNAL_REPLY");
route(FROM_FS);
exit;
}
# handle presence related requests
route(PRESENCE);
# handle registrations
route(REGISTRAR);
if ($rU==$null) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# dispatch destinations
route(DISPATCH);
return;
}
route[FROM_FS]
{
#record_route();
#loose_route_preloaded();
route(DLGURI);
route(RELAY);
exit;
}
route[RELAY] {
# enable additional event routes for forwarded requests
# - serial forking, RTP relaying handling, a.s.o.
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|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");
}
if (!t_relay()) {
sl_reply_error();
}
exit;
}
#reply_route {
# if(status == 403) {
# xlog("L_WARN", "Forbidden from $si:$sp blah...\n");
# xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
# }
#}
onreply_route[LOGRPL] {
if(status == 403) {
xlog("L_ALERT", "$rs response. Consider banning AVP \"ipbancandidate\" is $avp(ipbancandidate) ");
}
}
# Per SIP request initial checks
route[REQINIT] {
# no connect for sending replies
# Enable tracing for SNGREP
##sip_trace();
##setflag(24);
#
set_reply_no_connect();
# enforce symmetric signaling
# - send back replies to the source address of request
force_rport();
#!ifdef WITH_ANTIFLOOD
# flood detection from same IP and traffic ban for a while
# be sure you exclude checking trusted peers, such as pstn gateways
# - local host excluded (e.g., loop to self)
if(src_ip!=myself) {
if($sht(ipban=>$si)!=$null) {
# ip is already blocked
xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
exit;
}
if (!pike_check_req()) {
xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
$sht(ipban=>$si) = 1;
exit;
}
}
#!endif
if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent|pplsip|Hello\ SIP\ Automated") {
# silent drop for scanners - uncomment next line if want to reply
# sl_send_reply("200", "OK");
xlog("User agent is: $ua\n");
exit;
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(is_method("OPTIONS") && uri==myself && $rU==$null) {
sl_send_reply("200","Keepalive");
exit;
}
if(!sanity_check("17895", "7")) {
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
}
# Handle requests within SIP dialogs
route[WITHINDLG] {
if (!has_totag()) return;
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
xlog("L_INFO", "Routing before DLGURI\n");
route(DLGURI);
if (is_method("BYE")) {
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
} else if ( is_method("ACK") ) {
# ACK is forwarded statelessly
route(NATMANAGE);
} else if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
exit;
}
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(PRESENCE);
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
route(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"))
return;
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si\n");
add_path_received();
$avp(ipbancandidate) = $si;
if(isflagset(FLT_NATS)) {
setbflag(FLB_NATB);
#!ifdef WITH_NATSIPPING
# do SIP NAT pinging
setbflag(FLB_NATSIPPING);
#!endif
}
route(DISPATCH);
if (!save("location")) {
sl_reply_error();
}
exit;
}
# Presence server route
route[PRESENCE] {
if(!is_method("PUBLISH|SUBSCRIBE"))
return;
sl_send_reply("404", "Not here");
exit;
}
# Caller NAT detection
route[NATDETECT] {
#!ifdef WITH_NAT
if (nat_uac_test("19")) {
if (is_method("REGISTER")) {
#fix_nated_register(); Disabled as we proxy registrations
#fix_nated_contact();
set_contact_alias();
##add_contact_alias();
#fix_nated_sdp("3");
xlog("L_ALERT", "Nat Registration nat fixed.\n");
} else {
if(is_first_hop()) {
set_contact_alias();
xlog("L_ALERT", "Contact NAT fixed\n");
}
}
setflag(FLT_NATS);
xlog("L_ALERT", "FLT_NATS flag set\n");
}
#!endif
return;
}
# RTPProxy control and signaling updates for NAT traversal
route[NATMANAGE] {
#!ifdef WITH_NAT
if (is_request()) {
if(has_totag()) {
if(check_route_param("nat=yes")) {
setbflag(FLB_NATB);
}
}
}
if (nat_uac_test("3")) {
#fix_nated_contact();
set_contact_alias();
##add_contact_alias();
force_rport();
}
if (has_body("application/sdp") && nat_uac_test("8")) {
fix_nated_sdp("11");
}
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;
###!ifdef WITH_RTPENGINE
## xlog("RTPEngine enabled\n");
## if(nat_uac_test("8")) {
## xlog("RTP 1\n");
## rtpengine_manage("SIP-source-address replace-origin replace-session-connection");
## } else {
## rtpengine_manage("replace-origin replace-session-connection");
## }
###!else
## if(nat_uac_test("8")) {
## rtpproxy_manage("co");
## } else {
## rtpproxy_manage("cor");
## }
###!endif
if (is_request()) {
if (!has_totag()) {
if(t_is_branch_route()) {
add_rr_param(";nat=yes");
xlog("Nat notation added!\n");
}
}
}
if (is_reply()) {
if(isbflagset(FLB_NATB)) {
if(is_first_hop())
#fix_nated_contact();
set_contact_alias();
#add_contact_alias();
}
}
if(isbflagset(FLB_NATB)) {
# no connect message in a dialog involving NAT traversal
if (is_request()) {
if(has_totag()) {
set_forward_no_connect();
}
}
}
#!endif
return;
}
# URI update for dialog requests
route[DLGURI] {
#!ifdef WITH_NAT
if(!isdsturiset()) {
handle_ruri_alias();
xlog("L_INFO", "Routing in-dialog $rm from $fu to $du\n");
}
#!endif
return;
}
# Dispatch requests
route[DISPATCH] {
# round robin dispatching on gateways group '1'
remove_hf_re("Subject|P-.*|X-.*");
append_hf("X-Auth-IP: $si\r\n");
#add_rr_param(";nat=yes");
t_on_reply("LOGRPL");
if(!ds_select_dst("1", "0")) {
send_reply("404", "No destination");
exit;
}
#xdbg("--- SCRIPT: going to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");
xlog("L_WARN", "--- Going to <$ru>. src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si; $RAi; $Ri;\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
}
# Try next destionations in failure route
failure_route[RTF_DISPATCH] {
if (t_is_canceled()) {
exit;
}
# next DST - only for 500 or local timeout
if (t_check_status("500")
or (t_branch_timeout() and !t_branch_replied())) {
if(ds_next_dst()) {
xdbg("--- SCRIPT: retrying to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
exit;
}
}
}
# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");
xlog("L_ALERT", "Marker 20\n");
route(NATMANAGE);
return;
}
# Manage incoming replies
reply_route {
if(!sanity_check("17604", "6")) {
xlog("Malformed SIP response from $si:$sp\n");
drop;
}
return;
}
# Manage incoming replies in transaction context
onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
xlog("L_ALERT", "Marker 21\n");
if(status=~"[12][0-9][0-9]") {
route(NATMANAGE);
}
# if (has_body("application/sdp")) {
# rtpengine_manage();
# }
return;
}
# Manage failure routing cases
failure_route[MANAGE_FAILURE] {
xlog("L_ALERT", "Marker 23\n");
route(NATMANAGE);
if (t_is_canceled()) exit;
#!ifdef WITH_BLOCK3XX
# block call redirect based on 3xx replies.
if (t_check_status("3[0-9][0-9]")) {
t_reply("404","Not found");
exit;
}
#!endif
#!ifdef WITH_BLOCK401407
# block call redirect based on 401, 407 replies.
if (t_check_status("401|407")) {
t_reply("404","Not found");
exit;
}
#!endif
#!ifdef WITH_VOICEMAIL
# serial forking
# - route to voicemail on busy or no answer (timeout)
if (t_check_status("486|408")) {
$du = $null;
route(TOVOICEMAIL);
exit;
}
#!endif
return;
}