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).
I had another problem: there was always private address in contact of the TCP users behind NAT. The problem was that the function fix_contact() from module mediaproxy works only for the UDP requests. So I modified the source file modules/mediaproxy/functions.h, commented out the statement on line 116:
// if (uri.proto != PROTO_UDP && uri.proto != PROTO_NONE) // return -1;
Now the TCP routing works correctly.