From: Konstantinos Natsakis Date: Sun, 24 Nov 2013 12:20:28 +0000 (+0200) Subject: dnsproxy.cc and nameserver.cc use addCMsgSrcAddr() to add a source address control... X-Git-Tag: rec-3.6.0-rc1~270^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F1103%2Fhead;p=thirdparty%2Fpdns.git dnsproxy.cc and nameserver.cc use addCMsgSrcAddr() to add a source address control message before sendmsg --- diff --git a/pdns/dnsproxy.cc b/pdns/dnsproxy.cc index 8d586c90d6..fe280e438e 100644 --- a/pdns/dnsproxy.cc +++ b/pdns/dnsproxy.cc @@ -151,6 +151,10 @@ void DNSProxy::mainloop(void) char buffer[1500]; int len; + struct msghdr msgh; + struct iovec iov; + char cbuf[256]; + for(;;) { len=recv(d_sock, buffer, sizeof(buffer),0); // answer from our backend if(len<12) { @@ -195,72 +199,20 @@ void DNSProxy::mainloop(void) ", qname or qtype mismatch"<second.remote; - msgh.msg_namelen = i->second.remote.getSocklen(); - - if(i->second.anyLocal) { - if(i->second.anyLocal->sin4.sin_family == AF_INET6) { - struct in6_pktinfo *pkt; - - msgh.msg_control = cbuf; - msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt)); - - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = IPPROTO_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt)); - - pkt = (struct in6_pktinfo *) CMSG_DATA(cmsg); - memset(pkt, 0, sizeof(*pkt)); - pkt->ipi6_addr = i->second.anyLocal->sin6.sin6_addr; - msgh.msg_controllen = cmsg->cmsg_len; // makes valgrind happy and is slightly better style - } - else { -#ifdef IP_PKTINFO - struct in_pktinfo *pkt; - msgh.msg_control = cbuf; - msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt)); - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt)); - - pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); - memset(pkt, 0, sizeof(*pkt)); - pkt->ipi_spec_dst = i->second.anyLocal->sin4.sin_addr; -#endif -#ifdef IP_SENDSRCADDR - struct in_addr *in; - - msgh.msg_control = cbuf; - msgh.msg_controllen = CMSG_SPACE(sizeof(*in)); - - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_SENDSRCADDR; - cmsg->cmsg_len = CMSG_LEN(sizeof(*in)); - - in = (struct in_addr *) CMSG_DATA(cmsg); - *in = i->second.anyLocal->sin4.sin_addr; -#endif - msgh.msg_controllen = cmsg->cmsg_len; - } - } - sendmsg(i->second.outsock, &msgh, 0); + /* Set up iov and msgh structures. */ + memset(&msgh, 0, sizeof(struct msghdr)); + iov.iov_base = buffer; + iov.iov_len = len; + msgh.msg_iov = &iov; + msgh.msg_iovlen = 1; + msgh.msg_name = (struct sockaddr*)&i->second.remote; + msgh.msg_namelen = i->second.remote.getSocklen(); + + if(i->second.anyLocal) { + addCMsgSrcAddr(&msgh, cbuf, i->second.anyLocal.get_ptr()); } + sendmsg(i->second.outsock, &msgh, 0); PC.insert(&q, &p); i->second.created=0; diff --git a/pdns/misc.cc b/pdns/misc.cc index 5b3f895d8f..bc4ea96b57 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -45,6 +45,7 @@ #include "utility.hh" #include #include "logger.hh" +#include "iputils.hh" bool g_singleThreaded; @@ -761,3 +762,57 @@ Regex::Regex(const string &expr) if(regcomp(&d_preg, expr.c_str(), REG_ICASE|REG_NOSUB|REG_EXTENDED)) throw PDNSException("Regular expression did not compile"); } + +void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, ComboAddress* source) +{ + struct cmsghdr *cmsg; + + if(source->sin4.sin_family == AF_INET6) { + struct in6_pktinfo *pkt; + + msgh->msg_control = cmsgbuf; + msgh->msg_controllen = CMSG_SPACE(sizeof(*pkt)); + + cmsg = CMSG_FIRSTHDR(msgh); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt)); + + pkt = (struct in6_pktinfo *) CMSG_DATA(cmsg); + memset(pkt, 0, sizeof(*pkt)); + pkt->ipi6_addr = source->sin6.sin6_addr; + msgh->msg_controllen = cmsg->cmsg_len; // makes valgrind happy and is slightly better style + } + else { +#ifdef IP_PKTINFO + struct in_pktinfo *pkt; + + msgh->msg_control = cmsgbuf; + msgh->msg_controllen = CMSG_SPACE(sizeof(*pkt)); + + cmsg = CMSG_FIRSTHDR(msgh); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt)); + + pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); + memset(pkt, 0, sizeof(*pkt)); + pkt->ipi_spec_dst = source->sin4.sin_addr; +#endif +#ifdef IP_SENDSRCADDR + struct in_addr *in; + + msgh->msg_control = cmsgbuf; + msgh->msg_controllen = CMSG_SPACE(sizeof(*in)); + + cmsg = CMSG_FIRSTHDR(msgh); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_SENDSRCADDR; + cmsg->cmsg_len = CMSG_LEN(sizeof(*in)); + + in = (struct in_addr *) CMSG_DATA(cmsg); + *in = source->sin4.sin_addr; +#endif + msgh->msg_controllen = cmsg->cmsg_len; + } +} diff --git a/pdns/misc.hh b/pdns/misc.hh index 63857f595b..67480765c5 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -508,4 +508,6 @@ private: regex_t d_preg; }; +union ComboAddress; +void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, ComboAddress* source); #endif diff --git a/pdns/nameserver.cc b/pdns/nameserver.cc index c5b0bb0365..a9a6308560 100644 --- a/pdns/nameserver.cc +++ b/pdns/nameserver.cc @@ -254,7 +254,6 @@ void UDPNameserver::send(DNSPacket *p) g_rs.submitResponse(p->qtype.getCode(), buffer.length(), true); struct msghdr msgh; - struct cmsghdr *cmsg; struct iovec iov; char cbuf[256]; @@ -285,53 +284,7 @@ void UDPNameserver::send(DNSPacket *p) msgh.msg_namelen = p->d_remote.getSocklen(); if(p->d_anyLocal) { - if(p->d_anyLocal->sin4.sin_family == AF_INET6) { - struct in6_pktinfo *pkt; - - msgh.msg_control = cbuf; - msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt)); - - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = IPPROTO_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt)); - - pkt = (struct in6_pktinfo *) CMSG_DATA(cmsg); - memset(pkt, 0, sizeof(*pkt)); - pkt->ipi6_addr = p->d_anyLocal->sin6.sin6_addr; - msgh.msg_controllen = cmsg->cmsg_len; // makes valgrind happy and is slightly better style - } - else { -#ifdef IP_PKTINFO - struct in_pktinfo *pkt; - msgh.msg_control = cbuf; - msgh.msg_controllen = CMSG_SPACE(sizeof(*pkt)); - - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(*pkt)); - - pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); - memset(pkt, 0, sizeof(*pkt)); - pkt->ipi_spec_dst = p->d_anyLocal->sin4.sin_addr; -#endif -#ifdef IP_SENDSRCADDR - struct in_addr *in; - - msgh.msg_control = cbuf; - msgh.msg_controllen = CMSG_SPACE(sizeof(*in)); - - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_SENDSRCADDR; - cmsg->cmsg_len = CMSG_LEN(sizeof(*in)); - - in = (struct in_addr *) CMSG_DATA(cmsg); - *in = p->d_anyLocal->sin4.sin_addr; -#endif - msgh.msg_controllen = cmsg->cmsg_len; - } + addCMsgSrcAddr(&msgh, cbuf, p->d_anyLocal.get_ptr()); } DLOG(L<getRemote() <<" ("<< buffer.length()<<" octets)"< p->getMaxReplyLen()) {