[Serdev] Concept for a SIP cluster implementation

Andreas Granig andreas.granig at inode.info
Wed Sep 21 21:30:48 UTC 2005


Hi,

I'm planning to use SER proxies as SIP load balancers in front of a SER 
cluster, and I'd like to describe the concept here. Comments are highly 
welcome.

The scenario uses two load balancing proxies called Edge Proxies (EP), 
and a SER cluster with multiple registrars and proxies, called REG[] 
here, which stores all contacts into a common DB (a mysql cluster).

A REGISTER would for example be routed like this:

UA1 ---> EP1 ---> REG[x] ---> DB
UA2 ---> EP2 ---> REG[y] ---> DB

Using the cacheless usrloc module, no SIP replication is done between 
the registrars in the cluster, but it could also be used with the 
standard usrloc module in combination with SIP replication (I will 
implement it for both modules for compatibility reasons).

The proxies EP1 and EP2 are responsible for NAT pinging the UAs which 
registered via them. As a first step they will ping each UA no matter if 
it really registered via them, but for performance reasons this could be 
tuned to only ping the relevant UAs (will be done in a second step).

To make sure that subsequent requests towards the UAs are routed via the 
correct proxy (P1 or P2) for proper NAT traversal, I want to use the 
Path header, so an INVITE for the above scenario could look like this:

UA1 ---> EP1 ---> REG[z] ---> EP2 ---> UA2

The current path module implementation has quite some shortcomings, and 
don't really like the logical design, so my idea is to implement it in 
such a way:

P1 and P2 add themselves to the Path header of the REGISTER using a 
function add_to_path() (names of the functions are for just examples 
btw, and as a first step the Path header could even be added with 
append_hf()).

REG[] calls save("location"), and the Path vector is stored along with 
the contacts in the location table. Since a UA could register some 
contacts via P1 and some others via P2, there could be different Path 
vectors for an AOR, so a proper branch handling has to be done.

Now if UA1 calls UA2 like in the example above, lookup("location") 
fetches the contacts and stores the Path vector for each branch in AVPs. 
Before calling t_relay(), a branch_route is registered if Path vectors 
are available, and in this branch route the corresponding Path vector 
loaded from AVP is added to the Route set:

   route[x] {
     ...
     if(has_path()) {
       t_on_branch("1");
     }
     ...
     t_relay();
   }

   branch_route[1] {
     path_route();
   }

So what do you think about this approach? Is this a passable solution, 
and would there be any chance to get the changes into HEAD when finished?

Looking forward for comments,
Andy




More information about the Serdev mailing list