tproxy 1.2.0 missing ip_tproxy_sockref_uniq?
I was wondering something. Let's say somebody wants to perform a non-local LISTEN. Since the port isn't known ahead of time, both the local bind(2) operation *and* the ASSIGN use a port of 0 (pick one for me). Of course the 'local' socket (getsockaddr) gets a port, thanks to the kernel. However, getsockopt (QUERY) returns ports of 0 for both local *and* foreign. How does one determine what the 'remote' port is? With 2.4.21-23, there was (seeming) explicit support for this scenario involving the function ip_tproxy_sockref_uniq (from the setsockopt handler): /* check if the proxy requested a wildcard port, and allocate * a free port if necessary */ if (itp.itp_faddr.s_addr && (itp.itp_fport == 0)) { itp.itp_fport = htons(ip_tproxy_sockref_uniq(itp.itp_faddr, proto)); if (itp.itp_fport == 0) { /* port allocation failed */ res = -EAGAIN; goto read_unlk; } } Did support for automatically assigning a foreign port go away between 2.4.21-23 and 1.2.0? -- What do you call a fish with no eyes? A fsh. Jon Nelson <jnelson-tproxy@securepipe.com>
Hi, On Thu, 2004-01-08 at 21:55, Jon Nelson wrote:
Let's say somebody wants to perform a non-local LISTEN. Since the port isn't known ahead of time, both the local bind(2) operation *and* the ASSIGN use a port of 0 (pick one for me). Of course the 'local' socket (getsockaddr) gets a port, thanks to the kernel. However, getsockopt (QUERY) returns ports of 0 for both local *and* foreign. How does one determine what the 'remote' port is? With 2.4.21-23, there was (seeming) explicit support for this scenario involving the function ip_tproxy_sockref_uniq (from the setsockopt handler):
/* check if the proxy requested a wildcard port, and allocate * a free port if necessary */ if (itp.itp_faddr.s_addr && (itp.itp_fport == 0)) { itp.itp_fport = htons(ip_tproxy_sockref_uniq(itp.itp_faddr, proto)); if (itp.itp_fport == 0) { /* port allocation failed */ res = -EAGAIN; goto read_unlk; } }
Did support for automatically assigning a foreign port go away between 2.4.21-23 and 1.2.0?
Yes, it did. In the 1.2 branch, if a wildcard foreign port is specified at ASSIGN, Netfilter's NAT subsystem allocates a foreign port. This is very useful for connect()-ing from a wildcard foreign port, since it avoids "failed to apply NAT mapping" errors in a lot of cases. However, this allocation happens only when the first packet of the connection is traversing the Netfilter hook, so you cannot get the exact port number _before_ sending the first packet. In case of listening sockets, this makes no sense, of course, so as of 1.2.0 you cannot use 'wildcard' foreign ports for listening sockets. As a workaround, you should implement roughly the same in userspace, that is, you try to explicitly assign your sockets in a range of ports until the allocation succeeds. The next version of tproxy will address exactly these problems, it will have an ALLOC operation as well. This can be used to instantly allocate a foreign port if none was given, ip_tproxy_sockref_uniq() will be back. (ALLOC support is ready at the moment, however, some work/testing is still needed before the first development release will be published.) -- Regards, Krisztian KOVACS
On Fri, 9 Jan 2004, KOVACS Krisztian wrote:
Hi,
On Thu, 2004-01-08 at 21:55, Jon Nelson wrote:
Let's say somebody wants to perform a non-local LISTEN. Since the port isn't known ahead of time, both the local bind(2) operation *and* the ASSIGN use a port of 0 (pick one for me). Of course the 'local' socket (getsockaddr) gets a port, thanks to the kernel. However, getsockopt (QUERY) returns ports of 0 for both local *and* foreign. How does one determine what the 'remote' port is? With 2.4.21-23, there was (seeming) explicit support for this scenario involving the function ip_tproxy_sockref_uniq (from the setsockopt handler):
/* check if the proxy requested a wildcard port, and allocate * a free port if necessary */ if (itp.itp_faddr.s_addr && (itp.itp_fport == 0)) { itp.itp_fport = htons(ip_tproxy_sockref_uniq(itp.itp_faddr, proto)); if (itp.itp_fport == 0) { /* port allocation failed */ res = -EAGAIN; goto read_unlk; } }
Did support for automatically assigning a foreign port go away between 2.4.21-23 and 1.2.0?
Yes, it did. In the 1.2 branch, if a wildcard foreign port is specified at ASSIGN, Netfilter's NAT subsystem allocates a foreign port. This is very useful for connect()-ing from a wildcard foreign port, since it avoids "failed to apply NAT mapping" errors in a lot of cases. However, this allocation happens only when the first packet of the connection is traversing the Netfilter hook, so you cannot get the exact port number _before_ sending the first packet. In case of listening
I don't think that's true. I hand-applied a patch to add back ip_tproxy_sockref_uniq (and the code that calls it, shown above) and it works perfectly. After the ASSIGN I just use QUERY to get the IP and port which I can then use for my own devices. It works perfectly, and as expected. Tested with both listening and connect()'ing sockets.
sockets, this makes no sense, of course, so as of 1.2.0 you cannot use 'wildcard' foreign ports for listening sockets. As a workaround, you should implement roughly the same in userspace, that is, you try to explicitly assign your sockets in a range of ports until the allocation succeeds.
The next version of tproxy will address exactly these problems, it will have an ALLOC operation as well. This can be used to instantly allocate a foreign port if none was given, ip_tproxy_sockref_uniq() will be back. (ALLOC support is ready at the moment, however, some work/testing is still needed before the first development release will be published.)
-- Regards, Krisztian KOVACS
-- What do you call a fish with no eyes? A fsh. Jon Nelson <jnelson-tproxy@securepipe.com>
participants (2)
-
Jon Nelson
-
KOVACS Krisztian