What's the difference between sockaddr, sockaddr_in, and sockaddr_in6?
sockaddr_in
and sockaddr_in6
are both structures where first member is a sockaddr
structure.
According to the C standard, the address of a structure and its first member are the same, so you can cast the pointer to sockaddr_in(6)
in a pointer to sockaddr
.
Functions taking sockaddr_in(6)
as parameter may modify the sockaddr
part, and functions taking sockaddr
as parameter just care about that part.
It's a bit like inheritance.
I don't want to answer my question. But to give more information here which might be useful to other people, I decide to answer my question.
After dig into the source code of linux
. Following is my finding, there are possible multiple protocol which all implement the getsockname
. And each have themself underling address data structure, for example, for IPv4 it is sockaddr_in
, and IPV6 sockaddr_in6
, and sockaddr_un
for AF_UNIX
socket. sockaddr
are used as the common data strut in the signature of those APIs.
Those API will copy the socketaddr_in or sockaddr_in6 or sockaddr_un to sockaddr base on another parameter length
by memcpy.
And all of the data structure begin with same type field sa_family.
Base on those reason, the code snippet is valid, because both sockaddr_in
and sockaddr_in6
have sa_family
and then we can cast it to the correct data structure for usage after check sa_family
.
BTY, I'm not sure why the sizeof(sockaddr_in6) > sizeof(sockaddr)
, which cause allocate memory base on size of sockaddr is not enough for ipv6( that is error-prone), but I guess it is because of history reason.