Date: Sat, 20 Apr 2002 22:20:41 -0600 From: Brett Glass <brett@lariat.org> To: Terry Lambert <tlambert2@mindspring.com> Cc: chat@freebsd.org Subject: Re: How to control address used by INADDR_ANY? Message-ID: <4.3.2.7.2.20020420205440.021f37b0@nospam.lariat.org> In-Reply-To: <3CC2255D.6C9B4453@mindspring.com> References: <4.3.2.7.2.20020419144005.0358c610@nospam.lariat.org> <4.3.2.7.2.20020419152309.035a96d0@nospam.lariat.org> <4.3.2.7.2.20020420112056.021aaec0@nospam.lariat.org>
next in thread | previous in thread | raw e-mail | index | archive | help
At 08:35 PM 4/20/2002, Terry Lambert wrote: >No, you are talking about a program that operates as a proxy; Only in the particular case of the caching proxy. I want to be able to run other programs there that are not proxies at all and have them communicate properly with the Net. >How about this: if you can come up with an algorithm that will >"do what I want" for you for all cases, without crippling the >fast path, how about you tell us, and we can think about >implementing it? OK, here goes. First, let's restate the problem. The stack is choosing a source address for an outbound socket opened with a source address of INADDR_ANY based on the routing table at the time the socket is opened. It's saying, "Let's use one of our addresses on the subnet to which we'd route outbound packets which are headed for the destination address." This is normally not a bad idea, since it saves a bit of routing overhead within the system. But we need to be able to disqualify a subnet or interface from this process in situations where this algorithm would produce an undesirable result. As I understand it, you can do this on a Cisco router by saying that the interface is up but "unnumbered." But this isn't a perfect solution either. (For example, in my case, when I want to send a packet to a device inside the ISP's intranet, I want my machine to know that it has an address on that subnet, respond to ARP "who-has" requests, be able to treat them as local, etc.) What I want is to specify that processes on my local machine not use source addresses from that subnet even if they specify INADDR_ANY. To do this, I want to be able to do one of three things: 1) Tag an address assigned to an interface as being disqualified from the selection process. (It might be useful to turn this bit on by default when one assigns an unregistered address to an interface.) This would solve the problem automagically in the case of intranets that use unregistered addresses (such as many corporate WANs or the network of the ISP I'm dealing with). But it wouldn't interfere with NAT. 2) Specify a default source address for processes on the local machine that is independent of the routing table. (An "auto" option, indicated by an address of 0.0.0.0, would bring back the old algorithm.) This would actually speed up the opening of sockets, since no scan of the routing table would be required to pick a source address for the socket. And it wouldn't violate the semantics of INADDR_ANY.... The process opening the socket has indicated no preference, so why not let the administrator specify one?) 3) Do both of the above, since each might be useful in specific situations. >> It's doing hierarchical routing on 10.x. Their internal 10.x.x.x >> network is broken up into /24 subnets, one of which exists here. >> (They have a little router here, and a few other routers tie >> into it.) Packets for the "real" addresses are to be routed to >> a specific 10.x address which will be owned by the router I'm >> putting up. > >So you are trying to make the FreeBSD box act like a Cisco router. Not really. But why should there be things that a Cisco router can't do that a FreeBSD router can't? >As I said before, FreeBSD only considers the destination address >when deciding on a route, and this is technically the wrong thing >to do for this particualr weird setup you have. It's really doing something different than deciding on a route.... It's deciding what source address to drop into the socket. Again, since a socket is defined by the tuple {source address, source port, destination address, destination port} and the source address must be one to which the other machine can reply (it can't be INADDR_ANY, which is zero), the machine must pick something at the time the socket is opened and then stick with it, come what may. Even if the routing table changes so that a different address would have been picked at a later time. >Another thing that would likely work is to not try to run the >proxy services on the same machine that's acting as the router. It's the best place to run them, especially when one is doing interception caching. The CPU load from the routing is relatively light, so there are plenty of resources available for the caching. Didn't the InterJet do this? >Your information is insufficient. A block diagram, with a dotted >line around the blocks you expect to jam into a single FreeBSD >box would be useful. +-----------------+ | Router | Routable Rest of world (via ----| +--------------+|--- Subnet 1 Subnet 10 intranet) | |Interception || | | caching || | |--------------||--- Routable | | RBL zone xfer|| Subnet 2 | |--------------|| etc. | | DNS, DHCP || | |--------------|| | | sshd || | |--------------|| | | Utilities for|| | | maintenance || | | (e.g. ftp, || | |CVSup, scp || | +--------------+| +-----------------+ In other words, really just some basic firewall functions and interception caching. The box might not actually be running DNS or DHCP in all cases, but it'd be nice to be able to, so I've added them to the diagram. Note that to do DNS zone transfers, CVSup, FTP, or scp as a client, the box will need to be able to get to the rest of the world from local processes. >It really feels like you want something to work that we will all >say "you can't expect that to work!", It's perfectly reasonable to expect it to work. The only curve I've thrown it that it has not been able to handle is that its upstream network is an intranet with unroutable addresses. Not unusual either within ISPs or within corporate WANs. >Arrrrrrrrgh! Why don't you just post what I post back at >me, instead of saying the same thing, and spin-doctoring it? You're annoyed that I agree with you? ;-) >> Would it affect the "fastpath?" As I understand it, a socket's source >> address is defined when it's opened and stays that way thereafter. >> (Correct me if I'm wrong there, but isn't a socket uniquely defined during >> its lifetime by the tuple of {source address, source port, destination >> address, destination port}?) All that would need to be altered would be >> the *initial* decision about the source address used. Right? > >Not as such. It's uniquely identified at the host by the IP/port >destination tuple, *NOT* by *both* the source and destination >tuples. This can't be. When several clients connect to a server's well-known port at the server, the sessions must be distinguished by the source addresses and ports. If the source addresses are allowed to change, the server won't know which client (or session) is which! >In order to hack this properly, you would have to put two more >compares in the tcp_output and ip_output code, An option that assigned a fixed source address couldn't help but be a net win, because it would avoid a traversal of a linked list of routing table entries. Likewise, disqualifying an address would mean having a flag or leaving that routing table entry off a linked list. The latter would actually speed up the scan of the list because the list would be shorter! And one way to implement the fixed source address would be to aim the pointer to the linked list at a list with exactly one entry: one specifying the fixed address. This would introduce no more compares. So, you see, there's no need to add cycles. It's just a matter of determining whether adding a compare would be a net win. (It might be, if it shortened the code path most of the time.) >or you would have >to hack up the "clone" route to have different precedence ordering >of the IP addresses associated with the interface. The new SYN >cache code complicates this type of hack considerably. I don't understand. Why would this be? The SYN cache code deals with sockets on which the machine is listening, not outbound sockets. --Brett To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-chat" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4.3.2.7.2.20020420205440.021f37b0>