On Sat, Apr 01, 2006 at 12:03:00AM +0200, Adrian Knoth wrote: > On Fri, Mar 31, 2006 at 11:06:55AM -0800, Brooks Davis wrote: > > > > One little problem here is that it is possible to disable the > > > IPv6-mapped IPv4 addresses at least under Linux and some BSD variants. > > > For Linux, have a look at sys.net.ipv6.bindv6only. Some authors even > > More specifically, KAME derived (BSD) stacks disable them by default so > > In addition, OpenBSD doesn't provide mapped addresses. Though this > is a violation of RFC 4291, RFC 4038 "recommends" this approach: > > Note that some systems will disable (by default) support for internal > IPv4-mapped IPv6 addresses. The security concerns regarding these > are legitimate, but disabling them internally breaks one transition > mechanism for server applications originally written to bind() and > listen() to a single socket by using a wildcard address. This forces > the software developer to rewrite the daemon to create two separate > sockets, one for IPv4 only and the other for IPv6 only, and then to > use select(). However, mapping-enabling of IPv4 addresses on any > particular system is controlled by the OS owner and not necessarily > by a developer. This complicates developers' work, as they now have > to rewrite the daemon network code to handle both environments, even > for the same OS. > > > it might be best to assume it doesn't work since you'll probably have > > to support that case anyway. > > ACK. But what does this imply? Do we already have select()ed > binds, in other words, can we simply spawn two listen()-sockets?
Looking at the code in btl_tcp_component.c it looks like it mostly is.
You'd just have to add another socket and register another event for it.
> If we conclude not to use mapped addresses, will we end up
> with btl/tcp and btl/tcp6?
I'd certainly hope not.
> The OS support issue can be handled this way:
>
> union sockaddr_union {
> struct sockaddr sa;
> struct sockaddr_in sin;
> #ifdef HAVE_IPV6
> struct sockaddr_in6 sin6;
> #endif
> };
>
> and later:
>
> /* copy IP to sockaddr */
> static inline void
> sin_set_ip(union sockaddr_union *so, const struct ip_addr *ip)
> {
> if (ip == NULL) {
> #ifdef HAVE_IPV6
> so->sin6.sin6_family = AF_INET6;
> so->sin6.sin6_addr = in6addr_any;
> #else
> so->sin.sin_family = AF_INET;
> so->sin.sin_addr.s_addr = INADDR_ANY;
> #endif
> return;
> }
>
>
> (code shamelessly borrowed from dovecot/src/lib/network.c)
>
> It might be a little harder to read, but it keeps both
> versions (IPv4-only and IPv6) close together.
Based on experiences at work, I'd say dovecot is NOT a good example to
copy from. We're running it on a dual stack network and you have to run
two copies which is lame.
-- Brooks
--
Any statement of the form "X is the one, true Y" is FALSE.
PGP fingerprint 655D 519C 26A7 82E7 2529 9BF0 5D8E 8BE9 F238 1AD4
pgp4UMCu0tlPE.pgp
Description: PGP signature
