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()) {