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