[SR-Users] call forking using dbaliases not working for un-NATed clients

Yufei Tao yufei.tao at redembedded.com
Tue Sep 18 15:16:43 CEST 2012


Hi

I have a strange problem on forking calls to a group of users. For
example I have two users y2 and y3 in dbaliases, both with
alias_username 'group'. And y2 and y3 both registers with Kamailio fine.
When I make a call to 'group' from a third client y1, what my
kamailio.cfg does is: do an alias_db_lookup("dbaliases"), and goes to
BRANCH_ALIASDB, where a lookup location will be done for each of the
username resulting from lookup of dbaliases, something like this:

y1--INVITE 'group'-->lookup dbaliase-->[BRANCH_ALIASDB]--->'y2'-->lookup
location---¬

|                                                 |-->relay
                                  ---->[BRANCH_ALIASDB]--->'y3'-->lookup
location----

The all works well as long as all clients are NAT'ed. However when they
are not NAT'ed, e.g. all on the same LAN with Kamailio, the call only
goes to one of the group members, e.g. y2 only. When checking the log,
it seemed to have done the dbaliases lookup fine, and each location
lookup successfully. But Kamailio only relayed y2's IP, e.g. to the
client, while y3's to itself.

When comparing the location table when clients are NAT'ed or not, I find
that the 'received' column is only populated when I do
fix_nated_register. And group calls only works when 'received' column is
populated. That explains why when clients are NAT'ed group calls work,
as I only do fix_nated_register if nat_uac_test returns true.

But if this is the only reason, if two clients register using the same
username, e.g. both as y3, and when 'received' column of location table
is empty (no fix_nated_register done), I would expect a call to y3
should also only make 1 client ring. But in fact both of them rang! The
flow is like:

y1--INVITE 'y3'-->lookup location for 'y3'----> IP of 1st client
registered as 'y3'
                                           |
                                           ---> IP of 2nd client
registered as 'y3'

While a call to 'group' (thus dbaliases lookup took place) under such
un-NAT'ed set up made only 1 client ring.

So I can make it work by always doing fix_nated_register. But I'm not
clear about these things:
- why does a lookup of dbaliases before lookup of location make such
difference?
- does lookup location work differently depending on whether it is
called from trunk or from a route called from a branch route?


Following is relevant parts from my config file:

#############################################################
route[LOCATION]
{
   if ( alias_db_lookup("dbaliases") )
   {
     t_on_branch("BRANCH_ALIASDB"); # in branch_route[BRANCH_ALIASDB],
                                    # call another route that looks up
location,
                                    # if not existent, call drop()

   }
   else
   {
     xlog("L_DBG","LOCATION: not alias - go to lookup location trunk\n");
     route(LOCATION_TRUNK); # normal look up location and sending of 404 etc
   }

... ...
}
#############################################################
branch_route[BRANCH_ALIASDB]
{
   xlog("L_DBG", "BRANCH_ALIASDB: $fU@$fd ->  $rU@$rd; Method:$rm\n");
   route(LOCATION_BRANCH);
}

route[LOCATION_BRANCH]
{
   if (!lookup("location"))
   {
     # Drop this branch - it's going nowhere
     drop();
   }
}
#############################################################
route[RELAY] {
   xlog("L_DBG","RELAY: method=$rm, callid=$ci, cseq=$cs\n");


#!ifdef WITH_NAT
   if (check_route_param("nat=yes")) {
     setbflag(FLB_NATB);
   }
   if (isflagset(FLT_NATS) || isbflagset(FLB_NATB)) {
     xlog("L_DBG", "RELAY: about to call RTPPROXY\n");
     route(RTPPROXY);
   }
#!endif

   /* example how to enable some additional event routes */
   if (is_method("INVITE")) {
     t_on_reply("REPLY_ONE");
     t_on_failure("FAIL_ONE");
   }

   if (!t_relay()) {
     sl_reply_error();
   }

   exit;
}

############################################################
route[NAT] {
#!ifdef WITH_NAT
  xlog("L_DBG","NAT: method=$rm, callid=$ci, cseq=$cs\n");

    force_rport();
    if (nat_uac_test("2")) {
        if (method=="REGISTER") {
            fix_nated_register();
            xlog("L_DBG","NAT: Just done fix_nated_register in REGISTER
message in NAT route\n");
        } else {
          xlog("L_DBG","NAT: fix_nated_contact\n");
            fix_nated_contact();
        }
        setflag(FLT_NATS);
    }

#    setflag(FLT_NATS); ## -- YT: set NAT flag for all, so will force
media relay
#!endif
    return;
}

#############################################################
And in the main route, route LOCATION and RELAY are the last two routes:
route {
...
   route(NAT);

   ... ...

   # user location service
   route(LOCATION);

   route(RELAY);
}

Hope I have made it clear. Thanks very much!

Yufei
--
Yufei Tao
Red Embedded

This E-mail and any attachments hereto are strictly confidential and intended solely for the addressee. If you are not the intended addressee please notify the sender by return and delete the message.

You must not disclose, forward or copy this E-mail or attachments to any third party without the prior consent of the sender.

Red Embedded Design, Company Number 06688253 Registered in England: The Waterfront, Salts Mill Rd, Saltaire, BD17 7EZ



More information about the sr-users mailing list