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 <[email protected]>
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()) {