Hi all again,
from various examples in the SER admin_guide and my own SIP knowledge-base I conclude, that the action "loose-route()" is responsible for correct routing of those requests, that are not destined to the proxy (host of Request-URI is not the proxy) and that have a proper Route-header indicating "loose-routing".
As such the action "loose_route()" should be sufficient to modify the Request in such a way, that the following action "t-relay()" finishes processing of the request. Therefore the action short sequence ... if (loose_route()) { t_relay(); break; }; does all, what is necessary for loose routing of those requests.
My problem is, that I could not produce a condition, where "loose_route()" evaluates to true, so that the action block { t_relay(); break; } is executed. I expect, that in a simple call-scenario with one record-routing SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger the above mentioned "loose_route()" action. But unfortunately it does not. Why?
Please help (in best case confirm) my understanding of "loose_route()".
Franz
Hello,
On Friday 02 January 2004 14:46, Franz Edler wrote:
from various examples in the SER admin_guide and my own SIP knowledge-base I conclude, that the action "loose-route()" is responsible for correct routing of those requests, that are not destined to the proxy (host of Request-URI is not the proxy) and that have a proper Route-header indicating "loose-routing".
As such the action "loose_route()" should be sufficient to modify the Request in such a way, that the following action "t-relay()" finishes processing of the request. Therefore the action short sequence ... if (loose_route()) { t_relay(); break; }; does all, what is necessary for loose routing of those requests.
My problem is, that I could not produce a condition, where "loose_route()" evaluates to true, so that the action block { t_relay(); break; } is executed. I expect, that in a simple call-scenario with one record-routing SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger the above mentioned "loose_route()" action. But unfortunately it does not. Why?
Because you made the wrong assumption: loose_route() will directly deliver/forward the request if it contains a valid route header. If i'm not wrong the t_relay() in the if clause is only for the case loose_route fails e.g. because of a broken route header.
Greets Nils
Hello Nils,
From: Nils Ohlmeier Sent: Friday, January 02, 2004 6:19 PM
... if (loose_route()) { t_relay(); break; };
If i'm not wrong the t_relay() in the if clause is only for the case loose_route fails e.g. because of a broken route header.
I still have doubts, because this does not make much sense to me. If the request has to be forwarded according to the rules of loose-routing further script processing makes no sense and therefore it should exit script processing. In this case { t_relay(); break; } makes much sense, not in case of failure.
Maybe I have to look into the code, because there is not much documentation on the "loose_route" function in the "rr" module documentation.
Greets Franz
At 06:19 PM 1/2/2004, Nils Ohlmeier wrote:
Hello,
On Friday 02 January 2004 14:46, Franz Edler wrote:
from various examples in the SER admin_guide and my own SIP knowledge-base I conclude, that the action "loose-route()" is responsible for correct routing of those requests, that are not destined to the proxy (host of Request-URI is not the proxy) and that have a proper Route-header indicating "loose-routing".
As such the action "loose_route()" should be sufficient to modify the Request in such a way, that the following action "t-relay()" finishes processing of the request. Therefore the action short sequence ... if (loose_route()) { t_relay(); break; }; does all, what is necessary for loose routing of those requests.
My problem is, that I could not produce a condition, where "loose_route()" evaluates to true, so that the action block { t_relay(); break; } is executed. I expect, that in a simple call-scenario with one record-routing SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger the above mentioned "loose_route()" action. But unfortunately it does not. Why?
Because you made the wrong assumption: loose_route() will directly deliver/forward the request if it contains a valid route header. If i'm not wrong the t_relay() in the if clause is only for the case loose_route fails e.g. because of a broken route header.
not really. The consruct Franz mentioned is correct. his problems must live somehwere else.
-jiri
On Saturday 03 January 2004 15:28, Jiri Kuthan wrote:
At 06:19 PM 1/2/2004, Nils Ohlmeier wrote:
Because you made the wrong assumption: loose_route() will directly deliver/forward the request if it contains a valid route header. If i'm not wrong the t_relay() in the if clause is only for the case loose_route fails e.g. because of a broken route header.
not really. The consruct Franz mentioned is correct. his problems must live somehwere else.
Then i'm wondering how the loose_route() call could work before the if clause was introduced into the config. But after looking at the RR module code, you seem to be right.
Which probably means Franz, that the replies from the UA does not contain a Route header. As we did not saw any of the replies your are complaining about, please send them to us for review.
Greets Nils
On 03-01 16:33, Nils Ohlmeier wrote:
On Saturday 03 January 2004 15:28, Jiri Kuthan wrote:
At 06:19 PM 1/2/2004, Nils Ohlmeier wrote:
Because you made the wrong assumption: loose_route() will directly deliver/forward the request if it contains a valid route header. If i'm not wrong the t_relay() in the if clause is only for the case loose_route fails e.g. because of a broken route header.
not really. The consruct Franz mentioned is correct. his problems must live somehwere else.
Then i'm wondering how the loose_route() call could work before the if clause was introduced into the config. But after looking at the RR module code, you seem to be right.
Because loose_routing was not implemented at that time yet. This condition is necessary only when strict/loose routers are mixed and IP/hostname of the proxy can occur in the Request-URI, see my previous email.
Jan.
At 02:46 PM 1/2/2004, Franz Edler wrote:
Hi all again,
from various examples in the SER admin_guide and my own SIP knowledge-base I conclude, that the action "loose-route()" is responsible for correct routing of those requests, that are not destined to the proxy (host of Request-URI is not the proxy) and that have a proper Route-header indicating "loose-routing".
yes
As such the action "loose_route()" should be sufficient to modify the Request in such a way, that the following action "t-relay()" finishes processing of the request. Therefore the action short sequence ... if (loose_route()) { t_relay(); break; }; does all, what is necessary for loose routing of those requests.
yes
My problem is, that I could not produce a condition, where "loose_route()" evaluates to true, so that the action block { t_relay(); break; } is executed. I expect, that in a simple call-scenario with one record-routing SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger the above mentioned "loose_route()" action.
yes, that's what it is supposed to do.
But unfortunately it does not. Why?
Hard to say -- a trivial reason is you left out "record_route" from your script, another reason is a phone does not generate proper subsequent requests. If you post your config file and messages, perhaps someone on the mailing list will look at these.
-jiri
Speaking of loose_routing().
I've been working a few days on a script. That script supports 2 methods; INVITE and REGISTER.
route { if(loose_route()) { t_relay(); break; };
if(method=="INVITE") { do that deed, set record_route(); t_relay(); }; if(method=="REGISTER") { do that deed; t_relay(); };
# anything that reaches here is an error??? }
I don't use PRACK, COMET, SUBSCRIBE, NOTIFY.
I don't know what OPTIONS or INFO does, but I don't think I use them either.
Once the INVITE is done, are all messages routed with loose_route()?
---greg
Jiri Kuthan wrote:
At 02:46 PM 1/2/2004, Franz Edler wrote:
Hi all again,
from various examples in the SER admin_guide and my own SIP knowledge-base I
conclude, that the action "loose-route()" is responsible for correct routing of those requests, that are not destined to the proxy (host of Request-URI is not the proxy) and that have a proper Route-header indicating "loose-routing".
yes
As such the action "loose_route()" should be sufficient to modify the Request in such a way, that the following action "t-relay()" finishes processing of the request. Therefore the action short sequence ... if (loose_route()) { t_relay(); break; }; does all, what is necessary for loose routing of those requests.
yes
My problem is, that I could not produce a condition, where "loose_route()" evaluates to true, so that the action block { t_relay(); break; } is executed. I expect, that in a simple call-scenario with one record-routing SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger the above mentioned "loose_route()" action.
yes, that's what it is supposed to do.
But unfortunately it does not. Why?
Hard to say -- a trivial reason is you left out "record_route" from your script, another reason is a phone does not generate proper subsequent requests. If you post your config file and messages, perhaps someone on the mailing list will look at these.
-jiri
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Greg Fausak writes:
route { if(loose_route()) { t_relay(); break; };
if(method=="INVITE") { do that deed, set record_route(); t_relay(); }; if(method=="REGISTER") { do that deed; t_relay(); };
# anything that reaches here is an error??? }
I don't use PRACK, COMET, SUBSCRIBE, NOTIFY.
how about ACK and BYE? don't you use them either? also, i would suggest doing some checking before calling t_relay() after loose_route if you care how people are using your proxy or your pstn gw.
-- juha
Juha Heinanen wrote:
Greg Fausak writes:
route { if(loose_route()) { t_relay(); break; };
if(method=="INVITE") { do that deed, set record_route(); t_relay(); }; if(method=="REGISTER") { do that deed; t_relay(); };
# anything that reaches here is an error??? }
I don't use PRACK, COMET, SUBSCRIBE, NOTIFY.
how about ACK and BYE? don't you use them either?
Well, that is my question. Shouldn't all other messages be record routed if the invite was record routed?
also, i would suggest doing some checking before calling t_relay() after loose_route if you care how people are using your proxy or your pstn gw.
Good point. Is there any checking in loose_route()?
---greg
-- juha
On 03-01 10:47, Greg Fausak wrote:
Juha Heinanen wrote:
Greg Fausak writes:
route { if(loose_route()) { t_relay(); break; };
if(method=="INVITE") { do that deed, set record_route(); t_relay(); }; if(method=="REGISTER") { do that deed; t_relay(); };
# anything that reaches here is an error??? }
I don't use PRACK, COMET, SUBSCRIBE, NOTIFY.
how about ACK and BYE? don't you use them either?
Well, that is my question. Shouldn't all other messages be record routed if the invite was record routed?
Yes, it is recommended somewhere in the RFC.
also, i would suggest doing some checking before calling t_relay() after loose_route if you care how people are using your proxy or your pstn gw.
Good point. Is there any checking in loose_route()?
No, there is no checking.
Jan.
Greg Fausak writes:
Well, that is my question. Shouldn't all other messages be record routed if the invite was record routed?
no, because the route recorded for initial transaction that established the dialog will be used for all subsequent requests of that dialog. i was just referring to your script that asked if it is an error if you end up there. so you only need record route the initial request (the one without to tag).
Good point. Is there any checking in loose_route()?
i guess not,
-- juha
On 03-01 18:59, Juha Heinanen wrote:
Greg Fausak writes:
Well, that is my question. Shouldn't all other messages be record routed if the invite was record routed?
no, because the route recorded for initial transaction that established the dialog will be used for all subsequent requests of that dialog. i was just referring to your script that asked if it is an error if you end up there. so you only need record route the initial request (the one without to tag).
Basically you need to record route all target refreshing requests (as far as I know currently only INVITE and SUBSCRIBE) are target refreshers.
Generally you don't know if a message is target refresher because some other may be created in the future. That's the reason why it is recommended to record-route all requests.
So it is a tradeoff between efficiency and compatibility with future (or proprietary) extensions. If you want shorter messages (Record-Route headers can significantly bloat SIP messages, especially when proxy chains are involved, not even speaking of IPv6 addresses), record route INVITE and SUBSCRIBE requests only.
If you don't care about efficiency and huge messages, record-route everything.
Jan.
At 05:04 PM 1/3/2004, Juha Heinanen wrote:
Greg Fausak writes:
route { if(loose_route()) { t_relay(); break; };
if(method=="INVITE") { do that deed, set record_route(); t_relay(); }; if(method=="REGISTER") { do that deed; t_relay(); }; # anything that reaches here is an error???
}
I don't use PRACK, COMET, SUBSCRIBE, NOTIFY.
how about ACK and BYE? don't you use them either?
only INVITEs and SUBSCRIBEs needs to be record-routed. It is not harmful to record-route other requests (perhaps a new method, FOOBAR, will be used along with record-routing too and we won't have rewrite script for it then).
All message types with Route already in place are processed in the first line, and that's good so.
also, i would suggest doing some checking before calling t_relay() after loose_route if you care how people are using your proxy or your pstn gw.
indeed.
we do something like bellow....
if (loose_route()) { # check if someone has not introduced a pre-loaded INVITE -- if so, # verify caller's privileges before accepting rr-ing if ((method=="INVITE" || method=="ACK" || method=="CANCEL") && uri =~ "sip:[+0-9]+@10.1.0.1") { route(3); # Forward to PSTN gateway (that;s where all the ACLs are placed) } else { append_hf("P-hint: rr-enforced\r\n"); # account all BYEs if (method=="BYE") setflag(1); route(1); # Generic forward }; break; };
-jiri
On 02-01 14:46, Franz Edler wrote:
Hi all again,
from various examples in the SER admin_guide and my own SIP knowledge-base I conclude, that the action "loose-route()" is responsible for correct routing of those requests, that are not destined to the proxy (host of Request-URI is not the proxy) and that have a proper Route-header indicating "loose-routing".
Not really. loose_route() implements record routing. Because it must be backwards compatible with strict routers, it implements both, loose routing and strict routing.
It should process all messages that contain Route header fields, even those that have hostname or IP of the proxy in Request-URI (it can happen).
You should call loose_route() on every message unless you know what you are really doing.
As such the action "loose_route()" should be sufficient to modify the Request in such a way, that the following action "t-relay()" finishes processing of the request. Therefore the action short sequence ... if (loose_route()) { t_relay(); break; }; does all, what is necessary for loose routing of those requests.
I think that this one deserves some explanation. The reason why
if (loose_route()) { t_relay(); }
is needed and why just loose_route(); is not sufficient is as follows:
In some situations, SER needs to insert two Route header fields -- we call this double record-routing. It is necessary, for example, when a request comes over UDP and ser sends it over TCP. Suppose the following situation:
A -- UDP -- SER -- TCP -- B
A sends a SIP message over UDP to ser and ser forwards the message over TCP to B. Later if B sends a message within dialog, you usually want it to go the same way -- that means it should be sent over TCP to ser and ser forwards it over UDP to be.
To achieve this, ser needs to add two Record-Route header fields, one with UDP transport and one with TCP transport, they will look like this:
Record-Route: sip:ser@1.2.3.4;r2;transport=TCP Record-Route: sip:ser@1.2.3.4;r2
(the only difference is in the parameters). Client B sees the "TCP" Record-Route first and sends the further messages over TCP. Client A reverses the order of the header fields and sees the "UDP" Route first.
Because the ser in the middle created both headers, it also has to remove both resulting Route header fields. That's what r2 parameter is for -- it tells ser that another Route header field follows and it should be removed as well.
Unfortunately there are broken implementations in the wild that strip parameters that they don't know -- in this case the r2 parameter. ser will not remove the 2nd Route if the parameter is missing, instead it would forward the message to it. In some cases it doesn't harm -- the message will just spiral through the same proxy one more time.
Now the tough part -- in some cases it does harm -- for example when there are some strict routers along the path. In this case the message would contain the IP address of ser in the Request-URI (from the 2nd Route).
In most config files, loose_route() is usually followed by a condition like this:
if (uri==myself)
and that condition would match (because there is the IP of ser in the Request-URI). That's wrong, because mid-dialog requests should not be processed in this part of script.
loose_route() returns true in this case and you must make sure that if (uri==myself) is not reached.
That's the reason why t_relay() is called inside the condition -- message contained Route headers and shouldn't be processed by the script.
My problem is, that I could not produce a condition, where "loose_route()" evaluates to true, so that the action block { t_relay(); break; } is executed. I expect, that in a simple call-scenario with one record-routing SIP proxy (SER) the routing of the ACK- and the BYE-method should trigger the above mentioned "loose_route()" action. But unfortunately it does not. Why?
See above, this condition is a sort of safety net and normaly it is not triggered.
You should have t_relay(); at the end of your script which will take care of all other record-routed requests. See the default config file for more details.
Jan.
From: Jan Janak Sent: Saturday, January 03, 2004 7:05 PM
Thank you all for contributing to my questions even on weekend. Now everything is clear and SER works very well and behaves as I expect :-).
Thanks especially to Jan for his detailed explanations of some though background issues on "loose_route".
Thanks again Franz