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