This is an automated email from the ASF dual-hosted git repository.

maskit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 78995bf  Add dest addr information to UDPPacket class
78995bf is described below

commit 78995bf4e84fb1f6a39e56782ff4a10c71dc52a9
Author: Masakazu Kitajo <mas...@apache.org>
AuthorDate: Wed Jul 10 16:18:04 2019 +0900

    Add dest addr information to UDPPacket class
---
 iocore/net/P_UDPPacket.h |   6 ++-
 iocore/net/UnixUDPNet.cc | 122 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 122 insertions(+), 6 deletions(-)

diff --git a/iocore/net/P_UDPPacket.h b/iocore/net/P_UDPPacket.h
index 38364e6..d6473aa 100644
--- a/iocore/net/P_UDPPacket.h
+++ b/iocore/net/P_UDPPacket.h
@@ -225,7 +225,7 @@ new_UDPPacket(ink_hrtime when, Ptr<IOBufferBlock> buf)
 }
 
 TS_INLINE UDPPacket *
-new_incoming_UDPPacket(struct sockaddr *from, char *buf, int len)
+new_incoming_UDPPacket(struct sockaddr *from, struct sockaddr *to, char *buf, 
int len)
 {
   UDPPacketInternal *p = udpPacketAllocator.alloc();
 
@@ -233,6 +233,7 @@ new_incoming_UDPPacket(struct sockaddr *from, char *buf, 
int len)
   p->in_heap               = 0;
   p->delivery_time         = 0;
   ats_ip_copy(&p->from, from);
+  ats_ip_copy(&p->to, to);
 
   IOBufferBlock *body = new_IOBufferBlock();
   body->alloc(iobuffer_size_to_index(len));
@@ -244,7 +245,7 @@ new_incoming_UDPPacket(struct sockaddr *from, char *buf, 
int len)
 }
 
 TS_INLINE UDPPacket *
-new_incoming_UDPPacket(struct sockaddr *from, Ptr<IOBufferBlock> &block)
+new_incoming_UDPPacket(struct sockaddr *from, struct sockaddr *to, 
Ptr<IOBufferBlock> &block)
 {
   UDPPacketInternal *p = udpPacketAllocator.alloc();
 
@@ -252,6 +253,7 @@ new_incoming_UDPPacket(struct sockaddr *from, 
Ptr<IOBufferBlock> &block)
   p->in_heap               = 0;
   p->delivery_time         = 0;
   ats_ip_copy(&p->from, from);
+  ats_ip_copy(&p->to, to);
   p->chain = block;
 
   return p;
diff --git a/iocore/net/UnixUDPNet.cc b/iocore/net/UnixUDPNet.cc
index 8215cde..cd223c2 100644
--- a/iocore/net/UnixUDPNet.cc
+++ b/iocore/net/UnixUDPNet.cc
@@ -29,6 +29,11 @@
 
  ****************************************************************************/
 
+#if defined(darwin)
+/* This is for IPV6_PKTINFO and IPV6_RECVPKTINFO */
+#define __APPLE_USE_RFC_3542
+#endif
+
 #include "P_Net.h"
 #include "P_UDPNet.h"
 
@@ -162,12 +167,15 @@ UDPNetProcessorInternal::udp_read_from_net(UDPNetHandler 
*nh, UDPConnection *xuc
 
     // build struct msghdr
     sockaddr_in6 fromaddr;
+    sockaddr_in6 toaddr;
+    int toaddr_len = sizeof(toaddr);
+    char *cbuf[1024];
     msg.msg_name       = &fromaddr;
     msg.msg_namelen    = sizeof(fromaddr);
     msg.msg_iov        = tiovec;
     msg.msg_iovlen     = niov;
-    msg.msg_control    = nullptr;
-    msg.msg_controllen = 0;
+    msg.msg_control    = cbuf;
+    msg.msg_controllen = sizeof(cbuf);
 
     // receive data by recvmsg
     r = socketManager.recvmsg(uc->getFd(), &msg, 0);
@@ -197,8 +205,38 @@ UDPNetProcessorInternal::udp_read_from_net(UDPNetHandler 
*nh, UDPConnection *xuc
       }
     }
 
+    safe_getsockname(xuc->getFd(), reinterpret_cast<struct sockaddr 
*>(&toaddr), &toaddr_len);
+    for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr; cmsg = 
CMSG_NXTHDR(&msg, cmsg)) {
+      switch (cmsg->cmsg_type) {
+#ifdef IP_PKTINFO
+      case IP_PKTINFO:
+        if (cmsg->cmsg_level == IPPROTO_IP) {
+          struct in_pktinfo *pktinfo                                = 
reinterpret_cast<struct in_pktinfo *>(CMSG_DATA(cmsg));
+          reinterpret_cast<sockaddr_in *>(&toaddr)->sin_addr.s_addr = 
pktinfo->ipi_addr.s_addr;
+        }
+        break;
+#endif
+#ifdef IP_RECVDSTADDR
+      case IP_RECVDSTADDR:
+        if (cmsg->cmsg_level == IPPROTO_IP) {
+          struct in_addr *addr                                      = 
reinterpret_cast<struct in_addr *>(CMSG_DATA(cmsg));
+          reinterpret_cast<sockaddr_in *>(&toaddr)->sin_addr.s_addr = 
addr->s_addr;
+        }
+        break;
+#endif
+#if defined(IPV6_PKTINFO) || defined(IPV6_RECVPKTINFO)
+      case IPV6_PKTINFO: // IPV6_RECVPKTINFO uses IPV6_PKTINFO too
+        if (cmsg->cmsg_level == IPPROTO_IPV6) {
+          struct in6_pktinfo *pktinfo = reinterpret_cast<struct in6_pktinfo 
*>(CMSG_DATA(cmsg));
+          memcpy(toaddr.sin6_addr.s6_addr, &pktinfo->ipi6_addr, 16);
+        }
+        break;
+#endif
+      }
+    }
+
     // create packet
