]> granicus.if.org Git - pdns/commitdiff
Align cmsg aux data, as recommended by OpenBSD manpage.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 25 Jun 2019 12:27:00 +0000 (14:27 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 25 Jun 2019 12:27:00 +0000 (14:27 +0200)
pdns/calidns.cc
pdns/dnsdist.cc
pdns/dnsproxy.cc
pdns/iputils.cc
pdns/iputils.hh
pdns/misc.cc
pdns/misc.hh
pdns/nameserver.cc
pdns/pdns_recursor.cc

index 0f11e790fe588132fcce4c69ccea02d6dc235710..1d80ac81b90a8380d81801d610d2b9ebf455b7b1 100644 (file)
@@ -71,11 +71,13 @@ static void* recvThread(const vector<Socket*>* sockets)
 #if HAVE_RECVMMSG
   vector<struct mmsghdr> buf(100);
   for(auto& m : buf) {
-    fillMSGHdr(&m.msg_hdr, new struct iovec, new char[512], 512, new char[1500], 1500, new ComboAddress("127.0.0.1"));
+    cmsgbuf_aligned *cbuf = new cmsgbuf_aligned;
+    fillMSGHdr(&m.msg_hdr, new struct iovec, cbuf, sizeof(*cbuf), new char[1500], 1500, new ComboAddress("127.0.0.1"));
   }
 #else
   struct msghdr buf;
-  fillMSGHdr(&buf, new struct iovec, new char[512], 512, new char[1500], 1500, new ComboAddress("127.0.0.1"));
+  cmsgbuf_aligned *cbuf = new cmsgbuf_aligned;
+  fillMSGHdr(&buf, new struct iovec, cbuf, sizeof(*cbuf), new char[1500], 1500, new ComboAddress("127.0.0.1"));
 #endif
 
   while(!g_done) {
@@ -183,7 +185,7 @@ static void sendPackets(const vector<Socket*>* sockets, const vector<vector<uint
   struct Unit {
     struct msghdr msgh;
     struct iovec iov;
-    char cbuf[256];
+    cmsgbuf_aligned cbuf;
   };
   vector<unique_ptr<Unit> > units;
   int ret;
index d5c17029a986ca9f5ebabb205317182dcd1f3a8a..dddcb79d8a74af5c17afe4d350902305683e2329 100644 (file)
@@ -1224,10 +1224,10 @@ ssize_t udpClientSendRequestToBackend(const std::shared_ptr<DownstreamState>& ss
   else {
     struct msghdr msgh;
     struct iovec iov;
-    char cbuf[256];
+    cmsgbuf_aligned cbuf;
     ComboAddress remote(ss->remote);
-    fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), const_cast<char*>(request), requestLen, &remote);
-    addCMsgSrcAddr(&msgh, cbuf, &ss->sourceAddr, ss->sourceItf);
+    fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast<char*>(request), requestLen, &remote);
+    addCMsgSrcAddr(&msgh, &cbuf, &ss->sourceAddr, ss->sourceItf);
     result = sendmsg(sd, &msgh, 0);
   }
 
@@ -1321,7 +1321,7 @@ bool checkQueryHeaders(const struct dnsheader* dh)
 }
 
 #if defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE)
-static void queueResponse(const ClientState& cs, const char* response, uint16_t responseLen, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, char* cbuf)
+static void queueResponse(const ClientState& cs, const char* response, uint16_t responseLen, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cbuf_aligned* cbuf)
 {
   outMsg.msg_len = 0;
   fillMSGHdr(&outMsg.msg_hdr, iov, nullptr, 0, const_cast<char*>(response), responseLen, const_cast<ComboAddress*>(&remote));
@@ -1502,7 +1502,7 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders&
   return ProcessQueryResult::Drop;
 }
 
