Hi guys
I have a multihomed Kamailio proxy sitting between two B2BUAs on separate networks and record-routing all dialogs.
The problem I have is that when one of these devices receives a 200 OK, it does not populate the RURI of the ACK correctly. Instead of taking it from the Contact header on the 200 OK, it uses the user part from the Contact header and sets the domain to the proxy IP. It then also populates the Route headers.
The ACKs are below and the IPs are:
10.152.1.92:5060: UAC on outside 10.200.70.100:5060: proxy outside interface 192.168.242.100: proxy inside interface 192.168.242.102: UAS on inside
This the ACK message going into and coming out of the proxy.
# U 10.152.1.92:5060 -> 10.200.70.100:5060 ACK sip:natted_ua*9197**192.168.242.102*5080*udp@10.200.70.100 SIP/2.0. Via: SIP/2.0/UDP 127.0.1.1:5060;branch=z9hG4bK-2280-1-5. Route: sip:10.200.70.100;r2=on;lr=on;nat=yes,sip:192.168.242.100;r2=on;lr=on;nat=yes. From: sipp sip:sipp@127.0.1.1:5060;tag=2280SIPpTag001. To: sut sip:9197@10.200.70.100:5060;tag=p0FaeQ1QUS9ae. Call-ID: 1-2280@127.0.1.1. CSeq: 1 ACK. Contact: sip:sipp@127.0.1.1:5060. Max-Forwards: 70. Subject: Performance Test. Content-Length: 0. .
# U 10.200.70.100:5060 -> 192.168.242.100:5060 ACK sip:192.168.242.100;r2=on;lr=on;nat=yes SIP/2.0. Via: SIP/2.0/UDP 10.200.70.100;branch=z9hG4bKcydzigwkX. Via: SIP/2.0/UDP 127.0.1.1:5060;rport=5060;received=10.152.1.92;branch=z9hG4bK-2280-1-5. Route: . From: sipp sip:sipp@127.0.1.1:5060;tag=2280SIPpTag001. To: sut sip:9197@10.200.70.100:5060;tag=p0FaeQ1QUS9ae. Call-ID: 1-2280@127.0.1.1. CSeq: 1 ACK. Contact: sip:sipp@127.0.1.1:5060;alias=10.152.1.92~5060~1. Max-Forwards: 69. Subject: Performance Test. Content-Length: 0.
So I am trying to understand why it is trying to relay to itself (I have mhomed=1) and why it is rewriting the RURI as if it is a strict router.
Currently decode_contact() is disabled but enabling doesn't seem to help. Unless there is a very specific place where it belongs.
Any advice would be hugely appreciated. I can always paste logs / configs / traces.
Richard
-- Richard Brady M: +44 (0)7771 623 348 T: +44 (0)20 8144 8160 E: rnbrady@gmail.com
Richard,
well, the RURI of remote ACK has proxy IP address 10.200.70.100 so proxy thinks that previous hop was a strict router. I can't think of any workaround that would not be an ugly hack at the moment, though.
On 11/23/2012 03:24 AM, Richard Brady wrote:
Hi guys
I have a multihomed Kamailio proxy sitting between two B2BUAs on separate networks and record-routing all dialogs.
The problem I have is that when one of these devices receives a 200 OK, it does not populate the RURI of the ACK correctly. Instead of taking it from the Contact header on the 200 OK, it uses the user part from the Contact header and sets the domain to the proxy IP. It then also populates the Route headers.
The ACKs are below and the IPs are:
10.152.1.92:5060: UAC on outside 10.200.70.100:5060: proxy outside interface 192.168.242.100: proxy inside interface 192.168.242.102: UAS on inside
This the ACK message going into and coming out of the proxy.
# U 10.152.1.92:5060 -> 10.200.70.100:5060 ACK sip:natted_ua*9197**192.168.242.102*5080*udp@10.200.70.100 SIP/2.0. Via: SIP/2.0/UDP 127.0.1.1:5060;branch=z9hG4bK-2280-1-5. Route: sip:10.200.70.100;r2=on;lr=on;nat=yes,sip:192.168.242.100;r2=on;lr=on;nat=yes. From: sipp sip:sipp@127.0.1.1:5060;tag=2280SIPpTag001. To: sut sip:9197@10.200.70.100:5060;tag=p0FaeQ1QUS9ae. Call-ID: 1-2280@127.0.1.1. CSeq: 1 ACK. Contact: sip:sipp@127.0.1.1:5060. Max-Forwards: 70. Subject: Performance Test. Content-Length: 0. .
# U 10.200.70.100:5060 -> 192.168.242.100:5060 ACK sip:192.168.242.100;r2=on;lr=on;nat=yes SIP/2.0. Via: SIP/2.0/UDP 10.200.70.100;branch=z9hG4bKcydzigwkX. Via: SIP/2.0/UDP 127.0.1.1:5060;rport=5060;received=10.152.1.92;branch=z9hG4bK-2280-1-5. Route: . From: sipp sip:sipp@127.0.1.1:5060;tag=2280SIPpTag001. To: sut sip:9197@10.200.70.100:5060;tag=p0FaeQ1QUS9ae. Call-ID: 1-2280@127.0.1.1. CSeq: 1 ACK. Contact: sip:sipp@127.0.1.1:5060;alias=10.152.1.92~5060~1. Max-Forwards: 69. Subject: Performance Test. Content-Length: 0.
So I am trying to understand why it is trying to relay to itself (I have mhomed=1) and why it is rewriting the RURI as if it is a strict router.
Currently decode_contact() is disabled but enabling doesn't seem to help. Unless there is a very specific place where it belongs.
Any advice would be hugely appreciated. I can always paste logs / configs / traces.
Richard
-- Richard Brady M: +44 (0)7771 623 348 T: +44 (0)20 8144 8160 E: rnbrady@gmail.com
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list sr-users@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
Thanks Andrew
well, the RURI of remote ACK has proxy IP address 10.200.70.100 so proxy thinks that previous hop was a strict router.
Aha, that makes sense. But why would that make Kamailio apply strict routing?
I can't think of any workaround that would not be an ugly hack at the moment, though.
I thought encode_contact() and decode() contact were designed exactly for this? Except I can't get them to work so I believe you!
Richard
Hi Andrew
well, the RURI of remote ACK has proxy IP address 10.200.70.100 so proxy thinks that previous hop was a strict router.
Aha, that makes sense. But why would that make Kamailio apply strict routing?
Now I understand this! Kamailio is not copying the *next* Route URI into the R-URI because it is strict routing itself, but copying the *last* Route URI into the R-URI because it thinks the previous hop is a strict router. The fact that the next Route URI is the last one is what confused me. Thanks for helping me get to the bottom of it!
Interestingly the previous hop is not really a strict router, it's just badly behaved in that it takes the user part of the R-URI from the Contact header and the domain part from the next hop. I won't name the vendor but I am very surprised by this. I can only assume it's some type of NAT traversal that is tuned on.
W.r.t. the Kamailio's strict routing behaviour, I wanted to point something out. Here's the relevant bit from the RFC:
The proxy MUST inspect the Request-URI of the request. If the Request-URI of the request contains a value this proxy previously placed into a Record-Route header field (see Section 16.6 item 4), the proxy MUST replace the Request-URI in the request with the last value from the Route header field, and remove that value from the Route header field.
So what is meant here by "a value"? In my case this R-URI has the same IP as the proxy but contains a user part and parameters which were not inserted by the proxy into a Record-Route header so I don't think this test should pass, but because is_myself() is being used in loose_route() it does.
I can't think of any workaround that would not be an ugly hack at the moment, though.
I thought encode_contact() and decode() contact were designed exactly for this? Except I can't get them to work so I believe you!
The main issue with these is that loose_route() and decode_contact() do not play nicely together. Ideally you would want to call decode_contact() and then loose_route() which could look $ru / new_uri, but it will only ever inspect $ou /parsed_uri. So you can't put decode_contact() before loose_route().
Then on the other hand decode_contact() will only read from $ou if $ru is not set, and because loos_route() sets $ru in after_strict(), you also can't put decode_contact() after loose_route().
Unless you reset some of what loose_route() set, which is what I did get this working:
if (loose_route()) { if($ou =~ "^sip:natted_contact") { $ru = $ou; decode_contact(); $du = $ru; $fs = $null; } ... }
What would be really useful would be if loose_route() used new_uri where available or, to preserve backward compatibility, you could call loose_route($ru).
Richard