Hello community,
We're currently facing a couple of issues in our setup involving Kamailio (v6.1.0-dev1), RTPEngine, and FreeSWITCH, primarily with WebRTC/WSS endpoints and media handling. I would appreciate any guidance or suggestions to help resolve them.
Issue 1: ACK Dropped Due to .invalid Hostname – Call Drops After 32s We are experiencing a problem when using t_on_reply() where ACKs fail to route correctly, resulting in the following error:
<core> [core/resolve.c:1773]: sip_hostport2su(): could not resolve hostname: "2f3d6480-4e78-11f0-a25d-ad05fd2deba0.invalid" <core> [core/forward.c:536]: forward_request_mode(): bad host name 2f3d6480-4e78-11f0-a25d-ad05fd2deba0.invalid, dropping packet sl [sl_funcs.c:430]: sl_reply_error(): stateless error reply used: Unresolvable destination (478/SL)
This causes ACKs to fail and calls to drop after 32 seconds (likely due to lack of ACK for 200 OK).
Here is my WITHINDLG function.
route[WITHINDLG] {
if (has_totag()) { if (is_method("ACK")) {
# Fix invalid domains before forwarding if ($du =~ ".invalid") { xlog("L_WARN", "Fixing ACK destination for invalid domain: $ru\n"); handle_ruri_alias(); } xlog("L_INFO", "Processing ACK for call ID: $ci $ru\n"); if (t_check_trans()) { xlog("L_INFO", "Stateful ACK - relaying\n"); route(RELAY); exit; } else { xlog("L_WARN", "Stateless ACK - relaying anyway to ensure call stability $proto $ru\n"); route(RELAY); exit; } }
if (loose_route()) { xlog("L_INFO", "Loose routing enabled for $rm\n");
if ($du == "") { if (!handle_ruri_alias()) { xlog("L_ERR", "Bad alias <$ru>\n"); sl_send_reply("400", "Bad Request"); exit; } }
route(DLGURI);
if (is_method("BYE")) { setflag(FLT_ACC); # Do accounting setflag(FLT_ACCFAILED); # Even if the transaction fails } if (is_method("NOTIFY")) { record_route(); } route(RELAY); exit; } else { if (is_method("SUBSCRIBE") && uri == myself) { xlog("L_INFO", "Processing in-dialog SUBSCRIBE request\n"); exit; }
if (is_method("ACK")) { xlog("L_WARN", "Standalone ACK detected, ignoring\n"); exit; }
sl_send_reply("404", "Not Here"); exit; } } }
Questions:
Is there a more reliable way to handle .invalid hostnames in $du/$ru caused by upstream or downstream Contact headers?
Should I forcibly rewrite $du/$ru or avoid using t_on_reply() for certain scenarios?
Issue 2: Media Not Flowing Correctly – RTPEngine Flags for WSS ➝ Freeswitch ➝ WSS
We’re testing a WebRTC (WSS) → Freeswitch → WebRTC (WSS) flow, where Freeswitch is generating media with media_webrtc=true.
The general flow is:
Device Registred on Kamailio (WSS client) → Freeswitch → Kamailio/RTPEngine → WSS client
Our branch logic is as follows:
route[LOCATION] { t_on_branch("BRANCH_MEDIA"); lookup("location"); t_relay(); exit; }
branch_route[BRANCH_MEDIA] { if (is_method("INVITE")) { xlog("L_INFO", "BRANCH_MEDIA.......................................\n"); xlog("L_INFO", "Request for $proto $ru $du"); if ($ru =~ "transport=ws") { xlog("L_INFO", "This is a WSS phone call request to $proto $ru"); if (sdp_with_transport_like("RTP/SAVPF")) { rtpengine_offer("ICE=force-relay replace-origin DTLS=passive"); xlog("L_INFO", "[REPLY_WS_TO_WS]Request to REPLY_WS_TO_WS"); t_on_reply("REPLY_WS_TO_WS");
}else { rtpengine_offer("trust-address replace-origin replace-session-connection ICE=force RTP/SAVPF SDES-off rtcp-mux-offer"); xlog("L_INFO", "[REPLY_FROM_WS]Request to REPLY_FROM_WS"); t_on_reply("REPLY_FROM_WS"); }
} else if ($proto =~ "ws") { $var(rtpengine_offer_flags) = "trust-address replace-origin replace-session-connection rtcp-mux-demux ICE=remove UDP/TLS/RTP/SAVP"; t_on_reply("REPLY_TO_WS"); rtpengine_offer("$var(rtpengine_offer_flags)"); } else { $var(rtpengine_offer_flags) = "trust-address replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP"; t_on_reply("MANAGE_CLASSIC_REPLY"); rtpengine_offer("$var(rtpengine_offer_flags)"); }
} route(NATMANAGE); }
onreply_route[REPLY_WS_TO_WS] { if(status=~"[12][0-9][0-9]") { rtpengine_answer("ICE=force-relay replace-origin DTLS=passive"); route(NATMANAGE); } if (nat_uac_test("1")) { fix_nated_contact(); } }
onreply_route[REPLY_TO_WS] { if (is_method("INVITE") && has_totag() && t_check_status("200")) { xlog("L_INFO", "[REPLY_TO_WS]Reply from webrtc client: $rs"); $var(rtpengine_REPLY_TO_WS_flags) = "trust-address replace-origin replace-session-connection SDES-off ICE=force"; route(NATMANAGE); xlog("L_INFO","[REPLY_TO_WS] RTP Engine Flags Answer--------->: $var(rtpengine_REPLY_TO_WS_flags)\n"); rtpengine_answer("$var(rtpengine_REPLY_TO_WS_flags)"); } if (nat_uac_test("1")) { fix_nated_contact(); }
}
onreply_route[REPLY_FROM_WS] { if(status=~"[12][0-9][0-9]") { rtpengine_answer("trust-address replace-origin replace-session-connection DTLS=passive ICE=remove RTP/AVP rtcp-mux-demux label=$fU"); xlog("L_INFO", "----- $fU | Change RTP sources for WS reply $rs in REPLY_FROM_WS- M=$rm R=$ru F=$fu T=$tu IP=$pr:$si:$sp -----\n"); route(NATMANAGE); } if (nat_uac_test("1")) { fix_nated_contact(); } }
onreply_route[MANAGE_CLASSIC_REPLY] { if (is_method("INVITE") && has_totag() && t_check_status("200")) { xlog("L_INFO", "[MANAGE_CLASSIC_REPLY]Boring reply from softphone: $rs"); $var(rtpengine_flags) = "rtcp-mux-demux DTLS=off SDES-on ICE=remove RTP/SAVP inject-DTMF"; route(NATMANAGE); xlog("L_INFO","[MANAGE_CLASSIC_REPLY] RTP Engine Flags Answer--------->: $var(rtpengine_flags)\n"); rtpengine_answer("$var(rtpengine_flags)"); } if (nat_uac_test("1")) { fix_nated_contact(); } }
Despite this, media is not flowing properly between WSS clients, and we're suspecting either the wrong RTPEngine flags or SDP modifications.
Questions:
Is this the correct way to differentiate flags based on WSS versus UDP endpoints?
Is it recommended to split branch_route vs onreply_route in this manner?
Any help or suggestions from the community would be greatly appreciated. Thanks in advance!
Best regards,