Sad Clouds <cryintothebluesky%gmail.com@localhost> writes: > The sockaddr_storage structure came after the socket APIs were created, > so may be different systems handle this in slightly different ways. Generally, sockaddr_storage is used to store sockaddrs, when you don't know what kind you have. > My thinking was that connect() really should not care about the > exact size of the socket structure, as long as it is greater or equal > to the size required for sa_family_t. So if it is AF_INET then size > has to be at least sizeof(struct sockaddr_in), if it is AF_INET6, > then size has to be at lease sizeof(struct sockaddr_in6), etc. > > I try to write portable code for Linux, *BSD, Solaris, etc. I can't > think of a valid reason why connect() should fail for AF_INET with > larger socket structure, like sockaddr_storage, especially when it > is supported in NetBSD system headers. Is any of this specified by POSIX or RFC, and are you sure you are within the standards? Do other systems have a problem with using the right type and its length? > Below is fragment of my code that initializes socket address before > calling connect(). Various error checking is omitted for readability. > > > sa_family_t sa_family = 0; > struct in_addr addr_ipv4; > struct in6_addr addr_ipv6; > in_port_t port = 0; > struct sockaddr_storage addr; > > /* Specific IPv4 address */ > else if ((int_val = inet_pton(AF_INET, val, &addr_ipv4)) == 1) > { > sa_family = AF_INET; > } > /* Specific IPv6 address */ > else if ((int_val = inet_pton(AF_INET6, val, &addr_ipv6)) == 1) > { > sa_family = AF_INET6; > } > > /* Set port number */ > port = htons((uint16_t)u64); > > /* Fill sockaddr_storage structure based on sa_family */ > if (sa_family == AF_INET) > { > ((struct sockaddr_in *)&addr)->sin_family = sa_family; > ((struct sockaddr_in *)&addr)->sin_port = port; > ((struct sockaddr_in *)&addr)->sin_addr = addr_ipv4; > } > else if (sa_family == AF_INET6) > { > ((struct sockaddr_in6 *)&addr)->sin6_family = sa_family; > ((struct sockaddr_in6 *)&addr)->sin6_port = port; > ((struct sockaddr_in6 *)&addr)->sin6_addr = addr_ipv6; > } I see why you ended up where you did, but it's easy to set a length in the switch statement.
Attachment:
signature.asc
Description: PGP signature