strict aliasing and socket structures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Greetings

So I've been researching on this particular topic for past few days and haven't
yet reached a satisfactory conclusion - What would be a safe way to get/set
sockaddr_in, sockaddr_un or other similar structures from the generic
sockaddr_storage structure? I've read some textbooks including the recommended
'Unix Network Programming' by W.Richard Stevens and some others, and what I
gathered from there looks something like -

sockaddr_storage s;
memset(&s, 0, sizeof(s));
sockaddr_in *p = (sockaddr_in *) &s;
p->sin_family = AF_INET;
p->port = htons(80);

// now 's' is ready to be passed in socket api calls

int res = bind(sockfd, (sockaddr *) &s, sizeof(s));
// and similar calls

but recently I discovered that this method wasn't following strict aliasing
rules and was in fact a violation. So I made some stackoverflow threads -
[1] - http://stackoverflow.com/questions/42176962/fill-sockaddr-storage-struct-with-values-of-sockaddr-in
[2] - http://stackoverflow.com/questions/42178179/will-casting-around-sockaddr-storage-and-sockaddr-in-break-strict-aliasing

and read through official documentations, textbooks and other online resources
but couldn't get my doubts clear. getaddrinfo only supports ipv4/v6 and
therefore isn't a solution for me since I'm writing code that will support many
other socket domains eg unix, netlink etc..

Another recommended solution was to first declare appropriate structure type,
fill it -

struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port= htons(port);

and then use memcpy to transfer the data to original sockaddr_storage structure

memcpy(reinterpret_cast<char *>(&s),
       reinterpret_cast<char *>(&sin), sizeof(sin));

and now pass s to socket api function calls which can deduce the structure
themselves.. but can they?
Would this also work in reverse, like sending sockaddr_storage s to recvfrom
call and then checking its ss_family field, if it is AF_INET then create
sockaddr_in and memcpy data back to it, if sockaddr_in6 do memcpy to it and
similarly for other domains..

I need to do it using sockaddr_storage structure otherwise, I'll have to
write tons of overloaded methods for each socket domain and maintenance will
become more expensive compared to a single generic structure which was already
designed to do so.

Afaik Microsoft's compiler don't suffer from this problem since they explicitly
allow these structures to be casted and no concept of strict violation
is present. In
case of clang, I'm not sure if they've strict aliasing violation or
not, but they do
tend to follow gcc so that's where I'll put my guess.

Any sort of help would be beneficial to me, I'm open to
suggestions/advice as well


Abhinav Gauniyal



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux