Hm. This was a tricky one. I would like to ask a second opinion from you
NAT gurus on my musings below. What is the most appropriate response to
Ricardo's scenario? WARNING to others: This is getting fairly technical on
NAT/SDP... ;-)
The reINVITE from Asterisk has a valid IP address and a valid (but new) SDP
media ip (C=IN IP4 200.0.0.7). nat=yes is correctly not present in the
reINVITE from Asterisk (it is not NATed). Thus use_media_proxy is correctly
not used in the reINVITE, i.e. client_nat_test("3") and test on nat=yes will
not trigger under the has_totag if statement (loose route processing):
if (loose_route()) {
if (has_totag() && (method=="INVITE" || method=="ACK")) {
if (client_nat_test("3") || search("^Route:.*;nat=yes")) {
setflag(6);
use_media_proxy();
};
};
route(1);
break;
};
In the OK from the Linksys:
U 200.0.0.5:5060 -> 200.0.0.6:5060
SIP/2.0 200 OK.
To:
<sip:5555848114@sipvoiss.desarrollo.redvoiss.net>;tag=64d7492db018b13ai0.
From: "5565625858196"
<sip:5565625858196@sipvoiss.desarrollo.redvoiss.net>;tag=as5d352c9a.
Call-ID: 0848ef78297116742562204e2c04cbcb(a)sipvoiss.desarrollo.redvoiss.net.
CSeq: 104 INVITE.
Via: SIP/2.0/UDP 200.0.0.6:5060;branch=z9hG4bK518d870e.
Record-Route: <sip:200.0.0.5;ftag=as5d352c9a;lr=on>.
Contact: 5555848114 <sip:5555848114@200.0.0.4:46081>.
Server: Linksys/PAP2-2.0.10(LSb).
Content-Length: 237.
Content-Type: application/sdp.
.
v=0.
o=- 33068 33068 IN IP4 192.168.15.200.
s=-.
c=IN IP4 192.168.15.200.
t=0 0.
m=audio 16424 RTP/AVP 18 100 101.
a=rtpmap:18 G729/8000.
a=rtpmap:100 NSE/8000.
a=rtpmap:101 telephone-event/8000.
a=fmtp:101 0-15.
a=ptime:30.
a=sendrecv.
...you have 192.168.15.200, a private c= address in SDP, but the Contact has
correctly been fixed (200.0.0.4:46081). So it seems the OK is processed
correctly in onreply even though it does not show up in the debug. Flags 6
and 7 are not set, so use_media_proxy is correctly not run. The problem is
that flag 6 should have been set (the Linksys is NATed), but as the reINVITE
is not processed using lookup("location") the flag will not be picked up
from usrloc.
----------------------------------------
However, now that Asterisk in the reINVITE is requesting another (valid) IP
as media destination, the question is: what is propor behavior?
The most natural would be to add a lookup("location") after:
if (has_totag() && (method=="INVITE" || method=="ACK"))
and then add isflagset(6) to the or test:
if (isflagset(6) || client_nat_test("3") ||
search("^Route:.*;nat=yes")) {
setflag(6);
use_media_proxy();
};
However, I'm not sure the lookup will work, because the R-URI is likely to
be the direct address (5555848114@200.0.0.4:46081) and not the registered
URI (@domain.com). It would be tempting to try to see if we somehow could
make nat=yes set in the early INVITE. We would have to split the
record_route section in two. One to handle !="REGISTER &&
!="INVITE" with a
regular record_route() and wait until AFTER lookup("location") (maybe in
route[1], the default handler) to add the following:
if(method=="INVITE")){
if(isflagset(6)) {
# INSERT YOUR IP ADDRESS HERE
record_route_preset("192.0.2.13:5060;nat=yes");
} else {
record_route();
}
}
This would make sure that not only dialogs where caller is nated, but also
where callee is nated, will be tagged as nated. This again would cause
nat=yes to be set and rtp proxy forced, further flag 6 is set, and thus the
OK also processed with use_media_proxy().
BUT: Would this nat=yes cause any problems in other scenarios??? I'm not
sure, but I don't think so. If that is correct, this is maybe the right
solution.
---------------------------------------
OTHER (SIMPLER?) SOLUTIONS:
----------
Instead you could add ||client_nat_test("1") together with isflagset 6 and 7
in your reply route:
if ((isflagset(6) || isflagset(7) || client_nat_test("1")) &&
(status=~"(180)|(183)|2[0-9][0-9]"))
but it will not work because the reINVITE did not get use_media_proxy().
Or, you could instead add fix_nated_sdp("2"); in your onreply route:
if (client_nat_test("1")) {
fix_nated_contact();
fix_nated_sdp("2");
};
WARNING! You will have to add else in between this test and the previous to
avoid messing up use_media_proxy().
This will fix the SDP (c=IN IP4), but it will probably not help, because the
port is still unknown. You could use "3" instead in fix_nated_sdp, this
will add direction=active to the OK. However, another thread stated that
Asterisk does not support direction=active. If it does, it will probably
work and you get a non-proxied stream between Asterisk and the Linksys.
Or finally, the third option would be to add the (hopefully) fixed IP in the
loose_route test:
if (src_ip==200.0.0.6 || client_nat_test("3") ||
search("^Route:.*;nat=yes")) {
setflag(6);
use_media_proxy();
};
This would cause the OK automatically to get use_media_proxy.
Ricardo, could you please test these various solutions and see if they
really work or if (where...) I go wrong :-)
g-)
Ricardo Martinez wrote:
Hello Greger.
Thanks for your answer on this topic. Now i'm attaching more debug
information (the /var/log/messages from mediaproxy, the ngrep output
and some xlog statements in the ser.cfg file) beside some comments in
the file reINVITE_debug_problem.txt.
- Is your session really set up initially (before
the reINVITE)?
(mediaproxy reports 0/0/0 bytes)
At least i have ringback tone. Then, when the call is answered i
have an OK and a ACK message coming to my SER box, then inmediatly
the reINVITE message arrives Asterisk box.
For what i can see from the debug the "nat=yes" is never reached
because the caller has a "valid ip" and therefore the first "if" in
the statament
if (method=="INVITE" && client_nat_test("3")) {
# INSERT YOUR IP ADDRESS HERE
record_route_preset("64.76.148.246:5060;nat=yes");
xlog("L_INFO", "time [%Tf] RECORD ROUTE SECTION :
invite & client_nat_test(3) TRUE ,record_route_preset [%rm]\n");
} else if (method!="REGISTER") {
xlog("L_INFO", "time [%Tf] RECORD ROUTE SECTION :
record_route [%rm]\n");
record_route();
};
from the RECORD ROUTE SECTION is FALSE.
Also, i don't understand why the second OK (the one from the
reINVITE) is not procesed in the ONREPLY ROUTE, or at least i don't
see any statement from the "xlog" in the debug. Is this normal?
Thanks.!
Regards,
Ricardo Martinez.-
> -----Mensaje original-----
> De: Greger V. Teigre [mailto:greger@teigre.com]
> Enviado el: Lunes, 18 de Julio de 2005 2:45
> Para: Ricardo Martinez; serusers(a)lists.iptel.org
> Asunto: Re: [Serusers] Problem : Can SER process the reINVITE
> messages properly?
>
>
> Hi Ricardo,
> Thanks for a detailed analysis. Some questions:
- Is your session really set up initially (before
the reINVITE)?
(mediaproxy reports 0/0/0 bytes)
> - You didn't show the ngrep trace. The
script uses nat=yes in
> the Route
> header of the INVITE to detect a nat'ed client. Can you
> verify that the
> reINVITE has the nat=yes?
> - You haven't showed the mediaproxy log (it will show the
> callers reporting
> in etc). That could help (default /var/log/messages)
> - You can put a log statement in the loose_route section
> after the test for
> nat=yes to see if use_media_proxy was called
>
> g-)
>
> Ricardo Martinez wrote:
>> Hello.
>> I'm having problems trying to make SER, NAT'd endpoints
> and reINVITE
>> work together.
>> I was using the "gw-pstn3.07.cfg" file from
onsip.org to do some
>> tests, and this is what i have. In one side i have an Asterisk with
>> an endpoint registered in it (let's call it A). In the other side i
>> have a PAP2 under NAT (let's call it B).
>>
>>
>> A ---------- Asterisk ----------- SER ----------- B (NAT'd)
>> 200.0.0.7 200.0.0.6 200.0.0.5
>> 10.0.0.4
>>
>> When i make a call from "A" to "B" this is what i see (in
terms of
>> SDP). Looking from SER.
>>
>> A --------- Asterisk ------------ SER ------------ B (NAT'd)
>> Public:
>> 200.0.0.4
>> 200.0.0.7 200.0.0.6 200.0.0.5
> Inside:
>> 10.0.0.1
>>
>> INVITE
>> c:200.0.0.6:19996
>> ------------------->
>> INVITE
>> c:200.0.0.5:35010
>> ---------------->
>>
>>
>> Caller Via Called Status
>> Duration Codec Type Traffic
>>
> --------------------------------------------------------------
> ------------
>> 200.0.0.6:19996 - 200.0.0.5:35010 - ?.?.?.?:? inactive 0'04"
>> Unknown Audio 0/0/0
>>
>> Total traffic: 0bps/0bps/0bps (in1/in2/out)
>> Session count: 1
>>
>> So far is ok..........and the phone is answered
>> OK
>> c:10.0.0.1:16440
>> <---------------- (the phone is
>> answered)
>> OK
>> c:200.0.0.5:35010
>> <---------------------
>>
>> reINVITE
>> c:200.0.0.7:19996
>> --------------------->
>> reINVITE
>> c:200.0.0.7:19996
>> ---------------->
>>
>> OK
>> c:10.0.0.1:16440
>> <----------------
>> OK
>> c:10.0.0.1:16440
>> <---------------------
>>
>> Finally according to the "session" information :
>>
>> Caller Via Called
>> Status Duration Codec Type Traffic
>>
> --------------------------------------------------------------
> --------------
>> ----------
>> 200.0.0.6:19996 - 200.0.0.5:35010 - 200.0.0.7:16420 inactive
>> 0'26" G729 Audio 0/11.48k/11.48k
>>
>> Total traffic: 0bps/0bps/0bps (in1/in2/out)
>> Session count: 1
>> And the audio is only in one way. :(
>>
>> So. you can see the reINVITE message apparently is not being
>> processed as a call to a NAT'd endpoint and therefore is not using
>> the mediaproxy, you can see the second "OK" messsage has the invalid
>> IP from the NAT'd user is in his sdp information.
>> As i said it before i am using the gw-pstn configuration
> file from the
>>
onsip.org and as far as i can remember this configuration can handle
>> the reINVITE? isn't
>> I'm also using the last version of the mediaproxy (1.3.1).
>> Can someone tell me what i'm doing wrong?
>>
>> Hope someone could help me here.
>> Thanks in advance.
>> Regards...
>>
>> Ricardo Martinez.-
>>
>> _______________________________________________
>> Serusers mailing list
>> serusers(a)lists.iptel.org
>>
http://lists.iptel.org/mailman/listinfo/serusers