[Serusers] TCP endpoints behind NAT

Andrei Pelinescu-Onciul pelinescu-onciul at fokus.fraunhofer.de
Mon May 31 15:45:44 CEST 2004


On May 31, 2004 at 13:29, Martin Rusnak <mafo at cyberspace.sk> wrote:
> Andrei,
> 
> > > Hello
> > >
> > > I have following use case:
> > >
> > > Endpoint1 <------> NAT <------> SER <------> NAT <------> Endpoint2
> > > 10.0.0.10    TCP                                   TCP    192.168.0.4
> >
> >
> > First of all try to use UDP. NAT traversal works with UDP. Nobody really
> > tested it with TCP. Theoretically you could get it working with unstable
> > ser, special options and a well behaved UA (one that will always reuse
> > the tcp connections and will keep the nat bindings open).
> 
> I have been using UDP for kphone and it alvays works fine. But I use
> Windows Messenger too and it seems to me that the TCP is the only
> possibility to connect it from a NAT-ed network.

At least older WM version allow you to choose the protocol
(Accounts/Advanced/Connect using: ....).
> 
> > Yes, ser cannot find an open tcp connection and tries to open a new one.
> > To get arround this you should force tcp aliases and use a very high
> > timeout for the tcp connections (if a connection is not used, ser will
> > close it after some time):
> > - use  tcp_accept_aliases=yes in your ser.cfg if you have compliant UAs
> >   (I think only kphone knows about them)
> > - use force_tcp_alias(); if your UAs don't know about tcp alias.
> > - edit tcp_conn.h and change TCP_CON_TIMEOUT and TCP_CON_SEND_TIMEOUT
> >   to a very high value
> 
> I changed the constants and now the connections are permanent.
> But I still haven't solved the problem routing messages. Here is a snippet
> of code from my cfg file:
> 
> if (uri==myself) {
>   if (method=="REGISTER") {
>     # digest authentication
>     if (!www_authorize("i-tel.sk", "subscriber")) {
>       log(1, "Authorization failed\n");
>       www_challenge("i-tel.sk", "0");
>       log(1, "www_challenge sent\n");
>       break;
>     };
> 
>     # symmetric but don't advertise it -- force use of rport
>     if (client_nat_test("3")) {
>       log(1, "Client is behind a NAT\n");
>       if (! search("^Record-Route:")) {
>         fix_contact();
>         force_rport();
>       };
>     };
> 
>     log(1, "Forcing tcp alias\n");
>     force_tcp_alias();
> 
>     save("location");
>     break;
>   };
> };

Make sure you do the nat tests/modification for the other requests and
replies (not only for REGISTER). Start with a config that worked for
udp.

Also note that rport is not so important for tcp. In fact if your tcp
connections are not closed, rport is not needed (it willnot be used).
The replies are always sent through the same tcp connection the original
request came through, if the connection is still alive (using the "i"
parameter which is added to the Via header of forwarded tcp requests).

> 
> My undersanding is that the function force_tcp_alias() should add
> the source port of the tcp connection to the list of aliases.
> Then later existing connections are searched by userid and port
> to be reused. Please correct me if I'm wrong.

No, force_tcp_alias adds the via port to the aliases list.
The connection is identified by (ip_address, source_port). force_tcp_alias
adds an alias (ip_address, via_port) for (ip_address, source_port).

> 
> In my case it doesn't work, I found the following message in the log:
> 
> tcpconn_add_alias: alias port 5060 for hash 17, id 1
> 
> so it tries to add the port 5060 insted of the source port.

It's ok, see above.


Andrei




More information about the sr-users mailing list