Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Aug 1995 09:34:35 -0700 (PDT)
From:      pete@pelican.com (Pete Carah)
To:        paul@FreeBSD.ORG
Cc:        current@FreeBSD.ORG
Subject:   Re: workaround for talk's address problem
Message-ID:  <m0sfrbw-000K2lC@pelican.com>
In-Reply-To: <199508081032.LAA03138@server.netcraft.co.uk> from "Paul Richards" at Aug 8, 95 11:32:10 am

next in thread | previous in thread | raw e-mail | index | archive | help
Paul Richards writes:
> In reply to Pete Carah who said
...
> Ehh, I'd be interested to know how? All the servers in the tree at the
> moment bind to INADDR_ANY. The funtionality I'm adding is the ability to
> make servers bind to a particular address and only that particular address
> which is something we can't currently do.
Not XNTPD; it has a true kluge to get around the problem under discussion.
(and does it by binding to each address, or at least to one address on
each interface.)

That isn't really the problem under discussion; what it is, is once the
bind to inaddr_any has been done, of setting the 'from' field in 'reply'
packets.  xntpd gets around this by not binding to inaddr_any; it binds
to each interface separately.  What we (me, Garrett, Terry, anyhow) are
saying is that the need for this causes problems...  (inaddr_any is
*supposed* to handle incoming calls; it almost does for TCP; the alias
problem you refer to below can be handled since there actually is enough
state saved to do it (Garrett or Terry, correct me if that is wrong).
In UDP there isn't (and isn't supposed to be, either).  This is a problem 
of extending kernel software/structures that were never really designed
for multihomed situations at all, much less aliased interfaces.

> Incidentally, I've run into another, rather more difficult problem.

> If the local socket isn't specifically bound, which usually it isn't
> then in_pcbconnect (or in_pcbladdr as it is now I think) will try and
> find an appropriate value. This is a problem if you're trying to do what
> I'm doing. For instance, I've got a web server running in one virtual
> enviromment, say, foo.com and a browser in another, say bar.com.
 
> When in_pcbconnect gets called, I think what's happening is that the
> decision about the local addr is made by ifa_ifwithnet, since the
> destination address is an ip address aliased on this host it finds
> an ifaddr struct that has a match and it returns that as the local
> address. The result is that the web server in foo.com thinks the browser
> is also connecting from foo.com even though it's really connecting from
> bar.com.
Correct.  Aliases mess it up even more.  The (related) problem that
started this discussion is specific to UDP, though, and doesn't have
to occur in TCP; there can easily be enough state info saved for TCP.

When I tried alias addresses I couldn't even ping them from my own host;
apparently you've gotten around this and uncovered another bug...

I think the answer (for now) is to not use a host with aliased addresses
as both a server and client...  (or do an explicit bind of the 'accept'
socket, after the connection; I don't know if that will work.)
 
> It knackers security up completely if a client from one domain can
> access servers in another because the local addr of the client gets
> set to that of the server and not the client! In a multi-homed
> environment this seems bogus to me. 

The kernel TCP/IP route/address stuff doesn't work right in multihomed
cases.  This isn't the only time this shows up; kerberos and several other
UDP-based programs (talk is what started the discussion) have "interesting"
problems here too.  With TCP it at least can theoretically be handled.
There appears to not be a general solution in the UDP case without the
kernel maintaining more state information for a "connection" that isn't
supposed to be a connection...

> I'd like this to be changed in some way but I'm not exactly sure
> what the best way is. We could check the destination address and if
> it's actually an aliased address on this host then *not* return that
> as the local addr, that would solve the problem with bogus domains
> as I'm seeing above but I'm not sure how to work out what the correct
> local addr would be. What I want to happen is for the local addr to
> be set to the ip address of whatever hostname is. How much of a cludge
> would it be to do that? Since this would only happen if the dst addr was
> an exact match for an alias it wouldn't affect the cases where packets
> actually get out onto the wire and the local addr needs to be set to the
> outgoing interface.

In TCP there is a connected-address property that can be used; in UDP
there isn't.  You can't just to a sendto the socket that a recvfrom
came in on or it will pick some IP addr as the from address (which is
the first one to ever be set, apparently)  Usually TCP is a little better
since the incoming dest address is known.  (it is for recvfrom too but
that gets stripped before being presented to the application layer.)

Terry & Garrett both understand the problem pretty well; the real problem
is *very* basic to the UCB kernel TCP/IP implementation.  By hiding route
and other related info from the applications we lose some abilities...
(and "connectionless" is a fiction.)

Worked great in the old days when hosts were either never multihomed, or
the multihoming was handled by external routers.

-- Pete



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?m0sfrbw-000K2lC>