Hello,
Setup:
I activated the TOPOS module in my setup that looks something like this:
SIP Device ---> Proxy1(w/ topos) ---> Proxy2(no topos) ---> ??? --->
Freeswitch.
I am using Kamailio 6.0.1 (or 6.0.2, not sure).
Both my proxies and the other nodes I don't control in ??? part all add
Record-Route/Route headers for in-dialog requests.
So an INVITE coming from the SIP Device will go through these proxies, on
the 200 OK there are 3+ Record-Route headers which are consumed by TOPOS on
Proxy1.
With my baresip and Yealink phones, the phones send a 200 OK with NO Route
headers and the Route headers are readded by the TOPOS module before it
hits the routes in kamailio.
Problem:
Some SIP devices(I used an older Aastra device to reproduce the issue) like
to add a Route header with the target proxy, and so Kamailio receives
something like this(some headers stripped for brevity):
ACK sip:atpsh-68769b30-2b-1@192.168.0.25 SIP/2.0
Via: SIP/2.0/UDP 192.168.34.122:5060;branch=z9hG4bKe3a6fe355f721ae5b
Route: <sip:banana.mydomain.tld;lr>
From: "12015550000" <sip:12015550000@banana.mydomain.tld>;tag=ba05cb9826
To: <sip:13105550000@banana.mydomain.tld:5060;user=phone>;tag=1SvNyXFeQjUaN
Call-ID: 149a3a344dda2a1c
CSeq: 12259 ACK
With this, Kamailio receives the packet, internally somewhere runs the
myself check and sees banana.mydomain.tld isn't a local domain. So it
routes to that domain, which happens to resolve to this same Kamailio. So
Kamailio routes the packet to itself until Max-Forwards hits 0 and fails.
Solutions I tried:
So I thought maybe alias_subdomains would help here:
loadmodule "corex.so"
modparam("corex", "alias_subdomains", "mydomain.tld")
I ran this and found that it fixed the routing loop on the ACK, but then I
got a routing loop on the BYE instead.
So then I thought, maybe I can squeeze this out earlier:
event_route[topos:msg-incoming] {
if ( proto != TLS || !$tls_peer_verified || $Rp != "5061" ) {
xlog("L_NOTICE", "=======> User packet this one $rm\n");
remove_hf("Route");
}
else{
xlog("L_NOTICE", "=======> Server packet this one $rm\n");
}
This didn't work, it only ever is invoked for SIP OPTIONS.
So I tried with event_route[topos:msg-receiving] and saw messages like this:
16(1347) CRITICAL: <core> [core/ip_addr.c:234]: ip_addr2sbuf(): unknown
address family 0
I guess $Rp isn't available in this event route. and $proto is always null.
If I disable TOPOS completely, the Aastra phone will load the ACK with the
Route headers defined by the Record-Route headers in the 200 OK and the
call completes normally.
I added this to the top of my request_route:
xlog("L_NOTICE","$si - $rm - $hfl(Route) $hfl(Via)\n");
and the only route header that appeared for the ACK packet was the single
route header.
It would seem TOPOS can be 'defeated' by a rogue Route header.
I started reading through the source code on this but could not pinpoint
any code that would 'not restore TOPOS stripped headers when a rogue Route
header appears because the Route header doesn't match the myself condition
of Kamailio'.
I even tried adding to topos:msg-sending:
append_hf("Route: <sip:invalid.tld>\r\n");
To trick the phone into something that is predictable so I can strip it
before TOPOS parses the headers.
I'm not sure what to do next, I don't want to go back to TOPOH because I
need the packet size savings(some users have issues with big packets ).
I've seen other user-agents in the wild beyond these Aastras add Route
headers in unexpected places, so this is not a single issue.
I even went so far as to ask AI some help, but it just hallucinated the
entire time. (AI says this should say 'I also explored AI assistance but
didn't find relevant solutions for this specific scenario.' ).
Any suggestions on what to do next ?
Thanks,
David