Sorry for top-posting, but my stupid web email client has no way to work with replies(OWA I am looking at you)
I also thought at the caching solution and for me it seems it doesnt't work. We have this common setup
Customer ----> Internet ------> Proxy(stateless) -----> Registrar
The proxy has 2 interfaces (mhomed active) and the Registrar is in the same subnet (private) with the proxy.
When an REGISTER comes from a client it reaches the multihomed Proxy on the external interface, then it goes onto
the internal interface and then to the register. We can cache here the (internal iface, Registrar) pair , but when
when a reply from a Registrar comes in, the proxy can't know on what interface to send the reply back to the customer
so it must do a socket()/connect()/getsockbyname(). Multiply this by let's say 300 k customers and caching for me
doesn't sound that good. The same problem applies for INVITES and such.
I will continue to work on the patch. Thang you Andrei for the idea to register get_out_socket from a module.
Marius
-----Original Message-----
From: Andrei Pelinescu-Onciul [mailto:andrei@iptel.org]
Sent: Fri 11/27/2009 1:01 PM
To: Marius Zbihlei
Cc: sr-dev@lists.sip-router.org
Subject: Re: [sr-dev] Problems with mhomed
On Nov 27, 2009 at 11:40, Marius Zbihlei <Marius.Zbihlei@1and1.ro> wrote:
> As I see in sip-router and in kamailio, the mhomed implementation is very very slow . For each SIP packet a
> temporary socket is created, connected to the remote host and than checked to see what interface was selected
> to connect the socket(see method get_out_socket() in forward.c)
I agree.
>
> As test have shown, this implementation, albeit correct from a funtional point of view, it's really too slow
> (or too expensive) to be used in medium-large production setups.
>
> I am currently working on a patch that mitigates this problem. The way the patch works is like this:
>
> 1. Get the routing table from the kernel via NETLINK sockets(done at start)
> 2. Construct a link list of routes, each entry for one interface(either real of virtual). The structure will hold
> the address of the interface and the destination (as reported by route -n)(this will be a CIDR entry). Also it's
> decided if on that interface a default route has been assigned(done at start)
> 3. get_out_socket() will be changed to loop thru the list described above and decide based on the destination member
> of the struct describe above on what interface the packet is to be routed. If no destination is matched than the
> default one is selected.(done for each packet)
> 4.A NETLINK socket will be added to the poll()ing loop so it can monitor the changes in the kernel's routing table
> and update the internal structure if necessary.(done at start)(The table is updated only if administration changes the
> routing table via route or ip route commands)
>
> I have implemented the first 3 steps and preliminary tests look ok. step for is required only if we want updates on
> the routing table in real time.
>
> Limitations:
> 1. This only works for Linux, AF_INET sockets. AF_INET6 is also supported but i don't know to what extent
> 2. For BSD, route sockets should replace the NETLINK sockets
>
> What are your suggestion about this? Should this patch (when completely finished) be commited?
The fact that it cannot be done in a portable way is the biggest
problem.
I was thinking of simply keeping the current method (open new sock to
find the src address) and add a cache (look first in the caches, if
it's not in the cache do the socket stuff). That should solve most of
the performance problems.
However if you go ahead with your linux (and maybe bsd) specific
solution we could either have and #ifdef or better a get_out_socket()
callback that can be registered by a module (so that we can have several
methods).
Andrei