aboutsummaryrefslogtreecommitdiff
path: root/lib/connect.c
diff options
context:
space:
mode:
authorMarc Hoersken <info@marc-hoersken.de>2012-06-11 12:24:03 +0200
committerDaniel Stenberg <daniel@haxx.se>2012-06-11 15:26:30 +0200
commit9c94236e6cc078a0dc5a78b6e2fefc1403e5375e (patch)
tree15c4542b712a0ac9a000a86c6322cdf3a6575b16 /lib/connect.c
parent3f9ab7cf5deb892cc7b8cb3f36322e072898b789 (diff)
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.c38
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