Reputation: 2337
I write a little socket programm that only bind to specified ip:port, but bind() failed if the struct sockaddr_in is not bzero and gcc is with option -O2.
Here is the codes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
int main(int argc, char **argv){
struct sockaddr_in addr;
//bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons((unsigned short)9009);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
int sock;
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket error");
exit(0);
}
if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
printf("socket error: %d, %s\n", errno, strerror(errno));
exit(0);
}
return 0;
}
Please notice bzero(&addr, sizeof(addr));
is commented out, I intend to initial the sockadd_in by each member. Compile and run:
$ gcc a.c; ./a.out
OK
$ gcc -O2 a.c; ./a.out
socket error: 49, Can't assign requested address
We can know the struct sockadd_in is defined as:
struct in_addr {
in_addr_t s_addr; /* 32-bit IPv4 address */
/* network byte ordered */
};
struct sockaddr_in {
uint8_t sin_len; /* length of structure (16) */
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* 16-bit TCP or UDP port number */
/* network byte ordered */
struct in_addr sin_addr; /* 32-bit IPv4 address */
/* network byte ordered */
char sin_zero[8]; /* unused */
};
My question is, does the bind() implementation depends on sockaddr_in.sin_zero being cleared?
Edit: Mac OS X, Darwin Kernel Version 12.4.0 X86_64
Upvotes: 2
Views: 4547
Reputation: 729
The rules used in name binding vary between address families. and there's also this sin_zero field in struct sockaddr_in which some people claim must be set to zero. Other people don't claim anything about it (the Linux documentation doesn't even mention it at all), and there are other documentation which claim sin_zero has been removed from struct sockaddr_in, I have tried with both bzero commented and un-commented. The commented works good some time in a local network but un-commented version works all time either local network or not. so i guess bzeroing is good practice.
Upvotes: 1