Fix strict aliasing violation problems
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Thu, 17 Jun 2010 10:43:20 +0100
changeset 6360 15748df6a6f5
parent 6359 ac14db4d8547
child 6361 cb759b8b3a51
Fix strict aliasing violation problems
src/real-stack/real-udp-socket.cc
--- a/src/real-stack/real-udp-socket.cc	Tue Jun 15 19:03:05 2010 +0100
+++ b/src/real-stack/real-udp-socket.cc	Thu Jun 17 10:43:20 2010 +0100
@@ -49,18 +49,24 @@
 
 namespace {
 
+union SockAddr
+{
+  struct sockaddr base;
+  struct sockaddr_in in;
+  struct sockaddr_in6 in6;
+};
+
 bool
-ConvertAddressNs3ToUnix (const Address &ns3Address, struct sockaddr_storage *addr, socklen_t *addrlen)
+ConvertAddressNs3ToUnix (const Address &ns3Address, SockAddr *addr, socklen_t *addrlen)
 {
   if (InetSocketAddress::IsMatchingType (ns3Address))
     {
       InetSocketAddress ns3_inaddr = InetSocketAddress::ConvertFrom (ns3Address);
-      struct sockaddr_in *out_inaddr = reinterpret_cast<struct sockaddr_in *> (addr);
       
-      out_inaddr->sin_family = AF_INET;
-      out_inaddr->sin_port = htons (ns3_inaddr.GetPort ());
-      out_inaddr->sin_addr.s_addr = htonl (ns3_inaddr.GetIpv4 ().Get ());
-      *addrlen = sizeof (*out_inaddr);
+      addr->in.sin_family = AF_INET;
+      addr->in.sin_port = htons (ns3_inaddr.GetPort ());
+      addr->in.sin_addr.s_addr = htonl (ns3_inaddr.GetIpv4 ().Get ());
+      *addrlen = sizeof (addr->in);
 
       return true;
     }
@@ -69,14 +75,13 @@
 }
 
 bool
-ConvertAddressUnixToNs3 (struct sockaddr_storage const *addr, socklen_t addrlen, Address *out_ns3Address)
+ConvertAddressUnixToNs3 (SockAddr const *addr, socklen_t addrlen, Address *out_ns3Address)
 {  
-  switch (addr->ss_family)
+  switch (addr->base.sa_family)
     {
     case AF_INET:
-      struct sockaddr_in const *sin_addr = reinterpret_cast<struct sockaddr_in const *> (addr);
-      *out_ns3Address = InetSocketAddress (Ipv4Address (ntohl (sin_addr->sin_addr.s_addr)),
-                                           ntohs (sin_addr->sin_port));
+      *out_ns3Address = InetSocketAddress (Ipv4Address (ntohl (addr->in.sin_addr.s_addr)),
+                                           ntohs (addr->in.sin_port));
       return true;
     }
   // TODO: IPv6
@@ -199,8 +204,8 @@
   //
 
   int32_t len = -1;
-  struct sockaddr_storage addr;
-  socklen_t addrSize = sizeof (addr);
+  SockAddr addr;
+  socklen_t addrSize;
   NS_ASSERT_MSG (m_rtImpl, "RealUdpSocket::ReadThread(): Realtime simulator implementation pointer not set");
 
   for (;;) 
@@ -250,7 +255,8 @@
         }
 
       NS_LOG_LOGIC ("Calling recvfrom");
-      len = recvfrom (m_socketFd, buf, bufferSize, 0, (struct sockaddr *)&addr, &addrSize);
+      addrSize = sizeof (addr);
+      len = recvfrom (m_socketFd, buf, bufferSize, 0, &addr.base, &addrSize);
 
       if (len == -1)
         {
@@ -314,11 +320,11 @@
   NS_LOG_FUNCTION (this << address);
   NS_ASSERT (m_socketFd >= 0);
 
-  struct sockaddr_storage addr;
+  SockAddr addr;
   socklen_t addrlen = 0;
   ConvertAddressNs3ToUnix (address, &addr, &addrlen);
 
-  int ret = bind (m_socketFd, reinterpret_cast<struct sockaddr*> (&addr), addrlen);
+  int ret = bind (m_socketFd, &addr.base, addrlen);
   if (ret)
     {
       NS_LOG_DEBUG ("bind() failed: " << strerror (errno));
@@ -363,13 +369,13 @@
 {
   NS_LOG_FUNCTION (this << address);
 
-  struct sockaddr_storage addr;
+  SockAddr addr;
   socklen_t addrlen = 0;
   if (!ConvertAddressNs3ToUnix (address, &addr, &addrlen))
     {
       NS_FATAL_ERROR ("could not convert address");
     }
-  int ret = connect (m_socketFd, reinterpret_cast<struct sockaddr*> (&addr), addrlen);
+  int ret = connect (m_socketFd, &addr.base, addrlen);
   if (ret)
     {
       NS_LOG_DEBUG ("connect() failed: " << strerror (errno));
@@ -421,13 +427,13 @@
   uint8_t *buf = new uint8_t [len];
   p->CopyData (buf, len);
 
-  struct sockaddr_storage saddr;
+  SockAddr saddr;
   socklen_t slen;
   if (!ConvertAddressNs3ToUnix (address, &saddr, &slen))
     {
       NS_FATAL_ERROR ("could not convert address");
     }
-  ssize_t ret = sendto (m_socketFd, buf, len, 0, reinterpret_cast<struct sockaddr *> (&saddr), slen);
+  ssize_t ret = sendto (m_socketFd, buf, len, 0, &saddr.base, slen);
   delete [] buf;
   if (ret > 0) 
     {