-static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, char* query, uint16_t len, size_t queryBufferSize, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, char* respCBuf)
+static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, char* query, uint16_t len, size_t queryBufferSize, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, cmsgbuf_aligned* respCBuf)
 {
   assert(responsesVect == nullptr || (queuedResponses != nullptr && respIOV != nullptr && respCBuf != nullptr));
   uint16_t queryId = 0;
@@ -1619,7 +1619,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde
   {
     char packet[4096];
     /* used by HarvestDestinationAddress */
-    char cbuf[256];
+    cmsgbuf_aligned cbuf;
     ComboAddress remote;
     ComboAddress dest;
     struct iovec iov;
@@ -1639,7 +1639,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde
   /* initialize the structures needed to receive our messages */
   for (size_t idx = 0; idx < vectSize; idx++) {
     recvData[idx].remote.sin4.sin_family = cs->local.sin4.sin_family;
-    fillMSGHdr(&msgVec[idx].msg_hdr, &recvData[idx].iov, recvData[idx].cbuf, sizeof(recvData[idx].cbuf), recvData[idx].packet, s_udpIncomingBufferSize, &recvData[idx].remote);
+    fillMSGHdr(&msgVec[idx].msg_hdr, &recvData[idx].iov, &recvData[idx].cbuf, sizeof(recvData[idx].cbuf), recvData[idx].packet, s_udpIncomingBufferSize, &recvData[idx].remote);
   }
 
   /* go now */
@@ -1674,7 +1674,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde
         continue;
       }
 
-      processUDPQuery(*cs, holders, msgh, remote, recvData[msgIdx].dest, recvData[msgIdx].packet, static_cast<uint16_t>(got), sizeof(recvData[msgIdx].packet), outMsgVec.get(), &msgsToSend, &recvData[msgIdx].iov, recvData[msgIdx].cbuf);
+      processUDPQuery(*cs, holders, msgh, remote, recvData[msgIdx].dest, recvData[msgIdx].packet, static_cast<uint16_t>(got), sizeof(recvData[msgIdx].packet), outMsgVec.get(), &msgsToSend, &recvData[msgIdx].iov, &recvData[msgIdx].cbuf);
 
     }
 
@@ -1718,12 +1718,12 @@ try
     struct msghdr msgh;
     struct iovec iov;
     /* used by HarvestDestinationAddress */
-    char cbuf[256];
+    cmsgbuf_aligned cbuf;
 
     ComboAddress remote;
     ComboAddress dest;
     remote.sin4.sin_family = cs->local.sin4.sin_family;
-    fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), packet, sizeof(packet), &remote);
+    fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), packet, sizeof(packet), &remote);
 
     for(;;) {
       ssize_t got = recvmsg(cs->udpFD, &msgh, 0);
index 69e5fd1b56e4f856e44f8e9e8662db7836c31825..eafc6663efc6345988aacb75b09a0290a6e04672 100644 (file)
@@ -191,7 +191,7 @@ void DNSProxy::mainloop(void)
 
     struct msghdr msgh;
     struct iovec iov;
-    char cbuf[256];
+    cmsgbuf_aligned cbuf;
     ComboAddress fromaddr;
 
     for(;;) {
@@ -284,7 +284,7 @@ void DNSProxy::mainloop(void)
         msgh.msg_control=NULL;
 
         if(i->second.anyLocal) {
-          addCMsgSrcAddr(&msgh, cbuf, i->second.anyLocal.get_ptr(), 0);
+          addCMsgSrcAddr(&msgh, &cbuf, i->second.anyLocal.get_ptr(), 0);
         }
         if(sendmsg(i->second.outsock, &msgh, 0) < 0)
           g_log<<Logger::Warning<<"dnsproxy.cc: Error sending reply with sendmsg (socket="<<i->second.outsock<<"): "<<strerror(errno)<<endl;
index f58d0e31b2770cb2260ba261b1d4c2cb89580004..0f9edcd1c33cbce79c857858dee773ee7440e4f2 100644 (file)
@@ -221,7 +221,7 @@ ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const Comb
 {
   struct msghdr msgh;
   struct iovec iov;
-  char cbuf[256];
+  cmsgbuf_aligned cbuf;
 
   /* Set up iov and msgh structures. */
   memset(&msgh, 0, sizeof(struct msghdr));
@@ -233,7 +233,7 @@ ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const Comb
   msgh.msg_namelen = to.getSocklen();
 
   if(from.sin4.sin_family) {
-    addCMsgSrcAddr(&msgh, cbuf, &from, 0);
+    addCMsgSrcAddr(&msgh, &cbuf, &from, 0);
   }
   else {
     msgh.msg_control=NULL;
@@ -244,7 +244,7 @@ ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const Comb
 // be careful: when using this for receive purposes, make sure addr->sin4.sin_family is set appropriately so getSocklen works!
 // be careful: when using this function for *send* purposes, be sure to set cbufsize to 0!
 // be careful: if you don't call addCMsgSrcAddr after fillMSGHdr, make sure to set msg_control to NULL
-void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, char* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr)
+void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, cmsgbuf_aligned* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr)
 {
   iov->iov_base = data;
   iov->iov_len  = datalen;
@@ -294,7 +294,7 @@ size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAdd
 {
   struct msghdr msgh;
   struct iovec iov;
-  char cbuf[256];
+  cmsgbuf_aligned cbuf;
 
   /* Set up iov and msgh structures. */
   memset(&msgh, 0, sizeof(struct msghdr));
@@ -312,7 +312,7 @@ size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAdd
   msgh.msg_flags = 0;
 
   if (localItf != 0 && local) {
-    addCMsgSrcAddr(&msgh, cbuf, local, localItf);
+    addCMsgSrcAddr(&msgh, &cbuf, local, localItf);
   }
 
   iov.iov_base = reinterpret_cast<void*>(const_cast<char*>(buffer));
index 18d6e881949cd5d23a62bece3e23a4b69ef5018f..d0b01adddb47be1f3e0b19e0a189cc1869d07554 100644 (file)
@@ -1057,7 +1057,7 @@ void setSocketIgnorePMTU(int sockfd);
 bool IsAnyAddress(const ComboAddress& addr);
 bool HarvestDestinationAddress(const struct msghdr* msgh, ComboAddress* destination);
 bool HarvestTimestamp(struct msghdr* msgh, struct timeval* tv);
-void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, char* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr);
+void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, cmsgbuf_aligned* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr);
 ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const ComboAddress& from, const ComboAddress& to);
 size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAddress* dest, const ComboAddress* local, unsigned int localItf, int flags);
 
