[SR-Users] Problems with video behind NAT

Stoyan Mihaylov stoyan.v.mihaylov at gmail.com
Thu Dec 29 23:38:18 CET 2011


My whole configuration is:
[Sip clients] < = > Kamailio 3.2 <=> Asterisk servers (behind Kamailio)
Asterisk servers have only local IP addresses, and I use t_relay instead of
forward.
Kamailio runs on same server as rtpproxy.

Now I played lot of combinations and I have next results:
1. Clients are in same net with Kamailio server (and Asterisk server).
Client call Kamailio, Kamailio t_relay to Asterisk, Asterisk dial back to
Kamailio, and Kamailio dial Client. rtpproxy is working. Video and audio
are fine...
2. Same as above, but clients are behind NAT. Sound is perfect, no video.
3. Same as in point 1, but no rtpproxy, and no Asterisk servers. Sound and
video are perfect. With rtpproxy - no voice, no video.

I would like to find solution for point 2. Sound and video are on different
rports (seen in wireshark). As I understand, my error is either in wrong
forwarding of ACK (I do t_relay to Asterisk in case from and to addresses
are same), or may be I have to find correct FLAGS for rtpproxy_manage(), or
even replace it and place with rtpproxy_offer (answer etc).

Bellow is my kamailio.cfg:
####### Defined Values #########
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_USRLOCDB

#!define WITH_IPAUTH
#!define WITH_NAT
#!define WITH_PSTN

# *** Value defines - IDs used later in config
#!define DBURL "mysql://user:pass@192.168.2.251/openser"
#!define MULTIDOMAIN 0

#!define FLT_ACC 1
#!define FLT_ACCMISSED 2
#!define FLT_ACCFAILED 3
#!define FLT_NATS 5

#!define FLB_NATB 6
#!define FLB_NATSIPPING 7

####### Global Parameters #########

debug=3
log_stderror=no

memdbg=5
memlog=5

log_facility=LOG_LOCAL0

fork=yes
children=4

port=5060

tcp_connection_lifetime=3605
#!ifdef WITH_PSTN
pstn.gw_ip = "192.168.2.251" desc "PSTN GW Address"
#!endif


# set paths to location of modules (to sources or installation folders)
#!ifdef WITH_SRCPATH
mpath="modules_k:modules"
#!else
mpath="//lib64/kamailio/modules_k/://lib64/kamailio/modules/"
#!endif

#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif

loadmodule "mi_fifo.so"
loadmodule "kex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "mi_rpc.so"
loadmodule "acc.so"

#!ifdef WITH_AUTH
loadmodule "auth.so"
loadmodule "auth_db.so"
#!ifdef WITH_IPAUTH
loadmodule "permissions.so"
#!endif
#!endif

#!ifdef WITH_ALIASDB
loadmodule "alias_db.so"
#!endif

#!ifdef WITH_SPEEDDIAL
loadmodule "speeddial.so"
#!endif

#!ifdef WITH_MULTIDOMAIN
loadmodule "domain.so"
#!endif

#!ifdef WITH_PRESENCE
loadmodule "presence.so"
loadmodule "presence_xml.so"
#!endif

#!ifdef WITH_NAT
loadmodule "nathelper.so"
loadmodule "rtpproxy.so"
#!endif

#!ifdef WITH_TLS
loadmodule "tls.so"
#!endif

loadmodule "htable.so"
#!ifdef WITH_ANTIFLOOD
loadmodule "pike.so"
#!endif

#!ifdef WITH_XMLRPC
loadmodule "xmlrpc.so"
#!endif

#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif

# ----------------- setting module-specific parameters ---------------


loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", DBURL)
# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")


# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)


# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)


# ----- registrar params -----
modparam("registrar", "method_filtering", 1)
/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
# max value for expires of registrations
modparam("registrar", "max_expires", 3600)


