[Users] SIP over TCP or TLS - Contact Header - NAT problematic

Klaus Darilion klaus.mailinglists at pernau.at
Fri Dec 1 15:06:35 CET 2006


Christophe Irles wrote:
> Hi,
> 
> If a SIP device is using TCP, to accept incoming calls it must bind on port
> 5060.

No. If it is a server, it has to bind to the port announced in the SRV 
records (of course 5060 is a good idea too).

If it is a client, it has to bind to the port announced in the Contact: 
header of the REGISTER.

> To call someone, this device must create a socket to reach the proxy on port
> 5060. The port source of this socket cannot be 5060 ! In TCP you cannot bind
> on a port and in same time using it in another socket. So the port source is
> generally chosen randomly (XYZ)

Usually, the local port will be an ephemeral port.

But AFAIK it would also be possible to specify the local port which 
should be used, although this is usually not used.

> Now that all sockets and bind are done, what are the correct info used to
> create the Contact header ?

Example: client listens on tcp port 5060, and client created TCP 
connection to server (for REGISTER) from port 4321.

The client can use port 5060. But this works only if the client is not 
behind NAT.

The client can also use port 4321. In this case, the client has to 
ensure that the TCP connection keeps established also after the 
registration.

> For me, the port used in the contact header in this case must be 5060 since
> the device accepts incoming calls on this port and never XYZ.

That is a bad implemented client. The client should also accept messages 
on the TCP port XYZ. Which client do you use? minisip? It works with 
minisip.

> But in a NAT context, if this SIP device is behind a NAT, the port 5060
> cannot be used to reach it ! It's necessary to reuse the socket previously
> opensed to reach it.

correct.

> So in conclusion, the Contact header must be set with 5060 by the device and

if the client is behind NAT it is meaningless to put 5060 into the 
contact header.

> on the proxy side, if the client is detected behind a NAT, this Contact
> header is modified to used instead XYZ

There are 2 methods to handle this situation:

1. Either the client is intelligent (like eyebeam): Establish TCP 
connection. Send REGISTER (contact includes local socket). Wait for 200 
OK. Check rport and received parameter in Via header. If it is different 
to the registered contact then unregister this contact and reregister 
with the contact learned from the Via header. Of course the reregister 
must be done in the same TCP connection. The client also sends keep 
alive (CRLF) and if the TCP connection gets broken, the above process 
restarts: new TCP connection, unregister old contact, register new 
contact, learn from via header the public socket.

Although the client learned the public socket from Via header and uses 
this socket in the Contact header, the Via header is always populated 
with the local IP address.

The c= address in the SDP should be the public socket if STUN can be 
used, or the public IP if STUN can't be used.

This way the proxy can detect if the cleint is behind NAT or NAT (e.g. 
for forcing rtpproxy when the client is behind symmetric NAT).

2. The server makes the NAT traversal. This is the same as when using 
UDP. fix_nated_register (for REGISTER),fix_nated_contact, and force_rport.

> Am I right ? 

Almost. I suggest to watch eyebeam's / x-lite 3.0 REGISTER when using 
TCP. This helped me a lot. This is a real smart client.
> 
> For TLS, the problem is the same but instead of 5060 it's 5061.

yes.

regards
klaus

> 
> Thanks,
> Christophe
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Users mailing list
> Users at openser.org
> http://openser.org/cgi-bin/mailman/listinfo/users


-- 
Klaus Darilion
nic.at





More information about the Users mailing list