Hi,
I found what i think is a bug in the return value of loose_route() ...
bear with me because it is a rather long email.
First, the scenario:
phone1 ----- SER1 ----- SER2 ----- phone2
p1 to s1 and p2 to s2 use UDP
s1 to s2 uses tcp or tls
The bug comes into place when there is a change of protocol in ser,
from UDP into TCP or TLS.
We do not use a preloaded route set from the phones.
What ser does is it adds 2 route headers, using the r2 parameter.
Route: <route1>, <route2>
CASE A: --------------------------------------------
In this scenario, say p1 places a call to p2, going through s1 and s2,
creating the route set with the record-route.
Now, let's say p2 generates the BYE message.
When the BYE gets to s1, the last hop, in the config we do:
if( loose_route () ) {
t_relay();
}
But, and here is the inconsistency, loose_route (remember we are using
TCP/TLS, so there are 2 routes in one header field) returns FALSE.
CASE B: --------------------------------------------
If this experiment is repeated using ALL UDP, the route headers when they
get to s1 contain only one route, and the call to loose_route() returns .... TRUE!
Unless the config file does not allow blind sip message relaying, both cases end
up working ... the BYE gets to the final destination. But if the config file does not
accept relaying ... the request-uri in the BYE is not taken as a local domain ... and
thus the message is rejected ... (To Alex Mack: could this be the solution to your
problem?
the BYEs not reaching the phone? add some log output and check it ... )
================================================================
So, this is not consistent. Now, what is the solution?
I think that both case A and B should return the same, but what, true or false?
As I see it, the solution causing less trouble is that both return true. So, the last
proxy
considers this BYE as being loose_routed.
For this ... change the code in:
rr::loose_route.c:: static inline int after_loose(struct sip_msg* _m, int preloaded)
.....
if (enable_double_rr && is_2rr(&puri.params)) {
....
if (res > 0) { /* No next route found */
DBG("after_loose: No next URI
found\n");
return (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
or simply
return (preloaded RR_DRIVEN);
And now ... the other option is that both return false ... but this would make big
changes.
Correct me if i am wrong, but wouldn't this be the compliant solution?
Considering that the r-uri is not part of the route set, when the last proxy processes
all route headers and there are no more left, there is no loose routing done. The
destination is taken from the r-uri, not the route set ... thus loose_route should return
false.
Or I am getting it all wrong? rfc and goal of loose_route() ?
Regards,
Cesc
Unclassified