[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Adding ipv6 support.



On Mon, Feb 07, 2011 at 12:47:03PM -0800, William Ahern wrote:
> On Mon, Feb 07, 2011 at 02:40:03PM -0500, Simon Perreault wrote:
> > On 2011-02-07 14:09, William Ahern wrote:
> > >> Furthermore, you're ignoring alignment issues.
> > > 
> > > There are no alignment issues here, arguably not even if we're talking pure
> > > standard C. Certainly not in any implementation that supports the BSD
> > > sockets API and the .sa_family member overlay.
> > 
> > It should be 64-bit aligned (see RFC 3493).
> > 
> > Just add the appropriate compiler-specific magic, or simply use
> > sockaddr_storage.
> 
> The alignment of a union would be as strict as the strictest of its members,
> because the standard guarantees that a pointer to a member of a union is
> convertible to a pointer to that union, and vice versa. See C99 6.7.2.1.p14.
> But because you can convert such pointers with only a declaration in scope
> (and not a definition), it follows that all unions and structures must have
> the same alignment. Q.E.D.

I take this assertion back; it goes way too far. I wasn't thinking clearly.
But nevertheless the alignment of a union would need to be the least common
multiple of the member alignments.

In this case, using a union is the only well-defined way (in pure C at
least) to convert a struct sockaddr_in object to struct sockaddr without
copying.

The other issue with sockaddr_storage is that it's huge. Because on Unix
systems it must also be able to overlay a struct sockaddr_un, it's often
well over 100 bytes long. I've written HTTP proxies with barely more state
than that, if at all, per connection (using online, non-line buffered
parsing). Using a struct sockaddr_storage could seriously bloat memory in
some circumstances.

That said I usually think it's a good idea to support unix domain sockets in
my stream interfaces (especially handy during development, or for internal
host services where you can authenticate on peer credentials), and in most
cases I'll often use sockaddr_storage in a union or in place of a union. But
if you do support local domain sockets, you need to be chummier with the
address types than getnameinfo and sockaddr_storage permit. getnameinfo(3)
doesn't even support domain sockets at all. So, for example, when formatting
logging information where there's no port information for a domain socket,
the format specifier might be conditioned on the address type, and you'd
need to access .sun_path directly.

getaddrinfo()/getnameinfo() are definitely more abstract than their
predecessor interfaces, but they're not abstract enough. Rather than presume
IPv4, they basically presume TCP. (Or rather, the subset of TCP over IPv4
and IPv6, as IPv6 has all kinds of other oddities, like scoping; and you
can't control that stuff w/ getnameinfo().)
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.