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,