index 1f90bbcbd14c4ff8bf98c9d7d8729f712ed73bc7..4aedbc11b7514ce4fb1111747ad4a49d13cb2c8e 100644 (file)
@@ -884,7 +884,10 @@ Regex::Regex(const string &expr)
 // if you end up here because valgrind told you were are doing something wrong
 // with msgh->msg_controllen, please refer to https://github.com/PowerDNS/pdns/pull/3962
 // first.
-void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, const ComboAddress* source, int itfIndex)
+// Note that cmsgbuf should be aligned the same as a struct cmsghdr
+// This can be achieved by declaring it as
+//    union { struct cmsghdr hdr; char buf[CMSG_SPACE(spaceneeded)]; } cmsgbuf;
+void addCMsgSrcAddr(struct msghdr* msgh, cmsgbuf_aligned* cmsgbuf, const ComboAddress* source, int itfIndex)
 {
   struct cmsghdr *cmsg = NULL;
 
index 205f033d2daf22f814dfc4e6b382394dd96e8188..67472bd577af92a5f9c31ea1109a9a9eda506e1b 100644 (file)
@@ -515,8 +515,11 @@ private:
 };
 
 union ComboAddress;
+
+typedef union { struct cmsghdr hdr; char buf[256]; } cmsgbuf_aligned;
+
 /* itfIndex is an interface index, as returned by if_nametoindex(). 0 means default. */
-void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, const ComboAddress* source, int itfIndex);
+void addCMsgSrcAddr(struct msghdr* msgh, cmsgbuf_aligned* cbuf, const ComboAddress* source, int itfIndex);
 
 unsigned int getFilenumLimit(bool hardOrSoft=0);
 void setFilenumLimit(unsigned int lim);
index 55812391712774d76a0ad99c7365ad57e94bac66..6044a449238a8c3a9ecbc30afea5c4580cf6ecbe 100644 (file)
@@ -295,13 +295,13 @@ void UDPNameserver::send(DNSPacket *p)
 
   struct msghdr msgh;
   struct iovec iov;
-  char cbuf[256];
+  cmsgbuf_aligned cbuf;
 
