]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsproxy.cc and nameserver.cc use addCMsgSrcAddr() to add a source address control... 1103/head
authorKonstantinos Natsakis <github.com@aleph-0.net>
Sun, 24 Nov 2013 12:20:28 +0000 (14:20 +0200)
committerKonstantinos Natsakis <github.com@aleph-0.net>
Sun, 24 Nov 2013 12:20:28 +0000 (14:20 +0200)
pdns/dnsproxy.cc
pdns/misc.cc
pdns/misc.hh
pdns/nameserver.cc

index 8d586c90d6bd31040701658ab0ae62e0e571286b..fe280e438e938f6bd7c7f4210f00ee8bf7b846ce 100644 (file)
@@ -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"<<endl;
           continue;
         }
-        {
-          struct msghdr msgh;
-          struct cmsghdr *cmsg;
-          struct iovec iov;
-          char cbuf[256];
-
-          /* 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) {
-            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;
index 5b3f895d8f8643536bc3d6db548d465d34e262eb..bc4ea96b575026cac23747f853929b68446c952a 100644 (file)
@@ -45,6 +45,7 @@
 #include "utility.hh"
 #include <boost/algorithm/string.hpp>
 #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;
+  }
+}
index 63857f595b5835256f2c2378018e9cd3cc740253..67480765c56a17e3f5ef6dd2ebe47798d60f3212 100644 (file)
@@ -508,4 +508,6 @@ private:
   regex_t d_preg;
 };
 
+union ComboAddress;
+void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, ComboAddress* source);
 #endif
index c5b0bb036591996d48753b03e2c5f8a20057e490..a9a630856038e4fae7b7c6f45d7489f4a1d79225 100644 (file)
@@ -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<<Logger::Notice<<"Sending a packet to "<< p->getRemote() <<" ("<< buffer.length()<<" octets)"<<endl);
   if(buffer.length() > p->getMaxReplyLen()) {