# ----- acc params -----
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_ack", 0)
modparam("acc", "report_cancels", 0)
modparam("acc", "detect_direction", 0)
/* account triggers (flags) */
modparam("acc", "log_flag", FLT_ACC)
modparam("acc", "log_missed_flag", FLT_ACCMISSED)
modparam("acc", "log_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
/* enhanced DB accounting */
#!ifdef WITH_ACCDB
modparam("acc", "db_flag", FLT_ACC)
modparam("acc", "db_missed_flag", FLT_ACCMISSED)
modparam("acc", "db_url", DBURL)
modparam("acc", "db_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
#!endif
#!ifdef WITH_USRLOCDB
modparam("usrloc", "db_url", DBURL)
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "use_domain", MULTIDOMAIN)
#!endif
#!ifdef WITH_AUTH
modparam("auth_db", "db_url", DBURL)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "load_credentials", "")
modparam("auth_db", "use_domain", MULTIDOMAIN)
#!ifdef WITH_IPAUTH
modparam("permissions", "db_url", DBURL)
modparam("permissions", "db_mode", 1)
#!endif
#!endif
#!ifdef WITH_ALIASDB
modparam("alias_db", "db_url", DBURL)
modparam("alias_db", "use_domain", MULTIDOMAIN)
#!endif

# ----- speedial params -----
#!ifdef WITH_SPEEDDIAL
modparam("speeddial", "db_url", DBURL)
modparam("speeddial", "use_domain", MULTIDOMAIN)
#!endif


#!ifdef WITH_NAT
# ----- rtpproxy params -----
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")

# ----- nathelper params -----
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
modparam("nathelper", "sipping_from", "sip:pinger at kamailio.org")

# params needed for NAT traversal in other modules
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
modparam("usrloc", "nat_bflag", FLB_NATB)
#!endif


#!ifdef WITH_TLS
# ----- tls params -----
modparam("tls", "config", "//etc/kamailio/tls.cfg")
#!endif

modparam("htable", "htable", "forw=>size=8;autoexpire=7200;")


#!ifdef WITH_DEBUG
# ----- debugger params -----
modparam("debugger", "cfgtrace", 1)
#!endif

request_route {
xlog("L_ALERT","Pakage $rm from $fu (IP:$si:$sp)\n");
# per request initial checks
route(REQINIT);

# NAT detection
route(NATDETECT);
route(ACKBYE);

# handle requests within SIP dialogs
route(WITHINDLG);
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
route(AUTH);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# account only INVITEs
if (is_method("INVITE"))
{
setflag(FLT_ACC); # do accounting
}
route(SIPOUT);
route(PRESENCE);
route(REGISTRAR);
if ($rU==$null)
{
sl_send_reply("484","Address Incomplete");
exit;
}
route(PSTN);
route(LOCATION);
route(RELAY);
}

route[RELAY] {
if (is_method("INVITE|SUBSCRIBE")) {
t_on_branch("MANAGE_BRANCH");
t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
t_on_failure("MANAGE_FAILURE");
}
if (!t_relay()) {
sl_reply_error();
}
exit;
}

route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}

if(!sanity_check("1511", "7"))
{
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
}

# Handle requests within SIP dialogs
route[WITHINDLG] {
if (has_totag()) {
if (loose_route()) {
if (is_method("BYE")) {
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
}
if ( is_method("ACK") ) {
# ACK is forwarded statelessy
route(NATMANAGE);
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(PRESENCE);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
t_relay();
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}
}

# Handle SIP registrations
route[REGISTRAR] {
if (is_method("REGISTER"))
{
if(isflagset(FLT_NATS))
{
setbflag(FLB_NATB);
# uncomment next line to do SIP NAT pinging
## setbflag(FLB_NATSIPPING);
}
if (!save("location"))
sl_reply_error();
exit;
}
}

# USER location service
route[LOCATION] {
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
route(TOVOICEMAIL);
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
# when routing via usrloc, log the missed calls also
if (is_method("INVITE"))
{
setflag(FLT_ACCMISSED);
}
}

# Presence server route
route[PRESENCE] {
if(!is_method("PUBLISH|SUBSCRIBE"))
return;
 # if presence enabled, this part will not be executed
if (is_method("PUBLISH") || $rU==$null)
{
sl_send_reply("404", "Not here");
exit;
}
return;
}

# Authentication route
route[AUTH] {
#!ifdef WITH_AUTH
if (is_method("REGISTER"))
{
# authenticate the REGISTER requests (uncomment to enable auth)
if (!www_authorize("$td", "subscriber"))
{
www_challenge("$td", "0");
exit;
}

if ($au!=$tU)
{
sl_send_reply("403","Forbidden auth ID");
exit;
}
} else {

#!ifdef WITH_IPAUTH
if(allow_source_address())
{
# source IP allowed
return;
}
#!endif

# authenticate if from local subscriber
if (from_uri==myself)
{
if (!proxy_authorize("$fd", "subscriber")) {
proxy_challenge("$fd", "0");
exit;
}
if (is_method("PUBLISH"))
{
if ($au!=$fU || $au!=$tU) {
sl_send_reply("403","Forbidden auth ID");
exit;
}
if ($au!=$rU) {
sl_send_reply("403","Forbidden R-URI");
exit;
}
} else {
if ($au!=$fU) {
sl_send_reply("403","Forbidden auth ID");
exit;
}
}

consume_credentials();
# caller authenticated
} else {
# a local destination, otherwise deny, not an open relay here
if (!uri==myself)
{
sl_send_reply("403","Not relaying");
exit;
}
}
}
#!endif
return;
}

# Caller NAT detection route
route[NATDETECT] {
#!ifdef WITH_NAT
force_rport();
if (nat_uac_test("19")) {
if (is_method("REGISTER")) {
fix_nated_register();
} else {
fix_nated_contact();
}
setflag(FLT_NATS);
}
#!endif
return;
}

# RTPProxy control
route[NATMANAGE] {
#!ifdef WITH_NAT
if (is_request()) {
if(has_totag()) {
if(check_route_param("nat=yes")) {
setbflag(FLB_NATB);
}
}
}
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB)))
return;
rtpproxy_manage();
if (is_request()) {
if (!has_totag()) {
add_rr_param(";nat=yes");
}
}
if (is_reply()) {
if(isbflagset(FLB_NATB)) {
fix_nated_contact();
}
}
#!endif
return;
}

