Avoid extensive casting of sockaddr types in socket-default by using a union
Additionally fixes a strict-aliasing rule compiler warning with older gcc.
This commit is contained in:
@@ -433,22 +433,24 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
int family, u_int16_t *port)
|
int family, u_int16_t *port)
|
||||||
{
|
{
|
||||||
int on = TRUE;
|
int on = TRUE;
|
||||||
struct sockaddr_storage addr;
|
union {
|
||||||
|
struct sockaddr sockaddr;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
struct sockaddr_in6 sin6;
|
||||||
|
} addr;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
u_int sol, pktinfo = 0;
|
u_int sol, pktinfo = 0;
|
||||||
int skt;
|
int skt;
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.ss_family = family;
|
addr.sockaddr.sa_family = family;
|
||||||
/* precalculate constants depending on address family */
|
/* precalculate constants depending on address family */
|
||||||
switch (family)
|
switch (family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
addr.sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
|
addr.sin.sin_port = htons(*port);
|
||||||
htoun32(&sin->sin_addr.s_addr, INADDR_ANY);
|
addrlen = sizeof(addr.sin);
|
||||||
htoun16(&sin->sin_port, *port);
|
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
|
||||||
sol = SOL_IP;
|
sol = SOL_IP;
|
||||||
#ifdef IP_PKTINFO
|
#ifdef IP_PKTINFO
|
||||||
pktinfo = IP_PKTINFO;
|
pktinfo = IP_PKTINFO;
|
||||||
@@ -456,17 +458,13 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
pktinfo = IP_RECVDSTADDR;
|
pktinfo = IP_RECVDSTADDR;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
{
|
memcpy(&addr.sin6.sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
|
addr.sin6.sin6_port = htons(*port);
|
||||||
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
addrlen = sizeof(addr.sin6);
|
||||||
htoun16(&sin6->sin6_port, *port);
|
|
||||||
addrlen = sizeof(struct sockaddr_in6);
|
|
||||||
sol = SOL_IPV6;
|
sol = SOL_IPV6;
|
||||||
pktinfo = IPV6_RECVPKTINFO;
|
pktinfo = IPV6_RECVPKTINFO;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -485,7 +483,7 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* bind the socket */
|
/* bind the socket */
|
||||||
if (bind(skt, (struct sockaddr *)&addr, addrlen) < 0)
|
if (bind(skt, &addr.sockaddr, addrlen) < 0)
|
||||||
{
|
{
|
||||||
DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
|
DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
|
||||||
close(skt);
|
close(skt);
|
||||||
@@ -495,7 +493,7 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
/* retrieve randomly allocated port if needed */
|
/* retrieve randomly allocated port if needed */
|
||||||
if (*port == 0)
|
if (*port == 0)
|
||||||
{
|
{
|
||||||
if (getsockname(skt, (struct sockaddr *)&addr, &addrlen) < 0)
|
if (getsockname(skt, &addr.sockaddr, &addrlen) < 0)
|
||||||
{
|
{
|
||||||
DBG1(DBG_NET, "unable to determine port: %s", strerror(errno));
|
DBG1(DBG_NET, "unable to determine port: %s", strerror(errno));
|
||||||
close(skt);
|
close(skt);
|
||||||
@@ -504,17 +502,11 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
switch (family)
|
switch (family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
*port = ntohs(addr.sin.sin_port);
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
|
|
||||||
*port = untoh16(&sin->sin_port);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
{
|
*port = ntohs(addr.sin6.sin6_port);
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
|
|
||||||
*port = untoh16(&sin6->sin6_port);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user