Robert Elz
2013-01-25 13:06:21 UTC
Date: Tue, 22 Jan 2013 19:43:24 -0500 (EST)
From: Mouse <***@Rodents-Montreal.ORG>
Message-ID: <***@Sparkle.Rodents-Montreal.ORG>
| Unfortunately I think it's the only solution, not only just because we
| don't have any APIs more sophisicated but because it's not an easy
| problem.
Not easy to solve every case, that is perhaps, not easy to achieve
perfection, I agree - and the option of binding a particular source
address from the application would always be there. But for most
applications, a rather simpler API that the application can use would
solve enough of the problem (what typical apps actually need, most of the
time) that it would be useful I think.
| Perhaps, but "type" is somewhat ill-defined here. One application's
| idea of address type doesn't necessarily match the next's.
If you are thinking that by "type" I meant a simple integer list of
interface types, and you pick one, then I entirely agree. I didn't
get into that level of detail in the last message (and I won't in this
one) but the API that was planned (some students of mine did it as a
project a couple of years ago - unfortunately, they didn't implement
enough of it to ship it out, but they did do a reasonable design) was
more complicated than that, while still being quite easy to use.
| One may
| prefer "site-local reachable over this VPN tunnel" over "globally
| routed" over "other site-local", as a simple example that is unlikely
| to match any notion of "type" that's likely to make it into an API.
Aside from possibly the first of those criteria (which would make all of
this be a fairly unusual application) and even perhaps with that (aside
from the "site-local" part, as those are deprecated now, but if that was
just one of the local/unroutable addrs) then the API designed could handle
all of that (for the VPN part to work, as it was designed, that VPN local
address would need to be in a unique local addr scope - that is, the API
allowed address scopes (local/global/...) and scope id's (the equiv of
%ex0 but in the numeric internal form) to be specified, but not specific
VPNs (or prefixes) - an app with that kind of requirement probably would
need to use bind().
That is, the API was designed with the aim that to use it, the app would
not know (or care) what actual addresses, or prefixes, happened to exist,
and would just be specifying a type of address that it preferred, if
available (and if not, then next best is, and if not available, then...)
That would allow most app designers to write configuration free code that
would normally work, and work well, and only need to get to config options,
and more, in rare cases. So, in the actual case that caused a problem
here, the nfs client code could simply request stable addresses if
available (and either fall back on temp addrs if that's all the client
has, or fail in that case, at its choice) and it would just work,
regardless of whether the "prefer temp addrs" sysctl (global switch) was
set or not.
| Trouble is, that's suitable only when the kernel's preference rules
| match the application's. Since different applications want different
| rules, the application has to control local address selection somehow.
Yes, that's the point - to allow the application to specify its preference,
somehow, and to solve enough of the problem to be useful for the vast
majority of apps (and better than a single global "use temp addrs" switch).
Attempting to achieve perfection, and refusing anything that fails to
achieve it, just means never making any forward progress. If that had
been the criteria, we'd never have had the socket interface at all, as
it is certainly not perfect. Yet it remains useful, and of immense
benefit, and works for almost everyone - even as originally designed.
Its enhancements over the years have improved it, and more enhancements
can make it even better. It still won't be perfect.
| And I think we agree on that much. But it seems to me that an API that
| classifies addresses into some small number of types based on
| set-in-stone rules is going to be useful to too small a subset of
| applications to make it worth the various costs of adding it.
Yes, so let's not do that. Yet, believe it or not, the vast majority
of applications could actually use that kind of function, and find it
useful, even in a relatively simple design. Almost no apps (but only
almost) actually want or need to select one particular VPN, and other
stuff like that. But a global temp/stable switch (which is where this
discussion started - on how that doesn't work for NFS) isn't good enough
either. It would be almost enough to add a per socket sockopt that
allowed that switch to be set for each socket (with the default being the
global switch) - most apps need no more than that. But some really want
to use stable addresses (like nfs, which was the issue in the original
message on this thread, and MTAs, to avoid excessive grey listing, and spam
avoidance issues), whereas others (like browsers) really want to use
temporary addresses (for the reasons that address form was created).
Just adding that (a temp/stable sockopt) would be better than we have now,
though it doesn't add anything about scoped address use (when should local
addresses be used rather than global) and doesn't add anything about CGAs
or other more specialised address types that might exist.
| I would prefer to do this in userland,
Like everything else, we need a good API. Then whether it is implemented
in userland, or in the kernel, becomes an implementation decision, rather
than a design argument.
| with a library routine that fetches the list of addresses and selects
| one based on whatever criteria it wants,
That could work, except right now we're still missing the vital
information to make it work - which is where the address came from.
And since addresses can be autoconfigured (entirely inside the kernel)
the kernel interface needs to be able to at least provide that information.
So, I think we certainly need to add something to the kernel, so addresses
have some type information associated with them. Whether the code that
uses it actually runs inside the kernel, or the info ie exported (along
with the addresses themselves, and routing info, so the user routine can work
out which outgoing interface the kernel will be using) is something for
later discussion, and perhaps implementation experimentation.
| maybe even involving an application-provided callback.
But when things get that complex, that such a callback would be
useful, I think (at least for a basic API suitable for most apps)
that things have gotten far too complicated. Perhaps an advanced
API might allow that, but I think we need to get enough experience
with something simpler, so we know what really is required, and what
is just useful for one installation of one application, and no-one
else, and allow the latter to be handled via bind().
| And, shouldn't this be on tech-net?
Yes, probably, so I have cc'd this reply there (for anyone on tech-net
who does not read tech-kern, there are, I think, 4 messages in this thread
on tech-kern only that you might want to read, if this message does not make
the context clear enough.)
I have also (attempted to) arrange for replies to go to tech-net alone.
Unfortunately, 99% of mailers are so broken, that this is unlikely to work
(so people, if you are going to reply, please check the address you're
sending to, tech-net is all that is required.)
kre
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
From: Mouse <***@Rodents-Montreal.ORG>
Message-ID: <***@Sparkle.Rodents-Montreal.ORG>
| Unfortunately I think it's the only solution, not only just because we
| don't have any APIs more sophisicated but because it's not an easy
| problem.
Not easy to solve every case, that is perhaps, not easy to achieve
perfection, I agree - and the option of binding a particular source
address from the application would always be there. But for most
applications, a rather simpler API that the application can use would
solve enough of the problem (what typical apps actually need, most of the
time) that it would be useful I think.
| Perhaps, but "type" is somewhat ill-defined here. One application's
| idea of address type doesn't necessarily match the next's.
If you are thinking that by "type" I meant a simple integer list of
interface types, and you pick one, then I entirely agree. I didn't
get into that level of detail in the last message (and I won't in this
one) but the API that was planned (some students of mine did it as a
project a couple of years ago - unfortunately, they didn't implement
enough of it to ship it out, but they did do a reasonable design) was
more complicated than that, while still being quite easy to use.
| One may
| prefer "site-local reachable over this VPN tunnel" over "globally
| routed" over "other site-local", as a simple example that is unlikely
| to match any notion of "type" that's likely to make it into an API.
Aside from possibly the first of those criteria (which would make all of
this be a fairly unusual application) and even perhaps with that (aside
from the "site-local" part, as those are deprecated now, but if that was
just one of the local/unroutable addrs) then the API designed could handle
all of that (for the VPN part to work, as it was designed, that VPN local
address would need to be in a unique local addr scope - that is, the API
allowed address scopes (local/global/...) and scope id's (the equiv of
%ex0 but in the numeric internal form) to be specified, but not specific
VPNs (or prefixes) - an app with that kind of requirement probably would
need to use bind().
That is, the API was designed with the aim that to use it, the app would
not know (or care) what actual addresses, or prefixes, happened to exist,
and would just be specifying a type of address that it preferred, if
available (and if not, then next best is, and if not available, then...)
That would allow most app designers to write configuration free code that
would normally work, and work well, and only need to get to config options,
and more, in rare cases. So, in the actual case that caused a problem
here, the nfs client code could simply request stable addresses if
available (and either fall back on temp addrs if that's all the client
has, or fail in that case, at its choice) and it would just work,
regardless of whether the "prefer temp addrs" sysctl (global switch) was
set or not.
| Trouble is, that's suitable only when the kernel's preference rules
| match the application's. Since different applications want different
| rules, the application has to control local address selection somehow.
Yes, that's the point - to allow the application to specify its preference,
somehow, and to solve enough of the problem to be useful for the vast
majority of apps (and better than a single global "use temp addrs" switch).
Attempting to achieve perfection, and refusing anything that fails to
achieve it, just means never making any forward progress. If that had
been the criteria, we'd never have had the socket interface at all, as
it is certainly not perfect. Yet it remains useful, and of immense
benefit, and works for almost everyone - even as originally designed.
Its enhancements over the years have improved it, and more enhancements
can make it even better. It still won't be perfect.
| And I think we agree on that much. But it seems to me that an API that
| classifies addresses into some small number of types based on
| set-in-stone rules is going to be useful to too small a subset of
| applications to make it worth the various costs of adding it.
Yes, so let's not do that. Yet, believe it or not, the vast majority
of applications could actually use that kind of function, and find it
useful, even in a relatively simple design. Almost no apps (but only
almost) actually want or need to select one particular VPN, and other
stuff like that. But a global temp/stable switch (which is where this
discussion started - on how that doesn't work for NFS) isn't good enough
either. It would be almost enough to add a per socket sockopt that
allowed that switch to be set for each socket (with the default being the
global switch) - most apps need no more than that. But some really want
to use stable addresses (like nfs, which was the issue in the original
message on this thread, and MTAs, to avoid excessive grey listing, and spam
avoidance issues), whereas others (like browsers) really want to use
temporary addresses (for the reasons that address form was created).
Just adding that (a temp/stable sockopt) would be better than we have now,
though it doesn't add anything about scoped address use (when should local
addresses be used rather than global) and doesn't add anything about CGAs
or other more specialised address types that might exist.
| I would prefer to do this in userland,
Like everything else, we need a good API. Then whether it is implemented
in userland, or in the kernel, becomes an implementation decision, rather
than a design argument.
| with a library routine that fetches the list of addresses and selects
| one based on whatever criteria it wants,
That could work, except right now we're still missing the vital
information to make it work - which is where the address came from.
And since addresses can be autoconfigured (entirely inside the kernel)
the kernel interface needs to be able to at least provide that information.
So, I think we certainly need to add something to the kernel, so addresses
have some type information associated with them. Whether the code that
uses it actually runs inside the kernel, or the info ie exported (along
with the addresses themselves, and routing info, so the user routine can work
out which outgoing interface the kernel will be using) is something for
later discussion, and perhaps implementation experimentation.
| maybe even involving an application-provided callback.
But when things get that complex, that such a callback would be
useful, I think (at least for a basic API suitable for most apps)
that things have gotten far too complicated. Perhaps an advanced
API might allow that, but I think we need to get enough experience
with something simpler, so we know what really is required, and what
is just useful for one installation of one application, and no-one
else, and allow the latter to be handled via bind().
| And, shouldn't this be on tech-net?
Yes, probably, so I have cc'd this reply there (for anyone on tech-net
who does not read tech-kern, there are, I think, 4 messages in this thread
on tech-kern only that you might want to read, if this message does not make
the context clear enough.)
I have also (attempted to) arrange for replies to go to tech-net alone.
Unfortunately, 99% of mailers are so broken, that this is unlikely to work
(so people, if you are going to reply, please check the address you're
sending to, tech-net is all that is required.)
kre
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de