[Kamailio-Users] Multiple SIP Proxy Environment / Socket Information

Brandon Armstead brandon at cryy.com
Wed Apr 29 10:53:15 CEST 2009


Hey guys,

    Still facing a few challenges and seeing if any further input, I'm
specifically trying inaki's suggestions / method, but here are the current
problems:

sip:/etc/kamailio/m4cfgs# tail -f /var/log/openser.log | grep -v -E
'non-local|repeated' | grep branch_route
Apr 29 07:38:05 db06 /sbin/kamailio[21279]:
[77e4c600-147767fb at 172.16.1.35][branch_route][1]
ru=sip:CALLEE at 99.XX.XX.XX:5079
fu=sip:CALLER at sip.example.com<sip%3ACALLER at sip.example.com>tu=
sip:CALLEE at sip.example.com <sip%3ACALLEE at sip.example.com> si=99.XX.XX.XX
flag=96 du=<null>

This call is not sent to Proxy B (this is a result of bflag not being set)
??? My question is "Why", I look at the AOR / usrloc and they both have the
"same exact flags set", this call is rather sent directly to UAC endpoint.

---

Apr 29 07:38:05 db06 /sbin/kamailio[21279]:
[77e4c600-147767fb at 172.16.1.35][branch_route][2]
ru=sip:CALLEE at 99.XX.XX.XX:5062
fu=sip:CALLER at sip.example.com<sip%3ACALLER at sip.example.com>tu=
sip:CALLEE at sip.example.com <sip%3ACALLEE at sip.example.com> si=99.XX.XX.XX
flag=64 du=sip:PROXY_B;transport=udp;

This call is sent to Proxy B (however Proxy B) - however the X-Duri (is
null) as it is not existant in Proxy A's branch route? should I save this
from right after the lookup("location") result into an avp?


Again, thank you for all and any help, thanks!

On Mon, Apr 27, 2009 at 5:42 PM, Brandon Armstead <brandon at cryy.com> wrote:

