lkml.org 
[lkml]   [2001]   [Jun]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: Bug in nonlocal-bind (transparent proxy)?
    Hi,

    It's not a bug, it's willful.

    On Thu, Jun 07, 2001 at 05:08:25PM +0300, Nadav Har'El wrote:
    > I am writing a transparent-proxy-like application, that needs to be able to
    > bind a TCP socket with a non-local address (i.e., the proxy contacts the
    > origin-server, in the local network, pretending to be the original client.
    > The reply will get back to the proxy because it acts as the default
    > gateway, and the kernel needs to pass that reply to the socket).
    >
    > Bind()ing a non-local address worked fine in the 2.2 line of kernels if a
    > certain compile-time option was enabled (TRANSPARENT_PROXY, or something
    > like that). But it no longer seems to be working in the 2.4 kernels (I
    > tried this on 2.4.2 coming from the Redhat 7.1 distribution).
    >
    > First, bind() simply refused to work when given a non-local address (returning
    > EADDRNOTAVAIL). Reading the kernel's source I discovered that an undocumented
    > "ip_nonlocal_bind" sysctl makes the kernel agree to do such a bind (this
    > should really be in the bind() documentation...). Enabling this option
    > allowed bind to work (it can even catch the case of two sockets trying to
    > bind the same address), but the later connect() fails!
    > I tryed reading the kernel sources to figure out what's wrong with the
    > connect(), but failed to understand why it returns a EINVAL. I think this
    > is a bug, and include below a short program to reproduce it:
    >
    > If you run the program below, connect() will fail with EINVAL (it will do
    > so before even trying to output a packet). To see that nothing's actually
    > wrong with the connect, change the #if 1 to #if 0, eliminating the bind(),
    > and see that the connect works (or at least fails with a connection refused,
    > as it should because of the random IP address).
    > Note that you must run the program as root, and do
    > echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
    > to get the bind() to work at all. But once you do that, and bind() works,
    > how come connect() doesn't work?
    >
    > Thanks in advance for any insights or fixes!

    To make a custom kernel where you can use non-local addresses more freely,
    find source address checks in ip_route_output_slow() and get rid of all of
    them except considering
    MULTICAST(saddr) || BADCLASS(saddr) || ZERONET(saddr) ||
    saddr == htonl(INADDR_BROADCAST)
    as invalid.

    Andrey
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 12:55    [W:7.903 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site