-  fillMSGHdr(&msgh, &iov, cbuf, 0, (char*)buffer.c_str(), buffer.length(), &p->d_remote);
+  fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)buffer.c_str(), buffer.length(), &p->d_remote);
 
   msgh.msg_control=NULL;
   if(p->d_anyLocal) {
-    addCMsgSrcAddr(&msgh, cbuf, p->d_anyLocal.get_ptr(), 0);
+    addCMsgSrcAddr(&msgh, &cbuf, p->d_anyLocal.get_ptr(), 0);
   }
   DLOG(g_log<<Logger::Notice<<"Sending a packet to "<< p->getRemote() <<" ("<< buffer.length()<<" octets)"<<endl);
   if(buffer.length() > p->getMaxReplyLen()) {
@@ -320,10 +320,10 @@ DNSPacket *UDPNameserver::receive(DNSPacket *prefilled, std::string& buffer)
 
   struct msghdr msgh;
   struct iovec iov;
-  char cbuf[256];
+  cmsgbuf_aligned cbuf;
 
   remote.sin6.sin6_family=AF_INET6; // make sure it is big enough
-  fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), &buffer.at(0), buffer.size(), &remote);
+  fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), &buffer.at(0), buffer.size(), &remote);
   
   int err;
   vector<struct pollfd> rfds= d_rfds;
index f2306c46fbfb3a7f529a099fff721789cc8a7de5..c4ffc17ba32ad4d87b0f50436c4e3aab47d49f42 100644 (file)
@@ -1654,12 +1654,12 @@ static void startDoResolve(void *p)
     if(!dc->d_tcp) {
       struct msghdr msgh;
       struct iovec iov;
-      char cbuf[256];
-      fillMSGHdr(&msgh, &iov, cbuf, 0, (char*)&*packet.begin(), packet.size(), &dc->d_remote);
+      cmsgbuf_aligned cbuf;
+      fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)&*packet.begin(), packet.size(), &dc->d_remote);
       msgh.msg_control=NULL;
 
       if(g_fromtosockets.count(dc->d_socket)) {
-       addCMsgSrcAddr(&msgh, cbuf, &dc->d_local, 0);
+             addCMsgSrcAddr(&msgh, &cbuf, &dc->d_local, 0);
       }
       if(sendmsg(dc->d_socket, &msgh, 0) < 0 && g_logCommonErrors) 
         g_log<<Logger::Warning<<"Sending UDP reply to client "<<dc->getRemote()<<" failed with: "<<strerror(errno)<<endl;
@@ -2313,12 +2313,12 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr
       ageDNSPacket(response, age);
       struct msghdr msgh;
       struct iovec iov;
-      char cbuf[256];
-      fillMSGHdr(&msgh, &iov, cbuf, 0, (char*)response.c_str(), response.length(), const_cast<ComboAddress*>(&fromaddr));
+      cmsgbuf_aligned cbuf;
+      fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)response.c_str(), response.length(), const_cast<ComboAddress*>(&fromaddr));
       msgh.msg_control=NULL;
 
       if(g_fromtosockets.count(fd)) {
-       addCMsgSrcAddr(&msgh, cbuf, &destaddr, 0);
+        addCMsgSrcAddr(&msgh, &cbuf, &destaddr, 0);
       }
       if(sendmsg(fd, &msgh, 0) < 0 && g_logCommonErrors)
         g_log<<Logger::Warning<<"Sending UDP reply to client "<<source.toStringWithPort()<<(source != fromaddr ? " (via "+fromaddr.toStringWithPort()+")" : "")<<" failed with: "<<strerror(errno)<<endl;
@@ -2393,13 +2393,13 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
   ComboAddress fromaddr;
   struct msghdr msgh;
   struct iovec iov;
-  char cbuf[256];
+  cmsgbuf_aligned cbuf;
   bool firstQuery = true;
 
   for(size_t queriesCounter = 0; queriesCounter < s_maxUDPQueriesPerRound; queriesCounter++) {
     data.resize(maxIncomingQuerySize);
     fromaddr.sin6.sin6_family=AF_INET6; // this makes sure fromaddr is big enough
-    fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), &data[0], data.size(), &fromaddr);
+    fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), &data[0], data.size(), &fromaddr);
 
     if((len=recvmsg(fd, &msgh, 0)) >= 0) {