> Klaus, Inaki, Daniel,
>
>     Thanks!  Sorry I did not see this email come through, I'm going to go
> ahead and give this method a go, and I'll update with the results, I have
> optimistic views.
>
> As for the reason I was rewriting $ru and setting $du to null, is because
> originally when I just changed $du to the 'destination proxy' it did not
> seem to work at all (I do not even recall what exactly what was happening)
> however I decided to just change $ru, and have the other proxy just "lookup"
> the usrloc information again.  Again, this method looks interesting and I'll
> let you guys know how it goes, thanks for all the input and help!
>
> Sincerely,
> Brandon.
>
>
> On Fri, Apr 24, 2009 at 1:18 AM, Klaus Darilion <
> klaus.mailinglists at pernau.at> wrote:
>
>>
>>
>> Brandon Armstead schrieb:
>>
>>> Klaus,
>>>
>>>    So I took you and Inaki's input and essentially constructed a setup
>>> like so after the lookup("location") call:
>>>
>>> if(isbflagset(1)){
>>>    $du = null;
>>>    $rd = "P1";
>>> } else if(isbflagset(2)){
>>>    $du = null;
>>>    $rd = "P2";
>>> } else if(isbflagset(3)){
>>>    $du = null;
>>>    $rd = "P3";
>>> } else if(isbflagset(4)){
>>>    $du = null;
>>>    $rd = "P4";
>>> }
>>>
>>
>> 1. The above code has to be in the branch_route block - otherwise multiple
>> registrations of a single user are not handled correctly.
>>
>> 2. you are rewriting the RURI. You should not do that as some clients
>> wants to the in the RURI the Contact provided during REGISTER.
>>
>> 3. probably you use fix_nated_register() to store the public IP:port of
>> the client too. After lookup, this information is written to DURI. Thus, by
>> setting $du you overwrite this info. You should put it into a special header
>> so that you can restore it in the other proxy.
>>
>> Here a snippet how it should work (untested, no warranty): ( I use the
>> term "originating" proxy for the proxy which received the INVITE and the
>> term "serving" proxy for the proxy which handles the connection/registration
>> of a certain SIP client).
>>
>> e.g:
>> Alice -----INVITE-----> P1------->P2----->Bob2
>>                        /  \
>>                       /    \
>>                      /      V
>>                     V       P3---->Bob3
>>                  Bob1
>>
>> Bob's client Bob1 is connected to P1.
>> Bob's client Bob2 is connected to P2.
>> Bob's client Bob3 is connected to P3.
>>
>> So, P1 is the originating proxy. P2 is the serving proxy of Bob2. ....
>>
>> We do NAT traversal (note: we must not call fix_nated_contact() for
>> messages sent between the proxies!): the originating proxy for the call-leg
>> to the caller, the serving proxy for the call-leg to the callee.
>> The RTP proxy will be managed by the originating proxy only.
>>
>>
>>
>> route{
>> if (loose_route()) {
>>  ... additional loose route processing...
>>  if (check_route_param("rtpproxy=yes")) {
>>    force_rtp_proxy();
>>    setbflag(7);
>>  }
>>
>>  # downstream: in-dialog request is in the same direction as the
>>  # initial request
>>  if ( (check_route_param("nat=caller") && is_direction("downstream"))
>>    || (check_route_param("nat=callee") && is_direction("upstream"))) {
>>    fix_nated_contact();
>>  } else if (check_route_param("nat=both") {
>>    fix_nated_contact();
>>    setbflag(8);
>>  } else {
>>    setbflag(8);
>>  }
>>
>>  t_on_reply("1");
>>  t_relay();
>>  exit();
>> }
>> ...
>>
>> # I am proxy 1
>> if ((src_ip=ip.of.proxy.2) || (src_ip=ip.of.proxy.3)...) {
>>  # request comes from other proxy, that means I am the
>>  # serving proxy
>>  # do not lookup(), RURI is already set and
>>  # DURI is provided in our X-DURI header
>>  $du = $header(X-DURI);
>>  # we do not care about an RTP proxy because that's the task of the
>>  # proxy which performed the lookup() (the originating proxy)
>>  # add some record-route cookie to mark that we should perform
>>  # SIP NAT traversal for the callee
>>  add_rr_param(";nat=callee");
>>  # activate reply_route to fix_nated_contact of callee
>>  setbflag(8); # flag 8 = fix contact
>>  t_on_reply("1");
>>  record_route();
>>  t_relay();
>>  exit;
>> }
>>
>> ...
>> # a new request - thus I am the originating proxy
>>
>> if ($dU looks like phone number) {
>>   ... route to Gateway....
>>  exit;
>> }
>>
>> if (!lookup("location")) {
>>  sl_send_reply("404","not found");
>>  exit;
>> }
>> # activate branch route to have dedicated routing per branch
>> t_on_branch("1");
>>
>> # activate reply route to activate RTP proxy
>> t_on_reply("1");
>>
>> # NAT traversal
>> fix_nated_contact();
>>
>> record_route();
>> t_relay();
>> exit;
>> }
>>
>> branch_route[1]{
>>  if(isbflagset(1)){
>>   # oh, that's me
>>
>>   # add some record-route cookie to mark that we should perform
>>   # SIP NAT traversal for the callee and caller
>>   add_rr_param(";nat=both");
>>
>>   # add some record-route cookie to mark that we are
>>   # in charge for the RTP proxy
>>   add_rr_param(";rtpproxy=yes");
>>
>>   force_rtp_proxy();
>>   setbflag(7); # flag 7 = RTP proxy
>>  } else {
>>   # add some record-route cookie to mark that we should perform
>>   # SIP NAT traversal for the caller
>>   add_rr_param(";nat=caller");
>>
>>   # we have to route the request to the serving proxy
>>   # write DURI in the header
>>   append_hf("X-DURI: $du");
>>   if(isbflagset(2)){
>>       $du = sip:ip.of.proxy.2;transport=udp;
>>   } else if(isbflagset(3)){
>>       $du = sip:ip.of.proxy.3;transport=udp;
>>   } else if(isbflagset(4)){
>>       $du = sip:ip.of.proxy.4;transport=udp;
>>   }
>>  }
>> }
>>
>> reply_route[1]{
>>  if (isbflagset(7) && has_body("application/sdp")) {
>>    force_rtp_proxy()
>>  }
>>  if (isbflagset(8)) {
>>    fix_nated_contact()
>>  }
>> }
>>
>>
>>
>> Note: this code does not care about the received socket of the proxy. Thus
>> it works if the proxy listens only on one port.
>>
>> regards
>> klaus
>>
>>
>>  On each Proxy, I changed the code appropriately excluding the Proxy from
>>> itself (so it does not forward to itself).  I'm noticing weird behavior
>>> however as it seems as if what is happening is it created other issues such
>>> as:
>>>
>>> [INCOMING SERVER] -> P1 -> P2 -> P1 -> (loop?)
>>>
>>> Also I setup this test amongst two development servers (in which case it
>>> worked without issues).  Once I included in more development instances into
>>> the ring it seemed as if the flags were being set when they should not be?
>>>
>>> I.e. I placed a call FROM UA1 (with bflag 5 SET) From the above example
>>> configuration ^ code.  If you notice (flag 5) is missing.  To UA2 (Flag 3),
>>> again this looked to be doing some strange things such as acting as if
>>> another flag was set when it should not have been, thus forwarding to the
>>> wrong proxy or the wrong proxy order.  Do you guys have any further thoughts
>>> or input on this?  Thanks!
>>>
>>> On Thu, Apr 23, 2009 at 12:31 AM, Klaus Darilion <
>>> klaus.mailinglists at pernau.at <mailto:klaus.mailinglists at pernau.at>>
>>> wrote:
>>>
>>>    Hi Brandon!
>>>
>>>    Back to the original email ....
>>>
>>>    Brandon Armstead schrieb:
>>>
>>>        Hello guys,
>>>
>>>           Is there a method upon using lookup("location") to also pull
>>>        out the "socket" information for the original location the UAC
>>>        registered to, for scenarios of this example:
>>>
>>>        P1 & P2 share same usrloc database.
>>>
>>>        UA1 registers to P1
>>>        UA2 registers to P2
>>>
>>>        UA1 calls UA2
>>>
>>>        UA1 invites -> P1 -> INVITES -> UA2 (bypassing P2 -- where the
>>>        actual nat binding is).
>>>
>>>        Now upon P1 looking up usrloc for UA2, I would like to recognize
>>>        that P1 is not the Proxy to deliver the call, and forward the
>>>        request to P2 to send to UA2.
>>>
>>>        So currently I have:
>>>
>>>        UA1 INVITE -> P1 INVITE -> UA2
>>>
>>>        I wish to have:
>>>
>>>        UA1 INVITE -> P1 INVITE -> P2 INVITE -> UA2
>>>
>>>        Is there an easy method to do this?  I have been looking at the
>>>        new nat traversal module it looks like it is doable with this
>>>        (any further input as far as that?).  Also is it possible with
>>>        the classic Nat Helper module?  Any input is appreciated, thanks!
>>>
>>>
>>>    I think the nat_traversal module can not help you in this case, nor
>>>    nathelper.
>>>
>>>    One possibility would be to spoof at P1 the IP address of P2 -
>>>    nevertheless this would cause the reply sent back to P2, but the
>>>    transaction is created in P1. (and you need to hack Kamailio for IP
>>>    spoofing).
>>>
>>>    Another easy solution would be: In P1 set a certain branch-flag when
>>>    the client registers, e.g. bflag 1. In P2 set a certain branch-flag
>>>    when the client registers, e.g. bflag 2.
>>>
>>>    Now, if a user is called, just make a lookup() and t_relay. Further
>>>    in the branch_route check if:
>>>     in P1: isbflagset(2) --> forward to P2
>>>     in P2: isbflagset(1) --> forward to P1
>>>
>>>    klaus
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>  ------------------------------------------------------------------------
>>>
>>>        _______________________________________________
>>>        Kamailio (OpenSER) - Users mailing list
>>>        Users at lists.kamailio.org <mailto:Users at lists.kamailio.org>
>>>        http://lists.kamailio.org/cgi-bin/mailman/listinfo/users
>>>        http://lists.openser-project.org/cgi-bin/mailman/listinfo/users
>>>
>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kamailio.org/pipermail/users/attachments/20090429/b0c2ad33/attachment-0001.htm 


More information about the Users mailing list