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