Why does struct sockaddr contain an address family field? Isn't the address family already fixed with the call to socket()?
sockaddr is used in more places than just connect and bind, including places where you don't have some external knowledge of the address family involved - getaddrinfo being one.
Additionally, whilst I don't believe the following equates to practice anywhere, I can see it having been in the eye of whoever designed this stuff originally: the call to socket() defines the protocol family. sockaddr contains the address family. In practice, I believe these are always the same, but you could theoretically have a protocol capable of supporting two different address types.
EDIT: There's another way that the parameter is useful. If you're using datagram (UDP) sockets and you have a socket in a "connected" state with a default destination address, you can clear out that address by calling connect() with a sockaddr with sa_family set to AF_UNSPEC.
If you look at the getaddrinfo interface, which is the only modern correct way to convert between interchange representations of addresses (names or numeric addresses) and the sockaddr structures, I think you'll see why it's needed.
With that said, the whole struct sockaddr stuff is a huge mess of misdesigns, especially the userspace endian conversion.
Another good instance of why the sa_family field is needed is the getsockname and getpeername interfaces. If the program inherited the file descriptor from another program, and doesn't already know what type of socket it is, it needs to be able to determine that in order to make new connections or even convert the address to a representation suitable for interchange.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With