diff options
author | Marc Hoersken <info@marc-hoersken.de> | 2012-06-11 12:24:03 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2012-06-11 15:26:30 +0200 |
commit | 9c94236e6cc078a0dc5a78b6e2fefc1403e5375e (patch) | |
tree | 15c4542b712a0ac9a000a86c6322cdf3a6575b16 /lib/connect.c | |
parent | 3f9ab7cf5deb892cc7b8cb3f36322e072898b789 (diff) | |
download | curl-9c94236e6cc078a0dc5a78b6e2fefc1403e5375e.tar.gz |
connect.c/ftp.c: Fixed dereferencing pointer breakin strict-aliasing
Fixed warning: dereferencing pointer does break strict-aliasing rules
by using a union instead of separate pointer variables.
Internal union sockaddr_u could probably be moved to generic header.
Thanks to Paul Howarth for the hint about using unions for this.
Important for winbuild: Separate declaration of sockaddr_u pointer.
The pointer variable *sock cannot be declared and initialized right
after the union declaration. Therefore it has to be a separate statement.
Diffstat (limited to 'lib/connect.c')
-rw-r--r-- | lib/connect.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/lib/connect.c b/lib/connect.c index 42b626f1a..28c101930 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -253,12 +253,16 @@ static CURLcode bindlocal(struct connectdata *conn, struct SessionHandle *data = conn->data; struct Curl_sockaddr_storage sa; - struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */ curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */ - struct sockaddr_in *si4 = (struct sockaddr_in *)&sa; + + union sockaddr_u { + struct sockaddr sa; + struct sockaddr_in sa4; #ifdef ENABLE_IPV6 - struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa; + struct sockaddr_in6 sa6; #endif + }; + union sockaddr_u *sock = (union sockaddr_u *)&sa; /* bind to this address */ struct Curl_dns_entry *h=NULL; unsigned short port = data->set.localport; /* use this port number, 0 for @@ -373,18 +377,18 @@ static CURLcode bindlocal(struct connectdata *conn, #ifdef ENABLE_IPV6 /* ipv6 address */ if((af == AF_INET6) && - (Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0)) { - si6->sin6_family = AF_INET6; - si6->sin6_port = htons(port); + (Curl_inet_pton(AF_INET6, myhost, &sock->sa6.sin6_addr) > 0)) { + sock->sa6.sin6_family = AF_INET6; + sock->sa6.sin6_port = htons(port); sizeof_sa = sizeof(struct sockaddr_in6); } else #endif /* ipv4 address */ if((af == AF_INET) && - (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) { - si4->sin_family = AF_INET; - si4->sin_port = htons(port); + (Curl_inet_pton(AF_INET, myhost, &sock->sa4.sin_addr) > 0)) { + sock->sa4.sin_family = AF_INET; + sock->sa4.sin_port = htons(port); sizeof_sa = sizeof(struct sockaddr_in); } } @@ -398,21 +402,21 @@ static CURLcode bindlocal(struct connectdata *conn, /* no device was given, prepare sa to match af's needs */ #ifdef ENABLE_IPV6 if(af == AF_INET6) { - si6->sin6_family = AF_INET6; - si6->sin6_port = htons(port); + sock->sa6.sin6_family = AF_INET6; + sock->sa6.sin6_port = htons(port); sizeof_sa = sizeof(struct sockaddr_in6); } else #endif if(af == AF_INET) { - si4->sin_family = AF_INET; - si4->sin_port = htons(port); + sock->sa4.sin_family = AF_INET; + sock->sa4.sin_port = htons(port); sizeof_sa = sizeof(struct sockaddr_in); } } for(;;) { - if(bind(sockfd, sock, sizeof_sa) >= 0) { + if(bind(sockfd, &sock->sa, sizeof_sa) >= 0) { /* we succeeded to bind */ struct Curl_sockaddr_storage add; curl_socklen_t size = sizeof(add); @@ -432,11 +436,11 @@ static CURLcode bindlocal(struct connectdata *conn, infof(data, "Bind to local port %hu failed, trying next\n", port); port++; /* try next port */ /* We re-use/clobber the port variable here below */ - if(sock->sa_family == AF_INET) - si4->sin_port = ntohs(port); + if(sock->sa.sa_family == AF_INET) + sock->sa4.sin_port = ntohs(port); #ifdef ENABLE_IPV6 else - si6->sin6_port = ntohs(port); + sock->sa6.sin6_port = ntohs(port); #endif } else |