[SR-Users] Nathelper module, FLT_NATS, FLT_NATB

Klaus Darilion klaus.mailinglists at pernau.at
Fri Jun 22 10:07:42 CEST 2012


Hi Richard!

On 22.06.2012 01:33, Richard Brady wrote:
> Hi folks
>
> I've configured Kamailio as a simply multi-homed proxy offering NAT
> traversa, TCP connection management, etc to FreeSWICH behind it.
> FreeSWITCH acts as the registrar.
>
> I'm trying to understand the default config and the following things
> don't make sense to me (I can't find documentation on these):
>
> 1. The nat=yes flag. What does it mean exactly and why is it on the RR
> and not on the Contact/R-URI? Also, when double RR is enabled, why does
> it get added to both headers?

Kamailio is not dialog-stateful. Thus, when routing an in-dialog 
request, Kamailio does not know if a media-relay was activated with the 
initial INVITE. Thus, a "record-route cookie" is used to store the 
information for the whole dialog.

The proper location (contact or RR) depends on the exact meaning of 
nat=yes, e.g. it only signal if a media relay is used or also if the 
client needs NAT-traversal for SIP. In the first case it is a property 
of the call, in the later case it is a property of the caller/callee. 
Thus, in the later the contact/RURI would be fine too - but there are 
also other aspects: for example a call is routed via 2 SIP providers. If 
both store data in the contact/RURI, then both use the same data 
location and may confuse the other SIP proxy. If you store the cookie in 
the RR/Route header, then the cookie will only be interpreted by the 
proxy which inserted the cookie.

Regarding RR: This is just an implementation thing. IIRC the topmost RR 
is just ignored and the second (which is relevant as it defines the 
outgoing socket) is used - but depending of the direction of the request 
you need the cookie in both Route headers.

Thus, as you see there is not a single "correct" version to do it, but 
this one seems to work fine.

In the early days I had an "academic" approach and activated 
NAT-traversal (RTP and SIP) only when really needed and stored the data 
more detailed using for example: nat=both, nat=caller, nat=callee and 
nat=none. It was nice and worked - but nowadays I choose the pragmatic 
approach: always enforce NAT-traversal for SIP (never trust any data 
provided by the client) and always activate a media relay (less support 
calls for customers with strange NAT routers and possibility for legal 
intercept). Thus, in a pragmatic approach the parameter is not needed 
anymore.

> 2. The FLT_NATS and FLB_NATB flags. I'd like to know what this stands
> for, I guess "flag for transaction - NAT" and "flag for branch - NAT"
> but what do the S and the B stand for? More importantly what do these

IIRC:
s....script
b....branch

> flags mean? Is it correct to say that the first indicates the UAC /
> A-leg / requester is behind NAT and the second that the UAS / B-leg /
> responder is behind NAT?

yes. There can be multiple Bs (forking), thus the NAT information must 
be stored in a branch-flag.

> 3. In the the NATMANAGE route of the default config we have:
>
>          if (is_request()) {
>                  if(has_totag()) {
>                          if(check_route_param("nat=yes")) {
>                                  setbflag(FLB_NATB);
>                          }
>                  }
>          }
>
> Which to me means "if the message is a request inside an existing dialog
> ..." and I'm thinking, isn't this a bit late in the dialog to be setting
> NAT flags?

No. The idea is to make NAT checks on the first INVITE, then store the 
results in RR-cookies. During in-dialog requests you rely on the cookies.

 > I would expect to set the flag for the A-leg on the incoming
> request, and the flag for the B-leg on the incoming reply. I can't point
> in waiting for the ACK to try and work out whether this leg is behind
> NAT. And also it seem this set of if statements will also match incoming
> requests from the A-leg, so why are we setting a brach flag? Does that
> leg also also get the properties of a branch?

For in-dialog requests it is not about A (caller) and B (callee) but 
more about "sender of the request" and "receiver of the request". I 
guess in this case it is setting the branch-flag as the existing logic 
for NAT traversal (during inital INVITE) is triggered on this certain 
branch flag. Thus, by setting this specific branch flag the existing 
code can be reused for in-dialog requests.

> 4. When I get a 200 OK coming from behind NAT it is not subjected to
> fix_nated_contact(), and this seems to be because it doesn't have the
> FLB_NATB flag set:
>
>          if (is_reply()) {
>                  if(isbflagset(FLB_NATB)) {
>                          fix_nated_contact();
>                  }
>          }

When processing the initial INVITE, the lookup() function returns the 
destination addresses of all Bs and if these Bs need NAT traversal (by 
setting the FLB_NATB flag for the respective branches. This flag is also 
available during response processing. And if set, the contact will be fixed.

Thus, if the clients needs NAT traversal, but NAT traversal is not done, 
this indicates that the FLB_NATB flag was not set for this client during 
lookup(), which indicates that the NAT flag was not set when the save() 
function was called which indicates that the NAT-detection logic in 
REGISTER handling did not detected that NAT traversal is needed.

regards
Klaus



More information about the sr-users mailing list