-    UDPPacket *p = new_incoming_UDPPacket(ats_ip_sa_cast(&fromaddr), chain);
+    UDPPacket *p = new_incoming_UDPPacket(ats_ip_sa_cast(&fromaddr), 
ats_ip_sa_cast(&toaddr), chain);
     p->setConnection(uc);
     // queue onto the UDPConnection
     uc->inQueue.push((UDPPacketInternal *)p);
@@ -628,6 +666,42 @@ UDPNetProcessor::CreateUDPSocket(int *resfd, sockaddr 
const *remote_addr, Action
     }
   }
 
+  if (opt.ip_family == AF_INET) {
+    bool succeeded = false;
+    int enable     = 1;
+#ifdef IP_PKTINFO
+    if ((res = safe_setsockopt(fd, IPPROTO_IP, IP_PKTINFO, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+#ifdef IP_RECVDSTADDR
+    if ((res = safe_setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+    if (!succeeded) {
+      Debug("udpnet", "setsockeopt for pktinfo failed");
+      goto HardError;
+    }
+  } else if (opt.ip_family == AF_INET6) {
+    bool succeeded = false;
+    int enable     = 1;
+#ifdef IPV6_PKTINFO
+    if ((res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+#ifdef IPV6_RECVPKTINFO
+    if ((res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+    if (!succeeded) {
+      Debug("udpnet", "setsockeopt for pktinfo failed");
+      goto HardError;
+    }
+  }
+
   if (local_addr.port() || !is_any_address) {
     if (-1 == socketManager.ink_bind(fd, &local_addr.sa, 
ats_ip_size(&local_addr.sa))) {
       char buff[INET6_ADDRPORTSTRLEN];
@@ -683,6 +757,42 @@ UDPNetProcessor::UDPBind(Continuation *cont, sockaddr 
const *addr, int send_bufs
     goto Lerror;
   }
 
+  if (addr->sa_family == AF_INET) {
+    bool succeeded = false;
+    int enable     = 1;
+#ifdef IP_PKTINFO
+    if ((res = safe_setsockopt(fd, IPPROTO_IP, IP_PKTINFO, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+#ifdef IP_RECVDSTADDR
+    if ((res = safe_setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+    if (!succeeded) {
+      Debug("udpnet", "setsockeopt for pktinfo failed");
+      goto Lerror;
+    }
+  } else if (addr->sa_family == AF_INET6) {
+    bool succeeded = false;
+    int enable     = 1;
+#ifdef IPV6_PKTINFO
+    if ((res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+#ifdef IPV6_RECVPKTINFO
+    if ((res = safe_setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 
reinterpret_cast<char *>(&enable), sizeof(enable))) == 0) {
+      succeeded = true;
+    }
+#endif
+    if (!succeeded) {
+      Debug("udpnet", "setsockeopt for pktinfo failed");
+      goto Lerror;
+    }
+  }
+
   // If this is a class D address (i.e. multicast address), use REUSEADDR.
   if (ats_is_ip_multicast(addr)) {
     int enable_reuseaddr = 1;
@@ -692,6 +802,10 @@ UDPNetProcessor::UDPBind(Continuation *cont, sockaddr 
const *addr, int send_bufs
     }
   }
 
+  if (ats_is_ip6(addr) && (res = safe_setsockopt(fd, IPPROTO_IPV6, 
IPV6_V6ONLY, SOCKOPT_ON, sizeof(int))) < 0) {
+    goto Lerror;
+  }
+
   if ((res = socketManager.ink_bind(fd, addr, ats_ip_size(addr))) < 0) {
     goto Lerror;
   }
@@ -858,7 +972,7 @@ UDPQueue::SendUDPPacket(UDPPacketInternal *p, int32_t /* 
pktLen ATS_UNUSED */)
   msg.msg_flags      = 0;
 #endif
   msg.msg_name    = (caddr_t)&p->to.sa;
-  msg.msg_namelen = sizeof(p->to.sa);
+  msg.msg_namelen = ats_ip_size(p->to);
   iov_len         = 0;
 
   for (IOBufferBlock *b = p->chain.get(); b != nullptr; b = b->next.get()) {

Reply via email to