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@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 }
Hello,
is Asterisk supposed to forward the video stream as well? When you mean Asrerisk has only local address, means its address is not routable from the sip clients, right? If yes, have you set rtpproxy in bridged mode?
A ngrep trace of the sip signaling for a call which does not work would be useful to provide more details about what could be wrong there.
Cheers, Daniel
On 12/29/11 11:38 PM, Stoyan Mihaylov wrote: