[SR-Users] Problem with NAT and RTPProxy

Pavel Segeč Pavel.Segec at fri.uniza.sk
Mon Nov 14 18:58:40 CET 2011


Hi, 

 

from your topology description I'm not sure why you are trying to use RTPproxy when all your equipments are on private segments. RTPproxy should have an public IP address

 

palo

 

From: sr-users-bounces at lists.sip-router.org [mailto:sr-users-bounces at lists.sip-router.org] On Behalf Of David Candamil Santos
Sent: Monday, November 14, 2011 6:50 PM
To: sr-users at lists.sip-router.org
Subject: [SR-Users] Problem with NAT and RTPProxy

 

Hi, I am using Kamailio 3.2.0 (x86_64/linux) and since some days ago I am trying to call from a network with NAT to outside. This is the configuration:

 

Softphone (192.168.0.5) <--> Kamailio (192.168.0.3) <--> Router (192.168.0.1) <--> Softphone over smartphone

 

All the router ports are opened and redirected to 192.168.0.3. I have installed rtpproxy 1.2.1-1 with the following configuration:

 

--------------------------/etc/defaults/rtpproxy--------------------------------

# The control socket.

#CONTROL_SOCK="unix:/var/run/rtpproxy/rtpproxy.sock"

# To listen on an UDP socket, uncomment this line:

CONTROL_SOCK=udp:127.0.0.1:22222

 

# Additional options that are passed to the daemon.

EXTRA_OPTS="-l candamil.dyndns.org"

----------------------------------------------------------------------------------------

 

and works properly. This is the log message:

 

----------------------------------------------------------------------------------------------

Nov 12 20:09:13 condor kamailio[7001]: INFO: rtpproxy [rtpproxy.c:1415]:

rtp proxy <udp:127.0.0.1:22222> found, support for it enabled

-----------------------------------------------------------------------------------------------

 

 

Both softphones are "linphone". The configuration of the network softphone is the following:

 

SIP identity: sip:1001 at 192.168.0.3 <mailto:sip%3A1001 at 192.168.0.3> 

SIP proxy: sip:192.168.0.3

Direct connection to the Internet.

 

In the softphone of the smartphone I set as proxy and domain "candamil.dyndns.org", the DNS address of my router IP.

 

In this case, these are the symptoms:

Both softphones can autentify correctly. When calling, both softphones ring, but when I answer, the voice signal is not received. This is the log error:

 

----------------------------------------------------------------------------------------------

Nov 12 20:23:14 condor kamailio[6991]: ERROR: rtpproxy [rtpproxy.c:2260]:

incorrect port 0 in reply from rtp proxy

----------------------------------------------------------------------------------------------

 

 

The same happens if I set in the network softphone that it's behind NAT, and I set the router IP.

The same happens if I set in the network softphone that it's behind NAT and with a STUN server (stunserver.org). In the three cases, in the softphone over smartphone, the caller is 1001 at 192.168.0.3, and in the network softphone, the caller is 1002 at candamil.dyndns.org.

 

If I set in the network softphone the proxy as sip:candamil.dyndns.org <http://candamil.dyndns.org/> , the same happens.

If what I do is setting the SIP identity as  sip:1001 at candamil.dyndns.org <mailto:sip%3A1001 at candamil.dyndns.org> , when calling form inside to ouside the network, the softphone doesn't know that the call was answered, and there is the following error in the log:

 

----------------------------------------------------------------------------------------------------------

Nov 12 20:53:00 condor kamailio[7306]: ERROR: <core>

[parser/parse_via.c:2600]: ERROR: parse_via: invalid port number

<5060ranch=z9hG4bKc

50f.b4825246.0>

Nov 12 20:53:00 condor kamailio[7306]: ERROR: <core>

[parser/parse_via.c:2629]: ERROR: parse_via on: <SIP/2.0/UDP

192.168.0.3:5060ranch=z

9hG4bKc50f.b4825246.0;received=87.223.138.84#015# <tel:87.223.138.84%23015%23> 012Via: SIP/2.0/UDP

87.223.138.84:5060;rport=5060;branch=z9hG4bK1021772993#015#012From:

<sip:1001 at candamil.dyndns.org <mailto:sip%3A1001 at candamil.dyndns.org> >;tag=783852345#015#012To: <

sip:1002 at candamil.dyndns.org <mailto:sip%3A1002 at candamil.dyndns.org> >#015#012Call-ID: 1644787160#015#012CSeq: 21

INVITE#

015#012User-Agent: Linphone/3.4.0 (eXosip2/unknown)#015#012Content-Length:

0#015#012#015#012>

------------------------------------------------------------------------------------------------------------

 

If the call is from outside to inside the network, it happens the same than in the previous cases.

 

This is the relevant kamailio configuration:

 

-----------------------------------------kamailio.cfg----------------------------------------------------

#!define WITH_MYSQL

#!define WITH_AUTH

#!define WITH_NAT

 

####### Defined Values #########

 

# *** Value defines - IDs used later in config

#!ifdef WITH_MYSQL

# - database URL - used to connect to database server by modules such

#       as: auth_db, acc, usrloc, a.s.o.

#!define DBURL "mysql://openser:openserrw@localhost/openser"

#!endif

#!ifdef WITH_MULTIDOMAIN

# - the value for 'use_domain' parameters

#!define MULTIDOMAIN 1

#!else

#!define MULTIDOMAIN 0

#!endif

 

# - flags

#   FLT_ - per transaction (message) flags

# FLB_ - per branch flags

#!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 #########

/* uncomment the next line to disable the auto discovery of local aliases

  based on reverse DNS on IPs (default on) */

#auto_aliases=no

 

/* add local domain aliases */

alias="candamil.dyndns.org"

 

/* port to listen to

 * - can be specified more than once if needed to listen on many ports */

port=5060

 

#!ifdef WITH_TLS

enable_tls=yes

#!endif

 

# life time of TCP connection when there is no traffic

# - a bit higher than registration expires to cope with UA behind NAT

tcp_connection_lifetime=3605

 

####### Custom Parameters #########

 

#!ifdef WITH_PSTN

# PSTN GW Routing

#

# - pstn.gw_ip: valid IP or hostname as string value, example:

# pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"

#

# - by default is empty to avoid misrouting

pstn.gw_ip = "" desc "PSTN GW Address"

#!endif

 

####### Modules Section ########

 

#!ifdef WITH_MYSQL

loadmodule "db_mysql.so"

#!endif

 

#!ifdef WITH_AUTH

loadmodule "auth.so"

loadmodule "auth_db.so"

 

#!ifdef WITH_NAT

loadmodule "nathelper.so"

loadmodule "rtpproxy.so"

#!endif

 

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

 

# ----- auth_db params -----

#!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_NAT

# ----- rtpproxy params -----

modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:22222")

 

# ----- 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 <mailto:sip%3Apinger 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

 

####### Routing Logic ########

 

 

# Main SIP request routing logic

# - processing of any incoming SIP request starts with this route

# - note: this is the same as route { ... }

request_route {

 

# per request initial checks

route(REQINIT);

 

 # NAT detection

route(NATDETECT);

 

# handle requests within SIP dialogs

 route(WITHINDLG);

 

### only initial requests (no To tag)

 

 # CANCEL processing

if (is_method("CANCEL"))

{

 if (t_check_trans())

t_relay();

exit;

 }

 

t_check_trans();

 

# authentication

 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

}

 

# dispatch requests to foreign domains

route(SIPOUT);

 

 ### requests for my local domains

 

# handle presence related requests

 route(PRESENCE);

 

# handle registrations

route(REGISTRAR);

 

if ($rU==$null)

{

# request with no Username in RURI

 sl_send_reply("484","Address Incomplete");

exit;

}

 

# dispatch destinations to PSTN

