First of all, I love these kind of discussions, the best way to learn :)
El Martes, 7 de Julio de 2009, Daniel-Constantin Mierla escribió:
--------
REGISTER - called before save_location() or t_relay() (depending on
whether the proxy that received the REGISTER is also handling
registration for that subscriber or not). It will determine from either
the stateless reply generated by save_location() or the TM relayed reply
if the registration was successful and what is its expiration time. If
the registration was successful it will mark the given NAT endpoint for
keepalive for the registration condition using the detected expiration
time. If the REGISTER request is discarded after nat_keepalive() was
called or if it intercepts a negative reply it will have no effect and
the registration condition will not be activated for that endpoint.
--------
so it duplicated info stored by the usrloc module. It is what I meant by
keeping twice information. Nathelper fetches the contact details from
usrloc.
Ok, I get you now.
However, if you don't use db_mode=0 in usrloc, then there is a MySQL query
retrieving the natted contacts from usrloc table.
nat_traversal store them always in memory (not sure if it's a better
approach).
From what seems here, definitely does not deal with
PATH extension.
Not 100% sure, but I read this in the doc:
----------------
1.7.1. $keepalive.socket(nat_endpoint)
Returns the local socket used to send messages to the given NAT endpoint URI.
The socket has the form proto:ip:port. The NAT endpoint URI is in the form:
sip:ip:port[;transport=xxx] with transport missing if UDP. If the requested
NAT endpoint URI is present in the internal keepalive table for any condition,
it will return its associated local socket, else it will return null. The
nat_endpoint can be a string or another pseudo-variable.
This can be useful to restore the sending socket when relaying messages to a
given user agent in multi-proxy environments. Consider an example where 2
proxies are involved, P1 and P2. A user agent registers by sending a REGISTER
request to P1. P1 will call nat_keepalive() but because it determines that P2
should actually handle the user registration will forward the request to P2.
Now assume P2 receives an incoming INVITE for this user. It will determine
that the registration came through P1 and will forward the request to P1. P2
should also include the NAT endpoint URI where this request is to be relayed.
This information should have been provided by P1 when it relayed the REGISTER
request to P2. The means to do this is out of the scope of this example, but
one can either use the path extension or custom headers to do this. When P1
receives the INVITE it will use the NAT endpoint URI it has received along
with the request to determine the socket to send out the request, which should
be the same as the one where the registration request was originally received.
In the example below lets assume that P2 provided the original NAT endpoint
address in a custom header called X-NAT-URI and that it also provides a custom
----------------
As you won't use nathelper, nat pings are
performed only by
nat_traversal, so if to cope with crashes of the box, you need a
replication mechanism to a backup, so registered users are reachable
when backup becomes alive, in the case of shared IP HA.
With usrloc and nathelper, that is solved, as data is stored in db or
replicated with t_replicate().
With nat_traversal there is other approach:
Use nat_keepalive() for REGISTER and INVITE. When the server 1 crashes and
server 2 begin running, it has no NAT keepalive information, but if it's
receives a call from a natted UA, it will keepalive it (INVITE).
However, it's true that it couldn't receive calls from server 2... hum...
Also, note that you need to do nat pinging from the
presence server only
when you allow subscriptions from non-registered UA (again, very corner
case). Otherwise, just having it done only by registrar is enough.
Perhaps I miss something, but how could a presence server (running behind the
proxy) perform nat keepalive just for natted users? note that SIP signalling
is NAT fixed on the proxy. Perhaps using a custom header or paremter
"nat=yes"? In any case, how would Kamailio presence server mantain the
keepalive for non registered natted subscribers?
NAT keepalive
should not
be performed by an application (SIP presence) IMHO.
SIP is an application level protocol. So the special handling should be
done by the end point that understands the message. What happens if I
send a custom request? Should the proxy perform pinging? If it is not
creating a dialog, the case of MESSAGE? Or it does, case of SUBSCRIBE?
IMHO it's clear that the only requests requiring NAT keepalive are:
- REGISTER: to receive calls.
- INVITE: to receive in-dialog requests.
- SUBSCRIBE: to receive in-dialog requests.
IMO, it is totally broken to assume things in a
router/proxy. Do it on
endpoints, like it is now with registrar.
Well, I can assume that there will not appear a new SIP method creating a
dialog in the next 5 years XD
Also, imagine
other typical case:
a) Using nathelper:
- UA behind NAT uses a domain with SRV failover (servers 1.1.1.1 and
2.2.2.2). - It sends the REGISTER to 1.1.1.1.
- Registration expires in 10 minutes.
- Proxy 1.1.1.1 mantains the keepalive.
- Proxy 1.1.1.1 crashes.
What happens if someone calls that UA right now?
(note that in this case I mean using "nathelper").
UA wouldn't receive that call even if it arrives to server 2 since server 2 (a
different IP) has no way to communicate with UA.
- UA sends an
INVITE and since 1.1.1.1 doesn't respond it sends it to
2.2.2.2.
If I am not wrong, in this case should register again, since the
previous proxy is no longer available.
What about if UA receives a 503 since the server 1 cannot route more outgoing
calls but it can route calls to users? I'm really not sure of the expected
behaviour in UA.
What happens if proxy 1.1.1.1 is restarted. Does it
restore the hash
table of natted endpoints?
Well, when Kamailio/OpenSIPS is *properly* stopped, the NAT keepalive info is
stored:
/var/run/kamailio# cat keepalive_state
# Automatically generated file from internal keepalive state. Do NOT modify!
sip:222.231.250.231:5065 udp:93.141.79.216:5062 1245776309 0
sip:222.231.250.213:5060 udp:93.141.79.216:5062 1245776051 0
sip:84.84.127.147:5061 udp:93.141.79.216:5060 1245776226 0
b) Using
nat_traversal:
- UA behind NAT uses a domain with SRV failover (servers 1.1.1.1 and
2.2.2.2). - It sends the REGISTER to 1.1.1.1.
- Registration expires in 10 minutes.
- Proxy 1.1.1.1 mantains the keepalive (REGISTER).
- Proxy 1.1.1.1 crashes.
UA is no longer reachable, maybe called party was also on 1.1.1.1.
In case of shared IP, or load balancer+PATH, it is reachable and there
is no problem with calling or being called.
Agree.
It is not clear to me that it supports proxy restart
-- I admit I havent
investigated the code nor used the module.
Yes, it does.
I simply fail to see the reason of one extra place to
store data to be
able to do to nat pings.
Well, it extends the cases in which keepalive could be required (not just
registration).
Sincerely, I
think nat_traversal provides much better NAT solutions than
the limited nathelper module.
Just your opinion. I think it is the opposite. nat_traversal limits you
to one box for good servicing, otherwise no scalability and no HA for
proper voip servicing.
Well, I promise to investigate more about it. Most probably I needed this
thread :)
Regards.
--
Iñaki Baz Castillo <ibc(a)aliax.net>