# Routing to foreign domains
route[SIPOUT] {
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
}

route[ACKBYE] {
#!ifdef WITH_PSTN
if (is_method("BYE|ACK"))
{
xlog("L_ALERT","AB $rm $sht(forw=>$ft) $td");
if(($sht(forw=>$ft))=~"MessageCPIM"){
# Direct messages between clients
xlog("L_ALERT","AB $rm CPIM $td");
return;
}
if(src_ip==$td){
#I have to rewrite du - messages loop in Kamailio
xlog("L_ALERT","ACK,Bye Method equalIP");
$du=$sht(forw=>$ft);
xlog("L_ALERT","ACK,Bye $ft $du");
route(RELAY);
exit;
}
xlog("L_ALERT","ACK,Bye Not me");
}
#!endif
return;
}
route[PSTNINVITE] {
if(is_method("INVITE")){
if($rb=~"message/CPIM"){
# Direct messages between clients
$sht(forw=>$ft)="MessageCPIM";
route(LOCATION);
route(RELAY);
}
#This way I can select from multiple Asterisk servers. I will t_relay
instead of forward, because Asterisk servers are with local IP.
ds_select_dst("1","4");
$sht(forw=>$ft)=$du;
sl_send_reply("100","Trying");
route(RELAY);
exit();
}
}
route[PSTN] {
#I am using this routine to forward to Asterisks (instead of additional one
for balancing)
#!ifdef WITH_PSTN
# check if PSTN GW IP is defined
if (strempty($sel(cfg_get.pstn.gw_ip))) {
xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n");
return;
}
if(allow_source_address())
return;
if(from_uri!=myself) {
sl_send_reply("403", "Not Allowed");
exit;
}
if(is_method("MESSAGE"))
return;
route(PSTNINVITE);
route(RELAY);
exit;
#!endif
return;
}


# route to voicemail server
route[TOVOICEMAIL] {
return;
}

# manage outgoing branches
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");
route(NATMANAGE);
}

# manage incoming replies
onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");
if(status=~"[12][0-9][0-9]")
route(NATMANAGE);
}

# manage failure routing cases
failure_route[MANAGE_FAILURE] {
route(NATMANAGE);

if (t_is_canceled()) {
exit;
}

#!ifdef WITH_BLOCK3XX
# block call redirect based on 3xx replies.
if (t_check_status("3[0-9][0-9]")) {
t_reply("404","Not found");
exit;
}
#!endif

#!ifdef WITH_VOICEMAIL
# serial forking
# - route to voicemail on busy or no answer (timeout)
if (t_check_status("486|408")) {
route(TOVOICEMAIL);
exit;
}
#!endif
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20111230/333669b1/attachment-0001.htm>


More information about the sr-users mailing list