2009/4/1 Frank Durda IV <frank.durda(a)hypercube-llc.com>om>:
Now, I take it you are asking what happens in the case
of the INVITE
coming in from the calling party, and later the 183 or 200 comes back
from the called party, and for each of these a force_rtp_proxy()
is performed. How do you get both directions of the call to go to the
same rtpproxy instance, or if something else changes after the 200 OK,
even though nathelper maintains no call state? You have three options.
In fact I expected that, being transaction stateful, *SER uses the
same RtpProxy when running force_rtpproxy in request and response(s)
belongs to the same transaction. I'm not sure of it anyway.
My doubt was about the case of re-INVITE/BYE. More inline:
The limitions implicit in having the script specify
the proxy to
use via the Nn flag, combined with what I consider to be the most
stupid/horrible missing bit of functionality in SER (that of not
being able to pass variables to functions/modules*), and you
are greatly limited in what smart things you can do to scale
SER+rtpproxy, if you do it via the ser.cfg file.
*I note OpenSER supposedly allows you to pass variables to functions
(at least reading their lexical scanner seems to have added the
rules to allow this, but I don't know if it actually works or not.
I would certainly use it for a large number of other things if
it was available.)
yes, OpenSER allows pseudo-variable as argument in lots of functions (not all).
Three, SER quietly (and possibly inadvertantly) takes
care of this
issue by using the Call-ID as the variable value that is used to select
the rtpproxy. The Call-ID string is ground-up in a hashing algorithm
(see select_rtpp_node() in modules/nathelper/nathelper.c) and a value
between 0 and N comes out of that, and that combined with the total
number of weight possibilities selected at start time, skipping any
disabled proxies (presumably because they became unresponsive in the
past) dictates which rtpproxy that call will be sent to.
Ok, but since the chosen RtpProxy depends on the Call-ID and weight
combination, how to ensure that force_rtpproxy() in 200 selects the
same instance than the one selected by force_rtpproxy() in the INVITE?
(the same for re-INVITE/BYE).
This is, a call is established under some circumstances an these cause
a selection of a specific RtpProxy. After 30 minutes the call is put
on hold by sending a re-INVITE. Now (after 30 minutes) the
circumstances have changed so the same Call-ID causes force_rtpproxy()
to select other RtpProxy.
This basically means that the RTP session would remain open in the
first RtpProxy (until it expires?). And this also means that *SER
script cannot rely on the return code of "force_rtpproxy(l)" that is
very useful to check if the current in-dialog INVITE belongs to a call
for which initially force_rtpproxy() took place.
So, this means that each time force or unforce
rtpproxy calls,
this same hash gets performed on the same Call-ID for a given call,
and except for rare cases where a proxy has failed, you will end up
sending the force/unforce for a given Call-ID to the same rtpproxy
instance every time. At least, this is how I read the source code.
I believe that if the decision jsut depends on the Call-ID, but since
it also depends on the weight... perhaps I miss something?
I'll point out that if the initial selection of
rtpproxy from
the first force_rtp_proxy() of a given call session had simply been
recorded as an integer somewhere with the other trivia that is
maintained for the duration of a given call session,
It could be added as parameter to the Record-Route header (obviously
loose routing is required if we want the proxy to manage the RTP
stream via RtpProxy).
This is:
- In the initial INVITE force_rtpproxy() sets some variable
($rtpproxy_instance = 3).
- After it, the *SER script adds a parameter to Record-Route:
Record-Route: <sip:1.2.3.4:5060>;rtpproxy_instance=1
- Later when processing the 200 (or ACK if it has SDP), re-INVITE or
BYE, the *SER script reads the "rtpproxy_instance" from Route header
and set the RtpProxy according to it (in Kamailio there is a function
"set_rtpproxy").
Does it make sense?
Thanks a lot for your response.
--
Iñaki Baz Castillo
<ibc(a)aliax.net>