Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is zeroing out the "sockaddr_in" structure necessary?

Tags:

c++

c

sockets

Everywhere I look, I see the following piece of code:

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;

In C++, the same idea is usually expressed as

sockaddr_in addr = {}; // unneccesary(?) value-initialzation
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;

Yet nowhere I look (in terms of official documentation) do I see any requirement to zero out the structure before setting those members! Yes, usually BSD sockets implementations do have a sin_zero member defined for sockaddr_in, but they always say the member is needed for padding, to align the size of sockaddr_in with sockaddr. And they never request one to put any specific contents into it.

Is there any real, documentation proven need to zero out the struct?

P.S. Before you VTC the question as a duplicate of one of several SO questions regarding memset on sockaddr_in, please make sure the question your are suggesting as a duplicate has any links to official documentation rather than just speculation on 'initializing of unused members just in case'.

like image 954
SergeyA Avatar asked Mar 18 '16 14:03

SergeyA


People also ask

What is the structure of Sockaddr_in?

The SOCKADDR_IN structure specifies a transport address and port for the AF_INET address family.

What does the struct In_addr structure represent?

The in_addr structure represents an IPv4 Internet address.

Where is Sockaddr_in defined?

The <netinet/in. h> header shall define the sockaddr_in structure that includes at least the following members: sa_family_t sin_family AF_INET.

What is Sin_zero?

As struct sockaddr_in needs to be cast to struct sockaddr it has to be kept the same size, sin_zero is an unused member whose sole purpose is to pad the structure out to 16 bytes (which is the size of sock_addr). This padding size may vary depending on the address family.


1 Answers

Short answer:

The IEEE Standard doesn't require it.

But, I think it's best to be safe and zero out everything.


Long(er) answer:

The IEEE Standard 1003.1 specifies that the definition of sockaddr_in is (Emphasis mine):

The <netinet/in.h> header shall define the sockaddr_in structure that includes at least the following members:

sa_family_t sin_family AF_INET.

in_port_t sin_port Port number.

struct in_addr sin_addr IP address.

Note that, unlike the definition for sockaddr_in6, which specifies that it should be zeroed out:

The sockaddr_in6 structure shall be set to zero by an application prior to using it, since implementations are free to have additional, implementation-defined fields in sockaddr_in6.

There is no similar wording for sockaddr_in. However, such lack of wording gives platform implementors enough ambiguity to make their own requirements about zeroing out all or part of sockaddr_in.

Note that the definition of sockaddr_in used to require a sin_zero field to pad out the structure to make it compatible with sockaddr structures:

The sin_zero member was removed from the sockaddr_in structure as per The Open Group Base Resolution bwg2001-004.

And it's with sin_zero we find a discrepancy between Windows and Linux. Even though the field was removed from the official definition, both Windows and Linux implementation still include it (because it's not explicitly illegal thanks to the wording "at least").

Whether sin_zero always requires zeroing out or not for Windows platforms isn't clear, but in this blog post the writer did some digging and came up with the following:

On some architectures, it wont cause any problems not clearing sin_zero. But on other architectures it might. Its required by specification to clear sin_zero, so you must do this if you intend your code to be bug free for now and in the future.

For the part about "It's required by specification to clear sin_zero", I could only find the following Windows documentation (for Winsock Kernel) appearing to support the claim:

A WSK application should set the contents of this array to zero.

However, I can find no similar wording for Linux.

So to conclude, it appears that in some architectures you need to zero out at least one field, while in others you don't. I think it's best to be safe and zero out everything.

like image 56
AndyG Avatar answered Sep 27 '22 18:09

AndyG