Hi Andreas,
Thank you for sharing your setup with the list! It is one more of several
interesting reference designs/implementations that would be very useful to
index and provide access to from the
iptel.org site. I don't know who
controls the
iptel.org website? It could be as simple as a FAQ page where
each FAQ item is a link to a specific post on
mail.iptel.org (to keep the
work down). I'm sure many basic questions on the list could be avoided with
such a FAQ page.
See inline comments.
But here's my current (not perfect but perfectly
working) solution:
Locations are replicated on SIP-layer using forward_tcp(...) (thanks
to Juha for the hint) on one side and save_noreply(...) on the other
side. This works very reliable with three SERs although it wouldn't
scale much, so this has to be improved in the future.
The config looks like:
if(method == "REGISTER")
{
if(src_ip==<IP of peer1> || src_ip==<IP of peer2>)
{
save_noreply("location");
}
else
{
if(!www_authorize("<my domain>", "subscriber"))
{
www_challenge("<my domain>", "0");
break;
}
if(!check_to())
{
sl_send_reply("403", "Use To=username next time");
break;
}
if(!save("location")) { sl_reply_error(); break; }
forward_tcp("<IP of peer1", 5060);
forward_tcp("<IP of peer2", 5060);
}
break;
}
The usrloc modules operates in write-through-mode so locations are
always synched to the db.
I think the above is a good description of a simple, but generic replication
setup.
When a SER goes down, I've a script for recovering
the location
tables, and it looks like:
mysqldump -h${SER_PEER} -u${DB_RUSER} -p${DB_RPASS} -Q \
--extended-insert --add-drop-table ser ${SER_LOCATIONS} \
| mysql -u${DB_LUSER} -p${DB_LPASS} ser
/usr/local/ser/sbin/ser.sh start
where $SER_LOCATIONS holds the location tables like "location",
"aliases" and so on.
If I understand you correctly, you dump on one server (one that is up) and
load on the one that was down? Is this an automatic operation?
What still has to be done is replicating the nonce
value so UAs with
DNS-SRV implementations which change the server on each request and
SERs behind load balancers will work too.
It's not as nifty as using diameter or something like that but it
grants me some reprieve ;o)
Yes, this is where a DB setup gets complicated. However, maybe you could to
reduce the time for the nonce to go stale? There is a variable for setting
that value, I think the default is 300 seconds. The result would be many
more authentications. I'm not completely sure how this works for sql, as we
only use RADIUS auths, but I would imagine a new request to a new server
where the nonce is wrong would result in a new auth? Or is the response a
NAK and that's why you need replication?
It seems to me that the messages in a single authentication (REGISTER,
auth required, new REGISTER, ok) should go to the same server regardless of
UA SRV implementation The next auth will be an INVITE probably and the
nonce will probably be stale (300 secs) and result in a new auth. Also, a
load balancer should (with reference to previous serusers discussions)
probably make sure that all messages from one UA goes to the same server.
At least is that true for an application level balancer, so that NAT
problems are handled correctly. If the load balancer is a TCP/IP-level
balancer, you should probably distribute on src_ip and thus avoid your nonce
problem.
Sorry if this is not relevant to SQL auths... ;-)
For distributing FIFO commands to provision call
forwards and read
SER's status etc I wrote an XML-RPC server which communicates with
SER's unixsocket-FIFO-interface. So a simple PHP script communicating
with a SER looks like this:
$url = "http://my.server:5080/xmlrpc";
$method = "fifo.execute";
$fifocmd = "ul_show_contact";
$fifoparams = array("location", "012345");
$ar = array("cmdname"=>$fifocmd,"cmdparams"=>$fifoparams);
$request = xmlrpc_encode_request($method, $ar);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
$response = curl_exec($ch);
$xmlar = xmlrpc_decode($response);
if(xmlrpc_is_fault($xmlar))
{ /* fault processing, print the error */ }
else
{ /* normal processing, print the response parameters etc */ }
The XML-RPC solution seems to be more flexible to me than the
TCP-interface for SER because it can not only execute FIFO commands
but can easily be extended to communicate with the mediaproxy for
example. But this opinion may depend on one's needs.
The licensing question of the XML-RPC server is still not clear
(chiefs, you know), but I hope I get it licensed as GPL.
I agree with you, a pure TCP-interface is too low-level. I also agree with
Juha in that an XML-RPC/SOAP implementation should be done as an extension
to the current unix socket interface and be an integrated part of ser. Have
you coded it in C? If so, maybe the code be used as a starting point
(dependent on GPL from your chiefs)?
g-)