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.