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

Klaus Darilion klaus.mailinglists at pernau.at
Fri Apr 24 10:18:31 CEST 2009



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
> 
> 



More information about the Users mailing list