sockaddr vs. sockaddr_storage

Currently we use a private sockaddr_in in CAddressBytes to store our addresses.  Microsoft “recommends” that to perform transparently in both IPv4 & IPv6 environments, that you switch to using sockadd_storage.  Perusing the possibly relevant structures winsock shows the sockaddr struct which appears to be able to hold an IPv6 address.

True, it can, and it also has the sa_family (http://msdn.microsoft.com/en-us/library/ms740496%28VS.85%29.aspx) property.  Given that sockaddr is much smaller than sockaddr_storage, why not go ahead and use that? 

Visual Studio help link: ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/winsock/winsock/sockaddr_2.htm

There’s an interesting thread from the Samba mailing list on this issue:

From RFC-2553

   The sockaddr_storage structure solves the problem of declaring
   storage for automatic variables which is large enough and aligned
   enough for storing socket address data structure of any family. For
   example, code with a file descriptor and without the context of the
   address family can pass a pointer to a variable of this type where a
   pointer to a socket address structure is expected in calls such as
   getpeername() and determine the address family by accessing the
   received content after the call.

   The sockaddr_storage structure may also be useful and applied to
   certain other interfaces where a generic socket address large enough
   and aligned for use with multiple address families may be needed. A
   discussion of those interfaces is outside the scope of this document.




Gilligan, et. al.            Informational                     [Page 15]

RFC 2553       Basic Socket Interface Extensions for IPv6     March 1999


   Also, much existing code assumes that any socket address structure
   can fit in a generic sockaddr structure.  While this has been true
   for IPv4 socket address structures, it has always been false for Unix
   domain socket address structures (but in practice this has not been a
   problem) and it is also false for IPv6 socket address structures
   (which can be a problem).

   So now an application can do the following:

      struct sockaddr_storage __ss;
      struct sockaddr_in6 *sin6;
      sin6 = (struct sockaddr_in6 *) &__ss;

Pro:

  • Microsoft says so :

    “It is recommended that the SOCKADDR_STORAGE structure be used in place of the sockaddr structure.”
  • Other authorities make the same recommendation (revealed via Google)

Con:

  • It’s going to potentially use a lot* more memory (for smallish values of “lot”.  sockaddr_storage is padded out to 128 bytes max)
  • We don’t need protocol family independence, so why not just embed IPv4 & 6 structures?
  • We might want to support operating systems earlier than Windows Server 2003 (where this first appeared)

For the moment, I’m going to push ahead using sockaddr_storage, but will add a fast-access AF_FAMILY property to CAddressBytes() to make determining an address type as fast as possible.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s