Why is zero padding needed in sockaddr_in?
c, kernel, linux
Solution
The two more relevant pieces of information I could find are
- Setting sin_zero to 0
Talking about a snippet of code that does not clear the bytes
This is a bug. I see it occur occasionaly. This bug can cause undefined behaviour in applications.
Followed with some explications
Most of the net code does not use sockaddr_in, it uses sockaddr. When you use a function like sendto, you must explicitly cast sockaddr_in, or whatever address you are using, to sockaddr. sockaddr_in is the same size as sockaddr, but internally the sizes are the same because of a slight hack.
That hack is sin_zero. Really the length of useful data in sockaddr_in is shorter than sockaddr. But the difference is padded in sockaddr_in using a small buffer; that buffer is sin_zero.
and finally, an information that can be found at various places
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.
- The use of sin_zero
answering the question
why we need this 8 byte padding?
and the answer
Unix network programming chapter 3.2 says that, "The POSIX specification requires only three members in the structure: sin_family, sin_addr, and sin_port. It is acceptable for a POSIX-compliant implementation to define additional structure members, and this is normal for an Internet socket address structure. Almost all implementations add the sin_zero member so that all socket address structures are at least 16 bytes in size. "
It's kinda like structure padding, maybe reserved for extra fields in the future. You will never use it, just as commented.
which is consistent with the first link. Clearing the bytes tells the receiver "those bytes are not used on our side".
Problem
I googled it and some people says "To keep the same size with struct sockaddr". But Kernel will not use sockaddr directly(right?). When using it. kernel will cast it back to what it is. So why is zero padding needed? ``` struct sockaddr { unsigned short sa_family; // address family, AF_xxx char sa_data[14]; // 14 bytes of protocol address }; struct sockaddr_in { short sin_family; // e.g. AF_INET, AF_INET6 unsigned short sin_port; // e.g. htons(3490) struct in_addr sin_addr; // see struct in_addr, below char sin_zero[8]; // zero this if you want to }; struct in_addr { unsigned long s_addr; // load with inet_pton() }; ```