[Users] OpenSER as load balancer for several Asterisk servers

Edoardo Serra osdevel at webrainstorm.it
Mon Dec 18 19:57:56 CET 2006


Hi guys,
	I'm having a problem with an OpenSER acting as registrar server and 
load balancer for many Asterisk servers.

In a few words: "users are registering on openser and, when they want 
to make a call, OpenSER proxies the request to an Asterisk server 
with the dispatcher module"
Here is the intended data flow (SIP goes through OpenSER and media 
goes directly to Asterisk)
User <-- SIP --> OpenSER <-- SIP --> Asterisk
User <-- RTP --> Asterisk

Both, OpenSER and Asterisks have public IPs

I already have a working setup of that and everything seems working correctly.

I'm trying to replicate that setup on another site, same 
configurations of the boxes, same versions of OpenSER and Asterisk, 
etc... but I'm having monodirectional Audio.

Having a look with tethereal I see that OpenSER, when the 
communication is answered, sends a SIP packet (200 OK) to the user 
indicating itself as media endpoint instead of the Asterisks.

 From that moment I see RTP packets flowing from the client to OpenSER

This seems really strange to me because I just copied the same 
configurations file from a working setup to the new installation.

Tnx in advance for help.

Regards

P.S.: Here is my openser.cfg

## $Id: ser.cfg,v 1.21.4.1 2003/11/10 15:35:15 andrei Exp $
## simple quick-start config script
#
# ----------- global configuration parameters ------------------------

#debug=3 # debug level (cmd line: -dddddddddd)
fork=yes
#log_stderror=no # (cmd line: -E)

check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
#children=4
#port=5060
fifo="/tmp/ser_fifo"

#uid=nobody
#gid=nobody

# ------------------ module loading ----------------------------------
loadmodule "/usr/lib/openser/modules/sl.so"
loadmodule "/usr/lib/openser/modules/tm.so"
loadmodule "/usr/lib/openser/modules/rr.so"
loadmodule "/usr/lib/openser/modules/maxfwd.so"
loadmodule "/usr/lib/openser/modules/usrloc.so"
loadmodule "/usr/lib/openser/modules/registrar.so"
loadmodule "/usr/lib/openser/modules/nathelper.so"
loadmodule "/usr/lib/openser/modules/textops.so"
loadmodule "/usr/lib/openser/modules/exec.so"
loadmodule "/usr/lib/openser/modules/uri.so"
loadmodule "/usr/lib/openser/modules/uri_db.so"
loadmodule "/usr/lib/openser/modules/dispatcher.so"

# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/usr/lib/openser/modules/mysql.so"
loadmodule "/usr/lib/openser/modules/auth.so"
loadmodule "/usr/lib/openser/modules/auth_db.so"

modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url", "mysql://xxx:xxx@xxx.xxx.xxx.xxx/openser")
modparam("usrloc", "timer_interval", 120)

modparam("auth_db", "calculate_ha1", 0)
modparam("auth_db", "db_url", "mysql://xxx:xxx@xxx.xxx.xxx.xxx/voip")

modparam("uri_db", "db_url", "mysql://xxx:xxx@xxx.xxx.xxx.xxx/openser")

modparam("rr", "enable_full_lr", 1)

modparam("registrar", "nat_flag", 6)
modparam("registrar", "max_expires", 3600)
modparam("registrar", "min_expires", 60)
modparam("registrar", "append_branches", 0)
modparam("registrar", "desc_time_order", 1)

modparam("nathelper", "natping_interval", 20) # Ping interval 20 s
modparam("nathelper", "ping_nated_only", 1) # Ping only clients behind NAT

modparam("dispatcher", "force_dst", 1)

# ------------------------- request routing logic -------------------

# main routing logic

route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};
if ( msg:len > max_len ) {
sl_send_reply("513", "Message too big");
exit;
};

if ( (method=="OPTIONS") || (method=="SUBSCRIBE") || (method=="NOTIFY") ) {
sl_send_reply("405", "Method Not Allowed");
exit;
}

if (!method=="REGISTER") {
record_route();
};

if ((src_ip==xxx.xxx.xxx.xxx) || (src_ip==xxx.xxx.xxx.xxx)) { # IP of Asterisks
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
exit;
};
# forward to current uri now; use stateful forwarding; that
# works reliably even if we forward from TCP to UDP
if (!t_relay()) {
sl_reply_error();
};
exit;
};

if (nat_uac_test("3")) {
if ((method=="REGISTER") || (method=="INVITE") || (method=="OPTIONS")) {
fix_nated_contact();
force_rport();
setflag(6); # Mark as NATed
}
}
# if the request is for other domain use UsrLoc
# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (method=="REGISTER") {
if (!proxy_authorize("domain", "openser_view")) {
proxy_challenge("domain", "0");
exit;
}
if (!check_to()) {
sl_send_reply("403", "Digest username and URI username do NOT match! 
Stay away!");
exit;
}

save("location");

exit;
};


if (method=="INVITE") {
if (!proxy_authorize("domain", "openser_view")) {
proxy_challenge("domain", "0");
exit;
}

if (!check_from()) {
sl_send_reply("403", "Digest username and URI username do NOT match! 
Stay away!");
exit;
}
}

# loose-route processing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
exit;
};

if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(1);
exit;
};

append_hf("P-hint: usrloc applied\r\n");
route(1);
}

route[1]
{
# ! Nathelper
if (uri=~"[@:](192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" && 
!search("^Route:")){
sl_send_reply("479", "We don't forward to private IP addresses");
exit;
};

# NAT processing of replies; apply to all transactions (for example,
# re-INVITEs from public to private UA are hard to identify as
# NATed at the moment of request processing); look at replies
t_on_reply("1");

# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP

if ((src_ip!=xxx.xxx.xxx.xxx) && (src_ip!=xxx.xxx.xxx.xxx)) { # IP of Asterisks
ds_select_dst("2", "0");
}

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

# ! Nathelper
onreply_route[1] {
# NATed transaction ?
if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
fix_nated_contact();
# otherwise, is it a transaction behind a NAT and we did not
# know at time of request processing ? (RFC1918 contacts)
} else if (nat_uac_test("1")) {
fix_nated_contact();
};
}





More information about the sr-users mailing list