route(PSTN);

 

 # user location service

route(LOCATION);

 

route(RELAY);

}

 

 

route[RELAY] {

 

# enable additional event routes for forwarded requests

# - serial forking, RTP relaying handling, a.s.o.

 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;

}

 

# Per SIP request initial checks

route[REQINIT] {

#!ifdef WITH_ANTIFLOOD

# flood dection from same IP and traffic ban for a while

 # be sure you exclude checking trusted peers, such as pstn gateways

# - local host excluded (e.g., loop to self)

 if(src_ip!=myself)

{

if($sht(ipban=>$si)!=$null)

 {

# ip is already blocked

xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");

 exit;

}

if (!pike_check_req())

 {

xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");

 $sht(ipban=>$si) = 1;

exit;

}

 }

#!endif

 

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()) {

# sequential request withing a dialog should

 # take the path determined by record-routing

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() ) {

 # no loose-route, but stateful ACK;

# must be an ACK after a 487

# or e.g. 404 from upstream server

 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] {

 

#!ifdef WITH_SPEEDIAL

# search for short dialing - 2-digit extension

 if($rU=~"^[0-9][0-9]$")

if(sd_lookup("speed_dial"))

route(SIPOUT);

#!endif

 

#!ifdef WITH_ALIASDB

# search in DB-based aliases

if(alias_db_lookup("dbaliases"))

 route(SIPOUT);

#!endif

 

$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;

 

#!ifdef WITH_PRESENCE

if (!t_newtran())

{

sl_reply_error();

 exit;

};

 

if(is_method("PUBLISH"))

 {

handle_publish();

t_release();

 }

else

if( is_method("SUBSCRIBE"))

 {

handle_subscribe();

t_release();

 }

exit;

#!endif

 # 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;

}

#!ifdef WITH_MULTIDOMAIN

if ($fd!=$rd) {

 sl_send_reply("403","Forbidden R-URI domain");

exit;

 }

#!endif

} else {

if ($au!=$fU) {

 sl_send_reply("403","Forbidden auth ID");

exit;

 }

}

 

consume_credentials();

 # caller authenticated

} else {

# caller is not local subscriber, then check if it calls

 # 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);

}

}

 

# PSTN GW routing

route[PSTN] {

#!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;

 }

 

# route to PSTN dialed numbers starting with '+' or '00'

 #     (international format)

# - update the condition to match your dialing rules for PSTN routing

 if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))

return;

 

 # only local users allowed to call

if(from_uri!=myself) {

sl_send_reply("403", "Not Allowed");

 exit;

}

 

$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);

 

route(RELAY);

exit;

#!endif

 

return;

}

 

# XMLRPC routing

#!ifdef WITH_XMLRPC

route[XMLRPC] {

# allow XMLRPC from localhost

if ((method=="POST" || method=="GET")

 && (src_ip==127.0.0.1)) {

# close connection only for xmlrpclib user agents (there is a bug in

 # xmlrpclib: it waits for EOF before interpreting the response).

if ($hdr(User-Agent) =~ "xmlrpclib")

 set_reply_close();

set_reply_no_connect();

dispatch_rpc();

 exit;

}

send_reply("403", "Forbidden");

 exit;

}

#!endif

 

# route to voicemail server

route[TOVOICEMAIL] {

#!ifdef WITH_VOICEMAIL

 if(!is_method("INVITE"))

return;

 

# check if VoiceMail server IP is defined

 if (strempty($sel(cfg_get.voicemail.srv_ip))) {

xlog("SCRIPT: VoiceMail rotuing enabled but IP not defined\n");

 return;

}

if($avp(oexten)==$null)

 return;

 

$ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)

 + $sel(cfg_get.voicemail.srv_port);

route(RELAY);

exit;

#!endif

 

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

}

--------------------------------------------------------------------------------------------------------------

 

 

I hope you can help me. Thanks for your time.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20111114/fbe6944d/attachment-0001.htm>


More information about the sr-users mailing list