Matt,
I prefer that you copy the serusers lists. This way more people will benefit
from problems that others have had.
To understand this, you must understand what happens in if(!t_relay()): You
are actually relaying (or transfering) the call based on the processing you
have done so far. If the call fails, it's an error where you never reached
the onrepl_route (and not as you log: "Call NOT in usrloc"). Any answer from
the party you relayed to should be sent back, i.e.:
if (!t_relay()) {
sl_reply_error();
break;
};
Suggested example:
1. In your main route section, add something like this:
# Username part is our number range, route locally
if (uri=~"sip:[0-9]*@sipout\.netlogic\.net") {
route(1);
break;
};
2. Add a route 1 starting with:
if (!lookup("location")) {
log(1,"Not found in location");
sl_send_reply("404", "Not found");
break;
};
3. Then do your test on isflagset()/force proxy, set t_on_reply for handling
replies, and THEN call t_relay()
The best is to handle groups of requests together, i.e. your route 1 should
handle all local and inbound traffic. The test in item 1 above should then
match all calls from PSTN destined for your users. You may add a test for
src_ip or rewrite the uri.
Hope this helps. Ser's config script is very powerful and I think you
should think in terms of programming and flowcharts when designing a script,
not as a config file like the cfg extension implies.
g-)
Matt Schulte wrote:
I did have a followup question, if I may.. I can't
figure out how I
would do call routing with small IAD's (such as grandstream's,
sipura's, snom200). Basically we're going to be sending everything to
PSTN, no "internet" type routing. So our outbound calls are going to
look like this:
6365551212(a)proxy.netlogic.net
Incoming calls will also be phone number style:
6364444141(a)proxy.netlogic.net
As you may or may not tell, this is a problem. I'm trying to figure
out a way to route these calls in SER and am having no luck. This is
my "routing" line:
if (!t_relay()) {
log(1, "LOG: Call NOT in usrloc\n");
} else if (uri=~"^sip:[0-9]*@sipout\.netlogic\.net") { # ...
forward to gateways then;
forward(206.80.76.158, 5060);
log(1, "LOG: Tapping rowlf\n");
break;
}
As you can see I tried an alternate address to route the calls, what
happens is it creates a routing loop. If I try a METHOD==INVITE, then
the NAThelper stuff breaks (per my last problem). Any suggestions? I
was trying to make my sipura/snom send out as sipout.* but I can't
seem to figure out how to make them do that.
Thanks I hope this makes sense :/
Matt
-----Original Message-----
From: Greger V. Teigre [mailto:greger@teigre.com]
Sent: Monday, November 22, 2004 7:18 AM
To: Matt Schulte
Subject: Re: [Serusers] NATHelper + usrloc (+ rtpproxy?)
Good to hear! The uri==myself should have nothing to do with the
client.
It is a test for evaluating whether to To (uri) is destined for your
server.
The alias= statments at the beginning of ser.cfg will be used to
determine
this. The alias lookup will potentially change the uri, so it is
often used
to detect if the INVITE is still for this server or should be
forwarded. Regards, Greger
Matt Schulte wrote:
This is working now, I had my
t_relay/forward's below the t_on_reply
but they didn't work. I went back to the default nathelper.cfg and it
seems to work. Also to note, for some reason asterisk, sipura's, and
grandstream's don't seem to work with any uri==myself statements.
Even
if you debug sip it'll show it's going to
the proper address.
Thanks.
-----Original Message-----
From: Greger V. Teigre [mailto:greger@teigre.com]
Sent: Friday, November 19, 2004 6:21 AM
To: serusers(a)lists.iptel.org
Subject: Re: [Serusers] NATHelper + usrloc (+ rtpproxy?)
Hi Matt,
When a non-NATed incoming call to a NATed client is processed
(INVITE), you must make sure that you have a t_on_reply("1"); before
you call t_relay (or forward). The INVITE will not be detected as
behind a NAT, but the destination is (flag is set), and the reply
will
take care of the rewrite.
In your config, it looks like you call t_relay before setting
t_on_reply("1"); further down. A forward will only forward the SIP
INVITE to another SIP proxy for processing.
Paul (Java Rockx) just recently posted his config file with a
working NAThelper/RTPproxy setup. I suggest you look at the call
logic
found there. His config is also easy to read with
a lot of nice
headers I haven't tested RTP proxy between a client behind NAT and
Asterisk, but I believe that as long as you record-route the INVITE
(as you do) and handle the replies properly, it should work.
g-)
Matt Schulte wrote:
> Another note to this, I moved my 'forward' and lookup statements
> down
> below the t_onreply statement. I figured this
should allow ser to
> see
>> that the client is in fact behind a NAT. It catches that now
>> however
> I see
this in my debug (ser):
>
> ser[21770]: transaction was sent to a NATED client -> fix nated
> contact ser[21770]: ERROR: on_reply processing failed
>
> Could the last error be a/the problem? Come on I know someone else
> has had this problem. Please help!
> NOTE: I just tested this out on Asterisk (as a client behind NAT)
> and
> got the same results. It's simply not
changing the RTP IP address..
>
> --snippet--
>
> onreply_route[1] {
> # NATed transaction ?
> if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
> log(1, "transaction was sent to a NATED client -> fix nated
> contact\n");
> fix_nated_contact();
> force_rtp_proxy();
> # 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();
> };
>
>
> -----Original Message-----
> From: Matt Schulte
> Sent: Thursday, November 18, 2004 8:09 AM
> To: serusers(a)lists.iptel.org
> Subject: [Serusers] NATHelper + usrloc (+ rtpproxy?)
>
>
> All,
>
> This is my first post to this list so go easy on me. :-) I'm rather
> new to Ser, in fact I just installed it for the first time early in
> the week. I'm working on the NAThelper module to get traversal
> working, I have outbound (sip phone -> NATout -> ser) working just
> peachy, RTP works in both directions hooray. The question is I'm
> having problems getting RTP inbound, the ring of course goes
> through,
> and RTP from the NAT'd side of course
works fine however getting
> back
>> through the NAT (from outside) for RTP in this sense fails. Let me
>> explain the setup:
>>
>> I'm using the registrar, NAThelper, usrloc, and of course
>> (Portaone's) RTPproxy modules. The current SIP phone is an SNOM
>> (yes
>> yes, I know..). The "endpoint"
is Asterisk. When I do a sip debug
>> on
>> Asterisk, I see the RTP request however
it's coming from the NAT'd
>> fake address:
>>
>> v=0
>> o=root 780961119 780961119 IN IP4 192.168.1.101
>> s=call
>> c=IN IP4 192.168.1.101
>> t=0 0
>> m=audio 10004 RTP/AVP 0
>> a=rtpmap:0 pcmu/8000
>> a=sendrecv
>>
>>
>> I have an idea of what to fix just not sure how to fix it.
>> Obviously
> we
need it to goto RTPproxy, since this is "backwards" how would I
> get it to recognize the correct IP?
>
> See my config below, most of it is ripped off of the NAThelper.cfg
> example. :-) Thanks all..
>
> NOTE: All calls are destined for ${SIPDOMAIN}, in this case, the
> machines hostname. This is normal and intentional :-)
>
> # ---- SNIPPAGE ----
> modparam("rr", "enable_full_lr", 1)
>
> # !! Nathelper
> modparam("registrar", "nat_flag", 6)
> modparam("nathelper", "natping_interval", 30) # Ping interval 30
s
> modparam("nathelper", "ping_nated_only", 1) # Ping only
clients
> behind NAT
> # 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");
> break;
> };
> if (msg:len >= max_len ) {
> sl_send_reply("513", "Message too big");
> break;
> };
> # !! Nathelper
> # Special handling for NATed clients; first, NAT test is
> # executed: it looks for via!=received and RFC1918
> addresses # in Contact (may fail if line-folding is used);
> also, # the received test should, if completed, should
> check all # vias for rpesence of received
> if (nat_uac_test("3")) {
> # Allow RR-ed requests, as these may indicate that
> # a NAT-enabled proxy takes care of it; unless it
> is # a REGISTER
> log("LOG: Caught uac test 3 \n");
> if (method == "REGISTER" || !
> search("^Record-Route:")) {
> log("LOG: Someone trying to register from
> private
> IP, rewriting\n");
>
> # This will work only for user agents that
> support symmetric
> # communication. We tested quite many of them
> and
> majority is
> # smart enough to be symmetric. In some phones
> it
> takes a configuration
> # option. With Cisco 7960, it is called
> NAT_Enable=Yes, with kphone it is
> # called "symmetric media" and "symmetric
> signalling".
>
> fix_nated_contact(); # Rewrite contact with
> source IP of signalling
> if (method == "INVITE") {
> log("LOG: fix nated sdp\n");
> fix_nated_sdp("1"); # Add direction=active
> to
>> SDP
>> };
>> force_rport(); # Add rport parameter to topmost
>> Via setflag(6); # Mark as NATed
>> };
>> };
>>
>> # we record-route all messages -- to make sure that
>> # subsequent messages will go through our proxy; that's
>> # particularly good if upstream and downstream entities
>> # use different transport protocol
>> if (!method=="REGISTER") record_route();
>>
>> # subsequent messages withing a dialog should take the
>> # path determined by record-routing
>> if (loose_route()) {
>> # mark routing logic in request
>> append_hf("P-hint: rr-enforced\r\n");
>> route(1);
>> break;
>> };
>>
>> if (!uri==myself) {
>> # mark routing logic in request
>> append_hf("P-hint: outbound\r\n");
>> route(1);
>> break;
>> };
>>
>>
>> if (uri==myself) {
>>
>> if (method=="REGISTER") {
>> log("LOG: Caught register, registering user
>> in local db\n");
>> save("location");
>> break;
>> };
>>
>> lookup("aliases");
>> if (!uri==myself) {
>> append_hf("P-hint: outbound alias\r\n");
>> route(1);
>> break;
>> };
>> log("LOG: Caught uri myself\n");
>> # native SIP destinations are handled using our
>> USRLOC DB
>> #if (!lookup("location")) {
>> # sl_send_reply("404", "Do what now");
>> # break;
>> #};
>> };
>> 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");
>> break;
>> };
>> # if client or server know to be behind a NAT, enable relay
>> if (isflagset(6)) {
>> log("LOG: Caught NAT flag 6 forcing rtp proxy\n");
>> force_rtp_proxy();
>> };
>> if (method=="REGISTER") {
>> break;
>> log("LOG: Caught Register down in our call routing,
>> breaking\n");
>> };
>>
>> #### Below is mostly my own doing ####
>> if (method=="INVITE") {
>> log("LOG: Caught INVITE \n");
>> if (lookup("location")) {
>> log ("LOG: Caught registered invite,
>> sending
>>> there\n");
>>> # NOTE forcing rtp maybe bad idea for ALL
>>> users, this is
>>> # a quick fix (which doesn't work anyway!)
>>> #force_rtp_proxy();
>>> #forward(uri:host, uri:port); #nor does
>>> this t_relay();
>>> break;
>>> } else if (uri=~"^sip:[0-9]*@") { # ... forward to
>>> asterisk;
>>> forward(xxx.xxx.xxx.xxx, 5060);
>>> log("LOG: Tapping rowlf\n");
>>> break;
>>> };
>>> };
>>> #### ####
>>>
>>> t_on_reply("1");
>>>
>>> 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();
>>> force_rtp_proxy();
>>> # 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();
>>> };
>>> }
>>>
>>> _______________________________________________
>>> Serusers mailing list
>>> serusers(a)lists.iptel.org
http://lists.iptel.org/mailman/listinfo/serusers